diff options
| author | Jim Blandy | 1992-03-16 20:39:05 +0000 |
|---|---|---|
| committer | Jim Blandy | 1992-03-16 20:39:05 +0000 |
| commit | 3b4a6e271d44955328c39de1475e42cf0b4cd637 (patch) | |
| tree | 152d376aea6e45726ac7fec7214527a800c080ca | |
| parent | 71e40adf62e72eb22cc70c68af866946d278dddf (diff) | |
| download | emacs-3b4a6e271d44955328c39de1475e42cf0b4cd637.tar.gz emacs-3b4a6e271d44955328c39de1475e42cf0b4cd637.zip | |
Initial revision
| -rw-r--r-- | lisp/emerge.el | 2979 | ||||
| -rw-r--r-- | lisp/international/iso-ascii.el | 126 | ||||
| -rw-r--r-- | lisp/international/iso-insert.el | 620 | ||||
| -rw-r--r-- | lisp/international/iso-swed.el | 140 | ||||
| -rw-r--r-- | lisp/international/swedish.el | 145 | ||||
| -rw-r--r-- | lisp/rot13.el | 41 | ||||
| -rw-r--r-- | lisp/vt100-led.el | 61 |
7 files changed, 4112 insertions, 0 deletions
diff --git a/lisp/emerge.el b/lisp/emerge.el new file mode 100644 index 00000000000..659d50afcef --- /dev/null +++ b/lisp/emerge.el | |||
| @@ -0,0 +1,2979 @@ | |||
| 1 | ;;; emerge.el version 4 | ||
| 2 | |||
| 3 | ;;; 13 Dec 1991 | ||
| 4 | |||
| 5 | ;; LCD Archive Entry: | ||
| 6 | ;; emerge|Dale R. Worley|drw@math.mit.edu | ||
| 7 | ;; |File merge documentation | ||
| 8 | ;; |91-12-13|version 4|~/packages/emerge.doc.Z | ||
| 9 | |||
| 10 | ; - Changes from version 3 to version 4 | ||
| 11 | ; | ||
| 12 | ; More configuration variables are marked as user options. | ||
| 13 | ; | ||
| 14 | ; Code is included for an improved version of make-auto-save-file-name | ||
| 15 | ; which eliminates many problems with the default version. See the | ||
| 16 | ; documentation of emerge-make-auto-save-file-name to see how to | ||
| 17 | ; activate it. | ||
| 18 | ; | ||
| 19 | ; Emerge now works with Gnu diff3, which can produce the groups of lines | ||
| 20 | ; from the various files in the order 1, 2, 3 or 1, 3, 2. | ||
| 21 | ; | ||
| 22 | ; Added x f command to show what files or buffers are being operated on. | ||
| 23 | ; | ||
| 24 | ; The merge buffer now starts read-only, which being in fast mode it | ||
| 25 | ; should be. | ||
| 26 | ; | ||
| 27 | ; When merging buffers, Emerge writes their contents into temporary | ||
| 28 | ; files in the directory $TMPDIR (if it is defined), or /tmp by default. | ||
| 29 | ; | ||
| 30 | ; Added x j command to join two differences. | ||
| 31 | ; | ||
| 32 | ; Added x s command to split a difference into two differences. | ||
| 33 | ; | ||
| 34 | ; Added emerge-version variable and function to report the version of Emerge | ||
| 35 | ; being run. | ||
| 36 | ; | ||
| 37 | ; Added x t command to trim unchanged lines off top and bottom of | ||
| 38 | ; difference region. | ||
| 39 | ; | ||
| 40 | ; Added x d, x a, and x b commands to locate the differences at or near | ||
| 41 | ; a given location in one of the buffers. | ||
| 42 | ; | ||
| 43 | ; Emerge no longer tries to copy the minor modes from the A buffer to | ||
| 44 | ; the merge buffer, only the major mode. | ||
| 45 | ; | ||
| 46 | ; The programs executed to find the differences between versions of the file | ||
| 47 | ; are no longer controlled by emerge-diff/diff3-command, but rather by: | ||
| 48 | ; emerge-diff-program | ||
| 49 | ; Variable: *Name of the program which compares two files. | ||
| 50 | ; emerge-diff3-program | ||
| 51 | ; Variable: *Name of the program which compares an ancestor file | ||
| 52 | ; (first argument) and two variant files (second and third arguments). | ||
| 53 | ; emerge-diff-options | ||
| 54 | ; Variable: *Options to be passed to emerge-diff/diff3-program. | ||
| 55 | ; | ||
| 56 | ; The names of the files are expanded (see expand-file-name) before being | ||
| 57 | ; passed to emerge-diff/diff3-program, so diff need not invoked under a shell | ||
| 58 | ; that understands '~', for instance. | ||
| 59 | ; | ||
| 60 | ; If the diff/diff3 program reports errors, the user is notified and the | ||
| 61 | ; errors are displayed. | ||
| 62 | ; | ||
| 63 | ; The command "0j" can be used to suppress the flags from showing in the buffers. | ||
| 64 | ; | ||
| 65 | ; A discussion of the effect of the merge flags on indentation of code | ||
| 66 | ; has been added to the documentation. | ||
| 67 | ; | ||
| 68 | ; If kill-fix.el is loaded, Emerge control variables new have their | ||
| 69 | ; 'preserved' property set, so setting the major mode in the merge | ||
| 70 | ; buffer doesn't destroy Emerge's state. | ||
| 71 | ; | ||
| 72 | ; Added x c, x C, and x x commands to allow the A and B versions to be | ||
| 73 | ; combined into #ifdef - #endif forms. | ||
| 74 | ; | ||
| 75 | ; Replaced calls of "ding" to calls of "error" where appropriate. | ||
| 76 | ; | ||
| 77 | ; Added x m command to allow major mode of merge buffer to be changed. | ||
| 78 | ; | ||
| 79 | ; Added x 1 command to shrink the merge window to one line. | ||
| 80 | ; | ||
| 81 | ; Added emerge-startup-hooks to allow customization. | ||
| 82 | ; | ||
| 83 | ; Fixed a bug that is activated when a remote merge request is made when | ||
| 84 | ; the minibuffer window is selected. | ||
| 85 | ; | ||
| 86 | ; - Changes from version 2 to version 3 | ||
| 87 | ; | ||
| 88 | ; The directory into which temporary files are written is now controlled | ||
| 89 | ; by a user option (emerge-temp-file-prefix). | ||
| 90 | ; | ||
| 91 | ; The A and B versions of the difference can be loaded into the kill | ||
| 92 | ; ring with the "c a" and "c b" commands. | ||
| 93 | ; | ||
| 94 | ; The A and B versions of the difference can be inserted into the merge | ||
| 95 | ; buffer with the "i a" and "i b" commands. | ||
| 96 | ; | ||
| 97 | ; The difference region of the merge buffer can be surrounded by the | ||
| 98 | ; point and mark with the "m" command. | ||
| 99 | ; | ||
| 100 | ; The three windows can be scrolled together with the "^", "v", "<", | ||
| 101 | ; ">", and "|" commands. | ||
| 102 | ; | ||
| 103 | ; The "s s" and "s a" commands report the state of the option in the | ||
| 104 | ; echo area. Similarly, the "f" and "e" commands report what they do in | ||
| 105 | ; the echo area. | ||
| 106 | ; | ||
| 107 | ; The "q" command has been revamped, and its behavior is now controlled | ||
| 108 | ; by the manner in which Emerge is started. In particular, if you wish | ||
| 109 | ; to write the merge buffer into a file upon exiting, invoke | ||
| 110 | ; emerge-files[-with-ancestor] with a prefix argument, and it will | ||
| 111 | ; prompt you for the file name. Then exiting will write the merge | ||
| 112 | ; buffer to the file, unless "q" is given a prefix argument. | ||
| 113 | ; | ||
| 114 | ; The "i a" and "i b" commands now work in fast mode. | ||
| 115 | ; | ||
| 116 | ; The modifications that Emerge makes to save-buffer and write-file are | ||
| 117 | ; described. | ||
| 118 | ; | ||
| 119 | ; Emerge now handles merging narrowed buffers correctly. | ||
| 120 | ; | ||
| 121 | ; Emerge now isn't fooled when the buffer visiting a file is not the | ||
| 122 | ; same as the file on disk. | ||
| 123 | ; | ||
| 124 | ; - Starting | ||
| 125 | ; | ||
| 126 | ; To start Emerge, you must run one of four commands: | ||
| 127 | ; | ||
| 128 | ; emerge-files | ||
| 129 | ; emerge-files-with-ancestor | ||
| 130 | ; emerge-buffers | ||
| 131 | ; emerge-buffers-with-ancestor | ||
| 132 | ; | ||
| 133 | ; The "files" versions prompt you for two file names (the "A" and "B" | ||
| 134 | ; files), the "buffers" versions prompt you for two buffer names (the | ||
| 135 | ; "A" and "B" buffers). Emerge then runs a "diff" of the two entities | ||
| 136 | ; (emerge-buffers writes the buffers into temporary files for input to | ||
| 137 | ; diff) and digests the output to form a list of the differences between | ||
| 138 | ; the two files. Then three buffers are set up: two containing the | ||
| 139 | ; entities (emerge-files does a find-file (C-x C-f) on the files to get | ||
| 140 | ; them into buffers), and one, the "merge buffer", which contains the | ||
| 141 | ; working copy of the merged file that you are constructing. The three | ||
| 142 | ; buffers are put up in a nice three-window display, showing the A and B | ||
| 143 | ; buffers in the upper half and the merge buffer in the lower half. | ||
| 144 | ; | ||
| 145 | ; The versions of the command that say "with-ancestor" ask for a third | ||
| 146 | ; name, that of an entity which is a common ancestor from which the | ||
| 147 | ; versions being merged were derived. These commands use "diff3" to | ||
| 148 | ; compare all three versions. If one version of a difference agrees | ||
| 149 | ; with the ancestor, then it is presumed that the other version is the | ||
| 150 | ; "correct" version, and is said to be "preferred". | ||
| 151 | ; | ||
| 152 | ; (Note that if you use emerge-files, Emerge attempts to make sure that | ||
| 153 | ; file on disk and the file in the buffer are the same. If the file on | ||
| 154 | ; disk has been changed, Emerge offers to revert the buffer. If the | ||
| 155 | ; buffer has been modified, Emerge offers to save the buffer. If the | ||
| 156 | ; user declines the offer, or if the file on disk and the buffer have | ||
| 157 | ; both been modified, Emerge aborts with an error message. Emerge is | ||
| 158 | ; careful to widen the buffers containing the files if they have been | ||
| 159 | ; narrowed. If you use emerge-buffers, the buffers are not widened -- | ||
| 160 | ; only the visible portion is used.) | ||
| 161 | ; | ||
| 162 | ; During the merge, the A and B buffers are read-only, so you don't | ||
| 163 | ; damage them. (This is because the A and B versions of the differences | ||
| 164 | ; are extracted from these buffers.) When you quit the merge, the | ||
| 165 | ; read-only/read-write status and modified flag on the A and B buffers | ||
| 166 | ; are restored. In addition, auto-saving of the A and B buffers is | ||
| 167 | ; suppressed during the merge. This is because Emerge modifies the A | ||
| 168 | ; and B buffers to point out the text of the differences, and it would | ||
| 169 | ; be useless to save these changes. (Just before suppressing | ||
| 170 | ; auto-saving, Emerge forces an auto-save.) | ||
| 171 | ; | ||
| 172 | ; If you give a prefix argument to emerge-files or | ||
| 173 | ; emerge-files-with-ancestor, it prompts you for another file name, | ||
| 174 | ; which is the file into which the merged file is to be written when you | ||
| 175 | ; exit Emerge. The output file name defaults to the A file name. If | ||
| 176 | ; you successfully quit Emerge, the merge buffer will be written to the | ||
| 177 | ; output file, and the buffers for the A, B, and ancestor buffers will | ||
| 178 | ; be deleted (if they exist and are not modified). If you abort Emerge, | ||
| 179 | ; the merge buffer will not be written and the buffers will not be | ||
| 180 | ; deleted. | ||
| 181 | ; | ||
| 182 | ; You can have any number of merges going at once -- just don't use any | ||
| 183 | ; one buffer as input to more than one merge at once, since that will | ||
| 184 | ; cause the read-only/modified/auto-save status save-and-restore to | ||
| 185 | ; screw up. | ||
| 186 | ; | ||
| 187 | ; Beware that when Emerge starts up, it does a diff or diff3 of the | ||
| 188 | ; files, which can take many minutes for long files with many | ||
| 189 | ; differences. Emacs can't do anything else until diff finishes. | ||
| 190 | ; | ||
| 191 | ; If diff or diff3 produces error messages, Emerge will beep and display | ||
| 192 | ; the error messages instead of the merge buffer. There will be a | ||
| 193 | ; message in the echo area giving the name of the merge buffer. Note | ||
| 194 | ; that this is really just an informational message -- you still have | ||
| 195 | ; switch to the merge buffer and abort the merge to restore the | ||
| 196 | ; conditions before you ran Emerge. (Emerge considers any output line | ||
| 197 | ; that does not match the regexp emerge-diff/diff3-ok-lines to be an | ||
| 198 | ; error message.) | ||
| 199 | ; | ||
| 200 | ; After the merge has been set up, Emerge runs the hooks in | ||
| 201 | ; emerge-startup-hooks. | ||
| 202 | ; | ||
| 203 | ; - Merging | ||
| 204 | ; | ||
| 205 | ; Once you have started the merge, you manipulate the merge buffer with | ||
| 206 | ; special commands issued in the merge buffer. You may also edit the | ||
| 207 | ; buffer with ordinary Emacs commands. Emerge keeps track of each | ||
| 208 | ; difference between the A and B buffers and the corresponding section | ||
| 209 | ; of the merge buffer. Initially, all differences show the A version, | ||
| 210 | ; except those for which B is preferred (because A agrees with the | ||
| 211 | ; ancestor), which show the B version. Emerge always has its attention | ||
| 212 | ; focused on one particular difference, which is marked off in the three | ||
| 213 | ; buffers by "vvvvvvvvvvvvvvvvvvvv" above and "^^^^^^^^^^^^^^^^^^^^" | ||
| 214 | ; below. The number of the difference is shown in the mode line. | ||
| 215 | ; | ||
| 216 | ; A merge buffer can be in two modes: "fast" mode and "edit" mode. In | ||
| 217 | ; fast mode, emerge commands are single characters, and ordinary Emacs | ||
| 218 | ; commands are disabled. This makes Emerge operations fast, but | ||
| 219 | ; prevents you from doing more than selecing the A or the B version of | ||
| 220 | ; differences. In edit mode, all emerge commands must be prefixed with | ||
| 221 | ; C-c, and all (non-conflicting) Emacs commands are available. This | ||
| 222 | ; allows editing the merge buffer, but slows down Emerge operations. | ||
| 223 | ; Edit and fast modes are indicated by "F" and "E" in the minor modes in | ||
| 224 | ; the mode line. | ||
| 225 | ; | ||
| 226 | ; The Emerge commands are: | ||
| 227 | ; | ||
| 228 | ; p go to the previous difference | ||
| 229 | ; n go to the next difference | ||
| 230 | ; a select the A version of this difference | ||
| 231 | ; b select the B version of this difference | ||
| 232 | ; j go to a particular difference (prefix argument | ||
| 233 | ; specifies which difference) (0j suppresses display of | ||
| 234 | ; the flags) | ||
| 235 | ; q quit - finish the merge* | ||
| 236 | ; f go into fast mode | ||
| 237 | ; e go into edit mode | ||
| 238 | ; s a set/clear auto-advance mode* | ||
| 239 | ; s s set/clear skip-prefers mode* | ||
| 240 | ; l recenter (C-l) all three windows* | ||
| 241 | ; - and 0 through 9 | ||
| 242 | ; prefix numeric arguments | ||
| 243 | ; d a select the A version as the default from here down in | ||
| 244 | ; the merge buffer* | ||
| 245 | ; d b select the B version as the default from here down in | ||
| 246 | ; the merge buffer* | ||
| 247 | ; c a copy the A version of the difference into the kill | ||
| 248 | ; ring | ||
| 249 | ; c b copy the B version of the difference into the kill | ||
| 250 | ; ring | ||
| 251 | ; i a insert the A version of the difference at the point | ||
| 252 | ; i b insert the B version of the difference at the point | ||
| 253 | ; m put the point and mark around the difference region | ||
| 254 | ; ^ scroll-down (like M-v) the three windows* | ||
| 255 | ; v scroll-up (like C-v) the three windows* | ||
| 256 | ; < scroll-left (like C-x <) the three windows* | ||
| 257 | ; > scroll-right (like C-x >) the three windows* | ||
| 258 | ; | reset horizontal scroll on the three windows* | ||
| 259 | ; x 1 shrink the merge window to one line (use C-u l to restore it | ||
| 260 | ; to full size) | ||
| 261 | ; x a find the difference containing a location in the A buffer* | ||
| 262 | ; x b find the difference containing a location in the B buffer* | ||
| 263 | ; x c combine the two versions of this difference* | ||
| 264 | ; x C combine the two versions of this difference, using a | ||
| 265 | ; register's value as the template* | ||
| 266 | ; x d find the difference containing a location in the merge buffer* | ||
| 267 | ; x f show the files/buffers Emerge is operating on in Help window | ||
| 268 | ; (use C-u l to restore windows) | ||
| 269 | ; x j join this difference with the following one | ||
| 270 | ; (C-u x j joins this difference with the previous one) | ||
| 271 | ; x l show line numbers of points in A, B, and merge buffers | ||
| 272 | ; x m change major mode of merge buffer* | ||
| 273 | ; x s split this difference into two differences | ||
| 274 | ; (first position the point in all three buffers to the places | ||
| 275 | ; to split the difference) | ||
| 276 | ; x t trim identical lines off top and bottom of difference | ||
| 277 | ; (such lines occur when the A and B versions are | ||
| 278 | ; identical but differ from the ancestor version) | ||
| 279 | ; x x set the template for the x c command* | ||
| 280 | ; | ||
| 281 | ; * - more details on these commands are given below | ||
| 282 | ; | ||
| 283 | ; emerge-version is a variable giving the version number of Emerge. It | ||
| 284 | ; is also a function which displays emerge-version (when called | ||
| 285 | ; interactively) or returns it (when called from a program). | ||
| 286 | ; | ||
| 287 | ; - Differences and their states | ||
| 288 | ; | ||
| 289 | ; A difference can have one of seven states: | ||
| 290 | ; | ||
| 291 | ; A: the difference is showing the A version. | ||
| 292 | ; | ||
| 293 | ; B: the difference is showing the B version. | ||
| 294 | ; | ||
| 295 | ; default-A and default-B: the difference is showing the A or B state, | ||
| 296 | ; but has never been selected by the user. All differences start in the | ||
| 297 | ; default-A state (and thus the merge buffer is a copy of the A buffer), | ||
| 298 | ; except those for which one buffer or another is preferred. When the | ||
| 299 | ; user selects the difference, it changes to the A or B state. | ||
| 300 | ; | ||
| 301 | ; prefer-A and prefer-B: the difference is showing the A or B state. In | ||
| 302 | ; addition, the other buffer (that is, for prefer-A, the B buffer; for | ||
| 303 | ; prefer-B, the A buffer) agrees with the ancestor buffer. Thus, | ||
| 304 | ; presumably, the displayed version is the correct one. The "a" and "b" | ||
| 305 | ; commands override these states, and turn them into the A and B states. | ||
| 306 | ; | ||
| 307 | ; combined: the difference is showing a combination of the A and B | ||
| 308 | ; states that was constructed by the "x c" or "x C" commands. Since | ||
| 309 | ; this state is neither the A or B states, the "a" and "b" commands | ||
| 310 | ; won't alter the difference unless they are given a prefix argument. | ||
| 311 | ; | ||
| 312 | ; The state of the currently selected difference is shown in the mode | ||
| 313 | ; line of the merge window: | ||
| 314 | ; | ||
| 315 | ; state display | ||
| 316 | ; | ||
| 317 | ; A A | ||
| 318 | ; B B | ||
| 319 | ; prefer-A A* | ||
| 320 | ; prefer-B B* | ||
| 321 | ; combined comb | ||
| 322 | ; | ||
| 323 | ; - Select default commands (d a and d b) | ||
| 324 | ; | ||
| 325 | ; The d a and d b commands change all default-A's to default-B's (or | ||
| 326 | ; vice-versa) from the selected difference on down to the end of the | ||
| 327 | ; file to default-A or default-B, respectively. (Since a difference | ||
| 328 | ; that has been selected can not have state default-A or default-B, it | ||
| 329 | ; will never be affected by d a or d b. This leads to the unexpected | ||
| 330 | ; result that d a or d b never affects the difference selected at the | ||
| 331 | ; moment, but prevents differences that you have already looked at from | ||
| 332 | ; changing unexpectedly.) | ||
| 333 | ; | ||
| 334 | ; If you work your way down from the top of the file, using d a and d b | ||
| 335 | ; at judicious points, you can effectivly make the A version the default | ||
| 336 | ; for some sections of the merge buffer and the B version the default | ||
| 337 | ; for others. | ||
| 338 | ; | ||
| 339 | ; - Exiting (q) | ||
| 340 | ; | ||
| 341 | ; The quit command finishes the merge session by restoring the state of | ||
| 342 | ; the A and B buffers and removing the markers around the currently | ||
| 343 | ; selected difference. It also disables the Emerge commands in the | ||
| 344 | ; merge buffer, since executing them later could damage the contents of | ||
| 345 | ; the various buffers. | ||
| 346 | ; | ||
| 347 | ; The action of "q" depends on how Emerge was started and whether "q" | ||
| 348 | ; was given a prefix argument. If there was no prefix argument, it is | ||
| 349 | ; considered a "successful" finish. If there was a prefix argument, it | ||
| 350 | ; is considered an "unsuccessful" finish. In either case, you are asked | ||
| 351 | ; to cofirm the exit, and the confirmation message tells which sort of | ||
| 352 | ; exit you are confirming. | ||
| 353 | ; | ||
| 354 | ; If Emerge was started by some other process, success/failure is | ||
| 355 | ; reported to the caller. | ||
| 356 | ; | ||
| 357 | ; If Emerge was started with emerge-files or emerge-files-with-ancestor, | ||
| 358 | ; if a prefix argument was given to that command, then you specified a | ||
| 359 | ; file into which the merge is to be written. A successful exit writes | ||
| 360 | ; the merge into the output file and then kills the A, B, and ancestor | ||
| 361 | ; buffers (so they aren't lying around to confuse you, since they | ||
| 362 | ; probably all have similar names). | ||
| 363 | ; | ||
| 364 | ; - Auto-advance mode (s a) | ||
| 365 | ; | ||
| 366 | ; If auto-advance mode is set, the "a" and "b" commands perform an "n" | ||
| 367 | ; (select next difference) afterward. When auto-advance mode is set, | ||
| 368 | ; it is indicated by "A" in the minor modes in the mode line. | ||
| 369 | ; "s a" with a positive argument sets auto-advance, with a non-positive | ||
| 370 | ; argument clears it, and with no argument toggles it. | ||
| 371 | ; | ||
| 372 | ; - Skip-prefers mode (s s) | ||
| 373 | ; | ||
| 374 | ; If skip-prefers mode is set, the "n" and "p" commands skip over | ||
| 375 | ; differences with states prefer-A and prefer-B. Thus you will only see | ||
| 376 | ; differences for which one version isn't presumed "correct". When | ||
| 377 | ; skip-prefers mode is set, it is indicated by "S" in the minor modes in | ||
| 378 | ; the mode line. "s s" with a positive argument sets auto-advance, with | ||
| 379 | ; a non-positive argument clears it, and with no argument toggles it. | ||
| 380 | ; | ||
| 381 | ; - Recenter (l) | ||
| 382 | ; | ||
| 383 | ; The Emerge "l" command causes the selected difference to be brought | ||
| 384 | ; into view in the three windows, or at least, whichever of the three | ||
| 385 | ; merge buffers are visible at the moment. If a prefix argument is | ||
| 386 | ; given, then the original three-window display is set up before the | ||
| 387 | ; difference texts are shown. | ||
| 388 | ; | ||
| 389 | ; - Scrolling the text (^, v, <, >, and |) | ||
| 390 | ; | ||
| 391 | ; Emerge has several commands which scroll all three windows by the same | ||
| 392 | ; amount, thus allowing you to easily compare the versions of the text. | ||
| 393 | ; The commands are "^" (scroll-up), "v" (scroll-down), "<" | ||
| 394 | ; (scroll-left), ">" (scroll-right), and "|" (reset horizontal | ||
| 395 | ; scrolling). (Remember that Emacs names scrolling commands by the | ||
| 396 | ; motion of the text with respect to the window, so C-v is called | ||
| 397 | ; "scroll-up".) | ||
| 398 | ; | ||
| 399 | ; If these commands (except "|") are given an argument, that is the | ||
| 400 | ; number of lines or characters by which the windows are scrolled. | ||
| 401 | ; Otherwise, the amount of motion is computed based on the dimensions of | ||
| 402 | ; the merge buffer window -- the height of the merge buffer window | ||
| 403 | ; (minus next-screen-context-lines), or half the width of the merge | ||
| 404 | ; buffer window. (The A and B version windows are assumed to be as high | ||
| 405 | ; as the merge window, but half as wide.) If the argument is just `C-u | ||
| 406 | ; -', then the scrolling is half the default amount. | ||
| 407 | ; | ||
| 408 | ; - Finding the difference at or near a location (x d, x a, and x b) | ||
| 409 | ; | ||
| 410 | ; The "x d" command selects the difference containing the current point | ||
| 411 | ; in the merge buffer. If there is no difference containing the point, | ||
| 412 | ; an error is given. An argument can be given to the command to change | ||
| 413 | ; this behavior: if the argument is positive (e.g., C-u), the next | ||
| 414 | ; following difference is selected; if the argument is negative (e.g., | ||
| 415 | ; C-u -), the previous difference is selected. | ||
| 416 | ; | ||
| 417 | ; The "x a" and "x b" commands select the difference containing the | ||
| 418 | ; current point in the A and B buffers, respectively. Otherwise, they | ||
| 419 | ; act like the "x d" command. Note that although the point used in the | ||
| 420 | ; commands is not the merge buffer point, the commands can only be | ||
| 421 | ; issued in the merge buffer, because it is the only buffer with the | ||
| 422 | ; Emerge keymap. | ||
| 423 | ; | ||
| 424 | ; - Combining the two versions (x c, x C, and x x) | ||
| 425 | ; | ||
| 426 | ; Sometimes one wants to combine the two versions of a difference. For | ||
| 427 | ; instance, when merging two versions of a program, one wants to make | ||
| 428 | ; something like this: | ||
| 429 | ; | ||
| 430 | ; #ifdef NEW | ||
| 431 | ; ...new version of code... | ||
| 432 | ; #else /* NEW */ | ||
| 433 | ; ...old version of code... | ||
| 434 | ; #endif /* NEW */ | ||
| 435 | ; | ||
| 436 | ; The "x c" command will make such a combined version. (Note that any | ||
| 437 | ; combined version is not the same as either the A or B versions, and so | ||
| 438 | ; the "a" and "b" commands will refuse to alter it unless they are given | ||
| 439 | ; a prefix argument.) The combination is made under control of a | ||
| 440 | ; template, which is a character string with the following | ||
| 441 | ; interpolations: | ||
| 442 | ; | ||
| 443 | ; %a the A version of the difference | ||
| 444 | ; %b the B version of the difference | ||
| 445 | ; %% the character '%' | ||
| 446 | ; | ||
| 447 | ; Thus, the template used above is | ||
| 448 | ; | ||
| 449 | ; #ifdef NEW\n%b#else /* NEW */\n%a#endif /* NEW */\n | ||
| 450 | ; | ||
| 451 | ; (using \n here to represent newlines). The template is stored in the | ||
| 452 | ; variable emerge-combine-versions-template, and its initial value is | ||
| 453 | ; the one given above. The template can be set (from the current | ||
| 454 | ; region) by the "x x" command. (Be careful to get the newlines in the | ||
| 455 | ; template in the right places!) ("x x" was chosen by analogy with "C-x | ||
| 456 | ; x".) ("x x" is only available in the merge buffer, of course. | ||
| 457 | ; Elsewhere, M-x emerge-set-combine-versions-template can be used.) If | ||
| 458 | ; "x x" is given a prefix argument, emerge-combine-versions-template is | ||
| 459 | ; localized in the merge buffer before its value is set, so the "x x" | ||
| 460 | ; command's effect (and the effect of any later "x x" command in the | ||
| 461 | ; merge buffer) is only on the merge buffer. | ||
| 462 | ; | ||
| 463 | ; The "x C" command is like "x c", but it prompts for a character | ||
| 464 | ; which is the register whose value is to be used as the template. | ||
| 465 | ; This allows one to use multiple templates conveniently. | ||
| 466 | ; | ||
| 467 | ; - Changing the major mode of the edit buffer (x m) | ||
| 468 | ; | ||
| 469 | ; The "x m" command prompts for the name of a major-mode-setting command | ||
| 470 | ; and executes it. Ordinarily, major-mode-setting commands change the | ||
| 471 | ; mode line and local keymap, so the "x m" command then resets the | ||
| 472 | ; Emerge mode line and the fast or edit mode local keymap, as | ||
| 473 | ; appropriate. | ||
| 474 | ; | ||
| 475 | ; If you have already changed the major mode of the merge buffer and | ||
| 476 | ; lost the Emerge keymap, you can use M-x emerge-set-merge-mode to | ||
| 477 | ; execute this command. | ||
| 478 | ; | ||
| 479 | ; Beware that "x m" accepts any command name, not just | ||
| 480 | ; major-mode-setting commands. | ||
| 481 | ; | ||
| 482 | ; - Writing the merge buffer manually | ||
| 483 | ; | ||
| 484 | ; Emerge places a wrapper (emerge-query-and-call) on the key bindings of | ||
| 485 | ; save-buffer (usually "C-x C-s") and write-file (usually "C-x C-w"), in | ||
| 486 | ; order to protect the user from writing out the merge before it is | ||
| 487 | ; finished. Emerge-query-and-call asks the user if he is sure he wants | ||
| 488 | ; to write out the incomplete merge. If he answers yes, the buffer is | ||
| 489 | ; written out. The flags are suppressed while the write is being done. | ||
| 490 | ; As a result of this, the displayed portions of the buffers are | ||
| 491 | ; recentered (equivalent to "l"). | ||
| 492 | ; | ||
| 493 | ; - Running Emerge standalone | ||
| 494 | ; | ||
| 495 | ; If you invoke emacs with the following arguments, you can execute | ||
| 496 | ; Emerge as a standalone program: | ||
| 497 | ; | ||
| 498 | ; emacs -l emerge -f emerge-files-command file-a file-b file-out | ||
| 499 | ; | ||
| 500 | ; emacs -l emerge -f emerge-files-with-ancestor-command | ||
| 501 | ; file-a file-b file-ancestor file-out | ||
| 502 | ; | ||
| 503 | ; When the user gives the "q" (quit) command, Emerge will write out the | ||
| 504 | ; merge buffer in file-out and terminate Emacs. If a prefix argument is | ||
| 505 | ; given, Emacs will terminate with an unsuccessful return code (1), if | ||
| 506 | ; not, it will terminate with a successful return code (0). | ||
| 507 | ; | ||
| 508 | ; - Invoking Emerge remotely | ||
| 509 | ; | ||
| 510 | ; If you use the Emacs client/server code that supports remote | ||
| 511 | ; execution, then you can invoke Emerge remotely by executing one of the | ||
| 512 | ; Lisp calls: | ||
| 513 | ; | ||
| 514 | ; (emerge-files-remote "file A" "file B" "output file") | ||
| 515 | ; | ||
| 516 | ; (emerge-files-with-ancestor-remote "file A" "file B" | ||
| 517 | ; "ancestor file" "output file") | ||
| 518 | ; | ||
| 519 | ; Returning a successful/unsuccessful return code is not yet supported | ||
| 520 | ; by the Emacs client/server code. | ||
| 521 | ; | ||
| 522 | ; Beware that in systems of networked workstations, even though all user | ||
| 523 | ; directories are shared between all the workstations, the /tmp | ||
| 524 | ; directory on each workstation is not shared, so writing files into | ||
| 525 | ; /tmp and then remotely invoking Emerge is not likely to work. | ||
| 526 | ; | ||
| 527 | ; - Effect of merge flags on indenting code | ||
| 528 | ; | ||
| 529 | ; The presence of the flags confuses the indentation code of C and | ||
| 530 | ; Emacs-Lisp modes. Starting the flag strings | ||
| 531 | ; (emerge-{before,after}-flag) with '#' (for C) or ';' (for Lisp) | ||
| 532 | ; prevents the indentation code from noticing the flags. Remember to | ||
| 533 | ; change the flag strings before loading Emerge, or to execute | ||
| 534 | ; emerge-new-flags after changing them. But never change the flag | ||
| 535 | ; strings while a merge is being performed. | ||
| 536 | ; | ||
| 537 | ; - Autoloading | ||
| 538 | ; | ||
| 539 | ; The following autoloads will make all top-level Emerge files | ||
| 540 | ; autoloading. Make sure that "emerge" is in a directory on load-path. | ||
| 541 | ; | ||
| 542 | ; (autoload 'emerge-files "emerge" | ||
| 543 | ; "Run Emerge on two files." | ||
| 544 | ; t) | ||
| 545 | ; (autoload 'emerge-files-with-ancestor "emerge" | ||
| 546 | ; "Run Emerge on two files, giving another file as the ancestor." | ||
| 547 | ; t) | ||
| 548 | ; (autoload 'emerge-buffers "emerge" | ||
| 549 | ; "Run Emerge on two buffers." | ||
| 550 | ; t) | ||
| 551 | ; (autoload 'emerge-buffers-with-ancestor "emerge" | ||
| 552 | ; "Run Emerge on two buffers, giving another buffer as the ancestor." | ||
| 553 | ; t) | ||
| 554 | ; (autoload 'emerge-files-command "emerge") | ||
| 555 | ; (autoload 'emerge-files-with-ancestor-command "emerge") | ||
| 556 | ; (autoload 'emerge-files-remote "emerge") | ||
| 557 | ; (autoload 'emerge-files-with-ancestor-remote "emerge") | ||
| 558 | ; | ||
| 559 | ; ================================================================ | ||
| 560 | |||
| 561 | ;; Declare that we've got the subsystem loaded | ||
| 562 | ;; LCD Archive Entry: | ||
| 563 | ;; emerge|Dale R. Worley|drw@math.mit.edu | ||
| 564 | ;; |File merge | ||
| 565 | ;; |91-12-13|version 4|~/packages/emerge.el.Z | ||
| 566 | |||
| 567 | ;;; Macros | ||
| 568 | |||
| 569 | (defmacro emerge-eval-in-buffer (buffer &rest forms) | ||
| 570 | "Macro to switch to BUFFER, evaluate FORMS, returns to original buffer. | ||
| 571 | Differs from save-excursion in that it doesn't save the point and mark." | ||
| 572 | (` (let ((StartBuffer (current-buffer))) | ||
| 573 | (unwind-protect | ||
| 574 | (progn | ||
| 575 | (set-buffer (, buffer)) | ||
| 576 | (,@ forms)) | ||
| 577 | (set-buffer StartBuffer))))) | ||
| 578 | |||
| 579 | (defmacro emerge-defvar-local (var value doc) | ||
| 580 | "Defines SYMBOL as an advertised variable. Performs a defvar, then | ||
| 581 | executes make-variable-buffer-local on the variable. Also sets the | ||
| 582 | 'preserved' property, so that kill-all-local-variables (called by major-mode | ||
| 583 | setting commands) won't destroy Emerge control variables." | ||
| 584 | (` (progn | ||
| 585 | (defvar (, var) (, value) (, doc)) | ||
| 586 | (make-variable-buffer-local '(, var)) | ||
| 587 | (put '(, var) 'preserved t)))) | ||
| 588 | |||
| 589 | ;; Add entries to minor-mode-alist so that emerge modes show correctly | ||
| 590 | (setq emerge-minor-modes-list '((emerge-mode " Emerge") | ||
| 591 | (emerge-fast-mode " F") | ||
| 592 | (emerge-edit-mode " E") | ||
| 593 | (emerge-auto-advance " A") | ||
| 594 | (emerge-skip-prefers " S"))) | ||
| 595 | (if (not (assq 'emerge-mode minor-mode-alist)) | ||
| 596 | (setq minor-mode-alist (append emerge-minor-modes-list | ||
| 597 | minor-mode-alist))) | ||
| 598 | |||
| 599 | ;; We need to define this function so describe-mode can describe Emerge mode. | ||
| 600 | (defun emerge-mode () | ||
| 601 | "Emerge mode is used by the Emerge file-merging package. It is entered only | ||
| 602 | through one of the functions: | ||
| 603 | emerge-files | ||
| 604 | emerge-files-with-ancestor | ||
| 605 | emerge-buffers | ||
| 606 | emerge-buffers-with-ancestor | ||
| 607 | emerge-files-command | ||
| 608 | emerge-files-with-ancestor-command | ||
| 609 | emerge-files-remote | ||
| 610 | emerge-files-with-ancestor-remote | ||
| 611 | |||
| 612 | Commands: | ||
| 613 | \\{emerge-basic-keymap} | ||
| 614 | Commands must be prefixed by \\<emerge-fast-keymap>\\[emerge-basic-keymap] in 'edit' mode, but can be invoked directly | ||
| 615 | in 'fast' mode.") | ||
| 616 | |||
| 617 | (defvar emerge-version "4" | ||
| 618 | "The version of Emerge.") | ||
| 619 | |||
| 620 | (defun emerge-version () | ||
| 621 | "Return string describing the version of Emerge. When called interactively, | ||
| 622 | displays the version." | ||
| 623 | (interactive) | ||
| 624 | (if (interactive-p) | ||
| 625 | (message "Emerge version %s" (emerge-version)) | ||
| 626 | emerge-version)) | ||
| 627 | |||
| 628 | ;;; Emerge configuration variables | ||
| 629 | |||
| 630 | ;; Commands that produce difference files | ||
| 631 | ;; All that can be configured is the name of the programs to execute | ||
| 632 | ;; (emerge-diff-program and emerge-diff3-program) and the options | ||
| 633 | ;; to be provided (emerge-diff-options). The order in which the file names | ||
| 634 | ;; are given is fixed. | ||
| 635 | ;; The file names are always expanded (see expand-file-name) before being | ||
| 636 | ;; passed to diff, thus they need not be invoked under a shell that | ||
| 637 | ;; understands '~'. | ||
| 638 | ;; The code which processes the diff/diff3 output depends on all the | ||
| 639 | ;; finicky details of their output, including the somewhat strange | ||
| 640 | ;; way they number lines of a file. | ||
| 641 | (defvar emerge-diff-program "diff" | ||
| 642 | "*Name of the program which compares two files.") | ||
| 643 | (defvar emerge-diff3-program "diff3" | ||
| 644 | "*Name of the program which compares an ancestor file (first argument) | ||
| 645 | and two variant files (second and third arguments).") | ||
| 646 | (defvar emerge-diff-options "" | ||
| 647 | "*Options to be passed to emerge-diff/diff3-program.") | ||
| 648 | (defvar emerge-match-diff-line (let ((x "\\([0-9]+\\)\\(\\|,\\([0-9]+\\)\\)")) | ||
| 649 | (concat "^" x "\\([acd]\\)" x "$")) | ||
| 650 | "*Pattern to match lines produced by diff that describe differences (as | ||
| 651 | opposed to lines from the source files).") | ||
| 652 | (defvar emerge-diff-ok-lines | ||
| 653 | "^\\([0-9,]+[acd][0-9,]+$\\|[<>] \\|---\\)" | ||
| 654 | "*Regexp that matches normal output lines from emerge-diff-program . | ||
| 655 | Lines that do not match are assumed to be error output.") | ||
| 656 | (defvar emerge-diff3-ok-lines | ||
| 657 | "^\\([1-3]:\\|====\\| \\)" | ||
| 658 | "*Regexp that matches normal output lines from emerge-diff3-program . | ||
| 659 | Lines that do not match are assumed to be error output.") | ||
| 660 | |||
| 661 | ;; The flags used to mark differences in the buffers. | ||
| 662 | |||
| 663 | ;; These function definitions need to be up here, because they are used | ||
| 664 | ;; during loading. | ||
| 665 | (defun emerge-new-flags () | ||
| 666 | "Function to be called after emerge-{before,after}-flag are changed to | ||
| 667 | compute values that depend on the flags." | ||
| 668 | (setq emerge-before-flag-length (length emerge-before-flag)) | ||
| 669 | (setq emerge-before-flag-lines | ||
| 670 | (count-matches-string emerge-before-flag "\n")) | ||
| 671 | (setq emerge-before-flag-match (regexp-quote emerge-before-flag)) | ||
| 672 | (setq emerge-after-flag-length (length emerge-after-flag)) | ||
| 673 | (setq emerge-after-flag-lines | ||
| 674 | (count-matches-string emerge-after-flag "\n")) | ||
| 675 | (setq emerge-after-flag-match (regexp-quote emerge-after-flag))) | ||
| 676 | (defun count-matches-string (string regexp) | ||
| 677 | "Return the number of matches in STRING for REGEXP." | ||
| 678 | (let ((i 0) | ||
| 679 | (count 0)) | ||
| 680 | (while (string-match regexp string i) | ||
| 681 | (setq count (1+ count)) | ||
| 682 | (setq i (match-end 0))) | ||
| 683 | count)) | ||
| 684 | |||
| 685 | (defvar emerge-before-flag "vvvvvvvvvvvvvvvvvvvv\n" | ||
| 686 | "*Flag placed above the highlighted block of code. Must end with newline. | ||
| 687 | Must be set before Emerge is loaded, or emerge-new-flags must be run | ||
| 688 | after setting.") | ||
| 689 | (defvar emerge-after-flag "^^^^^^^^^^^^^^^^^^^^\n" | ||
| 690 | "*Flag placed below the highlighted block of code. Must end with newline. | ||
| 691 | Must be set before Emerge is loaded, or emerge-new-flags must be run | ||
| 692 | after setting.") | ||
| 693 | |||
| 694 | ;; Calculate dependent variables | ||
| 695 | (emerge-new-flags) | ||
| 696 | |||
| 697 | (defvar emerge-min-visible-lines 3 | ||
| 698 | "*Number of lines that we want to show above and below the flags when we are | ||
| 699 | displaying a difference.") | ||
| 700 | |||
| 701 | (defvar emerge-temp-file-prefix | ||
| 702 | (let ((env (getenv "TMPDIR")) | ||
| 703 | d) | ||
| 704 | (setq d (if (and env (> (length env) 0)) | ||
| 705 | env | ||
| 706 | "/tmp")) | ||
| 707 | (if (= (aref d (1- (length d))) ?/) | ||
| 708 | (setq d (substring d 0 -1))) | ||
| 709 | (concat d "/emerge")) | ||
| 710 | "*Prefix to put on Emerge temporary file names. | ||
| 711 | Do not start with '~/' or '~user-name/'.") | ||
| 712 | |||
| 713 | (defvar emerge-temp-file-mode 384 ; u=rw only | ||
| 714 | "*Mode for Emerge temporary files.") | ||
| 715 | |||
| 716 | (defvar emerge-combine-versions-template | ||
| 717 | "#ifdef NEW\n%b#else /* NEW */\n%a#endif /* NEW */\n" | ||
| 718 | "*Template for emerge-combine-versions to combine the two versions. | ||
| 719 | The template is inserted as a string, with the following interpolations: | ||
| 720 | %a the A version of the difference | ||
| 721 | %b the B version of the difference | ||
| 722 | %% the character '%' | ||
| 723 | Don't forget to end the template with a newline. | ||
| 724 | Note that this variable can be made local to a particular merge buffer by | ||
| 725 | giving a prefix argument to emerge-set-combine-versions-template .") | ||
| 726 | |||
| 727 | ;; Build keymaps | ||
| 728 | |||
| 729 | (defvar emerge-basic-keymap nil | ||
| 730 | "Keymap of Emerge commands. | ||
| 731 | Directly available in 'fast' mode; | ||
| 732 | must be prefixed by \\<emerge-fast-keymap>\\[emerge-basic-keymap] in 'edit' mode.") | ||
| 733 | |||
| 734 | (defvar emerge-fast-keymap nil | ||
| 735 | "Local keymap used in Emerge 'fast' mode. | ||
| 736 | Makes Emerge commands directly available.") | ||
| 737 | |||
| 738 | (defvar emerge-command-prefix "\C-c" | ||
| 739 | "*Command prefix for Emerge commands in 'edit' mode. | ||
| 740 | Must be set before Emerge is loaded.") | ||
| 741 | |||
| 742 | ;; This function sets up the fixed keymaps. It is executed when the first | ||
| 743 | ;; Emerge is done to allow the user maximum time to set up the global keymap. | ||
| 744 | (defun emerge-setup-fixed-keymaps () | ||
| 745 | ;; Set up the basic keymap | ||
| 746 | (setq emerge-basic-keymap (make-keymap)) | ||
| 747 | (suppress-keymap emerge-basic-keymap) ; this sets 0..9 to digit-argument and | ||
| 748 | ; - to negative-argument | ||
| 749 | (define-key emerge-basic-keymap "p" 'emerge-previous-difference) | ||
| 750 | (define-key emerge-basic-keymap "n" 'emerge-next-difference) | ||
| 751 | (define-key emerge-basic-keymap "a" 'emerge-select-A) | ||
| 752 | (define-key emerge-basic-keymap "b" 'emerge-select-B) | ||
| 753 | (define-key emerge-basic-keymap "j" 'emerge-jump-to-difference) | ||
| 754 | (define-key emerge-basic-keymap "q" 'emerge-quit) | ||
| 755 | (define-key emerge-basic-keymap "f" 'emerge-fast-mode) | ||
| 756 | (define-key emerge-basic-keymap "e" 'emerge-edit-mode) | ||
| 757 | (define-key emerge-basic-keymap "s" nil) | ||
| 758 | (define-key emerge-basic-keymap "sa" 'emerge-auto-advance) | ||
| 759 | (define-key emerge-basic-keymap "ss" 'emerge-skip-prefers) | ||
| 760 | (define-key emerge-basic-keymap "l" 'emerge-recenter) | ||
| 761 | (define-key emerge-basic-keymap "d" nil) | ||
| 762 | (define-key emerge-basic-keymap "da" 'emerge-default-A) | ||
| 763 | (define-key emerge-basic-keymap "db" 'emerge-default-B) | ||
| 764 | (define-key emerge-basic-keymap "c" nil) | ||
| 765 | (define-key emerge-basic-keymap "ca" 'emerge-copy-as-kill-A) | ||
| 766 | (define-key emerge-basic-keymap "cb" 'emerge-copy-as-kill-B) | ||
| 767 | (define-key emerge-basic-keymap "i" nil) | ||
| 768 | (define-key emerge-basic-keymap "ia" 'emerge-insert-A) | ||
| 769 | (define-key emerge-basic-keymap "ib" 'emerge-insert-B) | ||
| 770 | (define-key emerge-basic-keymap "m" 'emerge-mark-difference) | ||
| 771 | (define-key emerge-basic-keymap "v" 'emerge-scroll-up) | ||
| 772 | (define-key emerge-basic-keymap "^" 'emerge-scroll-down) | ||
| 773 | (define-key emerge-basic-keymap "<" 'emerge-scroll-left) | ||
| 774 | (define-key emerge-basic-keymap ">" 'emerge-scroll-right) | ||
| 775 | (define-key emerge-basic-keymap "|" 'emerge-scroll-reset) | ||
| 776 | (define-key emerge-basic-keymap "x" nil) | ||
| 777 | (define-key emerge-basic-keymap "x1" 'emerge-one-line-window) | ||
| 778 | (define-key emerge-basic-keymap "xa" 'emerge-find-difference-A) | ||
| 779 | (define-key emerge-basic-keymap "xb" 'emerge-find-difference-B) | ||
| 780 | (define-key emerge-basic-keymap "xc" 'emerge-combine-versions) | ||
| 781 | (define-key emerge-basic-keymap "xC" 'emerge-combine-versions-register) | ||
| 782 | (define-key emerge-basic-keymap "xd" 'emerge-find-difference) | ||
| 783 | (define-key emerge-basic-keymap "xf" 'emerge-file-names) | ||
| 784 | (define-key emerge-basic-keymap "xj" 'emerge-join-differences) | ||
| 785 | (define-key emerge-basic-keymap "xl" 'emerge-line-numbers) | ||
| 786 | (define-key emerge-basic-keymap "xm" 'emerge-set-merge-mode) | ||
| 787 | (define-key emerge-basic-keymap "xs" 'emerge-split-difference) | ||
| 788 | (define-key emerge-basic-keymap "xt" 'emerge-trim-difference) | ||
| 789 | (define-key emerge-basic-keymap "xx" 'emerge-set-combine-versions-template) | ||
| 790 | ;; Allow emerge-basic-keymap to be referenced indirectly | ||
| 791 | (fset 'emerge-basic-keymap emerge-basic-keymap) | ||
| 792 | ;; Set up the fast mode keymap | ||
| 793 | (setq emerge-fast-keymap (copy-keymap emerge-basic-keymap)) | ||
| 794 | ;; Allow prefixed commands to work in fast mode | ||
| 795 | (define-key emerge-fast-keymap emerge-command-prefix 'emerge-basic-keymap) | ||
| 796 | ;; Allow emerge-fast-keymap to be referenced indirectly | ||
| 797 | (fset 'emerge-fast-keymap emerge-fast-keymap) | ||
| 798 | ;; Suppress write-file and save-buffer | ||
| 799 | (emerge-shadow-key-definition 'write-file 'emerge-query-write-file | ||
| 800 | (current-global-map) emerge-fast-keymap) | ||
| 801 | (emerge-shadow-key-definition 'save-buffer 'emerge-query-save-buffer | ||
| 802 | (current-global-map) emerge-fast-keymap)) | ||
| 803 | |||
| 804 | ;; Variables which control each merge. They are local to the merge buffer. | ||
| 805 | |||
| 806 | ;; Mode variables | ||
| 807 | (emerge-defvar-local emerge-mode nil | ||
| 808 | "Indicator for emerge-mode.") | ||
| 809 | (emerge-defvar-local emerge-fast-mode nil | ||
| 810 | "Indicator for emerge-mode fast submode.") | ||
| 811 | (emerge-defvar-local emerge-edit-mode nil | ||
| 812 | "Indicator for emerge-mode edit submode.") | ||
| 813 | (emerge-defvar-local emerge-A-buffer nil | ||
| 814 | "The buffer in which the A variant is stored.") | ||
| 815 | (emerge-defvar-local emerge-B-buffer nil | ||
| 816 | "The buffer in which the B variant is stored.") | ||
| 817 | (emerge-defvar-local emerge-merge-buffer nil | ||
| 818 | "The buffer in which the merged file is manipulated.") | ||
| 819 | (emerge-defvar-local emerge-ancestor-buffer nil | ||
| 820 | "The buffer in which the ancestor variant is stored, | ||
| 821 | or nil if there is none.") | ||
| 822 | |||
| 823 | (defconst emerge-saved-variables | ||
| 824 | '((buffer-modified-p set-buffer-modified-p) | ||
| 825 | buffer-read-only | ||
| 826 | buffer-auto-save-file-name) | ||
| 827 | "Variables and properties of a buffer which are saved, modified and restored | ||
| 828 | during a merge.") | ||
| 829 | (defconst emerge-merging-values '(nil t nil) | ||
| 830 | "Values to be assigned to emerge-saved-variables during a merge.") | ||
| 831 | |||
| 832 | (emerge-defvar-local emerge-A-buffer-values nil | ||
| 833 | "Remembers emerge-saved-variables for emerge-A-buffer.") | ||
| 834 | (emerge-defvar-local emerge-B-buffer-values nil | ||
| 835 | "Remembers emerge-saved-variables for emerge-B-buffer.") | ||
| 836 | |||
| 837 | (emerge-defvar-local emerge-difference-list nil | ||
| 838 | "Vector of differences between the variants, and markers in the buffers to | ||
| 839 | show where they are. Each difference is represented by a vector of seven | ||
| 840 | elements. The first two are markers to the beginning and end of the difference | ||
| 841 | section in the A buffer, the second two are markers for the B buffer, the third | ||
| 842 | two are markers for the merge buffer, and the last element is the \"state\" of | ||
| 843 | that difference in the merge buffer. | ||
| 844 | A section of a buffer is described by two markers, one to the beginning of | ||
| 845 | the first line of the section, and one to the beginning of the first line | ||
| 846 | after the section. (If the section is empty, both markers point to the same | ||
| 847 | point.) If the section is part of the selected difference, then the markers | ||
| 848 | are moved into the flags, so the user can edit the section without disturbing | ||
| 849 | the markers. | ||
| 850 | The \"states\" are: | ||
| 851 | A the merge buffer currently contains the A variant | ||
| 852 | B the merge buffer currently contains the B variant | ||
| 853 | default-A the merge buffer contains the A variant by default, | ||
| 854 | but this difference hasn't been selected yet, so | ||
| 855 | change-default commands can alter it | ||
| 856 | default-B the merge buffer contains the B variant by default, | ||
| 857 | but this difference hasn't been selected yet, so | ||
| 858 | change-default commands can alter it | ||
| 859 | prefer-A in a three-file merge, the A variant is the prefered | ||
| 860 | choice | ||
| 861 | prefer-B in a three-file merge, the B variant is the prefered | ||
| 862 | choice") | ||
| 863 | (emerge-defvar-local emerge-current-difference -1 | ||
| 864 | "The difference that is currently selected.") | ||
| 865 | (emerge-defvar-local emerge-number-of-differences nil | ||
| 866 | "Number of differences found.") | ||
| 867 | (emerge-defvar-local emerge-edit-keymap nil | ||
| 868 | "The local keymap for the merge buffer, with the emerge commands defined in | ||
| 869 | it. Used to save the local keymap during fast mode, when the local keymap is | ||
| 870 | replaced by emerge-fast-keymap.") | ||
| 871 | (emerge-defvar-local emerge-old-keymap nil | ||
| 872 | "The original local keymap for the merge buffer.") | ||
| 873 | (emerge-defvar-local emerge-auto-advance nil | ||
| 874 | "*If non-nil, emerge-select-A and emerge-select-B automatically advance to | ||
| 875 | the next difference.") | ||
| 876 | (emerge-defvar-local emerge-skip-prefers nil | ||
| 877 | "*If non-nil, differences for which there is a preference are automatically | ||
| 878 | skipped.") | ||
| 879 | (emerge-defvar-local emerge-startup-hooks nil | ||
| 880 | "*Hooks to run in the merge buffer after the merge has been set up.") | ||
| 881 | (emerge-defvar-local emerge-quit-hooks nil | ||
| 882 | "Hooks to run in the merge buffer after the merge has been finished. | ||
| 883 | emerge-prefix-argument will be bound to the prefix argument of the emerge-quit | ||
| 884 | command. | ||
| 885 | This is not a user option, since Emerge uses it for its own processing.") | ||
| 886 | (emerge-defvar-local emerge-output-description nil | ||
| 887 | "Describes output destination of the merge, for the use of | ||
| 888 | emerge-file-names.") | ||
| 889 | |||
| 890 | ;;; Setup functions for two-file mode. | ||
| 891 | |||
| 892 | (defun emerge-files-internal (file-A file-B &optional startup-hooks quit-hooks | ||
| 893 | output-file) | ||
| 894 | (let ((buffer-A (find-file-noselect file-A)) | ||
| 895 | (buffer-B (find-file-noselect file-B))) | ||
| 896 | ;; Make sure the entire files are seen, and they reflect what is on disk | ||
| 897 | (emerge-eval-in-buffer buffer-A | ||
| 898 | (widen) | ||
| 899 | (emerge-verify-file-buffer)) | ||
| 900 | (emerge-eval-in-buffer buffer-B | ||
| 901 | (widen) | ||
| 902 | (emerge-verify-file-buffer)) | ||
| 903 | (emerge-setup buffer-A file-A buffer-B file-B startup-hooks quit-hooks | ||
| 904 | output-file))) | ||
| 905 | |||
| 906 | ;; Start up Emerge on two files | ||
| 907 | (defun emerge-setup (buffer-A file-A buffer-B file-B startup-hooks quit-hooks | ||
| 908 | output-file) | ||
| 909 | (setq file-A (expand-file-name file-A)) | ||
| 910 | (setq file-B (expand-file-name file-B)) | ||
| 911 | (setq output-file (and output-file (expand-file-name output-file))) | ||
| 912 | (let* ((merge-buffer-name (emerge-unique-buffer-name "*merge" "*")) | ||
| 913 | ;; create the merge buffer from buffer A, so it inherits buffer A's | ||
| 914 | ;; default directory, etc. | ||
| 915 | (merge-buffer (emerge-eval-in-buffer | ||
| 916 | buffer-A | ||
| 917 | (get-buffer-create merge-buffer-name)))) | ||
| 918 | (emerge-eval-in-buffer | ||
| 919 | merge-buffer | ||
| 920 | (emerge-copy-modes buffer-A) | ||
| 921 | (setq buffer-read-only nil) | ||
| 922 | (auto-save-mode 1) | ||
| 923 | (setq emerge-mode t) | ||
| 924 | (setq emerge-A-buffer buffer-A) | ||
| 925 | (setq emerge-B-buffer buffer-B) | ||
| 926 | (setq emerge-ancestor-buffer nil) | ||
| 927 | (setq emerge-merge-buffer merge-buffer) | ||
| 928 | (setq emerge-output-description | ||
| 929 | (if output-file | ||
| 930 | (concat "Output to file: " output-file) | ||
| 931 | (concat "Output to buffer: " (buffer-name merge-buffer)))) | ||
| 932 | (insert-buffer emerge-A-buffer) | ||
| 933 | (emerge-set-keys) | ||
| 934 | (setq emerge-difference-list (emerge-make-diff-list file-A file-B)) | ||
| 935 | (setq emerge-number-of-differences (length emerge-difference-list)) | ||
| 936 | (setq emerge-current-difference -1) | ||
| 937 | (setq emerge-quit-hooks quit-hooks) | ||
| 938 | (emerge-remember-buffer-characteristics)) | ||
| 939 | (emerge-setup-windows buffer-A buffer-B merge-buffer t) | ||
| 940 | (emerge-eval-in-buffer merge-buffer | ||
| 941 | (run-hooks 'startup-hooks 'emerge-startup-hooks) | ||
| 942 | (setq buffer-read-only t)))) | ||
| 943 | |||
| 944 | ;; Generate the Emerge difference list between two files | ||
| 945 | (defun emerge-make-diff-list (file-A file-B) | ||
| 946 | (setq emerge-diff-buffer (get-buffer-create "*emerge-diff*")) | ||
| 947 | (emerge-eval-in-buffer | ||
| 948 | emerge-diff-buffer | ||
| 949 | (erase-buffer) | ||
| 950 | (shell-command | ||
| 951 | (format "%s %s %s %s" | ||
| 952 | emerge-diff-program emerge-diff-options file-A file-B) | ||
| 953 | t)) | ||
| 954 | (emerge-prepare-error-list emerge-diff-ok-lines) | ||
| 955 | (emerge-convert-diffs-to-markers | ||
| 956 | emerge-A-buffer emerge-B-buffer emerge-merge-buffer | ||
| 957 | (emerge-extract-diffs emerge-diff-buffer))) | ||
| 958 | |||
| 959 | (defun emerge-extract-diffs (diff-buffer) | ||
| 960 | (let (list) | ||
| 961 | (emerge-eval-in-buffer | ||
| 962 | diff-buffer | ||
| 963 | (goto-char (point-min)) | ||
| 964 | (while (re-search-forward emerge-match-diff-line nil t) | ||
| 965 | (let* ((a-begin (string-to-int (buffer-substring (match-beginning 1) | ||
| 966 | (match-end 1)))) | ||
| 967 | (a-end (let ((b (match-beginning 3)) | ||
| 968 | (e (match-end 3))) | ||
| 969 | (if b | ||
| 970 | (string-to-int (buffer-substring b e)) | ||
| 971 | a-begin))) | ||
| 972 | (diff-type (buffer-substring (match-beginning 4) (match-end 4))) | ||
| 973 | (b-begin (string-to-int (buffer-substring (match-beginning 5) | ||
| 974 | (match-end 5)))) | ||
| 975 | (b-end (let ((b (match-beginning 7)) | ||
| 976 | (e (match-end 7))) | ||
| 977 | (if b | ||
| 978 | (string-to-int (buffer-substring b e)) | ||
| 979 | b-begin)))) | ||
| 980 | ;; fix the beginning and end numbers, because diff is somewhat | ||
| 981 | ;; strange about how it numbers lines | ||
| 982 | (if (string-equal diff-type "a") | ||
| 983 | (progn | ||
| 984 | (setq b-end (1+ b-end)) | ||
| 985 | (setq a-begin (1+ a-begin)) | ||
| 986 | (setq a-end a-begin)) | ||
| 987 | (if (string-equal diff-type "d") | ||
| 988 | (progn | ||
| 989 | (setq a-end (1+ a-end)) | ||
| 990 | (setq b-begin (1+ b-begin)) | ||
| 991 | (setq b-end b-begin)) | ||
| 992 | ;; (string-equal diff-type "c") | ||
| 993 | (progn | ||
| 994 | (setq a-end (1+ a-end)) | ||
| 995 | (setq b-end (1+ b-end))))) | ||
| 996 | (setq list (cons (vector a-begin a-end | ||
| 997 | b-begin b-end | ||
| 998 | 'default-A) | ||
| 999 | list))))) | ||
| 1000 | (nreverse list))) | ||
| 1001 | |||
| 1002 | ;; Set up buffer of diff/diff3 error messages. | ||
| 1003 | (defun emerge-prepare-error-list (ok-regexp) | ||
| 1004 | (setq emerge-diff-error-buffer (get-buffer-create "*emerge-diff-errors*")) | ||
| 1005 | (emerge-eval-in-buffer | ||
| 1006 | emerge-diff-error-buffer | ||
| 1007 | (erase-buffer) | ||
| 1008 | (insert-buffer emerge-diff-buffer) | ||
| 1009 | (delete-matching-lines ok-regexp))) | ||
| 1010 | |||
| 1011 | ;;; Top-level and setup functions for three-file mode. | ||
| 1012 | |||
| 1013 | (defun emerge-files-with-ancestor-internal (file-A file-B file-ancestor | ||
| 1014 | &optional startup-hooks quit-hooks | ||
| 1015 | output-file) | ||
| 1016 | (let ((buffer-A (find-file-noselect file-A)) | ||
| 1017 | (buffer-B (find-file-noselect file-B)) | ||
| 1018 | (buffer-ancestor (find-file-noselect file-ancestor))) | ||
| 1019 | ;; Make sure the entire files are seen, and they reflect what is on disk | ||
| 1020 | (emerge-eval-in-buffer buffer-A | ||
| 1021 | (widen) | ||
| 1022 | (emerge-verify-file-buffer)) | ||
| 1023 | (emerge-eval-in-buffer buffer-B | ||
| 1024 | (widen) | ||
| 1025 | (emerge-verify-file-buffer)) | ||
| 1026 | (emerge-eval-in-buffer buffer-ancestor | ||
| 1027 | (widen) | ||
| 1028 | (emerge-verify-file-buffer)) | ||
| 1029 | (emerge-setup-with-ancestor buffer-A file-A buffer-B file-B | ||
| 1030 | buffer-ancestor file-ancestor | ||
| 1031 | startup-hooks quit-hooks output-file))) | ||
| 1032 | |||
| 1033 | ;; Start up Emerge on two files with an ancestor | ||
| 1034 | (defun emerge-setup-with-ancestor (buffer-A file-A buffer-B file-B | ||
| 1035 | buffer-ancestor file-ancestor | ||
| 1036 | &optional startup-hooks quit-hooks | ||
| 1037 | output-file) | ||
| 1038 | (setq file-A (expand-file-name file-A)) | ||
| 1039 | (setq file-B (expand-file-name file-B)) | ||
| 1040 | (setq file-ancestor (expand-file-name file-ancestor)) | ||
| 1041 | (setq output-file (and output-file (expand-file-name output-file))) | ||
| 1042 | (let* ((merge-buffer-name (emerge-unique-buffer-name "*merge" "*")) | ||
| 1043 | ;; create the merge buffer from buffer A, so it inherits buffer A's | ||
| 1044 | ;; default directory, etc. | ||
| 1045 | (merge-buffer (emerge-eval-in-buffer | ||
| 1046 | buffer-A | ||
| 1047 | (get-buffer-create merge-buffer-name)))) | ||
| 1048 | (emerge-eval-in-buffer | ||
| 1049 | merge-buffer | ||
| 1050 | (emerge-copy-modes buffer-A) | ||
| 1051 | (setq buffer-read-only nil) | ||
| 1052 | (auto-save-mode 1) | ||
| 1053 | (setq emerge-mode t) | ||
| 1054 | (setq emerge-A-buffer buffer-A) | ||
| 1055 | (setq emerge-B-buffer buffer-B) | ||
| 1056 | (setq emerge-ancestor-buffer buffer-ancestor) | ||
| 1057 | (setq emerge-merge-buffer merge-buffer) | ||
| 1058 | (setq emerge-output-description | ||
| 1059 | (if output-file | ||
| 1060 | (concat "Output to file: " output-file) | ||
| 1061 | (concat "Output to buffer: " (buffer-name merge-buffer)))) | ||
| 1062 | (insert-buffer emerge-A-buffer) | ||
| 1063 | (emerge-set-keys) | ||
| 1064 | (setq emerge-difference-list | ||
| 1065 | (emerge-make-diff3-list file-A file-B file-ancestor)) | ||
| 1066 | (setq emerge-number-of-differences (length emerge-difference-list)) | ||
| 1067 | (setq emerge-current-difference -1) | ||
| 1068 | (setq emerge-quit-hooks quit-hooks) | ||
| 1069 | (emerge-remember-buffer-characteristics) | ||
| 1070 | (emerge-select-prefer-Bs)) | ||
| 1071 | (emerge-setup-windows buffer-A buffer-B merge-buffer t) | ||
| 1072 | (emerge-eval-in-buffer merge-buffer | ||
| 1073 | (run-hooks 'startup-hooks 'emerge-startup-hooks) | ||
| 1074 | (setq buffer-read-only t)))) | ||
| 1075 | |||
| 1076 | ;; Generate the Emerge difference list between two files with an ancestor | ||
| 1077 | (defun emerge-make-diff3-list (file-A file-B file-ancestor) | ||
| 1078 | (setq emerge-diff-buffer (get-buffer-create "*emerge-diff*")) | ||
| 1079 | (emerge-eval-in-buffer | ||
| 1080 | emerge-diff-buffer | ||
| 1081 | (erase-buffer) | ||
| 1082 | (shell-command | ||
| 1083 | (format "%s %s %s %s %s" | ||
| 1084 | emerge-diff3-program emerge-diff-options | ||
| 1085 | file-ancestor file-A file-B) | ||
| 1086 | t)) | ||
| 1087 | (emerge-prepare-error-list emerge-diff3-ok-lines) | ||
| 1088 | (emerge-convert-diffs-to-markers | ||
| 1089 | emerge-A-buffer emerge-B-buffer emerge-merge-buffer | ||
| 1090 | (emerge-extract-diffs3 emerge-diff-buffer))) | ||
| 1091 | |||
| 1092 | (defun emerge-extract-diffs3 (diff-buffer) | ||
| 1093 | (let (list) | ||
| 1094 | (emerge-eval-in-buffer | ||
| 1095 | diff-buffer | ||
| 1096 | (while (re-search-forward "^====\\(.?\\)$" nil t) | ||
| 1097 | ;; leave point after matched line | ||
| 1098 | (beginning-of-line 2) | ||
| 1099 | (let ((agreement (buffer-substring (match-beginning 1) (match-end 1)))) | ||
| 1100 | ;; if the A and B files are the same, ignore the difference | ||
| 1101 | (if (not (string-equal agreement "1")) | ||
| 1102 | (setq list | ||
| 1103 | (cons | ||
| 1104 | (let ((group-2 (emerge-get-diff3-group "2")) | ||
| 1105 | (group-3 (emerge-get-diff3-group "3"))) | ||
| 1106 | (vector (car group-2) (car (cdr group-2)) | ||
| 1107 | (car group-3) (car (cdr group-3)) | ||
| 1108 | (cond ((string-equal agreement "2") 'prefer-A) | ||
| 1109 | ((string-equal agreement "3") 'prefer-B) | ||
| 1110 | (t 'default-A)))) | ||
| 1111 | list)))))) | ||
| 1112 | (nreverse list))) | ||
| 1113 | |||
| 1114 | (defun emerge-get-diff3-group (file) | ||
| 1115 | ;; This save-excursion allows emerge-get-diff3-group to be called for the | ||
| 1116 | ;; various groups of lines (1, 2, 3) in any order, and for the lines to | ||
| 1117 | ;; appear in any order. The reason this is necessary is that Gnu diff3 | ||
| 1118 | ;; can produce the groups in the order 1, 2, 3 or 1, 3, 2. | ||
| 1119 | (save-excursion | ||
| 1120 | (re-search-forward | ||
| 1121 | (concat "^" file ":\\([0-9]+\\)\\(,\\([0-9]+\\)\\)?\\([ac]\\)$")) | ||
| 1122 | (beginning-of-line 2) | ||
| 1123 | ;; treatment depends on whether it is an "a" group or a "c" group | ||
| 1124 | (if (string-equal (buffer-substring (match-beginning 4) (match-end 4)) "c") | ||
| 1125 | ;; it is a "c" group | ||
| 1126 | (if (match-beginning 2) | ||
| 1127 | ;; it has two numbers | ||
| 1128 | (list (string-to-int | ||
| 1129 | (buffer-substring (match-beginning 1) (match-end 1))) | ||
| 1130 | (1+ (string-to-int | ||
| 1131 | (buffer-substring (match-beginning 3) (match-end 3))))) | ||
| 1132 | ;; it has one number | ||
| 1133 | (let ((x (string-to-int | ||
| 1134 | (buffer-substring (match-beginning 1) (match-end 1))))) | ||
| 1135 | (list x (1+ x)))) | ||
| 1136 | ;; it is an "a" group | ||
| 1137 | (let ((x (1+ (string-to-int | ||
| 1138 | (buffer-substring (match-beginning 1) (match-end 1)))))) | ||
| 1139 | (list x x))))) | ||
| 1140 | |||
| 1141 | ;;; Functions to start Emerge on files | ||
| 1142 | |||
| 1143 | (defun emerge-files (arg file-A file-B file-out &optional startup-hooks | ||
| 1144 | quit-hooks) | ||
| 1145 | "Run Emerge on two files." | ||
| 1146 | (interactive | ||
| 1147 | (let (f) | ||
| 1148 | (list current-prefix-arg | ||
| 1149 | (setq f (read-file-name "File A to merge: " nil nil 'confirm)) | ||
| 1150 | (read-file-name "File B to merge: " nil nil 'confirm) | ||
| 1151 | (and current-prefix-arg | ||
| 1152 | (read-file-name | ||
| 1153 | (format "Output file: (default %s) " f) | ||
| 1154 | nil f nil))))) | ||
| 1155 | (emerge-files-internal | ||
| 1156 | file-A file-B startup-hooks | ||
| 1157 | (if arg | ||
| 1158 | (cons (` (lambda () (emerge-files-exit (, file-out)))) | ||
| 1159 | quit-hooks) | ||
| 1160 | quit-hooks) | ||
| 1161 | file-out)) | ||
| 1162 | |||
| 1163 | (defun emerge-files-with-ancestor (arg file-A file-B file-ancestor file-out | ||
| 1164 | &optional startup-hooks quit-hooks) | ||
| 1165 | "Run Emerge on two files, giving another file as the ancestor." | ||
| 1166 | (interactive | ||
| 1167 | (let (f) | ||
| 1168 | (list current-prefix-arg | ||
| 1169 | (setq f (read-file-name "File A to merge: " nil nil 'confirm)) | ||
| 1170 | (read-file-name "File B to merge: " nil nil 'confirm) | ||
| 1171 | (read-file-name "Ancestor file: " nil nil 'confirm) | ||
| 1172 | (and current-prefix-arg | ||
| 1173 | (read-file-name | ||
| 1174 | (format "Output file: (default %s) " f) | ||
| 1175 | nil f nil))))) | ||
| 1176 | (emerge-files-with-ancestor-internal | ||
| 1177 | file-A file-B file-ancestor startup-hooks | ||
| 1178 | (if arg | ||
| 1179 | (cons (` (lambda () (emerge-files-exit (, file-out)))) | ||
| 1180 | quit-hooks) | ||
| 1181 | quit-hooks) | ||
| 1182 | file-out)) | ||
| 1183 | |||
| 1184 | ;; Write the merge buffer out in place of the file the A buffer is visiting. | ||
| 1185 | (defun emerge-files-exit (file-out) | ||
| 1186 | ;; if merge was successful was given, save to disk | ||
| 1187 | (if (not emerge-prefix-argument) | ||
| 1188 | (emerge-write-and-delete file-out))) | ||
| 1189 | |||
| 1190 | ;;; Functions to start Emerge on buffers | ||
| 1191 | |||
| 1192 | (defun emerge-buffers (buffer-A buffer-B &optional startup-hooks quit-hooks) | ||
| 1193 | "Run Emerge on two buffers." | ||
| 1194 | (interactive "bBuffer A to merge: \nbBuffer B to merge: ") | ||
| 1195 | (let ((emerge-file-A (emerge-make-temp-file "A")) | ||
| 1196 | (emerge-file-B (emerge-make-temp-file "B"))) | ||
| 1197 | (emerge-eval-in-buffer | ||
| 1198 | buffer-A | ||
| 1199 | (write-region (point-min) (point-max) emerge-file-A nil 'no-message)) | ||
| 1200 | (emerge-eval-in-buffer | ||
| 1201 | buffer-B | ||
| 1202 | (write-region (point-min) (point-max) emerge-file-B nil 'no-message)) | ||
| 1203 | (emerge-setup (get-buffer buffer-A) emerge-file-A | ||
| 1204 | (get-buffer buffer-B) emerge-file-B | ||
| 1205 | (cons (function (lambda () | ||
| 1206 | (delete-file emerge-file-A) | ||
| 1207 | (delete-file emerge-file-B))) | ||
| 1208 | startup-hooks) | ||
| 1209 | quit-hooks | ||
| 1210 | nil))) | ||
| 1211 | |||
| 1212 | (defun emerge-buffers-with-ancestor (buffer-A buffer-B buffer-ancestor | ||
| 1213 | &optional startup-hooks | ||
| 1214 | quit-hooks) | ||
| 1215 | "Run Emerge on two buffers, giving another buffer as the ancestor." | ||
| 1216 | (interactive | ||
| 1217 | "bBuffer A to merge: \nbBuffer B to merge: \nbAncestor buffer: ") | ||
| 1218 | (let ((emerge-file-A (emerge-make-temp-file "A")) | ||
| 1219 | (emerge-file-B (emerge-make-temp-file "B")) | ||
| 1220 | (emerge-file-ancestor (emerge-make-temp-file "anc"))) | ||
| 1221 | (emerge-eval-in-buffer | ||
| 1222 | buffer-A | ||
| 1223 | (write-region (point-min) (point-max) emerge-file-A nil 'no-message)) | ||
| 1224 | (emerge-eval-in-buffer | ||
| 1225 | buffer-B | ||
| 1226 | (write-region (point-min) (point-max) emerge-file-B nil 'no-message)) | ||
| 1227 | (emerge-eval-in-buffer | ||
| 1228 | buffer-ancestor | ||
| 1229 | (write-region (point-min) (point-max) emerge-file-ancestor nil | ||
| 1230 | 'no-message)) | ||
| 1231 | (emerge-setup-with-ancestor (get-buffer buffer-A) emerge-file-A | ||
| 1232 | (get-buffer buffer-B) emerge-file-B | ||
| 1233 | (get-buffer buffer-ancestor) | ||
| 1234 | emerge-file-ancestor | ||
| 1235 | (cons (function (lambda () | ||
| 1236 | (delete-file emerge-file-A) | ||
| 1237 | (delete-file emerge-file-B) | ||
| 1238 | (delete-file | ||
| 1239 | emerge-file-ancestor))) | ||
| 1240 | startup-hooks) | ||
| 1241 | quit-hooks | ||
| 1242 | nil))) | ||
| 1243 | |||
| 1244 | ;;; Functions to start Emerge from the command line | ||
| 1245 | |||
| 1246 | (defun emerge-files-command () | ||
| 1247 | (let ((file-a (nth 0 command-line-args-left)) | ||
| 1248 | (file-b (nth 1 command-line-args-left)) | ||
| 1249 | (file-out (nth 2 command-line-args-left))) | ||
| 1250 | (setq command-line-args-left (nthcdr 3 command-line-args-left)) | ||
| 1251 | (emerge-files-internal | ||
| 1252 | file-a file-b nil | ||
| 1253 | (list (` (lambda () (emerge-command-exit (, file-out)))))))) | ||
| 1254 | |||
| 1255 | (defun emerge-files-with-ancestor-command () | ||
| 1256 | (let (file-a file-b file-anc file-out) | ||
| 1257 | ;; check for a -a flag, for filemerge compatibility | ||
| 1258 | (if (string= (car command-line-args-left) "-a") | ||
| 1259 | ;; arguments are "-a ancestor file-a file-b file-out" | ||
| 1260 | (progn | ||
| 1261 | (setq file-a (nth 2 command-line-args-left)) | ||
| 1262 | (setq file-b (nth 3 command-line-args-left)) | ||
| 1263 | (setq file-anc (nth 1 command-line-args-left)) | ||
| 1264 | (setq file-out (nth 4 command-line-args-left)) | ||
| 1265 | (setq command-line-args-left (nthcdr 5 command-line-args-left))) | ||
| 1266 | ;; arguments are "file-a file-b ancestor file-out" | ||
| 1267 | (setq file-a (nth 0 command-line-args-left)) | ||
| 1268 | (setq file-b (nth 1 command-line-args-left)) | ||
| 1269 | (setq file-anc (nth 2 command-line-args-left)) | ||
| 1270 | (setq file-out (nth 3 command-line-args-left)) | ||
| 1271 | (setq command-line-args-left (nthcdr 4 command-line-args-left))) | ||
| 1272 | (emerge-files-with-ancestor-internal | ||
| 1273 | file-a file-b file-anc nil | ||
| 1274 | (list (` (lambda () (emerge-command-exit (, file-out)))))))) | ||
| 1275 | |||
| 1276 | (defun emerge-command-exit (file-out) | ||
| 1277 | (emerge-write-and-delete file-out) | ||
| 1278 | (kill-emacs (if emerge-prefix-argument 1 0))) | ||
| 1279 | |||
| 1280 | ;;; Functions to start Emerge via remote request | ||
| 1281 | |||
| 1282 | (defun emerge-files-remote (file-a file-b file-out) | ||
| 1283 | (setq emerge-file-out file-out) | ||
| 1284 | (emerge-files-internal | ||
| 1285 | file-a file-b nil | ||
| 1286 | (list (` (lambda () (emerge-remote-exit (, file-out) '(, exit-func))))) | ||
| 1287 | file-out) | ||
| 1288 | (throw 'client-wait nil)) | ||
| 1289 | |||
| 1290 | (defun emerge-files-with-ancestor-remote (file-a file-b file-anc file-out) | ||
| 1291 | (setq emerge-file-out file-out) | ||
| 1292 | (emerge-files-with-ancestor-internal | ||
| 1293 | file-a file-b file-anc nil | ||
| 1294 | (list (` (lambda () (emerge-remote-exit (, file-out) '(, exit-func))))) | ||
| 1295 | file-out) | ||
| 1296 | (throw 'client-wait nil)) | ||
| 1297 | |||
| 1298 | (defun emerge-remote-exit (file-out exit-func) | ||
| 1299 | (emerge-write-and-delete file-out) | ||
| 1300 | (kill-buffer emerge-merge-buffer) | ||
| 1301 | (funcall exit-func (if emerge-prefix-argument 1 0))) | ||
| 1302 | |||
| 1303 | ;;; Common setup routines | ||
| 1304 | |||
| 1305 | ;; Set up the window configuration. If POS is given, set the points to | ||
| 1306 | ;; the beginnings of the buffers. | ||
| 1307 | (defun emerge-setup-windows (buffer-A buffer-B merge-buffer &optional pos) | ||
| 1308 | ;; Make sure we are not in the minibuffer window when we try to delete | ||
| 1309 | ;; all other windows. | ||
| 1310 | (if (eq (selected-window) (minibuffer-window)) | ||
| 1311 | (other-window 1)) | ||
| 1312 | (delete-other-windows) | ||
| 1313 | (switch-to-buffer merge-buffer) | ||
| 1314 | (emerge-refresh-mode-line) | ||
| 1315 | (split-window-vertically) | ||
| 1316 | (split-window-horizontally) | ||
| 1317 | (switch-to-buffer buffer-A) | ||
| 1318 | (if pos | ||
| 1319 | (goto-char (point-min))) | ||
| 1320 | (other-window 1) | ||
| 1321 | (switch-to-buffer buffer-B) | ||
| 1322 | (if pos | ||
| 1323 | (goto-char (point-min))) | ||
| 1324 | (other-window 1) | ||
| 1325 | (if pos | ||
| 1326 | (goto-char (point-min))) | ||
| 1327 | ;; If diff/diff3 reports errors, display them rather than the merge buffer. | ||
| 1328 | (if (/= 0 (emerge-eval-in-buffer emerge-diff-error-buffer (buffer-size))) | ||
| 1329 | (progn | ||
| 1330 | (ding) | ||
| 1331 | (message "Errors found in diff/diff3 output. Merge buffer is %s." | ||
| 1332 | (buffer-name emerge-merge-buffer)) | ||
| 1333 | (switch-to-buffer emerge-diff-error-buffer)))) | ||
| 1334 | |||
| 1335 | ;; Set up the keymap in the merge buffer | ||
| 1336 | (defun emerge-set-keys () | ||
| 1337 | ;; Set up fixed keymaps if necessary | ||
| 1338 | (if (not emerge-basic-keymap) | ||
| 1339 | (emerge-setup-fixed-keymaps)) | ||
| 1340 | ;; Save the old local map | ||
| 1341 | (setq emerge-old-keymap (current-local-map)) | ||
| 1342 | ;; Construct the edit keymap | ||
| 1343 | (setq emerge-edit-keymap (if emerge-old-keymap | ||
| 1344 | (copy-keymap emerge-old-keymap) | ||
| 1345 | (make-sparse-keymap))) | ||
| 1346 | ;; Install the Emerge commands | ||
| 1347 | (emerge-force-define-key emerge-edit-keymap emerge-command-prefix | ||
| 1348 | 'emerge-basic-keymap) | ||
| 1349 | ;; Suppress write-file and save-buffer | ||
| 1350 | (emerge-recursively-substitute-key-definition 'write-file | ||
| 1351 | 'emerge-query-write-file | ||
| 1352 | emerge-edit-keymap) | ||
| 1353 | (emerge-recursively-substitute-key-definition 'save-buffer | ||
| 1354 | 'emerge-query-save-buffer | ||
| 1355 | emerge-edit-keymap) | ||
| 1356 | (emerge-shadow-key-definition 'write-file 'emerge-query-write-file | ||
| 1357 | (current-global-map) emerge-edit-keymap) | ||
| 1358 | (emerge-shadow-key-definition 'save-buffer 'emerge-query-save-buffer | ||
| 1359 | (current-global-map) emerge-edit-keymap) | ||
| 1360 | (use-local-map emerge-fast-keymap) | ||
| 1361 | (setq emerge-edit-mode nil) | ||
| 1362 | (setq emerge-fast-mode t)) | ||
| 1363 | |||
| 1364 | (defun emerge-remember-buffer-characteristics () | ||
| 1365 | "Must be called in the merge buffer. Remembers certain properties of the | ||
| 1366 | buffers being merged (read-only, modified, auto-save), and saves them in | ||
| 1367 | buffer local variables. Sets the buffers read-only and turns off auto-save. | ||
| 1368 | These characteristics are restored by emerge-restore-buffer-characteristics." | ||
| 1369 | ;; force auto-save, because we will turn off auto-saving in buffers for the | ||
| 1370 | ;; duration | ||
| 1371 | (do-auto-save) | ||
| 1372 | ;; remember and alter buffer characteristics | ||
| 1373 | (setq emerge-A-buffer-values | ||
| 1374 | (emerge-eval-in-buffer | ||
| 1375 | emerge-A-buffer | ||
| 1376 | (prog1 | ||
| 1377 | (emerge-save-variables emerge-saved-variables) | ||
| 1378 | (emerge-restore-variables emerge-saved-variables | ||
| 1379 | emerge-merging-values)))) | ||
| 1380 | (setq emerge-B-buffer-values | ||
| 1381 | (emerge-eval-in-buffer | ||
| 1382 | emerge-B-buffer | ||
| 1383 | (prog1 | ||
| 1384 | (emerge-save-variables emerge-saved-variables) | ||
| 1385 | (emerge-restore-variables emerge-saved-variables | ||
| 1386 | emerge-merging-values))))) | ||
| 1387 | |||
| 1388 | (defun emerge-restore-buffer-characteristics () | ||
| 1389 | "Restores the characteristics remembered by | ||
| 1390 | emerge-remember-buffer-characteristics." | ||
| 1391 | (let ((A-values emerge-A-buffer-values) | ||
| 1392 | (B-values emerge-B-buffer-values)) | ||
| 1393 | (emerge-eval-in-buffer emerge-A-buffer | ||
| 1394 | (emerge-restore-variables emerge-saved-variables | ||
| 1395 | A-values)) | ||
| 1396 | (emerge-eval-in-buffer emerge-B-buffer | ||
| 1397 | (emerge-restore-variables emerge-saved-variables | ||
| 1398 | B-values)))) | ||
| 1399 | |||
| 1400 | (defun emerge-convert-diffs-to-markers (A-buffer | ||
| 1401 | B-buffer | ||
| 1402 | merge-buffer | ||
| 1403 | lineno-list) | ||
| 1404 | (let* (marker-list | ||
| 1405 | (A-point-min (emerge-eval-in-buffer A-buffer (point-min))) | ||
| 1406 | (offset (1- A-point-min)) | ||
| 1407 | (A-hidden-lines (emerge-eval-in-buffer | ||
| 1408 | A-buffer | ||
| 1409 | (save-restriction | ||
| 1410 | (widen) | ||
| 1411 | (count-lines 1 A-point-min)))) | ||
| 1412 | (B-point-min (emerge-eval-in-buffer B-buffer (point-min))) | ||
| 1413 | (B-hidden-lines (emerge-eval-in-buffer | ||
| 1414 | B-buffer | ||
| 1415 | (save-restriction | ||
| 1416 | (widen) | ||
| 1417 | (count-lines 1 B-point-min))))) | ||
| 1418 | (while lineno-list | ||
| 1419 | (let* ((list-element (car lineno-list)) | ||
| 1420 | a-begin-marker | ||
| 1421 | a-end-marker | ||
| 1422 | b-begin-marker | ||
| 1423 | b-end-marker | ||
| 1424 | (a-begin (aref list-element 0)) | ||
| 1425 | (a-end (aref list-element 1)) | ||
| 1426 | (b-begin (aref list-element 2)) | ||
| 1427 | (b-end (aref list-element 3)) | ||
| 1428 | (state (aref list-element 4))) | ||
| 1429 | ;; place markers at the appropriate places in the buffers | ||
| 1430 | (emerge-eval-in-buffer | ||
| 1431 | A-buffer | ||
| 1432 | (goto-line (+ a-begin A-hidden-lines)) | ||
| 1433 | (setq a-begin-marker (point-marker)) | ||
| 1434 | (goto-line (+ a-end A-hidden-lines)) | ||
| 1435 | (setq a-end-marker (point-marker))) | ||
| 1436 | (emerge-eval-in-buffer | ||
| 1437 | B-buffer | ||
| 1438 | (goto-line (+ b-begin B-hidden-lines)) | ||
| 1439 | (setq b-begin-marker (point-marker)) | ||
| 1440 | (goto-line (+ b-end B-hidden-lines)) | ||
| 1441 | (setq b-end-marker (point-marker))) | ||
| 1442 | (setq merge-begin-marker (set-marker | ||
| 1443 | (make-marker) | ||
| 1444 | (- (marker-position a-begin-marker) | ||
| 1445 | offset) | ||
| 1446 | merge-buffer)) | ||
| 1447 | (setq merge-end-marker (set-marker | ||
| 1448 | (make-marker) | ||
| 1449 | (- (marker-position a-end-marker) | ||
| 1450 | offset) | ||
| 1451 | merge-buffer)) | ||
| 1452 | ;; record all the markers for this difference | ||
| 1453 | (setq marker-list (cons (vector a-begin-marker a-end-marker | ||
| 1454 | b-begin-marker b-end-marker | ||
| 1455 | merge-begin-marker merge-end-marker | ||
| 1456 | state) | ||
| 1457 | marker-list))) | ||
| 1458 | (setq lineno-list (cdr lineno-list))) | ||
| 1459 | ;; convert the list of difference information into a vector for | ||
| 1460 | ;; fast access | ||
| 1461 | (setq emerge-difference-list (apply 'vector (nreverse marker-list))))) | ||
| 1462 | |||
| 1463 | ;; If we have an ancestor, select all B variants that we prefer | ||
| 1464 | (defun emerge-select-prefer-Bs () | ||
| 1465 | (let ((n 0)) | ||
| 1466 | (while (< n emerge-number-of-differences) | ||
| 1467 | (if (eq (aref (aref emerge-difference-list n) 6) 'prefer-B) | ||
| 1468 | (progn | ||
| 1469 | (emerge-unselect-and-select-difference n t) | ||
| 1470 | (emerge-select-B) | ||
| 1471 | (aset (aref emerge-difference-list n) 6 'prefer-B))) | ||
| 1472 | (setq n (1+ n)))) | ||
| 1473 | (emerge-unselect-and-select-difference -1)) | ||
| 1474 | |||
| 1475 | ;;; Common exit routines | ||
| 1476 | |||
| 1477 | (defun emerge-write-and-delete (file-out) | ||
| 1478 | ;; clear screen format | ||
| 1479 | (delete-other-windows) | ||
| 1480 | ;; delete A, B, and ancestor buffers, if they haven't been changed | ||
| 1481 | (if (not (buffer-modified-p emerge-A-buffer)) | ||
| 1482 | (kill-buffer emerge-A-buffer)) | ||
| 1483 | (if (not (buffer-modified-p emerge-B-buffer)) | ||
| 1484 | (kill-buffer emerge-B-buffer)) | ||
| 1485 | (if (and emerge-ancestor-buffer | ||
| 1486 | (not (buffer-modified-p emerge-ancestor-buffer))) | ||
| 1487 | (kill-buffer emerge-ancestor-buffer)) | ||
| 1488 | ;; Write merge buffer to file | ||
| 1489 | (write-file file-out)) | ||
| 1490 | |||
| 1491 | ;;; Commands | ||
| 1492 | |||
| 1493 | (defun emerge-recenter (&optional arg) | ||
| 1494 | "Bring the highlighted region of all three merge buffers into view, | ||
| 1495 | if they are in windows. If an ARGUMENT is given, the default three-window | ||
| 1496 | display is reestablished." | ||
| 1497 | (interactive "P") | ||
| 1498 | ;; If there is an argument, rebuild the window structure | ||
| 1499 | (if arg | ||
| 1500 | (emerge-setup-windows emerge-A-buffer emerge-B-buffer | ||
| 1501 | emerge-merge-buffer)) | ||
| 1502 | ;; Redisplay whatever buffers are showing, if there is a selected difference | ||
| 1503 | (if (and (>= emerge-current-difference 0) | ||
| 1504 | (< emerge-current-difference emerge-number-of-differences)) | ||
| 1505 | (let* ((merge-buffer emerge-merge-buffer) | ||
| 1506 | (buffer-A emerge-A-buffer) | ||
| 1507 | (buffer-B emerge-B-buffer) | ||
| 1508 | (window-A (get-buffer-window buffer-A)) | ||
| 1509 | (window-B (get-buffer-window buffer-B)) | ||
| 1510 | (merge-window (get-buffer-window merge-buffer)) | ||
| 1511 | (diff-vector | ||
| 1512 | (aref emerge-difference-list emerge-current-difference))) | ||
| 1513 | (if window-A (progn | ||
| 1514 | (select-window window-A) | ||
| 1515 | (emerge-position-region | ||
| 1516 | (- (aref diff-vector 0) | ||
| 1517 | (1- emerge-before-flag-length)) | ||
| 1518 | (+ (aref diff-vector 1) | ||
| 1519 | (1- emerge-after-flag-length)) | ||
| 1520 | (1+ (aref diff-vector 0))))) | ||
| 1521 | (if window-B (progn | ||
| 1522 | (select-window window-B) | ||
| 1523 | (emerge-position-region | ||
| 1524 | (- (aref diff-vector 2) | ||
| 1525 | (1- emerge-before-flag-length)) | ||
| 1526 | (+ (aref diff-vector 3) | ||
| 1527 | (1- emerge-after-flag-length)) | ||
| 1528 | (1+ (aref diff-vector 2))))) | ||
| 1529 | (if merge-window (progn | ||
| 1530 | (select-window merge-window) | ||
| 1531 | (emerge-position-region | ||
| 1532 | (- (aref diff-vector 4) | ||
| 1533 | (1- emerge-before-flag-length)) | ||
| 1534 | (+ (aref diff-vector 5) | ||
| 1535 | (1- emerge-after-flag-length)) | ||
| 1536 | (1+ (aref diff-vector 4)))))))) | ||
| 1537 | |||
| 1538 | ;;; Window scrolling operations | ||
| 1539 | ;; These operations are designed to scroll all three windows the same amount, | ||
| 1540 | ;; so as to keep the text in them aligned. | ||
| 1541 | |||
| 1542 | ;; Perform some operation on all three windows (if they are showing). | ||
| 1543 | ;; Catches all errors on the operation in the A and B windows, but not | ||
| 1544 | ;; in the merge window. Usually, errors come from scrolling off the | ||
| 1545 | ;; beginning or end of the buffer, and this gives a nice error message: | ||
| 1546 | ;; End of buffer is reported in the merge buffer, but if the scroll was | ||
| 1547 | ;; possible in the A or B windows, it is performed there before the error | ||
| 1548 | ;; is reported. | ||
| 1549 | (defun emerge-operate-on-windows (operation arg) | ||
| 1550 | (let* ((merge-buffer emerge-merge-buffer) | ||
| 1551 | (buffer-A emerge-A-buffer) | ||
| 1552 | (buffer-B emerge-B-buffer) | ||
| 1553 | (window-A (get-buffer-window buffer-A)) | ||
| 1554 | (window-B (get-buffer-window buffer-B)) | ||
| 1555 | (merge-window (get-buffer-window merge-buffer))) | ||
| 1556 | (if window-A (progn | ||
| 1557 | (select-window window-A) | ||
| 1558 | (condition-case nil | ||
| 1559 | (funcall operation arg) | ||
| 1560 | (error)))) | ||
| 1561 | (if window-B (progn | ||
| 1562 | (select-window window-B) | ||
| 1563 | (condition-case nil | ||
| 1564 | (funcall operation arg) | ||
| 1565 | (error)))) | ||
| 1566 | (if merge-window (progn | ||
| 1567 | (select-window merge-window) | ||
| 1568 | (funcall operation arg))))) | ||
| 1569 | |||
| 1570 | (defun emerge-scroll-up (&optional arg) | ||
| 1571 | "Scroll up all three merge buffers, if they are in windows. | ||
| 1572 | If an ARGUMENT is given, that is how many lines are scrolled, else nearly | ||
| 1573 | the size of the merge window. `C-u -' alone as argument scrolls half the | ||
| 1574 | size of the merge window." | ||
| 1575 | (interactive "P") | ||
| 1576 | (emerge-operate-on-windows | ||
| 1577 | 'scroll-up | ||
| 1578 | ;; calculate argument to scroll-up | ||
| 1579 | ;; if there is an explicit argument | ||
| 1580 | (if (and arg (not (equal arg '-))) | ||
| 1581 | ;; use it | ||
| 1582 | (prefix-numeric-value arg) | ||
| 1583 | ;; if not, see if we can determine a default amount (the window height) | ||
| 1584 | (let ((merge-window (get-buffer-window emerge-merge-buffer))) | ||
| 1585 | (if (null merge-window) | ||
| 1586 | ;; no window, use nil | ||
| 1587 | nil | ||
| 1588 | (let ((default-amount | ||
| 1589 | (- (window-height merge-window) 1 next-screen-context-lines))) | ||
| 1590 | ;; the window was found | ||
| 1591 | (if arg | ||
| 1592 | ;; C-u as argument means half of default amount | ||
| 1593 | (/ default-amount 2) | ||
| 1594 | ;; no argument means default amount | ||
| 1595 | default-amount))))))) | ||
| 1596 | |||
| 1597 | (defun emerge-scroll-down (&optional arg) | ||
| 1598 | "Scroll down all three merge buffers, if they are in windows. | ||
| 1599 | If an ARGUMENT is given, that is how many lines are scrolled, else nearly | ||
| 1600 | the size of the merge window. `C-u -' alone as argument scrolls half the | ||
| 1601 | size of the merge window." | ||
| 1602 | (interactive "P") | ||
| 1603 | (emerge-operate-on-windows | ||
| 1604 | 'scroll-down | ||
| 1605 | ;; calculate argument to scroll-down | ||
| 1606 | ;; if there is an explicit argument | ||
| 1607 | (if (and arg (not (equal arg '-))) | ||
| 1608 | ;; use it | ||
| 1609 | (prefix-numeric-value arg) | ||
| 1610 | ;; if not, see if we can determine a default amount (the window height) | ||
| 1611 | (let ((merge-window (get-buffer-window emerge-merge-buffer))) | ||
| 1612 | (if (null merge-window) | ||
| 1613 | ;; no window, use nil | ||
| 1614 | nil | ||
| 1615 | (let ((default-amount | ||
| 1616 | (- (window-height merge-window) 1 next-screen-context-lines))) | ||
| 1617 | ;; the window was found | ||
| 1618 | (if arg | ||
| 1619 | ;; C-u as argument means half of default amount | ||
| 1620 | (/ default-amount 2) | ||
| 1621 | ;; no argument means default amount | ||
| 1622 | default-amount))))))) | ||
| 1623 | |||
| 1624 | (defun emerge-scroll-left (&optional arg) | ||
| 1625 | "Scroll left all three merge buffers, if they are in windows. | ||
| 1626 | If an ARGUMENT is given, that is how many columns are scrolled, else nearly | ||
| 1627 | the width of the A and B windows. `C-u -' alone as argument scrolls half the | ||
| 1628 | width of the A and B windows." | ||
| 1629 | (interactive "P") | ||
| 1630 | (emerge-operate-on-windows | ||
| 1631 | 'scroll-left | ||
| 1632 | ;; calculate argument to scroll-left | ||
| 1633 | ;; if there is an explicit argument | ||
| 1634 | (if (and arg (not (equal arg '-))) | ||
| 1635 | ;; use it | ||
| 1636 | (prefix-numeric-value arg) | ||
| 1637 | ;; if not, see if we can determine a default amount | ||
| 1638 | ;; (half the window width) | ||
| 1639 | (let ((merge-window (get-buffer-window emerge-merge-buffer))) | ||
| 1640 | (if (null merge-window) | ||
| 1641 | ;; no window, use nil | ||
| 1642 | nil | ||
| 1643 | (let ((default-amount | ||
| 1644 | (- (/ (window-width merge-window) 2) 3))) | ||
| 1645 | ;; the window was found | ||
| 1646 | (if arg | ||
| 1647 | ;; C-u as argument means half of default amount | ||
| 1648 | (/ default-amount 2) | ||
| 1649 | ;; no argument means default amount | ||
| 1650 | default-amount))))))) | ||
| 1651 | |||
| 1652 | (defun emerge-scroll-right (&optional arg) | ||
| 1653 | "Scroll right all three merge buffers, if they are in windows. | ||
| 1654 | If an ARGUMENT is given, that is how many columns are scrolled, else nearly | ||
| 1655 | the width of the A and B windows. `C-u -' alone as argument scrolls half the | ||
| 1656 | width of the A and B windows." | ||
| 1657 | (interactive "P") | ||
| 1658 | (emerge-operate-on-windows | ||
| 1659 | 'scroll-right | ||
| 1660 | ;; calculate argument to scroll-right | ||
| 1661 | ;; if there is an explicit argument | ||
| 1662 | (if (and arg (not (equal arg '-))) | ||
| 1663 | ;; use it | ||
| 1664 | (prefix-numeric-value arg) | ||
| 1665 | ;; if not, see if we can determine a default amount | ||
| 1666 | ;; (half the window width) | ||
| 1667 | (let ((merge-window (get-buffer-window emerge-merge-buffer))) | ||
| 1668 | (if (null merge-window) | ||
| 1669 | ;; no window, use nil | ||
| 1670 | nil | ||
| 1671 | (let ((default-amount | ||
| 1672 | (- (/ (window-width merge-window) 2) 3))) | ||
| 1673 | ;; the window was found | ||
| 1674 | (if arg | ||
| 1675 | ;; C-u as argument means half of default amount | ||
| 1676 | (/ default-amount 2) | ||
| 1677 | ;; no argument means default amount | ||
| 1678 | default-amount))))))) | ||
| 1679 | |||
| 1680 | (defun emerge-scroll-reset () | ||
| 1681 | "Reset horizontal scrolling of all three merge buffers to the left margin, | ||
| 1682 | if they are in windows." | ||
| 1683 | (interactive) | ||
| 1684 | (emerge-operate-on-windows | ||
| 1685 | (function (lambda (x) (set-window-hscroll (selected-window) 0))) | ||
| 1686 | nil)) | ||
| 1687 | |||
| 1688 | ;; Attempt to show the region nicely. | ||
| 1689 | ;; If there are min-lines lines above and below the region, then don't do | ||
| 1690 | ;; anything. | ||
| 1691 | ;; If not, recenter the region to make it so. | ||
| 1692 | ;; If that isn't possible, remove context lines balancedly from top and botton | ||
| 1693 | ;; so the entire region shows. | ||
| 1694 | ;; If that isn't possible, show the top of the region. | ||
| 1695 | ;; BEG must be at the beginning of a line. | ||
| 1696 | (defun emerge-position-region (beg end pos) | ||
| 1697 | ;; First test whether the entire region is visible with | ||
| 1698 | ;; emerge-min-visible-lines above and below it | ||
| 1699 | (if (not (and (<= (progn | ||
| 1700 | (move-to-window-line emerge-min-visible-lines) | ||
| 1701 | (point)) | ||
| 1702 | beg) | ||
| 1703 | (<= end (progn | ||
| 1704 | (move-to-window-line | ||
| 1705 | (- (1+ emerge-min-visible-lines))) | ||
| 1706 | (point))))) | ||
| 1707 | ;; We failed that test, see if it fits at all | ||
| 1708 | ;; Meanwhile positioning it correctly in case it doesn't fit | ||
| 1709 | (progn | ||
| 1710 | (set-window-start (selected-window) beg) | ||
| 1711 | (setq fits (pos-visible-in-window-p end)) | ||
| 1712 | (if fits | ||
| 1713 | ;; Determine the number of lines that the region occupies | ||
| 1714 | (let ((lines 0)) | ||
| 1715 | (while (> end (progn | ||
| 1716 | (move-to-window-line lines) | ||
| 1717 | (point))) | ||
| 1718 | (setq lines (1+ lines))) | ||
| 1719 | ;; And position the beginning on the right line | ||
| 1720 | (goto-char beg) | ||
| 1721 | (recenter (/ (1+ (- (1- (window-height (selected-window))) | ||
| 1722 | lines)) | ||
| 1723 | 2)))))) | ||
| 1724 | (goto-char pos)) | ||
| 1725 | |||
| 1726 | (defun emerge-next-difference () | ||
| 1727 | "Advance to the next difference." | ||
| 1728 | (interactive) | ||
| 1729 | (if (< emerge-current-difference emerge-number-of-differences) | ||
| 1730 | (let ((n (1+ emerge-current-difference))) | ||
| 1731 | (while (and emerge-skip-prefers | ||
| 1732 | (< n emerge-number-of-differences) | ||
| 1733 | (memq (aref (aref emerge-difference-list n) 6) | ||
| 1734 | '(prefer-A prefer-B))) | ||
| 1735 | (setq n (1+ n))) | ||
| 1736 | (let ((buffer-read-only nil)) | ||
| 1737 | (emerge-unselect-and-select-difference n))) | ||
| 1738 | (error "At end"))) | ||
| 1739 | |||
| 1740 | (defun emerge-previous-difference () | ||
| 1741 | "Go to the previous difference." | ||
| 1742 | (interactive) | ||
| 1743 | (if (> emerge-current-difference -1) | ||
| 1744 | (let ((n (1- emerge-current-difference))) | ||
| 1745 | (while (and emerge-skip-prefers | ||
| 1746 | (> n -1) | ||
| 1747 | (memq (aref (aref emerge-difference-list n) 6) | ||
| 1748 | '(prefer-A prefer-B))) | ||
| 1749 | (setq n (1- n))) | ||
| 1750 | (let ((buffer-read-only nil)) | ||
| 1751 | (emerge-unselect-and-select-difference n))) | ||
| 1752 | (error "At beginning"))) | ||
| 1753 | |||
| 1754 | (defun emerge-jump-to-difference (difference-number) | ||
| 1755 | "Go to the N-th difference." | ||
| 1756 | (interactive "p") | ||
| 1757 | (let ((buffer-read-only nil)) | ||
| 1758 | (setq difference-number (1- difference-number)) | ||
| 1759 | (if (and (>= difference-number -1) | ||
| 1760 | (< difference-number (1+ emerge-number-of-differences))) | ||
| 1761 | (emerge-unselect-and-select-difference difference-number) | ||
| 1762 | (error "Bad difference number")))) | ||
| 1763 | |||
| 1764 | (defun emerge-quit (arg) | ||
| 1765 | "Finish an Emerge session. Prefix ARGUMENT means to abort rather than | ||
| 1766 | successfully finish. The difference depends on how the merge was started, | ||
| 1767 | but usually means to not write over one of the original files, or to signal | ||
| 1768 | to some process which invoked Emerge a failure code. | ||
| 1769 | |||
| 1770 | Unselects the selected difference, if any, restores the read-only and modified | ||
| 1771 | flags of the merged file buffers, restores the local keymap of the merge | ||
| 1772 | buffer, and sets off various emerge flags. Using Emerge commands in this | ||
| 1773 | buffer after this will cause serious problems." | ||
| 1774 | (interactive "P") | ||
| 1775 | (if (prog1 | ||
| 1776 | (y-or-n-p | ||
| 1777 | (if (not arg) | ||
| 1778 | "Do you really want to successfully finish this merge? " | ||
| 1779 | "Do you really want to abort this merge? ")) | ||
| 1780 | (message "")) | ||
| 1781 | (emerge-really-quit arg))) | ||
| 1782 | |||
| 1783 | ;; Perform the quit operations. | ||
| 1784 | (defun emerge-really-quit (arg) | ||
| 1785 | (setq buffer-read-only nil) | ||
| 1786 | (emerge-unselect-and-select-difference -1) | ||
| 1787 | (emerge-restore-buffer-characteristics) | ||
| 1788 | ;; null out the difference markers so they don't slow down future editing | ||
| 1789 | ;; operations | ||
| 1790 | (mapcar (function (lambda (d) | ||
| 1791 | (set-marker (aref d 0) nil) | ||
| 1792 | (set-marker (aref d 1) nil) | ||
| 1793 | (set-marker (aref d 2) nil) | ||
| 1794 | (set-marker (aref d 3) nil) | ||
| 1795 | (set-marker (aref d 4) nil) | ||
| 1796 | (set-marker (aref d 5) nil))) | ||
| 1797 | emerge-difference-list) | ||
| 1798 | ;; allow them to be garbage collected | ||
| 1799 | (setq emerge-difference-list nil) | ||
| 1800 | ;; restore the local map | ||
| 1801 | (use-local-map emerge-old-keymap) | ||
| 1802 | ;; turn off all the emerge modes | ||
| 1803 | (setq emerge-mode nil) | ||
| 1804 | (setq emerge-fast-mode nil) | ||
| 1805 | (setq emerge-edit-mode nil) | ||
| 1806 | (setq emerge-auto-advance nil) | ||
| 1807 | (setq emerge-skip-prefers nil) | ||
| 1808 | ;; restore mode line | ||
| 1809 | (kill-local-variable 'mode-line-buffer-identification) | ||
| 1810 | (let ((emerge-prefix-argument arg)) | ||
| 1811 | (run-hooks 'emerge-quit-hooks))) | ||
| 1812 | |||
| 1813 | (defun emerge-select-A (&optional force) | ||
| 1814 | "Select the A variant of this difference. Refuses to function if this | ||
| 1815 | difference has been edited, i.e., if it is neither the A nor the B variant. | ||
| 1816 | An ARGUMENT forces the variant to be selected even if the difference has | ||
| 1817 | been edited." | ||
| 1818 | (interactive "P") | ||
| 1819 | (let ((operate | ||
| 1820 | (function (lambda () | ||
| 1821 | (emerge-select-A-edit merge-begin merge-end A-begin A-end) | ||
| 1822 | (if emerge-auto-advance | ||
| 1823 | (emerge-next-difference))))) | ||
| 1824 | (operate-no-change | ||
| 1825 | (function (lambda () | ||
| 1826 | (if emerge-auto-advance | ||
| 1827 | (emerge-next-difference)))))) | ||
| 1828 | (emerge-select-version force operate-no-change operate operate))) | ||
| 1829 | |||
| 1830 | ;; Actually select the A variant | ||
| 1831 | (defun emerge-select-A-edit (merge-begin merge-end A-begin A-end) | ||
| 1832 | (emerge-eval-in-buffer | ||
| 1833 | emerge-merge-buffer | ||
| 1834 | (delete-region merge-begin merge-end) | ||
| 1835 | (goto-char merge-begin) | ||
| 1836 | (insert-buffer-substring emerge-A-buffer A-begin A-end) | ||
| 1837 | (goto-char merge-begin) | ||
| 1838 | (aset diff-vector 6 'A) | ||
| 1839 | (emerge-refresh-mode-line))) | ||
| 1840 | |||
| 1841 | (defun emerge-select-B (&optional force) | ||
| 1842 | "Select the B variant of this difference. Refuses to function if this | ||
| 1843 | difference has been edited, i.e., if it is neither the A nor the B variant. | ||
| 1844 | An ARGUMENT forces the variant to be selected even if the difference has | ||
| 1845 | been edited." | ||
| 1846 | (interactive "P") | ||
| 1847 | (let ((operate | ||
| 1848 | (function (lambda () | ||
| 1849 | (emerge-select-B-edit merge-begin merge-end B-begin B-end) | ||
| 1850 | (if emerge-auto-advance | ||
| 1851 | (emerge-next-difference))))) | ||
| 1852 | (operate-no-change | ||
| 1853 | (function (lambda () | ||
| 1854 | (if emerge-auto-advance | ||
| 1855 | (emerge-next-difference)))))) | ||
| 1856 | (emerge-select-version force operate operate-no-change operate))) | ||
| 1857 | |||
| 1858 | ;; Actually select the B variant | ||
| 1859 | (defun emerge-select-B-edit (merge-begin merge-end B-begin B-end) | ||
| 1860 | (emerge-eval-in-buffer | ||
| 1861 | emerge-merge-buffer | ||
| 1862 | (delete-region merge-begin merge-end) | ||
| 1863 | (goto-char merge-begin) | ||
| 1864 | (insert-buffer-substring emerge-B-buffer B-begin B-end) | ||
| 1865 | (goto-char merge-begin) | ||
| 1866 | (aset diff-vector 6 'B) | ||
| 1867 | (emerge-refresh-mode-line))) | ||
| 1868 | |||
| 1869 | (defun emerge-default-A () | ||
| 1870 | "Selects the A variant for all differences from here down in the buffer | ||
| 1871 | which are still defaulted, i.e., which the user has not selected and for | ||
| 1872 | which there is no preference." | ||
| 1873 | (interactive) | ||
| 1874 | (let ((buffer-read-only nil)) | ||
| 1875 | (let ((selected-difference emerge-current-difference) | ||
| 1876 | (n (max emerge-current-difference 0))) | ||
| 1877 | (while (< n emerge-number-of-differences) | ||
| 1878 | (let ((diff-vector (aref emerge-difference-list n))) | ||
| 1879 | (if (eq (aref diff-vector 6) 'default-B) | ||
| 1880 | (progn | ||
| 1881 | (emerge-unselect-and-select-difference n t) | ||
| 1882 | (emerge-select-A) | ||
| 1883 | (aset diff-vector 6 'default-A)))) | ||
| 1884 | (setq n (1+ n)) | ||
| 1885 | (if (= (* (/ n 10) 10) n) | ||
| 1886 | (message "Setting default to A...%d" n))) | ||
| 1887 | (emerge-unselect-and-select-difference selected-difference))) | ||
| 1888 | (message "Default A set")) | ||
| 1889 | |||
| 1890 | (defun emerge-default-B () | ||
| 1891 | "Selects the B variant for all differences from here down in the buffer | ||
| 1892 | which are still defaulted, i.e., which the user has not selected and for | ||
| 1893 | which there is no preference." | ||
| 1894 | (interactive) | ||
| 1895 | (let ((buffer-read-only nil)) | ||
| 1896 | (let ((selected-difference emerge-current-difference) | ||
| 1897 | (n (max emerge-current-difference 0))) | ||
| 1898 | (while (< n emerge-number-of-differences) | ||
| 1899 | (let ((diff-vector (aref emerge-difference-list n))) | ||
| 1900 | (if (eq (aref diff-vector 6) 'default-A) | ||
| 1901 | (progn | ||
| 1902 | (emerge-unselect-and-select-difference n t) | ||
| 1903 | (emerge-select-B) | ||
| 1904 | (aset diff-vector 6 'default-B)))) | ||
| 1905 | (setq n (1+ n)) | ||
| 1906 | (if (= (* (/ n 10) 10) n) | ||
| 1907 | (message "Setting default to B...%d" n))) | ||
| 1908 | (emerge-unselect-and-select-difference selected-difference))) | ||
| 1909 | (message "Default B set")) | ||
| 1910 | |||
| 1911 | (defun emerge-fast-mode () | ||
| 1912 | "Set fast mode, in which ordinary Emacs commands are disabled, and Emerge | ||
| 1913 | commands are need not be prefixed with \\<emerge-fast-keymap>\\[emerge-basic-keymap]." | ||
| 1914 | (interactive) | ||
| 1915 | (setq buffer-read-only t) | ||
| 1916 | (use-local-map emerge-fast-keymap) | ||
| 1917 | (setq emerge-mode t) | ||
| 1918 | (setq emerge-fast-mode t) | ||
| 1919 | (setq emerge-edit-mode nil) | ||
| 1920 | (message "Fast mode set") | ||
| 1921 | ;; force mode line redisplay | ||
| 1922 | (set-buffer-modified-p (buffer-modified-p))) | ||
| 1923 | |||
| 1924 | (defun emerge-edit-mode () | ||
| 1925 | "Set edit mode, in which ordinary Emacs commands are available, and Emerge | ||
| 1926 | commands must be prefixed with \\<emerge-fast-keymap>\\[emerge-basic-keymap]." | ||
| 1927 | (interactive) | ||
| 1928 | (setq buffer-read-only nil) | ||
| 1929 | (use-local-map emerge-edit-keymap) | ||
| 1930 | (setq emerge-mode t) | ||
| 1931 | (setq emerge-fast-mode nil) | ||
| 1932 | (setq emerge-edit-mode t) | ||
| 1933 | (message "Edit mode set") | ||
| 1934 | ;; force mode line redisplay | ||
| 1935 | (set-buffer-modified-p (buffer-modified-p))) | ||
| 1936 | |||
| 1937 | (defun emerge-auto-advance (arg) | ||
| 1938 | "Toggle auto-advance mode, which causes emerge-select-A and | ||
| 1939 | emerge-select-B to automatically advance to the next difference. (See | ||
| 1940 | emerge-auto-advance.) | ||
| 1941 | If a positive ARGUMENT is given, it turns on auto-advance mode. | ||
| 1942 | If a negative ARGUMENT is given, it turns off auto-advance mode." | ||
| 1943 | (interactive "P") | ||
| 1944 | (setq emerge-auto-advance (if (null arg) | ||
| 1945 | (not emerge-auto-advance) | ||
| 1946 | (> (prefix-numeric-value arg) 0))) | ||
| 1947 | (message (if emerge-skip-prefers | ||
| 1948 | "Auto-advance set" | ||
| 1949 | "Auto-advance cleared")) | ||
| 1950 | ;; force mode line redisplay | ||
| 1951 | (set-buffer-modified-p (buffer-modified-p))) | ||
| 1952 | |||
| 1953 | (defun emerge-skip-prefers (arg) | ||
| 1954 | "Toggle skip-prefers mode, which causes emerge-next-difference and | ||
| 1955 | emerge-previous-difference to automatically skip over differences for which | ||
| 1956 | there is a preference. (See emerge-skip-prefers.) | ||
| 1957 | If a positive ARGUMENT is given, it turns on skip-prefers mode. | ||
| 1958 | If a negative ARGUMENT is given, it turns off skip-prefers mode." | ||
| 1959 | (interactive "P") | ||
| 1960 | (setq emerge-skip-prefers (if (null arg) | ||
| 1961 | (not emerge-skip-prefers) | ||
| 1962 | (> (prefix-numeric-value arg) 0))) | ||
| 1963 | (message (if emerge-skip-prefers | ||
| 1964 | "Skip-prefers set" | ||
| 1965 | "Skip-prefers cleared")) | ||
| 1966 | ;; force mode line redisplay | ||
| 1967 | (set-buffer-modified-p (buffer-modified-p))) | ||
| 1968 | |||
| 1969 | (defun emerge-copy-as-kill-A () | ||
| 1970 | "Put the A variant of this difference in the kill ring." | ||
| 1971 | (interactive) | ||
| 1972 | (emerge-validate-difference) | ||
| 1973 | (let* ((diff-vector | ||
| 1974 | (aref emerge-difference-list emerge-current-difference)) | ||
| 1975 | (A-begin (1+ (aref diff-vector 0))) | ||
| 1976 | (A-end (1- (aref diff-vector 1))) | ||
| 1977 | ;; so further kills don't append | ||
| 1978 | this-command) | ||
| 1979 | (save-excursion | ||
| 1980 | (set-buffer emerge-A-buffer) | ||
| 1981 | (copy-region-as-kill A-begin A-end)))) | ||
| 1982 | |||
| 1983 | (defun emerge-copy-as-kill-B () | ||
| 1984 | "Put the B variant of this difference in the kill ring." | ||
| 1985 | (interactive) | ||
| 1986 | (emerge-validate-difference) | ||
| 1987 | (let* ((diff-vector | ||
| 1988 | (aref emerge-difference-list emerge-current-difference)) | ||
| 1989 | (B-begin (1+ (aref diff-vector 2))) | ||
| 1990 | (B-end (1- (aref diff-vector 3))) | ||
| 1991 | ;; so further kills don't append | ||
| 1992 | this-command) | ||
| 1993 | (save-excursion | ||
| 1994 | (set-buffer emerge-B-buffer) | ||
| 1995 | (copy-region-as-kill B-begin B-end)))) | ||
| 1996 | |||
| 1997 | (defun emerge-insert-A (arg) | ||
| 1998 | "Insert the A variant of this difference at the point. | ||
| 1999 | Leaves point after text, mark before. | ||
| 2000 | With prefix argument, puts point before, mark after." | ||
| 2001 | (interactive "P") | ||
| 2002 | (emerge-validate-difference) | ||
| 2003 | (let* ((diff-vector | ||
| 2004 | (aref emerge-difference-list emerge-current-difference)) | ||
| 2005 | (A-begin (1+ (aref diff-vector 0))) | ||
| 2006 | (A-end (1- (aref diff-vector 1))) | ||
| 2007 | (opoint (point)) | ||
| 2008 | (buffer-read-only nil)) | ||
| 2009 | (insert-buffer-substring emerge-A-buffer A-begin A-end) | ||
| 2010 | (if (not arg) | ||
| 2011 | (set-mark opoint) | ||
| 2012 | (set-mark (point)) | ||
| 2013 | (goto-char opoint)))) | ||
| 2014 | |||
| 2015 | (defun emerge-insert-B (arg) | ||
| 2016 | "Insert the B variant of this difference at the point. | ||
| 2017 | Leaves point after text, mark before. | ||
| 2018 | With prefix argument, puts point before, mark after." | ||
| 2019 | (interactive "P") | ||
| 2020 | (emerge-validate-difference) | ||
| 2021 | (let* ((diff-vector | ||
| 2022 | (aref emerge-difference-list emerge-current-difference)) | ||
| 2023 | (B-begin (1+ (aref diff-vector 2))) | ||
| 2024 | (B-end (1- (aref diff-vector 3))) | ||
| 2025 | (opoint (point)) | ||
| 2026 | (buffer-read-only nil)) | ||
| 2027 | (insert-buffer-substring emerge-B-buffer B-begin B-end) | ||
| 2028 | (if (not arg) | ||
| 2029 | (set-mark opoint) | ||
| 2030 | (set-mark (point)) | ||
| 2031 | (goto-char opoint)))) | ||
| 2032 | |||
| 2033 | (defun emerge-mark-difference (arg) | ||
| 2034 | "Leaves the point before this difference and the mark after it. | ||
| 2035 | With prefix argument, puts mark before, point after." | ||
| 2036 | (interactive "P") | ||
| 2037 | (emerge-validate-difference) | ||
| 2038 | (let* ((diff-vector | ||
| 2039 | (aref emerge-difference-list emerge-current-difference)) | ||
| 2040 | (merge-begin (1+ (aref diff-vector 4))) | ||
| 2041 | (merge-end (1- (aref diff-vector 5)))) | ||
| 2042 | (if (not arg) | ||
| 2043 | (progn | ||
| 2044 | (goto-char merge-begin) | ||
| 2045 | (set-mark merge-end)) | ||
| 2046 | (goto-char merge-end) | ||
| 2047 | (set-mark merge-begin)))) | ||
| 2048 | |||
| 2049 | (defun emerge-file-names () | ||
| 2050 | "Show the names of the buffers or files being operated on by Emerge. | ||
| 2051 | Use ^U L to reset the windows afterward." | ||
| 2052 | (interactive) | ||
| 2053 | (delete-other-windows) | ||
| 2054 | (let ((temp-buffer-show-hook | ||
| 2055 | (function (lambda (buf) | ||
| 2056 | (split-window-vertically) | ||
| 2057 | (switch-to-buffer buf) | ||
| 2058 | (other-window 1))))) | ||
| 2059 | (with-output-to-temp-buffer "*Help*" | ||
| 2060 | (emerge-eval-in-buffer emerge-A-buffer | ||
| 2061 | (if buffer-file-name | ||
| 2062 | (progn | ||
| 2063 | (princ "File A is: ") | ||
| 2064 | (princ buffer-file-name)) | ||
| 2065 | (progn | ||
| 2066 | (princ "Buffer A is: ") | ||
| 2067 | (princ (buffer-name)))) | ||
| 2068 | (princ "\n")) | ||
| 2069 | (emerge-eval-in-buffer emerge-B-buffer | ||
| 2070 | (if buffer-file-name | ||
| 2071 | (progn | ||
| 2072 | (princ "File B is: ") | ||
| 2073 | (princ buffer-file-name)) | ||
| 2074 | (progn | ||
| 2075 | (princ "Buffer B is: ") | ||
| 2076 | (princ (buffer-name)))) | ||
| 2077 | (princ "\n")) | ||
| 2078 | (if emerge-ancestor-buffer | ||
| 2079 | (emerge-eval-in-buffer emerge-ancestor-buffer | ||
| 2080 | (if buffer-file-name | ||
| 2081 | (progn | ||
| 2082 | (princ "Ancestor file is: ") | ||
| 2083 | (princ buffer-file-name)) | ||
| 2084 | (progn | ||
| 2085 | (princ "Ancestor buffer is: ") | ||
| 2086 | (princ (buffer-name)))) | ||
| 2087 | (princ "\n"))) | ||
| 2088 | (princ emerge-output-description)))) | ||
| 2089 | |||
| 2090 | (defun emerge-join-differences (arg) | ||
| 2091 | "Join the selected difference with the following one. With a prefix | ||
| 2092 | argument, join with the preceeding one." | ||
| 2093 | (interactive "P") | ||
| 2094 | (let ((n emerge-current-difference)) | ||
| 2095 | ;; adjust n to be first difference to join | ||
| 2096 | (if arg | ||
| 2097 | (setq n (1- n))) | ||
| 2098 | ;; n and n+1 are the differences to join | ||
| 2099 | ;; check that they are both differences | ||
| 2100 | (if (or (< n 0) (>= n (1- emerge-number-of-differences))) | ||
| 2101 | (error "Incorrect differences to join")) | ||
| 2102 | ;; remove the flags | ||
| 2103 | (emerge-unselect-difference emerge-current-difference) | ||
| 2104 | ;; decrement total number of differences | ||
| 2105 | (setq emerge-number-of-differences (1- emerge-number-of-differences)) | ||
| 2106 | ;; build new differences vector | ||
| 2107 | (let ((i 0) | ||
| 2108 | (new-differences (make-vector emerge-number-of-differences nil))) | ||
| 2109 | (while (< i emerge-number-of-differences) | ||
| 2110 | (aset new-differences i | ||
| 2111 | (cond | ||
| 2112 | ((< i n) (aref emerge-difference-list i)) | ||
| 2113 | ((> i n) (aref emerge-difference-list (1+ i))) | ||
| 2114 | (t (let ((prev (aref emerge-difference-list i)) | ||
| 2115 | (next (aref emerge-difference-list (1+ i)))) | ||
| 2116 | (vector (aref prev 0) | ||
| 2117 | (aref next 1) | ||
| 2118 | (aref prev 2) | ||
| 2119 | (aref next 3) | ||
| 2120 | (aref prev 4) | ||
| 2121 | (aref next 5) | ||
| 2122 | (let ((ps (aref prev 6)) | ||
| 2123 | (ns (aref next 6))) | ||
| 2124 | (cond | ||
| 2125 | ((eq ps ns) | ||
| 2126 | ps) | ||
| 2127 | ((and (or (eq ps 'B) (eq ps 'prefer-B)) | ||
| 2128 | (or (eq ns 'B) (eq ns 'prefer-B))) | ||
| 2129 | 'B) | ||
| 2130 | (t 'A)))))))) | ||
| 2131 | (setq i (1+ i))) | ||
| 2132 | (setq emerge-difference-list new-differences)) | ||
| 2133 | ;; set the current difference correctly | ||
| 2134 | (setq emerge-current-difference n) | ||
| 2135 | ;; fix the mode line | ||
| 2136 | (emerge-refresh-mode-line) | ||
| 2137 | ;; reinsert the flags | ||
| 2138 | (emerge-select-difference emerge-current-difference) | ||
| 2139 | (emerge-recenter))) | ||
| 2140 | |||
| 2141 | (defun emerge-split-difference () | ||
| 2142 | "Split the current difference where the points are in the three windows." | ||
| 2143 | (interactive) | ||
| 2144 | (let ((n emerge-current-difference)) | ||
| 2145 | ;; check that this is a valid difference | ||
| 2146 | (emerge-validate-difference) | ||
| 2147 | ;; get the point values and old difference | ||
| 2148 | (let ((A-point (emerge-eval-in-buffer emerge-A-buffer | ||
| 2149 | (point-marker))) | ||
| 2150 | (B-point (emerge-eval-in-buffer emerge-B-buffer | ||
| 2151 | (point-marker))) | ||
| 2152 | (merge-point (point-marker)) | ||
| 2153 | (old-diff (aref emerge-difference-list n))) | ||
| 2154 | ;; check location of the points, give error if they aren't in the | ||
| 2155 | ;; differences | ||
| 2156 | (if (or (< A-point (aref old-diff 0)) | ||
| 2157 | (> A-point (aref old-diff 1))) | ||
| 2158 | (error "Point outside of difference in A buffer")) | ||
| 2159 | (if (or (< B-point (aref old-diff 2)) | ||
| 2160 | (> B-point (aref old-diff 3))) | ||
| 2161 | (error "Point outside of difference in B buffer")) | ||
| 2162 | (if (or (< merge-point (aref old-diff 4)) | ||
| 2163 | (> merge-point (aref old-diff 5))) | ||
| 2164 | (error "Point outside of difference in merge buffer")) | ||
| 2165 | ;; remove the flags | ||
| 2166 | (emerge-unselect-difference emerge-current-difference) | ||
| 2167 | ;; increment total number of differences | ||
| 2168 | (setq emerge-number-of-differences (1+ emerge-number-of-differences)) | ||
| 2169 | ;; build new differences vector | ||
| 2170 | (let ((i 0) | ||
| 2171 | (new-differences (make-vector emerge-number-of-differences nil))) | ||
| 2172 | (while (< i emerge-number-of-differences) | ||
| 2173 | (aset new-differences i | ||
| 2174 | (cond | ||
| 2175 | ((< i n) | ||
| 2176 | (aref emerge-difference-list i)) | ||
| 2177 | ((> i (1+ n)) | ||
| 2178 | (aref emerge-difference-list (1- i))) | ||
| 2179 | ((= i n) | ||
| 2180 | (vector (aref old-diff 0) | ||
| 2181 | A-point | ||
| 2182 | (aref old-diff 2) | ||
| 2183 | B-point | ||
| 2184 | (aref old-diff 4) | ||
| 2185 | merge-point | ||
| 2186 | (aref old-diff 6))) | ||
| 2187 | (t | ||
| 2188 | (vector (copy-marker A-point) | ||
| 2189 | (aref old-diff 1) | ||
| 2190 | (copy-marker B-point) | ||
| 2191 | (aref old-diff 3) | ||
| 2192 | (copy-marker merge-point) | ||
| 2193 | (aref old-diff 5) | ||
| 2194 | (aref old-diff 6))))) | ||
| 2195 | (setq i (1+ i))) | ||
| 2196 | (setq emerge-difference-list new-differences)) | ||
| 2197 | ;; set the current difference correctly | ||
| 2198 | (setq emerge-current-difference n) | ||
| 2199 | ;; fix the mode line | ||
| 2200 | (emerge-refresh-mode-line) | ||
| 2201 | ;; reinsert the flags | ||
| 2202 | (emerge-select-difference emerge-current-difference) | ||
| 2203 | (emerge-recenter)))) | ||
| 2204 | |||
| 2205 | (defun emerge-trim-difference () | ||
| 2206 | "Trim lines off the top and bottom of a difference that are the same in | ||
| 2207 | both the A and B versions. (This can happen when the A and B versions | ||
| 2208 | have common lines that the ancestor version does not share.)" | ||
| 2209 | (interactive) | ||
| 2210 | ;; make sure we are in a real difference | ||
| 2211 | (emerge-validate-difference) | ||
| 2212 | ;; remove the flags | ||
| 2213 | (emerge-unselect-difference emerge-current-difference) | ||
| 2214 | (let* ((diff (aref emerge-difference-list emerge-current-difference)) | ||
| 2215 | (top-a (marker-position (aref diff 0))) | ||
| 2216 | (bottom-a (marker-position (aref diff 1))) | ||
| 2217 | (top-b (marker-position (aref diff 2))) | ||
| 2218 | (bottom-b (marker-position (aref diff 3))) | ||
| 2219 | (top-m (marker-position (aref diff 4))) | ||
| 2220 | (bottom-m (marker-position (aref diff 5))) | ||
| 2221 | size success sa sb sm) | ||
| 2222 | ;; move down the tops of the difference regions as much as possible | ||
| 2223 | ;; Try advancing comparing 1000 chars at a time. | ||
| 2224 | ;; When that fails, go 500 chars at a time, and so on. | ||
| 2225 | (setq size 1000) | ||
| 2226 | (while (> size 0) | ||
| 2227 | (setq success t) | ||
| 2228 | (while success | ||
| 2229 | (setq size (min size (- bottom-a top-a) (- bottom-b top-b) | ||
| 2230 | (- bottom-m top-m))) | ||
| 2231 | (setq sa (emerge-eval-in-buffer emerge-A-buffer | ||
| 2232 | (buffer-substring top-a | ||
| 2233 | (+ size top-a)))) | ||
| 2234 | (setq sb (emerge-eval-in-buffer emerge-B-buffer | ||
| 2235 | (buffer-substring top-b | ||
| 2236 | (+ size top-b)))) | ||
| 2237 | (setq sm (buffer-substring top-m (+ size top-m))) | ||
| 2238 | (setq success (and (> size 0) (equal sa sb) (equal sb sm))) | ||
| 2239 | (if success | ||
| 2240 | (setq top-a (+ top-a size) | ||
| 2241 | top-b (+ top-b size) | ||
| 2242 | top-m (+ top-m size)))) | ||
| 2243 | (setq size (/ size 2))) | ||
| 2244 | ;; move up the bottoms of the difference regions as much as possible | ||
| 2245 | ;; Try advancing comparing 1000 chars at a time. | ||
| 2246 | ;; When that fails, go 500 chars at a time, and so on. | ||
| 2247 | (setq size 1000) | ||
| 2248 | (while (> size 0) | ||
| 2249 | (setq success t) | ||
| 2250 | (while success | ||
| 2251 | (setq size (min size (- bottom-a top-a) (- bottom-b top-b) | ||
| 2252 | (- bottom-m top-m))) | ||
| 2253 | (setq sa (emerge-eval-in-buffer emerge-A-buffer | ||
| 2254 | (buffer-substring (- bottom-a size) | ||
| 2255 | bottom-a))) | ||
| 2256 | (setq sb (emerge-eval-in-buffer emerge-B-buffer | ||
| 2257 | (buffer-substring (- bottom-b size) | ||
| 2258 | bottom-b))) | ||
| 2259 | (setq sm (buffer-substring (- bottom-m size) bottom-m)) | ||
| 2260 | (setq success (and (> size 0) (equal sa sb) (equal sb sm))) | ||
| 2261 | (if success | ||
| 2262 | (setq bottom-a (- bottom-a size) | ||
| 2263 | bottom-b (- bottom-b size) | ||
| 2264 | bottom-m (- bottom-m size)))) | ||
| 2265 | (setq size (/ size 2))) | ||
| 2266 | ;; {top,bottom}-{a,b,m} are now set at the new beginnings and ends | ||
| 2267 | ;; of the difference regions. Move them to the beginning of lines, as | ||
| 2268 | ;; appropriate. | ||
| 2269 | (emerge-eval-in-buffer emerge-A-buffer | ||
| 2270 | (goto-char top-a) | ||
| 2271 | (beginning-of-line) | ||
| 2272 | (aset diff 0 (point-marker)) | ||
| 2273 | (goto-char bottom-a) | ||
| 2274 | (beginning-of-line 2) | ||
| 2275 | (aset diff 1 (point-marker))) | ||
| 2276 | (emerge-eval-in-buffer emerge-B-buffer | ||
| 2277 | (goto-char top-b) | ||
| 2278 | (beginning-of-line) | ||
| 2279 | (aset diff 2 (point-marker)) | ||
| 2280 | (goto-char bottom-b) | ||
| 2281 | (beginning-of-line 2) | ||
| 2282 | (aset diff 3 (point-marker))) | ||
| 2283 | (goto-char top-m) | ||
| 2284 | (beginning-of-line) | ||
| 2285 | (aset diff 4 (point-marker)) | ||
| 2286 | (goto-char bottom-m) | ||
| 2287 | (beginning-of-line 2) | ||
| 2288 | (aset diff 5 (point-marker)) | ||
| 2289 | ;; put the flags back in, recenter the display | ||
| 2290 | (emerge-select-difference emerge-current-difference) | ||
| 2291 | (emerge-recenter))) | ||
| 2292 | |||
| 2293 | (defun emerge-find-difference (arg) | ||
| 2294 | "Find the difference containing the current position of the point. | ||
| 2295 | If there is no containing difference and the prefix argument is positive, | ||
| 2296 | it finds the nearest following difference. A negative prefix argument finds | ||
| 2297 | the nearest previous difference." | ||
| 2298 | (interactive "P") | ||
| 2299 | ;; search for the point in the merge buffer, using the markers | ||
| 2300 | ;; for the beginning and end of the differences in the merge buffer | ||
| 2301 | (emerge-find-difference1 arg (point) 4 5)) | ||
| 2302 | |||
| 2303 | (defun emerge-find-difference-A (arg) | ||
| 2304 | "Find the difference containing the current position of the point in the | ||
| 2305 | A buffer. (Nonetheless, this command must be executed in the merge buffer.) | ||
| 2306 | If there is no containing difference and the prefix argument is positive, | ||
| 2307 | it finds the nearest following difference. A negative prefix argument finds | ||
| 2308 | the nearest previous difference." | ||
| 2309 | (interactive "P") | ||
| 2310 | ;; search for the point in the A buffer, using the markers | ||
| 2311 | ;; for the beginning and end of the differences in the A buffer | ||
| 2312 | (emerge-find-difference1 arg | ||
| 2313 | (emerge-eval-in-buffer emerge-A-buffer (point)) | ||
| 2314 | 0 1)) | ||
| 2315 | |||
| 2316 | (defun emerge-find-difference-B (arg) | ||
| 2317 | "Find the difference containing the current position of the point in the | ||
| 2318 | B buffer. (Nonetheless, this command must be executed in the merge buffer.) | ||
| 2319 | If there is no containing difference and the prefix argument is positive, | ||
| 2320 | it finds the nearest following difference. A negative prefix argument finds | ||
| 2321 | the nearest previous difference." | ||
| 2322 | (interactive "P") | ||
| 2323 | ;; search for the point in the B buffer, using the markers | ||
| 2324 | ;; for the beginning and end of the differences in the B buffer | ||
| 2325 | (emerge-find-difference1 arg | ||
| 2326 | (emerge-eval-in-buffer emerge-B-buffer (point)) | ||
| 2327 | 2 3)) | ||
| 2328 | |||
| 2329 | (defun emerge-find-difference1 (arg location begin end) | ||
| 2330 | (let* ((index | ||
| 2331 | ;; find first difference containing or after the current position | ||
| 2332 | (catch 'search | ||
| 2333 | (let ((n 0)) | ||
| 2334 | (while (< n emerge-number-of-differences) | ||
| 2335 | (let ((diff-vector (aref emerge-difference-list n))) | ||
| 2336 | (if (<= location (marker-position (aref diff-vector end))) | ||
| 2337 | (throw 'search n))) | ||
| 2338 | (setq n (1+ n)))) | ||
| 2339 | emerge-number-of-differences)) | ||
| 2340 | (contains | ||
| 2341 | ;; whether the found difference contains the current position | ||
| 2342 | (and (< index emerge-number-of-differences) | ||
| 2343 | (<= (marker-position (aref (aref emerge-difference-list index) | ||
| 2344 | begin)) | ||
| 2345 | location))) | ||
| 2346 | (arg-value | ||
| 2347 | ;; numeric value of prefix argument | ||
| 2348 | (prefix-numeric-value arg))) | ||
| 2349 | (emerge-unselect-and-select-difference | ||
| 2350 | (cond | ||
| 2351 | ;; if the point is in a difference, select it | ||
| 2352 | (contains index) | ||
| 2353 | ;; if the arg is nil and the point is not in a difference, error | ||
| 2354 | ((null arg) (error "No difference contains point")) | ||
| 2355 | ;; if the arg is positive, select the following difference | ||
| 2356 | ((> arg-value 0) | ||
| 2357 | (if (< index emerge-number-of-differences) | ||
| 2358 | index | ||
| 2359 | (error "No difference contains or follows point"))) | ||
| 2360 | ;; if the arg is negative, select the preceeding difference | ||
| 2361 | (t | ||
| 2362 | (if (> index 0) | ||
| 2363 | (1- index) | ||
| 2364 | (error "No difference contains or preceeds point"))))))) | ||
| 2365 | |||
| 2366 | (defun emerge-line-numbers () | ||
| 2367 | "Display the current line numbers of the points in the A, B, and | ||
| 2368 | merge buffers." | ||
| 2369 | (interactive) | ||
| 2370 | (let* ((valid-diff | ||
| 2371 | (and (>= emerge-current-difference 0) | ||
| 2372 | (< emerge-current-difference emerge-number-of-differences))) | ||
| 2373 | (diff (and valid-diff | ||
| 2374 | (aref emerge-difference-list emerge-current-difference))) | ||
| 2375 | (merge-line (emerge-line-number-in-buf 4 5)) | ||
| 2376 | (A-line (emerge-eval-in-buffer emerge-A-buffer | ||
| 2377 | (emerge-line-number-in-buf 0 1))) | ||
| 2378 | (B-line (emerge-eval-in-buffer emerge-B-buffer | ||
| 2379 | (emerge-line-number-in-buf 2 3)))) | ||
| 2380 | (message "At lines: merge = %d, A = %d, B = %d" | ||
| 2381 | merge-line A-line B-line))) | ||
| 2382 | |||
| 2383 | (defun emerge-line-number-in-buf (begin-marker end-marker) | ||
| 2384 | (let (temp) | ||
| 2385 | (setq temp (save-excursion | ||
| 2386 | (beginning-of-line) | ||
| 2387 | (1+ (count-lines 1 (point))))) | ||
| 2388 | (if valid-diff | ||
| 2389 | (progn | ||
| 2390 | (if (> (point) (aref diff begin-marker)) | ||
| 2391 | (setq temp (- temp emerge-before-flag-lines))) | ||
| 2392 | (if (> (point) (aref diff end-marker)) | ||
| 2393 | (setq temp (- temp emerge-after-flag-lines))))) | ||
| 2394 | temp)) | ||
| 2395 | |||
| 2396 | (defun emerge-set-combine-versions-template (start end &optional localize) | ||
| 2397 | "Copy region into emerge-combine-versions-template which controls how | ||
| 2398 | emerge-combine-versions will combine the two versions. | ||
| 2399 | With prefix argument, emerge-combine-versions is made local to this | ||
| 2400 | merge buffer. Localization is permanent for any particular merge buffer." | ||
| 2401 | (interactive "r\nP") | ||
| 2402 | (if localize | ||
| 2403 | (make-local-variable 'emerge-combine-versions-template)) | ||
| 2404 | (setq emerge-combine-versions-template (buffer-substring start end)) | ||
| 2405 | (message | ||
| 2406 | (if (assq 'emerge-combine-versions-template (buffer-local-variables)) | ||
| 2407 | "emerge-set-combine-versions-template set locally." | ||
| 2408 | "emerge-set-combine-versions-template set."))) | ||
| 2409 | |||
| 2410 | (defun emerge-combine-versions (&optional force) | ||
| 2411 | "Combine the two versions using the template in | ||
| 2412 | emerge-combine-versions-template. | ||
| 2413 | Refuses to function if this difference has been edited, i.e., if it is | ||
| 2414 | neither the A nor the B variant. | ||
| 2415 | An ARGUMENT forces the variant to be selected even if the difference has | ||
| 2416 | been edited." | ||
| 2417 | (interactive "P") | ||
| 2418 | (emerge-combine-versions-internal emerge-combine-versions-template force)) | ||
| 2419 | |||
| 2420 | (defun emerge-combine-versions-register (char &optional force) | ||
| 2421 | "Combine the two versions using the template in register REG. | ||
| 2422 | See documentation of the variable emerge-combine-versions-template | ||
| 2423 | for how the template is interpreted. | ||
| 2424 | Refuses to function if this difference has been edited, i.e., if it is | ||
| 2425 | neither the A nor the B variant. | ||
| 2426 | An ARGUMENT forces the variant to be selected even if the difference has | ||
| 2427 | been edited." | ||
| 2428 | (interactive "cRegister containing template: \nP") | ||
| 2429 | (let ((template (get-register char))) | ||
| 2430 | (if (not (stringp template)) | ||
| 2431 | (error "Register does not contain text")) | ||
| 2432 | (emerge-combine-versions-internal template force))) | ||
| 2433 | |||
| 2434 | (defun emerge-combine-versions-internal (template force) | ||
| 2435 | (let ((operate | ||
| 2436 | (function (lambda () | ||
| 2437 | (emerge-combine-versions-edit merge-begin merge-end | ||
| 2438 | A-begin A-end B-begin B-end) | ||
| 2439 | (if emerge-auto-advance | ||
| 2440 | (emerge-next-difference)))))) | ||
| 2441 | (emerge-select-version force operate operate operate))) | ||
| 2442 | |||
| 2443 | (defun emerge-combine-versions-edit (merge-begin merge-end | ||
| 2444 | A-begin A-end B-begin B-end) | ||
| 2445 | (emerge-eval-in-buffer | ||
| 2446 | emerge-merge-buffer | ||
| 2447 | (delete-region merge-begin merge-end) | ||
| 2448 | (goto-char merge-begin) | ||
| 2449 | (let ((i 0)) | ||
| 2450 | (while (< i (length template)) | ||
| 2451 | (let ((c (aref template i))) | ||
| 2452 | (if (= c ?%) | ||
| 2453 | (progn | ||
| 2454 | (setq i (1+ i)) | ||
| 2455 | (setq c | ||
| 2456 | (condition-case nil | ||
| 2457 | (aref template i) | ||
| 2458 | (error ?%))) | ||
| 2459 | (cond ((= c ?a) | ||
| 2460 | (insert-buffer-substring emerge-A-buffer A-begin A-end)) | ||
| 2461 | ((= c ?b) | ||
| 2462 | (insert-buffer-substring emerge-B-buffer B-begin B-end)) | ||
| 2463 | ((= c ?%) | ||
| 2464 | (insert ?%) | ||
| 2465 | (t | ||
| 2466 | (insert c))))) | ||
| 2467 | (insert c))) | ||
| 2468 | (setq i (1+ i)))) | ||
| 2469 | (goto-char merge-begin) | ||
| 2470 | (aset diff-vector 6 'combined) | ||
| 2471 | (emerge-refresh-mode-line))) | ||
| 2472 | |||
| 2473 | (defun emerge-set-merge-mode (mode) | ||
| 2474 | "Set the major mode in a merge buffer. Overrides any change that the mode | ||
| 2475 | might make to the mode line or local keymap. Leaves merge in fast mode." | ||
| 2476 | (interactive | ||
| 2477 | (list (intern (completing-read "New major mode for merge buffer: " | ||
| 2478 | obarray 'commandp t nil)))) | ||
| 2479 | (funcall mode) | ||
| 2480 | (emerge-refresh-mode-line) | ||
| 2481 | (if emerge-fast-mode | ||
| 2482 | (emerge-fast-mode) | ||
| 2483 | (emerge-edit-mode))) | ||
| 2484 | |||
| 2485 | (defun emerge-one-line-window () | ||
| 2486 | (interactive) | ||
| 2487 | (let ((window-min-height 1)) | ||
| 2488 | (shrink-window (- (window-height) 2)))) | ||
| 2489 | |||
| 2490 | ;;; Support routines | ||
| 2491 | |||
| 2492 | ;; Select a difference by placing the visual flags around the appropriate | ||
| 2493 | ;; group of lines in the A, B, and merge buffers | ||
| 2494 | (defun emerge-select-difference (n) | ||
| 2495 | (let ((diff-vector (aref emerge-difference-list n))) | ||
| 2496 | (emerge-place-flags-in-buffer emerge-A-buffer | ||
| 2497 | (aref diff-vector 0) (aref diff-vector 1)) | ||
| 2498 | (emerge-place-flags-in-buffer emerge-B-buffer | ||
| 2499 | (aref diff-vector 2) (aref diff-vector 3)) | ||
| 2500 | (emerge-place-flags-in-buffer emerge-merge-buffer | ||
| 2501 | (aref diff-vector 4) (aref diff-vector 5)))) | ||
| 2502 | |||
| 2503 | (defun emerge-place-flags-in-buffer (buffer before after) | ||
| 2504 | (if (eq buffer emerge-merge-buffer) | ||
| 2505 | (emerge-place-flags-in-buffer1 buffer before after) | ||
| 2506 | (emerge-eval-in-buffer | ||
| 2507 | buffer | ||
| 2508 | (emerge-place-flags-in-buffer1 buffer before after)))) | ||
| 2509 | |||
| 2510 | (defun emerge-place-flags-in-buffer1 (buffer before after) | ||
| 2511 | (let ((buffer-read-only nil)) | ||
| 2512 | ;; insert the flags | ||
| 2513 | (goto-char before) | ||
| 2514 | (insert-before-markers emerge-before-flag) | ||
| 2515 | (goto-char after) | ||
| 2516 | (insert emerge-after-flag) | ||
| 2517 | ;; put the markers into the flags, so alterations above or below won't move | ||
| 2518 | ;; them | ||
| 2519 | ;; before marker is one char before the end of the before flag | ||
| 2520 | ;; after marker is one char after the beginning of the after flag | ||
| 2521 | (set-marker before (1- before)) | ||
| 2522 | (set-marker after (1+ after)))) | ||
| 2523 | |||
| 2524 | ;; Unselect a difference by removing the visual flags in the buffers. | ||
| 2525 | (defun emerge-unselect-difference (n) | ||
| 2526 | (let ((diff-vector (aref emerge-difference-list n))) | ||
| 2527 | (emerge-remove-flags-in-buffer emerge-A-buffer | ||
| 2528 | (aref diff-vector 0) (aref diff-vector 1)) | ||
| 2529 | (emerge-remove-flags-in-buffer emerge-B-buffer | ||
| 2530 | (aref diff-vector 2) (aref diff-vector 3)) | ||
| 2531 | (emerge-remove-flags-in-buffer emerge-merge-buffer | ||
| 2532 | (aref diff-vector 4) (aref diff-vector 5)))) | ||
| 2533 | |||
| 2534 | (defun emerge-remove-flags-in-buffer (buffer before after) | ||
| 2535 | (emerge-eval-in-buffer | ||
| 2536 | buffer | ||
| 2537 | (let ((buffer-read-only nil)) | ||
| 2538 | ;; put the markers at the beginning of the flags | ||
| 2539 | (set-marker before (- before (1- emerge-before-flag-length))) | ||
| 2540 | (set-marker after (1- after)) | ||
| 2541 | ;; remove the flags | ||
| 2542 | (goto-char before) | ||
| 2543 | (if (looking-at emerge-before-flag-match) | ||
| 2544 | (delete-char emerge-before-flag-length) | ||
| 2545 | ;; the flag isn't there | ||
| 2546 | (ding) | ||
| 2547 | (message "Trouble removing flag.")) | ||
| 2548 | (goto-char after) | ||
| 2549 | (if (looking-at emerge-after-flag-match) | ||
| 2550 | (delete-char emerge-after-flag-length) | ||
| 2551 | ;; the flag isn't there | ||
| 2552 | (ding) | ||
| 2553 | (message "Trouble removing flag."))))) | ||
| 2554 | |||
| 2555 | ;; Select a difference, removing an flags that exist now. | ||
| 2556 | (defun emerge-unselect-and-select-difference (n &optional suppress-display) | ||
| 2557 | (if (and (>= emerge-current-difference 0) | ||
| 2558 | (< emerge-current-difference emerge-number-of-differences)) | ||
| 2559 | (emerge-unselect-difference emerge-current-difference)) | ||
| 2560 | (if (and (>= n 0) (< n emerge-number-of-differences)) | ||
| 2561 | (progn | ||
| 2562 | (emerge-select-difference n) | ||
| 2563 | (let* ((diff-vector (aref emerge-difference-list n)) | ||
| 2564 | (selection-type (aref diff-vector 6))) | ||
| 2565 | (if (eq selection-type 'default-A) | ||
| 2566 | (aset diff-vector 6 'A) | ||
| 2567 | (if (eq selection-type 'default-B) | ||
| 2568 | (aset diff-vector 6 'B)))))) | ||
| 2569 | (setq emerge-current-difference n) | ||
| 2570 | (if (not suppress-display) | ||
| 2571 | (progn | ||
| 2572 | (emerge-recenter) | ||
| 2573 | (emerge-refresh-mode-line)))) | ||
| 2574 | |||
| 2575 | ;; Perform tests to see whether user should be allowed to select a version | ||
| 2576 | ;; of this difference: | ||
| 2577 | ;; a valid difference has been selected; and | ||
| 2578 | ;; the difference text in the merge buffer is: | ||
| 2579 | ;; the A version (execute a-version), or | ||
| 2580 | ;; the B version (execute b-version), or | ||
| 2581 | ;; empty (execute neither-version), or | ||
| 2582 | ;; argument FORCE is true (execute neither-version) | ||
| 2583 | ;; Otherwise, signal an error. | ||
| 2584 | (defun emerge-select-version (force a-version b-version neither-version) | ||
| 2585 | (emerge-validate-difference) | ||
| 2586 | (let ((buffer-read-only nil)) | ||
| 2587 | (let* ((diff-vector | ||
| 2588 | (aref emerge-difference-list emerge-current-difference)) | ||
| 2589 | (A-begin (1+ (aref diff-vector 0))) | ||
| 2590 | (A-end (1- (aref diff-vector 1))) | ||
| 2591 | (B-begin (1+ (aref diff-vector 2))) | ||
| 2592 | (B-end (1- (aref diff-vector 3))) | ||
| 2593 | (merge-begin (1+ (aref diff-vector 4))) | ||
| 2594 | (merge-end (1- (aref diff-vector 5)))) | ||
| 2595 | (if (emerge-compare-buffers emerge-A-buffer A-begin A-end | ||
| 2596 | emerge-merge-buffer merge-begin | ||
| 2597 | merge-end) | ||
| 2598 | (funcall a-version) | ||
| 2599 | (if (emerge-compare-buffers emerge-B-buffer B-begin B-end | ||
| 2600 | emerge-merge-buffer merge-begin | ||
| 2601 | merge-end) | ||
| 2602 | (funcall b-version) | ||
| 2603 | (if (or force (= merge-begin merge-end)) | ||
| 2604 | (funcall neither-version) | ||
| 2605 | (error "This difference region has been edited."))))))) | ||
| 2606 | |||
| 2607 | ;; Revise the mode line to display which difference we have selected | ||
| 2608 | |||
| 2609 | (defun emerge-refresh-mode-line () | ||
| 2610 | (setq mode-line-buffer-identification | ||
| 2611 | (list (format "Emerge: %%b diff %d of %d%s" | ||
| 2612 | (1+ emerge-current-difference) | ||
| 2613 | emerge-number-of-differences | ||
| 2614 | (if (and (>= emerge-current-difference 0) | ||
| 2615 | (< emerge-current-difference | ||
| 2616 | emerge-number-of-differences)) | ||
| 2617 | (cdr (assq (aref (aref emerge-difference-list | ||
| 2618 | emerge-current-difference) | ||
| 2619 | 6) | ||
| 2620 | '((A . " - A") | ||
| 2621 | (B . " - B") | ||
| 2622 | (prefer-A . " - A*") | ||
| 2623 | (prefer-B . " - B*") | ||
| 2624 | (combined . " - comb")))) | ||
| 2625 | "")))) | ||
| 2626 | ;; Force mode-line redisplay | ||
| 2627 | (set-buffer-modified-p (buffer-modified-p))) | ||
| 2628 | |||
| 2629 | ;; compare two regions in two buffers for containing the same text | ||
| 2630 | (defun emerge-compare-buffers (buffer-x x-begin x-end buffer-y y-begin y-end) | ||
| 2631 | ;; first check that the two regions are the same length | ||
| 2632 | (if (not (and (= (- x-end x-begin) (- y-end y-begin)))) | ||
| 2633 | nil | ||
| 2634 | (catch 'exit | ||
| 2635 | (while (< x-begin x-end) | ||
| 2636 | ;; bite off and compare no more than 1000 characters at a time | ||
| 2637 | (let* ((compare-length (min (- x-end x-begin) 1000)) | ||
| 2638 | (x-string (emerge-eval-in-buffer | ||
| 2639 | buffer-x | ||
| 2640 | (buffer-substring x-begin | ||
| 2641 | (+ x-begin compare-length)))) | ||
| 2642 | (y-string (emerge-eval-in-buffer | ||
| 2643 | buffer-y | ||
| 2644 | (buffer-substring y-begin | ||
| 2645 | (+ y-begin compare-length))))) | ||
| 2646 | (if (not (string-equal x-string y-string)) | ||
| 2647 | (throw 'exit nil) | ||
| 2648 | (setq x-begin (+ x-begin compare-length)) | ||
| 2649 | (setq y-begin (+ y-begin compare-length))))) | ||
| 2650 | t))) | ||
| 2651 | |||
| 2652 | ;; Construct a unique buffer name. | ||
| 2653 | ;; The first one tried is prefixsuffix, then prefix<2>suffix, | ||
| 2654 | ;; prefix<3>suffix, etc. | ||
| 2655 | (defun emerge-unique-buffer-name (prefix suffix) | ||
| 2656 | (if (null (get-buffer (concat prefix suffix))) | ||
| 2657 | (concat prefix suffix) | ||
| 2658 | (let ((n 2)) | ||
| 2659 | (while (get-buffer (format "%s<%d>%s" prefix n suffix)) | ||
| 2660 | (setq n (1+ n))) | ||
| 2661 | (format "%s<%d>%s" prefix n suffix)))) | ||
| 2662 | |||
| 2663 | ;; Verify that we have a difference selected. | ||
| 2664 | (defun emerge-validate-difference () | ||
| 2665 | (if (not (and (>= emerge-current-difference 0) | ||
| 2666 | (< emerge-current-difference emerge-number-of-differences))) | ||
| 2667 | (error "No difference selected"))) | ||
| 2668 | |||
| 2669 | ;;; Functions for saving and restoring a batch of variables | ||
| 2670 | |||
| 2671 | ;; These functions save (get the values of) and restore (set the values of) | ||
| 2672 | ;; a list of variables. The argument is a list of symbols (the names of | ||
| 2673 | ;; the variables). A list element can also be a list of two functions, | ||
| 2674 | ;; the first of which (when called with no arguments) gets the value, and | ||
| 2675 | ;; the second (when called with a value as an argment) sets the value. | ||
| 2676 | ;; A "function" is anything that funcall can handle as an argument. | ||
| 2677 | |||
| 2678 | (defun emerge-save-variables (vars) | ||
| 2679 | (mapcar (function (lambda (v) (if (symbolp v) | ||
| 2680 | (symbol-value v) | ||
| 2681 | (funcall (car v))))) | ||
| 2682 | vars)) | ||
| 2683 | |||
| 2684 | (defun emerge-restore-variables (vars values) | ||
| 2685 | (while vars | ||
| 2686 | (let ((var (car vars)) | ||
| 2687 | (value (car values))) | ||
| 2688 | (if (symbolp var) | ||
| 2689 | (set var value) | ||
| 2690 | (funcall (car (cdr var)) value))) | ||
| 2691 | (setq vars (cdr vars)) | ||
| 2692 | (setq values (cdr values)))) | ||
| 2693 | |||
| 2694 | ;; Make a temporary file that only we have access to. | ||
| 2695 | ;; PREFIX is appended to emerge-temp-file-prefix to make the filename prefix. | ||
| 2696 | (defun emerge-make-temp-file (prefix) | ||
| 2697 | (let ((f (make-temp-name (concat emerge-temp-file-prefix prefix)))) | ||
| 2698 | ;; create the file | ||
| 2699 | (write-region (point-min) (point-min) f nil 'no-message) | ||
| 2700 | (set-file-modes f emerge-temp-file-mode) | ||
| 2701 | f)) | ||
| 2702 | |||
| 2703 | ;;; Functions that query the user before he can write out the current buffer. | ||
| 2704 | |||
| 2705 | (defun emerge-query-write-file () | ||
| 2706 | "Query the user if he really wants to write out the incomplete merge. | ||
| 2707 | If he says yes, call write-file to do so. See emerge-query-and-call | ||
| 2708 | for details of the querying process." | ||
| 2709 | (interactive) | ||
| 2710 | (emerge-query-and-call 'write-file)) | ||
| 2711 | |||
| 2712 | (defun emerge-query-save-buffer () | ||
| 2713 | "Query the user if he really wants to write out the incomplete merge. | ||
| 2714 | If he says yes, call save-buffer to do so. See emerge-query-and-call | ||
| 2715 | for details of the querying process." | ||
| 2716 | (interactive) | ||
| 2717 | (emerge-query-and-call 'save-buffer)) | ||
| 2718 | |||
| 2719 | (defun emerge-query-and-call (command) | ||
| 2720 | "Query the user if he really wants to write out the incomplete merge. | ||
| 2721 | If he says yes, call COMMAND interactively. During the call, the flags | ||
| 2722 | around the current difference are removed." | ||
| 2723 | (if (yes-or-no-p "Do you really write to write out this unfinished merge? ") | ||
| 2724 | ;; He really wants to do it -- unselect the difference for the duration | ||
| 2725 | (progn | ||
| 2726 | (if (and (>= emerge-current-difference 0) | ||
| 2727 | (< emerge-current-difference emerge-number-of-differences)) | ||
| 2728 | (emerge-unselect-difference emerge-current-difference)) | ||
| 2729 | ;; call-interactively takes the value of current-prefix-arg as the | ||
| 2730 | ;; prefix argument value to be passed to the command. Thus, we have | ||
| 2731 | ;; to do nothing special to make sure the prefix argument is | ||
| 2732 | ;; transmitted to the command. | ||
| 2733 | (call-interactively command) | ||
| 2734 | (if (and (>= emerge-current-difference 0) | ||
| 2735 | (< emerge-current-difference emerge-number-of-differences)) | ||
| 2736 | (progn | ||
| 2737 | (emerge-select-difference emerge-current-difference) | ||
| 2738 | (emerge-recenter)))) | ||
| 2739 | ;; He's being smart and not doing it | ||
| 2740 | (message "Not written"))) | ||
| 2741 | |||
| 2742 | ;; Make sure the current buffer (for a file) has the same contents as the | ||
| 2743 | ;; file on disk, and attempt to remedy the situation if not. | ||
| 2744 | ;; Signal an error if we can't make them the same, or the user doesn't want | ||
| 2745 | ;; to do what is necessary to make them the same. | ||
| 2746 | (defun emerge-verify-file-buffer () | ||
| 2747 | ;; First check if the file has been modified since the buffer visited it. | ||
| 2748 | (if (verify-visited-file-modtime (current-buffer)) | ||
| 2749 | (if (buffer-modified-p) | ||
| 2750 | ;; If buffer is not obsolete and is modified, offer to save | ||
| 2751 | (if (yes-or-no-p (format "Save file %s? " buffer-file-name)) | ||
| 2752 | (save-buffer) | ||
| 2753 | (error "Buffer out of sync for file %s" buffer-file-name)) | ||
| 2754 | ;; If buffer is not obsolete and is not modified, do nothing | ||
| 2755 | nil) | ||
| 2756 | (if (buffer-modified-p) | ||
| 2757 | ;; If buffer is obsolete and is modified, give error | ||
| 2758 | (error "Buffer out of sync for file %s" buffer-file-name) | ||
| 2759 | ;; If buffer is obsolete and is not modified, offer to revert | ||
| 2760 | (if (yes-or-no-p (format "Revert file %s? " buffer-file-name)) | ||
| 2761 | (revert-buffer t t) | ||
| 2762 | (error "Buffer out of sync for file %s" buffer-file-name))))) | ||
| 2763 | |||
| 2764 | ;; Utilities that might have value outside of Emerge. | ||
| 2765 | |||
| 2766 | ;; Set up the mode in the current buffer to duplicate the mode in another | ||
| 2767 | ;; buffer. | ||
| 2768 | (defun emerge-copy-modes (buffer) | ||
| 2769 | ;; Set the major mode | ||
| 2770 | (funcall (emerge-eval-in-buffer buffer major-mode))) | ||
| 2771 | |||
| 2772 | ;; Define a key, even if a prefix of it is defined | ||
| 2773 | (defun emerge-force-define-key (keymap key definition) | ||
| 2774 | "Like define-key, but is not stopped if a prefix of KEY is a defined | ||
| 2775 | command." | ||
| 2776 | ;; Find out if a prefix of key is defined | ||
| 2777 | (let ((v (lookup-key keymap key))) | ||
| 2778 | ;; If so, undefine it | ||
| 2779 | (if (integerp v) | ||
| 2780 | (define-key keymap (substring key 0 v) nil))) | ||
| 2781 | ;; Now define the key | ||
| 2782 | (define-key keymap key definition)) | ||
| 2783 | |||
| 2784 | ;;; Improvements to describe-mode, so that it describes minor modes as well | ||
| 2785 | ;;; as the major mode | ||
| 2786 | (defun describe-mode (&optional minor) | ||
| 2787 | "Display documentation of current major mode. | ||
| 2788 | If optional MINOR is non-nil (or prefix argument is given if interactive), | ||
| 2789 | display documentation of acive minor modes as well. | ||
| 2790 | For this to work correctly for a minor mode, the mode's indicator variable | ||
| 2791 | (listed in minor-mode-alist) must also be a function whose documentation | ||
| 2792 | describes the minor mode." | ||
| 2793 | (interactive) | ||
| 2794 | (with-output-to-temp-buffer "*Help*" | ||
| 2795 | (princ mode-name) | ||
| 2796 | (princ " Mode:\n") | ||
| 2797 | (princ (documentation major-mode)) | ||
| 2798 | (let ((minor-modes minor-mode-alist) | ||
| 2799 | (locals (buffer-local-variables))) | ||
| 2800 | (while minor-modes | ||
| 2801 | (let* ((minor-mode (car (car minor-modes))) | ||
| 2802 | (indicator (car (cdr (car minor-modes)))) | ||
| 2803 | (local-binding (assq minor-mode locals))) | ||
| 2804 | ;; Document a minor mode if it is listed in minor-mode-alist, | ||
| 2805 | ;; bound locally in this buffer, non-nil, and has a function | ||
| 2806 | ;; definition. | ||
| 2807 | (if (and local-binding | ||
| 2808 | (cdr local-binding) | ||
| 2809 | (fboundp minor-mode)) | ||
| 2810 | (progn | ||
| 2811 | (princ (format "\n\n\n%s minor mode (indicator%s):\n" | ||
| 2812 | minor-mode indicator)) | ||
| 2813 | (princ (documentation minor-mode))))) | ||
| 2814 | (setq minor-modes (cdr minor-modes)))) | ||
| 2815 | (print-help-return-message))) | ||
| 2816 | |||
| 2817 | ;; Adjust things so that keyboard macro definitions are documented correctly. | ||
| 2818 | (fset 'defining-kbd-macro (symbol-function 'start-kbd-macro)) | ||
| 2819 | |||
| 2820 | ;; Function to shadow a definition in a keymap with definitions in another. | ||
| 2821 | (defun emerge-shadow-key-definition (olddef newdef keymap shadowmap) | ||
| 2822 | "Shadow OLDDEF with NEWDEF for any keys in KEYMAP with entries in SHADOWMAP. | ||
| 2823 | In other words, SHADOWMAP will now shadow all definitions of OLDDEF in KEYMAP | ||
| 2824 | with NEWDEF. Does not affect keys that are already defined in SHADOWMAP, | ||
| 2825 | including those whose definition is OLDDEF." | ||
| 2826 | ;; loop through all keymaps accessible from keymap | ||
| 2827 | (let ((maps (accessible-keymaps keymap))) | ||
| 2828 | (while maps | ||
| 2829 | (let ((prefix (car (car maps))) | ||
| 2830 | (map (cdr (car maps)))) | ||
| 2831 | ;; examine a keymap | ||
| 2832 | (if (arrayp map) | ||
| 2833 | ;; array keymap | ||
| 2834 | (let ((len (length map)) | ||
| 2835 | (i 0)) | ||
| 2836 | (while (< i len) | ||
| 2837 | (if (eq (aref map i) olddef) | ||
| 2838 | ;; set the shadowing definition | ||
| 2839 | (let ((key (concat prefix (char-to-string i)))) | ||
| 2840 | (emerge-define-key-if-possible shadowmap key newdef))) | ||
| 2841 | (setq i (1+ i)))) | ||
| 2842 | ;; sparse keymap | ||
| 2843 | (while map | ||
| 2844 | (if (eq (cdr-safe (car-safe map)) olddef) | ||
| 2845 | ;; set the shadowing definition | ||
| 2846 | (let ((key | ||
| 2847 | (concat prefix (char-to-string (car (car map)))))) | ||
| 2848 | (emerge-define-key-if-possible shadowmap key newdef))) | ||
| 2849 | (setq map (cdr map))))) | ||
| 2850 | (setq maps (cdr maps))))) | ||
| 2851 | |||
| 2852 | ;; Define a key if it (or a prefix) is not already defined in the map. | ||
| 2853 | (defun emerge-define-key-if-possible (keymap key definition) | ||
| 2854 | ;; look up the present definition of the key | ||
| 2855 | (let ((present (lookup-key keymap key))) | ||
| 2856 | (if (integerp present) | ||
| 2857 | ;; if it is "too long", look up the valid prefix | ||
| 2858 | (if (not (lookup-key keymap (substring key 0 present))) | ||
| 2859 | ;; if the prefix isn't defined, define it | ||
| 2860 | (define-key keymap key definition)) | ||
| 2861 | ;; if there is no present definition, define it | ||
| 2862 | (if (not present) | ||
| 2863 | (define-key keymap key definition))))) | ||
| 2864 | |||
| 2865 | (defun emerge-recursively-substitute-key-definition (olddef newdef keymap) | ||
| 2866 | "Like substitute-key-definition, but examines and substitutes in all | ||
| 2867 | keymaps accessible from KEYMAP. Make sure that subordinate keymaps aren't | ||
| 2868 | shared with other keymaps! (copy-keymap will suffice.)" | ||
| 2869 | ;; Loop through all keymaps accessible from keymap | ||
| 2870 | (let ((maps (accessible-keymaps keymap))) | ||
| 2871 | (while maps | ||
| 2872 | ;; Substitute in this keymap | ||
| 2873 | (substitute-key-definition olddef newdef (cdr (car maps))) | ||
| 2874 | (setq maps (cdr maps))))) | ||
| 2875 | |||
| 2876 | ;; Show the name of the file in the buffer. | ||
| 2877 | (defun emerge-show-file-name () | ||
| 2878 | "Displays the name of the file loaded into the current buffer. | ||
| 2879 | If the name won't fit on one line, the minibuffer is expanded to hold it, | ||
| 2880 | and the command waits for a keystroke from the user. If the keystroke is | ||
| 2881 | SPC, it is ignored; if it is anything else, it is processed as a command." | ||
| 2882 | (interactive) | ||
| 2883 | (let ((name (buffer-file-name))) | ||
| 2884 | (or name | ||
| 2885 | (setq name "Buffer has no file name.")) | ||
| 2886 | (save-window-excursion | ||
| 2887 | (select-window (minibuffer-window)) | ||
| 2888 | (erase-buffer) | ||
| 2889 | (insert name) | ||
| 2890 | (if (not (pos-visible-in-window-p)) | ||
| 2891 | (let ((echo-keystrokes 0)) | ||
| 2892 | (while (and (not (pos-visible-in-window-p)) | ||
| 2893 | (> (1- (screen-height)) (window-height))) | ||
| 2894 | (enlarge-window 1)) | ||
| 2895 | (let ((c (read-char))) | ||
| 2896 | (if (/= c 32) | ||
| 2897 | (setq unread-command-char c)))))))) | ||
| 2898 | |||
| 2899 | ;; Improved auto-save file names. | ||
| 2900 | ;; This function fixes many problems with the standard auto-save file names: | ||
| 2901 | ;; Auto-save files for non-file buffers get put in the default directory | ||
| 2902 | ;; for the buffer, whether that makes sense or not. | ||
| 2903 | ;; Auto-save files for file buffers get put in the directory of the file, | ||
| 2904 | ;; regardless of whether we can write into it or not. | ||
| 2905 | ;; Auto-save files for non-file buffers don't use the process id, so if a | ||
| 2906 | ;; user runs more than on Emacs, they can make auto-save files that overwrite | ||
| 2907 | ;; each other. | ||
| 2908 | ;; To use this function, do: | ||
| 2909 | ;; (fset 'make-auto-save-file-name | ||
| 2910 | ;; (symbol-function 'emerge-make-auto-save-file-name)) | ||
| 2911 | (defun emerge-make-auto-save-file-name () | ||
| 2912 | "Return file name to use for auto-saves of current buffer. | ||
| 2913 | Does not consider auto-save-visited-file-name; that is checked | ||
| 2914 | before calling this function. | ||
| 2915 | You can redefine this for customization. | ||
| 2916 | See also auto-save-file-name-p." | ||
| 2917 | (if buffer-file-name | ||
| 2918 | ;; if buffer has a file, try the format <file directory>/#<file name># | ||
| 2919 | (let ((f (concat (file-name-directory buffer-file-name) | ||
| 2920 | "#" | ||
| 2921 | (file-name-nondirectory buffer-file-name) | ||
| 2922 | "#"))) | ||
| 2923 | (if (file-writable-p f) | ||
| 2924 | ;; the file is writable, so use it | ||
| 2925 | f | ||
| 2926 | ;; the file isn't writable, so use the format | ||
| 2927 | ;; ~/#&<file name>&<hash of directory># | ||
| 2928 | (concat (getenv "HOME") | ||
| 2929 | "/#&" | ||
| 2930 | (file-name-nondirectory buffer-file-name) | ||
| 2931 | "&" | ||
| 2932 | (hash-string-into-string | ||
| 2933 | (file-name-directory buffer-file-name)) | ||
| 2934 | "#"))) | ||
| 2935 | ;; if buffer has no file, use the format ~/#%<buffer name>%<process id># | ||
| 2936 | (expand-file-name (concat (getenv "HOME") | ||
| 2937 | "/#%" | ||
| 2938 | ;; quote / into \! and \ into \\ | ||
| 2939 | (unslashify-name (buffer-name)) | ||
| 2940 | "%" | ||
| 2941 | (make-temp-name "") | ||
| 2942 | "#")))) | ||
| 2943 | |||
| 2944 | ;; Hash a string into five characters more-or-less suitable for use in a file | ||
| 2945 | ;; name. (Allowed characters are ! through ~, except /.) | ||
| 2946 | (defun hash-string-into-string (s) | ||
| 2947 | (let ((bins (vector 0 0 0 0 0)) | ||
| 2948 | (i 0)) | ||
| 2949 | (while (< i (length s)) | ||
| 2950 | (aset bins (% i 5) (% (+ (* (aref bins (% i 5)) 35) | ||
| 2951 | (aref s i)) | ||
| 2952 | 65536)) | ||
| 2953 | (setq i (1+ i))) | ||
| 2954 | (mapconcat (function (lambda (b) | ||
| 2955 | (setq b (+ (% b 93) ?!)) | ||
| 2956 | (if (>= b ?/) | ||
| 2957 | (setq b (1+ b))) | ||
| 2958 | (char-to-string b))) | ||
| 2959 | bins ""))) | ||
| 2960 | |||
| 2961 | ;; Quote any /s in a string by replacing them with \!. | ||
| 2962 | ;; Also, replace any \s by \\, to make it one-to-one. | ||
| 2963 | (defun unslashify-name (s) | ||
| 2964 | (let ((limit 0)) | ||
| 2965 | (while (string-match "[/\\]" s limit) | ||
| 2966 | (setq s (concat (substring s 0 (match-beginning 0)) | ||
| 2967 | (if (string= (substring s (match-beginning 0) | ||
| 2968 | (match-end 0)) | ||
| 2969 | "/") | ||
| 2970 | "\\!" | ||
| 2971 | "\\\\") | ||
| 2972 | (substring s (match-end 0)))) | ||
| 2973 | (setq limit (1+ (match-end 0))))) | ||
| 2974 | s) | ||
| 2975 | |||
| 2976 | ;;;;;;;;;;;;;;;; end emerge.el ;;;;;;;;;;;;;;;; | ||
| 2977 | |||
| 2978 | (provide 'emerge) | ||
| 2979 | |||
diff --git a/lisp/international/iso-ascii.el b/lisp/international/iso-ascii.el new file mode 100644 index 00000000000..13aeaaa8c76 --- /dev/null +++ b/lisp/international/iso-ascii.el | |||
| @@ -0,0 +1,126 @@ | |||
| 1 | ;; Set up char tables for ISO 8859/1 character set for ASCII terminals. | ||
| 2 | ;; Copyright (C) 1987 Free Software Foundation, Inc. | ||
| 3 | |||
| 4 | ;; This file is part of GNU Emacs. | ||
| 5 | |||
| 6 | ;; GNU Emacs is free software; you can redistribute it and/or modify | ||
| 7 | ;; it under the terms of the GNU General Public License as published by | ||
| 8 | ;; the Free Software Foundation; either version 1, or (at your option) | ||
| 9 | ;; any later version. | ||
| 10 | |||
| 11 | ;; GNU Emacs is distributed in the hope that it will be useful, | ||
| 12 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | ;; GNU General Public License for more details. | ||
| 15 | |||
| 16 | ;; You should have received a copy of the GNU General Public License | ||
| 17 | ;; along with GNU Emacs; see the file COPYING. If not, write to | ||
| 18 | ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 19 | |||
| 20 | |||
| 21 | ;; Written by Howard Gayle. See display-table.el for details. | ||
| 22 | |||
| 23 | ;; This code sets up to display ISO 8859/1 characters on plain | ||
| 24 | ;; ASCII terminals. The display strings for the characters are | ||
| 25 | ;; more-or-less based on TeX. | ||
| 26 | |||
| 27 | (require 'disp-table) | ||
| 28 | |||
| 29 | (standard-display-ascii 160 "{_}") ; NBSP (no-break space) | ||
| 30 | (standard-display-ascii 161 "{!}") ; inverted exclamation mark | ||
| 31 | (standard-display-ascii 162 "{c}") ; cent sign | ||
| 32 | (standard-display-ascii 163 "{GBP}") ; pound sign | ||
| 33 | (standard-display-ascii 164 "{$}") ; general currency sign | ||
| 34 | (standard-display-ascii 165 "{JPY}") ; yen sign | ||
| 35 | (standard-display-ascii 166 "{|}") ; broken vertical line | ||
| 36 | (standard-display-ascii 167 "{S}") ; section sign | ||
| 37 | (standard-display-ascii 168 "{\"}") ; diaeresis | ||
| 38 | (standard-display-ascii 169 "{C}") ; copyright sign | ||
| 39 | (standard-display-ascii 170 "{_a}") ; ordinal indicator, feminine | ||
| 40 | (standard-display-ascii 171 "{<<}") ; left angle quotation mark | ||
| 41 | (standard-display-ascii 172 "{~}") ; not sign | ||
| 42 | (standard-display-ascii 173 "{-}") ; soft hyphen | ||
| 43 | (standard-display-ascii 174 "{R}") ; registered sign | ||
| 44 | (standard-display-ascii 175 "{=}") ; macron | ||
| 45 | (standard-display-ascii 176 "{o}") ; degree sign | ||
| 46 | (standard-display-ascii 177 "{+-}") ; plus or minus sign | ||
| 47 | (standard-display-ascii 178 "{2}") ; superscript two | ||
| 48 | (standard-display-ascii 179 "{3}") ; superscript three | ||
| 49 | (standard-display-ascii 180 "{'}") ; acute accent | ||
| 50 | (standard-display-ascii 181 "{u}") ; micro sign | ||
| 51 | (standard-display-ascii 182 "{P}") ; pilcrow | ||
| 52 | (standard-display-ascii 183 "{.}") ; middle dot | ||
| 53 | (standard-display-ascii 184 "{,}") ; cedilla | ||
| 54 | (standard-display-ascii 185 "{1}") ; superscript one | ||
| 55 | (standard-display-ascii 186 "{_o}") ; ordinal indicator, masculine | ||
| 56 | (standard-display-ascii 187 "{>>}") ; right angle quotation mark | ||
| 57 | (standard-display-ascii 188 "{1/4}") ; fraction one-quarter | ||
| 58 | (standard-display-ascii 189 "{1/2}") ; fraction one-half | ||
| 59 | (standard-display-ascii 190 "{3/4}") ; fraction three-quarters | ||
| 60 | (standard-display-ascii 191 "{?}") ; inverted question mark | ||
| 61 | (standard-display-ascii 192 "{`A}") ; A with grave accent | ||
| 62 | (standard-display-ascii 193 "{'A}") ; A with acute accent | ||
| 63 | (standard-display-ascii 194 "{^A}") ; A with circumflex accent | ||
| 64 | (standard-display-ascii 195 "{~A}") ; A with tilde | ||
| 65 | (standard-display-ascii 196 "{\"A}") ; A with diaeresis or umlaut mark | ||
| 66 | (standard-display-ascii 197 "{AA}") ; A with ring | ||
| 67 | (standard-display-ascii 198 "{AE}") ; AE diphthong | ||
| 68 | (standard-display-ascii 199 "{,C}") ; C with cedilla | ||
| 69 | (standard-display-ascii 200 "{`E}") ; E with grave accent | ||
| 70 | (standard-display-ascii 201 "{'E}") ; E with acute accent | ||
| 71 | (standard-display-ascii 202 "{^E}") ; E with circumflex accent | ||
| 72 | (standard-display-ascii 203 "{\"E}") ; E with diaeresis or umlaut mark | ||
| 73 | (standard-display-ascii 204 "{`I}") ; I with grave accent | ||
| 74 | (standard-display-ascii 205 "{'I}") ; I with acute accent | ||
| 75 | (standard-display-ascii 206 "{^I}") ; I with circumflex accent | ||
| 76 | (standard-display-ascii 207 "{\"I}") ; I with diaeresis or umlaut mark | ||
| 77 | (standard-display-ascii 208 "{-D}") ; D with stroke, Icelandic eth | ||
| 78 | (standard-display-ascii 209 "{~N}") ; N with tilde | ||
| 79 | (standard-display-ascii 210 "{`O}") ; O with grave accent | ||
| 80 | (standard-display-ascii 211 "{'O}") ; O with acute accent | ||
| 81 | (standard-display-ascii 212 "{^O}") ; O with circumflex accent | ||
| 82 | (standard-display-ascii 213 "{~O}") ; O with tilde | ||
| 83 | (standard-display-ascii 214 "{\"O}") ; O with diaeresis or umlaut mark | ||
| 84 | (standard-display-ascii 215 "{x}") ; multiplication sign | ||
| 85 | (standard-display-ascii 216 "{/O}") ; O with slash | ||
| 86 | (standard-display-ascii 217 "{`U}") ; U with grave accent | ||
| 87 | (standard-display-ascii 218 "{'U}") ; U with acute accent | ||
| 88 | (standard-display-ascii 219 "{^U}") ; U with circumflex accent | ||
| 89 | (standard-display-ascii 220 "{\"U}") ; U with diaeresis or umlaut mark | ||
| 90 | (standard-display-ascii 221 "{'Y}") ; Y with acute accent | ||
| 91 | (standard-display-ascii 222 "{TH}") ; capital thorn, Icelandic | ||
| 92 | (standard-display-ascii 223 "{ss}") ; small sharp s, German | ||
| 93 | (standard-display-ascii 224 "{`a}") ; a with grave accent | ||
| 94 | (standard-display-ascii 225 "{'a}") ; a with acute accent | ||
| 95 | (standard-display-ascii 226 "{^a}") ; a with circumflex accent | ||
| 96 | (standard-display-ascii 227 "{~a}") ; a with tilde | ||
| 97 | (standard-display-ascii 228 "{\"a}") ; a with diaeresis or umlaut mark | ||
| 98 | (standard-display-ascii 229 "{aa}") ; a with ring | ||
| 99 | (standard-display-ascii 230 "{ae}") ; ae diphthong | ||
| 100 | (standard-display-ascii 231 "{,c}") ; c with cedilla | ||
| 101 | (standard-display-ascii 232 "{`e}") ; e with grave accent | ||
| 102 | (standard-display-ascii 233 "{'e}") ; e with acute accent | ||
| 103 | (standard-display-ascii 234 "{^e}") ; e with circumflex accent | ||
| 104 | (standard-display-ascii 235 "{\"e}") ; e with diaeresis or umlaut mark | ||
| 105 | (standard-display-ascii 236 "{`i}") ; i with grave accent | ||
| 106 | (standard-display-ascii 237 "{'i}") ; i with acute accent | ||
| 107 | (standard-display-ascii 238 "{^i}") ; i with circumflex accent | ||
| 108 | (standard-display-ascii 239 "{\"i}") ; i with diaeresis or umlaut mark | ||
| 109 | (standard-display-ascii 240 "{-d}") ; d with stroke, Icelandic eth | ||
| 110 | (standard-display-ascii 241 "{~n}") ; n with tilde | ||
| 111 | (standard-display-ascii 242 "{`o}") ; o with grave accent | ||
| 112 | (standard-display-ascii 243 "{'o}") ; o with acute accent | ||
| 113 | (standard-display-ascii 244 "{^o}") ; o with circumflex accent | ||
| 114 | (standard-display-ascii 245 "{~o}") ; o with tilde | ||
| 115 | (standard-display-ascii 246 "{\"o}") ; o with diaeresis or umlaut mark | ||
| 116 | (standard-display-ascii 247 "{/}") ; division sign | ||
| 117 | (standard-display-ascii 248 "{/o}") ; o with slash | ||
| 118 | (standard-display-ascii 249 "{`u}") ; u with grave accent | ||
| 119 | (standard-display-ascii 250 "{'u}") ; u with acute accent | ||
| 120 | (standard-display-ascii 251 "{^u}") ; u with circumflex accent | ||
| 121 | (standard-display-ascii 252 "{\"u}") ; u with diaeresis or umlaut mark | ||
| 122 | (standard-display-ascii 253 "{'y}") ; y with acute accent | ||
| 123 | (standard-display-ascii 254 "{th}") ; small thorn, Icelandic | ||
| 124 | (standard-display-ascii 255 "{\"y}") ; small y with diaeresis or umlaut mark | ||
| 125 | |||
| 126 | (provide 'iso8859-1-ascii) | ||
diff --git a/lisp/international/iso-insert.el b/lisp/international/iso-insert.el new file mode 100644 index 00000000000..3ea2e8530e8 --- /dev/null +++ b/lisp/international/iso-insert.el | |||
| @@ -0,0 +1,620 @@ | |||
| 1 | ;; Insert functions for ISO 8859/1. | ||
| 2 | ;; Copyright (C) 1987 Free Software Foundation, Inc. | ||
| 3 | |||
| 4 | ;; This file is part of GNU Emacs. | ||
| 5 | |||
| 6 | ;; GNU Emacs is free software; you can redistribute it and/or modify | ||
| 7 | ;; it under the terms of the GNU General Public License as published by | ||
| 8 | ;; the Free Software Foundation; either version 1, or (at your option) | ||
| 9 | ;; any later version. | ||
| 10 | |||
| 11 | ;; GNU Emacs is distributed in the hope that it will be useful, | ||
| 12 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | ;; GNU General Public License for more details. | ||
| 15 | |||
| 16 | ;; You should have received a copy of the GNU General Public License | ||
| 17 | ;; along with GNU Emacs; see the file COPYING. If not, write to | ||
| 18 | ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 19 | |||
| 20 | |||
| 21 | ;; Written by Howard Gayle. See case-table.el for details. | ||
| 22 | |||
| 23 | (defun insert-no-break-space () | ||
| 24 | (interactive "*") | ||
| 25 | (insert 160) | ||
| 26 | ) | ||
| 27 | |||
| 28 | (defun insert-inverted-exclamation-mark () | ||
| 29 | (interactive "*") | ||
| 30 | (insert 161) | ||
| 31 | ) | ||
| 32 | |||
| 33 | (defun insert-cent-sign () | ||
| 34 | (interactive "*") | ||
| 35 | (insert 162) | ||
| 36 | ) | ||
| 37 | |||
| 38 | (defun insert-pound-sign () | ||
| 39 | (interactive "*") | ||
| 40 | (insert 163) | ||
| 41 | ) | ||
| 42 | |||
| 43 | (defun insert-general-currency-sign () | ||
| 44 | (interactive "*") | ||
| 45 | (insert 164) | ||
| 46 | ) | ||
| 47 | |||
| 48 | (defun insert-yen-sign () | ||
| 49 | (interactive "*") | ||
| 50 | (insert 165) | ||
| 51 | ) | ||
| 52 | |||
| 53 | (defun insert-broken-vertical-line () | ||
| 54 | (interactive "*") | ||
| 55 | (insert 166) | ||
| 56 | ) | ||
| 57 | |||
| 58 | (defun insert-section-sign () | ||
| 59 | (interactive "*") | ||
| 60 | (insert 167) | ||
| 61 | ) | ||
| 62 | |||
| 63 | (defun insert-diaeresis () | ||
| 64 | (interactive "*") | ||
| 65 | (insert 168) | ||
| 66 | ) | ||
| 67 | |||
| 68 | (defun insert-copyright-sign () | ||
| 69 | (interactive "*") | ||
| 70 | (insert 169) | ||
| 71 | ) | ||
| 72 | |||
| 73 | (defun insert-ordinal-indicator-feminine () | ||
| 74 | (interactive "*") | ||
| 75 | (insert 170) | ||
| 76 | ) | ||
| 77 | |||
| 78 | (defun insert-angle-quotation-mark-left () | ||
| 79 | (interactive "*") | ||
| 80 | (insert 171) | ||
| 81 | ) | ||
| 82 | |||
| 83 | (defun insert-not-sign () | ||
| 84 | (interactive "*") | ||
| 85 | (insert 172) | ||
| 86 | ) | ||
| 87 | |||
| 88 | (defun insert-soft-hyphen () | ||
| 89 | (interactive "*") | ||
| 90 | (insert 173) | ||
| 91 | ) | ||
| 92 | |||
| 93 | (defun insert-registered-sign () | ||
| 94 | (interactive "*") | ||
| 95 | (insert 174) | ||
| 96 | ) | ||
| 97 | |||
| 98 | (defun insert-macron () | ||
| 99 | (interactive "*") | ||
| 100 | (insert 175) | ||
| 101 | ) | ||
| 102 | |||
| 103 | (defun insert-degree-sign () | ||
| 104 | (interactive "*") | ||
| 105 | (insert 176) | ||
| 106 | ) | ||
| 107 | |||
| 108 | (defun insert-plus-or-minus-sign () | ||
| 109 | (interactive "*") | ||
| 110 | (insert 177) | ||
| 111 | ) | ||
| 112 | |||
| 113 | (defun insert-superscript-two () | ||
| 114 | (interactive "*") | ||
| 115 | (insert 178) | ||
| 116 | ) | ||
| 117 | |||
| 118 | (defun insert-superscript-three () | ||
| 119 | (interactive "*") | ||
| 120 | (insert 179) | ||
| 121 | ) | ||
| 122 | |||
| 123 | (defun insert-acute-accent () | ||
| 124 | (interactive "*") | ||
| 125 | (insert 180) | ||
| 126 | ) | ||
| 127 | |||
| 128 | (defun insert-micro-sign () | ||
| 129 | (interactive "*") | ||
| 130 | (insert 181) | ||
| 131 | ) | ||
| 132 | |||
| 133 | (defun insert-pilcrow () | ||
| 134 | (interactive "*") | ||
| 135 | (insert 182) | ||
| 136 | ) | ||
| 137 | |||
| 138 | (defun insert-middle-dot () | ||
| 139 | (interactive "*") | ||
| 140 | (insert 183) | ||
| 141 | ) | ||
| 142 | |||
| 143 | (defun insert-cedilla () | ||
| 144 | (interactive "*") | ||
| 145 | (insert 184) | ||
| 146 | ) | ||
| 147 | |||
| 148 | (defun insert-superscript-one () | ||
| 149 | (interactive "*") | ||
| 150 | (insert 185) | ||
| 151 | ) | ||
| 152 | |||
| 153 | (defun insert-ordinal-indicator-masculine () | ||
| 154 | (interactive "*") | ||
| 155 | (insert 186) | ||
| 156 | ) | ||
| 157 | |||
| 158 | (defun insert-angle-quotation-mark-right () | ||
| 159 | (interactive "*") | ||
| 160 | (insert 187) | ||
| 161 | ) | ||
| 162 | |||
| 163 | (defun insert-fraction-one-quarter () | ||
| 164 | (interactive "*") | ||
| 165 | (insert 188) | ||
| 166 | ) | ||
| 167 | |||
| 168 | (defun insert-fraction-one-half () | ||
| 169 | (interactive "*") | ||
| 170 | (insert 189) | ||
| 171 | ) | ||
| 172 | |||
| 173 | (defun insert-fraction-three-quarters () | ||
| 174 | (interactive "*") | ||
| 175 | (insert 190) | ||
| 176 | ) | ||
| 177 | |||
| 178 | (defun insert-inverted-question-mark () | ||
| 179 | (interactive "*") | ||
| 180 | (insert 191) | ||
| 181 | ) | ||
| 182 | |||
| 183 | (defun insert-A-grave () | ||
| 184 | (interactive "*") | ||
| 185 | (insert 192) | ||
| 186 | ) | ||
| 187 | |||
| 188 | (defun insert-A-acute () | ||
| 189 | (interactive "*") | ||
| 190 | (insert 193) | ||
| 191 | ) | ||
| 192 | |||
| 193 | (defun insert-A-circumflex () | ||
| 194 | (interactive "*") | ||
| 195 | (insert 194) | ||
| 196 | ) | ||
| 197 | |||
| 198 | (defun insert-A-tilde () | ||
| 199 | (interactive "*") | ||
| 200 | (insert 195) | ||
| 201 | ) | ||
| 202 | |||
| 203 | (defun insert-A-umlaut () | ||
| 204 | (interactive "*") | ||
| 205 | (insert 196) | ||
| 206 | ) | ||
| 207 | |||
| 208 | (defun insert-A-ring () | ||
| 209 | (interactive "*") | ||
| 210 | (insert 197) | ||
| 211 | ) | ||
| 212 | |||
| 213 | (defun insert-AE () | ||
| 214 | (interactive "*") | ||
| 215 | (insert 198) | ||
| 216 | ) | ||
| 217 | |||
| 218 | (defun insert-C-cedilla () | ||
| 219 | (interactive "*") | ||
| 220 | (insert 199) | ||
| 221 | ) | ||
| 222 | |||
| 223 | (defun insert-E-grave () | ||
| 224 | (interactive "*") | ||
| 225 | (insert 200) | ||
| 226 | ) | ||
| 227 | |||
| 228 | (defun insert-E-acute () | ||
| 229 | (interactive "*") | ||
| 230 | (insert 201) | ||
| 231 | ) | ||
| 232 | |||
| 233 | (defun insert-E-circumflex () | ||
| 234 | (interactive "*") | ||
| 235 | (insert 202) | ||
| 236 | ) | ||
| 237 | |||
| 238 | (defun insert-E-umlaut () | ||
| 239 | (interactive "*") | ||
| 240 | (insert 203) | ||
| 241 | ) | ||
| 242 | |||
| 243 | (defun insert-I-grave () | ||
| 244 | (interactive "*") | ||
| 245 | (insert 204) | ||
| 246 | ) | ||
| 247 | |||
| 248 | (defun insert-I-acute () | ||
| 249 | (interactive "*") | ||
| 250 | (insert 205) | ||
| 251 | ) | ||
| 252 | |||
| 253 | (defun insert-I-circumflex () | ||
| 254 | (interactive "*") | ||
| 255 | (insert 206) | ||
| 256 | ) | ||
| 257 | |||
| 258 | (defun insert-I-umlaut () | ||
| 259 | (interactive "*") | ||
| 260 | (insert 207) | ||
| 261 | ) | ||
| 262 | |||
| 263 | (defun insert-D-stroke () | ||
| 264 | (interactive "*") | ||
| 265 | (insert 208) | ||
| 266 | ) | ||
| 267 | |||
| 268 | (defun insert-N-tilde () | ||
| 269 | (interactive "*") | ||
| 270 | (insert 209) | ||
| 271 | ) | ||
| 272 | |||
| 273 | (defun insert-O-grave () | ||
| 274 | (interactive "*") | ||
| 275 | (insert 210) | ||
| 276 | ) | ||
| 277 | |||
| 278 | (defun insert-O-acute () | ||
| 279 | (interactive "*") | ||
| 280 | (insert 211) | ||
| 281 | ) | ||
| 282 | |||
| 283 | (defun insert-O-circumflex () | ||
| 284 | (interactive "*") | ||
| 285 | (insert 212) | ||
| 286 | ) | ||
| 287 | |||
| 288 | (defun insert-O-tilde () | ||
| 289 | (interactive "*") | ||
| 290 | (insert 213) | ||
| 291 | ) | ||
| 292 | |||
| 293 | (defun insert-O-umlaut () | ||
| 294 | (interactive "*") | ||
| 295 | (insert 214) | ||
| 296 | ) | ||
| 297 | |||
| 298 | (defun insert-multiplication-sign () | ||
| 299 | (interactive "*") | ||
| 300 | (insert 215) | ||
| 301 | ) | ||
| 302 | |||
| 303 | (defun insert-O-slash () | ||
| 304 | (interactive "*") | ||
| 305 | (insert 216) | ||
| 306 | ) | ||
| 307 | |||
| 308 | (defun insert-U-grave () | ||
| 309 | (interactive "*") | ||
| 310 | (insert 217) | ||
| 311 | ) | ||
| 312 | |||
| 313 | (defun insert-U-acute () | ||
| 314 | (interactive "*") | ||
| 315 | (insert 218) | ||
| 316 | ) | ||
| 317 | |||
| 318 | (defun insert-U-circumflex () | ||
| 319 | (interactive "*") | ||
| 320 | (insert 219) | ||
| 321 | ) | ||
| 322 | |||
| 323 | (defun insert-U-umlaut () | ||
| 324 | (interactive "*") | ||
| 325 | (insert 220) | ||
| 326 | ) | ||
| 327 | |||
| 328 | (defun insert-Y-acute () | ||
| 329 | (interactive "*") | ||
| 330 | (insert 221) | ||
| 331 | ) | ||
| 332 | |||
| 333 | (defun insert-THORN () | ||
| 334 | (interactive "*") | ||
| 335 | (insert 222) | ||
| 336 | ) | ||
| 337 | |||
| 338 | (defun insert-ss () | ||
| 339 | (interactive "*") | ||
| 340 | (insert 223) | ||
| 341 | ) | ||
| 342 | |||
| 343 | (defun insert-a-grave () | ||
| 344 | (interactive "*") | ||
| 345 | (insert 224) | ||
| 346 | ) | ||
| 347 | |||
| 348 | (defun insert-a-acute () | ||
| 349 | (interactive "*") | ||
| 350 | (insert 225) | ||
| 351 | ) | ||
| 352 | |||
| 353 | (defun insert-a-circumflex () | ||
| 354 | (interactive "*") | ||
| 355 | (insert 226) | ||
| 356 | ) | ||
| 357 | |||
| 358 | (defun insert-a-tilde () | ||
| 359 | (interactive "*") | ||
| 360 | (insert 227) | ||
| 361 | ) | ||
| 362 | |||
| 363 | (defun insert-a-umlaut () | ||
| 364 | (interactive "*") | ||
| 365 | (insert 228) | ||
| 366 | ) | ||
| 367 | |||
| 368 | (defun insert-a-ring () | ||
| 369 | (interactive "*") | ||
| 370 | (insert 229) | ||
| 371 | ) | ||
| 372 | |||
| 373 | (defun insert-ae () | ||
| 374 | (interactive "*") | ||
| 375 | (insert 230) | ||
| 376 | ) | ||
| 377 | |||
| 378 | (defun insert-c-cedilla () | ||
| 379 | (interactive "*") | ||
| 380 | (insert 231) | ||
| 381 | ) | ||
| 382 | |||
| 383 | (defun insert-e-grave () | ||
| 384 | (interactive "*") | ||
| 385 | (insert 232) | ||
| 386 | ) | ||
| 387 | |||
| 388 | (defun insert-e-acute () | ||
| 389 | (interactive "*") | ||
| 390 | (insert 233) | ||
| 391 | ) | ||
| 392 | |||
| 393 | (defun insert-e-circumflex () | ||
| 394 | (interactive "*") | ||
| 395 | (insert 234) | ||
| 396 | ) | ||
| 397 | |||
| 398 | (defun insert-e-umlaut () | ||
| 399 | (interactive "*") | ||
| 400 | (insert 235) | ||
| 401 | ) | ||
| 402 | |||
| 403 | (defun insert-i-grave () | ||
| 404 | (interactive "*") | ||
| 405 | (insert 236) | ||
| 406 | ) | ||
| 407 | |||
| 408 | (defun insert-i-acute () | ||
| 409 | (interactive "*") | ||
| 410 | (insert 237) | ||
| 411 | ) | ||
| 412 | |||
| 413 | (defun insert-i-circumflex () | ||
| 414 | (interactive "*") | ||
| 415 | (insert 238) | ||
| 416 | ) | ||
| 417 | |||
| 418 | (defun insert-i-umlaut () | ||
| 419 | (interactive "*") | ||
| 420 | (insert 239) | ||
| 421 | ) | ||
| 422 | |||
| 423 | (defun insert-d-stroke () | ||
| 424 | (interactive "*") | ||
| 425 | (insert 240) | ||
| 426 | ) | ||
| 427 | |||
| 428 | (defun insert-n-tilde () | ||
| 429 | (interactive "*") | ||
| 430 | (insert 241) | ||
| 431 | ) | ||
| 432 | |||
| 433 | (defun insert-o-grave () | ||
| 434 | (interactive "*") | ||
| 435 | (insert 242) | ||
| 436 | ) | ||
| 437 | |||
| 438 | (defun insert-o-acute () | ||
| 439 | (interactive "*") | ||
| 440 | (insert 243) | ||
| 441 | ) | ||
| 442 | |||
| 443 | (defun insert-o-circumflex () | ||
| 444 | (interactive "*") | ||
| 445 | (insert 244) | ||
| 446 | ) | ||
| 447 | |||
| 448 | (defun insert-o-tilde () | ||
| 449 | (interactive "*") | ||
| 450 | (insert 245) | ||
| 451 | ) | ||
| 452 | |||
| 453 | (defun insert-o-umlaut () | ||
| 454 | (interactive "*") | ||
| 455 | (insert 246) | ||
| 456 | ) | ||
| 457 | |||
| 458 | (defun insert-division-sign () | ||
| 459 | (interactive "*") | ||
| 460 | (insert 247) | ||
| 461 | ) | ||
| 462 | |||
| 463 | (defun insert-o-slash () | ||
| 464 | (interactive "*") | ||
| 465 | (insert 248) | ||
| 466 | ) | ||
| 467 | |||
| 468 | (defun insert-u-grave () | ||
| 469 | (interactive "*") | ||
| 470 | (insert 249) | ||
| 471 | ) | ||
| 472 | |||
| 473 | (defun insert-u-acute () | ||
| 474 | (interactive "*") | ||
| 475 | (insert 250) | ||
| 476 | ) | ||
| 477 | |||
| 478 | (defun insert-u-circumflex () | ||
| 479 | (interactive "*") | ||
| 480 | (insert 251) | ||
| 481 | ) | ||
| 482 | |||
| 483 | (defun insert-u-umlaut () | ||
| 484 | (interactive "*") | ||
| 485 | (insert 252) | ||
| 486 | ) | ||
| 487 | |||
| 488 | (defun insert-y-acute () | ||
| 489 | (interactive "*") | ||
| 490 | (insert 253) | ||
| 491 | ) | ||
| 492 | |||
| 493 | (defun insert-thorn () | ||
| 494 | (interactive "*") | ||
| 495 | (insert 254) | ||
| 496 | ) | ||
| 497 | |||
| 498 | (defun insert-y-umlaut () | ||
| 499 | (interactive "*") | ||
| 500 | (insert 255) | ||
| 501 | ) | ||
| 502 | |||
| 503 | (defvar 8859-1-map nil "Keymap for ISO 8859/1 character insertion.") | ||
| 504 | (if 8859-1-map nil | ||
| 505 | (setq 8859-1-map (make-keymap)) | ||
| 506 | (define-key 8859-1-map " " 'insert-no-break-space) | ||
| 507 | (define-key 8859-1-map "!" 'insert-inverted-exclamation-mark) | ||
| 508 | (define-key 8859-1-map "\"" (make-sparse-keymap)) | ||
| 509 | (define-key 8859-1-map "\"\"" 'insert-diaeresis) | ||
| 510 | (define-key 8859-1-map "\"A" 'insert-A-umlaut) | ||
| 511 | (define-key 8859-1-map "\"E" 'insert-E-umlaut) | ||
| 512 | (define-key 8859-1-map "\"I" 'insert-I-umlaut) | ||
| 513 | (define-key 8859-1-map "\"O" 'insert-O-umlaut) | ||
| 514 | (define-key 8859-1-map "\"U" 'insert-U-umlaut) | ||
| 515 | (define-key 8859-1-map "\"a" 'insert-a-umlaut) | ||
| 516 | (define-key 8859-1-map "\"e" 'insert-e-umlaut) | ||
| 517 | (define-key 8859-1-map "\"i" 'insert-i-umlaut) | ||
| 518 | (define-key 8859-1-map "\"o" 'insert-o-umlaut) | ||
| 519 | (define-key 8859-1-map "\"u" 'insert-u-umlaut) | ||
| 520 | (define-key 8859-1-map "\"y" 'insert-y-umlaut) | ||
| 521 | (define-key 8859-1-map "'" (make-sparse-keymap)) | ||
| 522 | (define-key 8859-1-map "''" 'insert-acute-accent) | ||
| 523 | (define-key 8859-1-map "'A" 'insert-A-acute) | ||
| 524 | (define-key 8859-1-map "'E" 'insert-E-acute) | ||
| 525 | (define-key 8859-1-map "'I" 'insert-I-acute) | ||
| 526 | (define-key 8859-1-map "'O" 'insert-O-acute) | ||
| 527 | (define-key 8859-1-map "'U" 'insert-U-acute) | ||
| 528 | (define-key 8859-1-map "'Y" 'insert-Y-acute) | ||
| 529 | (define-key 8859-1-map "'a" 'insert-a-acute) | ||
| 530 | (define-key 8859-1-map "'e" 'insert-e-acute) | ||
| 531 | (define-key 8859-1-map "'i" 'insert-i-acute) | ||
| 532 | (define-key 8859-1-map "'o" 'insert-o-acute) | ||
| 533 | (define-key 8859-1-map "'u" 'insert-u-acute) | ||
| 534 | (define-key 8859-1-map "'y" 'insert-y-acute) | ||
| 535 | (define-key 8859-1-map "$" 'insert-general-currency-sign) | ||
| 536 | (define-key 8859-1-map "+" 'insert-plus-or-minus-sign) | ||
| 537 | (define-key 8859-1-map "," (make-sparse-keymap)) | ||
| 538 | (define-key 8859-1-map ",," 'insert-cedilla) | ||
| 539 | (define-key 8859-1-map ",C" 'insert-C-cedilla) | ||
| 540 | (define-key 8859-1-map ",c" 'insert-c-cedilla) | ||
| 541 | (define-key 8859-1-map "-" 'insert-soft-hyphen) | ||
| 542 | (define-key 8859-1-map "." 'insert-middle-dot) | ||
| 543 | (define-key 8859-1-map "/" (make-sparse-keymap)) | ||
| 544 | (define-key 8859-1-map "//" 'insert-division-sign) | ||
| 545 | (define-key 8859-1-map "/O" 'insert-O-slash) | ||
| 546 | (define-key 8859-1-map "/o" 'insert-o-slash) | ||
| 547 | (define-key 8859-1-map "1" (make-sparse-keymap)) | ||
| 548 | (define-key 8859-1-map "1/" (make-sparse-keymap)) | ||
| 549 | (define-key 8859-1-map "1/2" 'insert-fraction-one-half) | ||
| 550 | (define-key 8859-1-map "1/4" 'insert-fraction-one-quarter) | ||
| 551 | (define-key 8859-1-map "3" (make-sparse-keymap)) | ||
| 552 | (define-key 8859-1-map "3/" (make-sparse-keymap)) | ||
| 553 | (define-key 8859-1-map "3/4" 'insert-fraction-three-quarters) | ||
| 554 | (define-key 8859-1-map "<" 'insert-angle-quotation-mark-left) | ||
| 555 | (define-key 8859-1-map "=" 'insert-macron) | ||
| 556 | (define-key 8859-1-map ">" 'insert-angle-quotation-mark-right) | ||
| 557 | (define-key 8859-1-map "?" 'insert-inverted-question-mark) | ||
| 558 | (define-key 8859-1-map "A" (make-sparse-keymap)) | ||
| 559 | (define-key 8859-1-map "AA" 'insert-A-ring) | ||
| 560 | (define-key 8859-1-map "AE" 'insert-AE) | ||
| 561 | (define-key 8859-1-map "C" 'insert-copyright-sign) | ||
| 562 | (define-key 8859-1-map "D" 'insert-D-stroke) | ||
| 563 | (define-key 8859-1-map "L" 'insert-pound-sign) | ||
| 564 | (define-key 8859-1-map "P" 'insert-pilcrow) | ||
| 565 | (define-key 8859-1-map "R" 'insert-registered-sign) | ||
| 566 | (define-key 8859-1-map "S" 'insert-section-sign) | ||
| 567 | (define-key 8859-1-map "T" 'insert-THORN) | ||
| 568 | (define-key 8859-1-map "Y" 'insert-yen-sign) | ||
| 569 | (define-key 8859-1-map "^" (make-sparse-keymap)) | ||
| 570 | (define-key 8859-1-map "^1" 'insert-superscript-one) | ||
| 571 | (define-key 8859-1-map "^2" 'insert-superscript-two) | ||
| 572 | (define-key 8859-1-map "^3" 'insert-superscript-three) | ||
| 573 | (define-key 8859-1-map "^A" 'insert-A-circumflex) | ||
| 574 | (define-key 8859-1-map "^E" 'insert-E-circumflex) | ||
| 575 | (define-key 8859-1-map "^I" 'insert-I-circumflex) | ||
| 576 | (define-key 8859-1-map "^O" 'insert-O-circumflex) | ||
| 577 | (define-key 8859-1-map "^U" 'insert-U-circumflex) | ||
| 578 | (define-key 8859-1-map "^a" 'insert-a-circumflex) | ||
| 579 | (define-key 8859-1-map "^e" 'insert-e-circumflex) | ||
| 580 | (define-key 8859-1-map "^i" 'insert-i-circumflex) | ||
| 581 | (define-key 8859-1-map "^o" 'insert-o-circumflex) | ||
| 582 | (define-key 8859-1-map "^u" 'insert-u-circumflex) | ||
| 583 | (define-key 8859-1-map "_" (make-sparse-keymap)) | ||
| 584 | (define-key 8859-1-map "_a" 'insert-ordinal-indicator-feminine) | ||
| 585 | (define-key 8859-1-map "_o" 'insert-ordinal-indicator-masculine) | ||
| 586 | (define-key 8859-1-map "`" (make-sparse-keymap)) | ||
| 587 | (define-key 8859-1-map "`A" 'insert-A-grave) | ||
| 588 | (define-key 8859-1-map "`E" 'insert-E-grave) | ||
| 589 | (define-key 8859-1-map "`I" 'insert-I-grave) | ||
| 590 | (define-key 8859-1-map "`O" 'insert-O-grave) | ||
| 591 | (define-key 8859-1-map "`U" 'insert-U-grave) | ||
| 592 | (define-key 8859-1-map "`a" 'insert-a-grave) | ||
| 593 | (define-key 8859-1-map "`e" 'insert-e-grave) | ||
| 594 | (define-key 8859-1-map "`i" 'insert-i-grave) | ||
| 595 | (define-key 8859-1-map "`o" 'insert-o-grave) | ||
| 596 | (define-key 8859-1-map "`u" 'insert-u-grave) | ||
| 597 | (define-key 8859-1-map "a" (make-sparse-keymap)) | ||
| 598 | (define-key 8859-1-map "aa" 'insert-a-ring) | ||
| 599 | (define-key 8859-1-map "ae" 'insert-ae) | ||
| 600 | (define-key 8859-1-map "c" 'insert-cent-sign) | ||
| 601 | (define-key 8859-1-map "d" 'insert-d-stroke) | ||
| 602 | (define-key 8859-1-map "o" 'insert-degree-sign) | ||
| 603 | (define-key 8859-1-map "s" 'insert-ss) | ||
| 604 | (define-key 8859-1-map "t" 'insert-thorn) | ||
| 605 | (define-key 8859-1-map "u" 'insert-micro-sign) | ||
| 606 | (define-key 8859-1-map "x" 'insert-multiplication-sign) | ||
| 607 | (define-key 8859-1-map "|" 'insert-broken-vertical-line) | ||
| 608 | (define-key 8859-1-map "~" (make-sparse-keymap)) | ||
| 609 | (define-key 8859-1-map "~A" 'insert-A-tilde) | ||
| 610 | (define-key 8859-1-map "~N" 'insert-N-tilde) | ||
| 611 | (define-key 8859-1-map "~O" 'insert-O-tilde) | ||
| 612 | (define-key 8859-1-map "~a" 'insert-a-tilde) | ||
| 613 | (define-key 8859-1-map "~n" 'insert-n-tilde) | ||
| 614 | (define-key 8859-1-map "~o" 'insert-o-tilde) | ||
| 615 | (define-key 8859-1-map "~~" 'insert-not-sign) | ||
| 616 | (if (not (lookup-key global-map "\C-x8")) | ||
| 617 | (define-key global-map "\C-x8" 8859-1-map)) | ||
| 618 | ) | ||
| 619 | |||
| 620 | (provide 'iso8859-1-insert) | ||
diff --git a/lisp/international/iso-swed.el b/lisp/international/iso-swed.el new file mode 100644 index 00000000000..9ab2134381a --- /dev/null +++ b/lisp/international/iso-swed.el | |||
| @@ -0,0 +1,140 @@ | |||
| 1 | ;; Set up char tables for ISO 8859/1 for Swedish/Finnish terminals. | ||
| 2 | ;; Copyright (C) 1987 Free Software Foundation, Inc. | ||
| 3 | |||
| 4 | ;; This file is part of GNU Emacs. | ||
| 5 | |||
| 6 | ;; GNU Emacs is free software; you can redistribute it and/or modify | ||
| 7 | ;; it under the terms of the GNU General Public License as published by | ||
| 8 | ;; the Free Software Foundation; either version 1, or (at your option) | ||
| 9 | ;; any later version. | ||
| 10 | |||
| 11 | ;; GNU Emacs is distributed in the hope that it will be useful, | ||
| 12 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | ;; GNU General Public License for more details. | ||
| 15 | |||
| 16 | ;; You should have received a copy of the GNU General Public License | ||
| 17 | ;; along with GNU Emacs; see the file COPYING. If not, write to | ||
| 18 | ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 19 | |||
| 20 | |||
| 21 | ;; Written by Howard Gayle. See case-table.el for details. | ||
| 22 | |||
| 23 | ;; This code sets up to display ISO 8859/1 characters on | ||
| 24 | ;; terminals that have ASCII in the G0 set and a Swedish/Finnish | ||
| 25 | ;; version of ISO 646 in the G1 set. The G1 set differs from | ||
| 26 | ;; ASCII as follows: | ||
| 27 | ;; | ||
| 28 | ;; ASCII G1 | ||
| 29 | ;; $ general currency sign | ||
| 30 | ;; @ capital E with acute accent | ||
| 31 | ;; [ capital A with diaeresis or umlaut mark | ||
| 32 | ;; \ capital O with diaeresis or umlaut mark | ||
| 33 | ;; ] capital A with ring | ||
| 34 | ;; ^ capital U with diaeresis or umlaut mark | ||
| 35 | ;; ` small e with acute accent | ||
| 36 | ;; { small a with diaeresis or umlaut mark | ||
| 37 | ;; | small o with diaeresis or umlaut mark | ||
| 38 | ;; } small a with ring | ||
| 39 | ;; ~ small u with diaeresis or umlaut mark | ||
| 40 | |||
| 41 | (require 'disp-table) | ||
| 42 | |||
| 43 | (standard-display-ascii 160 "{_}") ; NBSP (no-break space) | ||
| 44 | (standard-display-ascii 161 "{!}") ; inverted exclamation mark | ||
| 45 | (standard-display-ascii 162 "{c}") ; cent sign | ||
| 46 | (standard-display-ascii 163 "{GBP}") ; pound sign | ||
| 47 | (standard-display-g1 164 ?$) ; general currency sign | ||
| 48 | (standard-display-ascii 165 "{JPY}") ; yen sign | ||
| 49 | (standard-display-ascii 166 "{|}") ; broken vertical line | ||
| 50 | (standard-display-ascii 167 "{S}") ; section sign | ||
| 51 | (standard-display-ascii 168 "{\"}") ; diaeresis | ||
| 52 | (standard-display-ascii 169 "{C}") ; copyright sign | ||
| 53 | (standard-display-ascii 170 "{_a}") ; ordinal indicator, feminine | ||
| 54 | (standard-display-ascii 171 "{<<}") ; left angle quotation mark | ||
| 55 | (standard-display-ascii 172 "{~}") ; not sign | ||
| 56 | (standard-display-ascii 173 "{-}") ; soft hyphen | ||
| 57 | (standard-display-ascii 174 "{R}") ; registered sign | ||
| 58 | (standard-display-ascii 175 "{=}") ; macron | ||
| 59 | (standard-display-ascii 176 "{o}") ; degree sign | ||
| 60 | (standard-display-ascii 177 "{+-}") ; plus or minus sign | ||
| 61 | (standard-display-ascii 178 "{2}") ; superscript two | ||
| 62 | (standard-display-ascii 179 "{3}") ; superscript three | ||
| 63 | (standard-display-ascii 180 "{'}") ; acute accent | ||
| 64 | (standard-display-ascii 181 "{u}") ; micro sign | ||
| 65 | (standard-display-ascii 182 "{P}") ; pilcrow | ||
| 66 | (standard-display-ascii 183 "{.}") ; middle dot | ||
| 67 | (standard-display-ascii 184 "{,}") ; cedilla | ||
| 68 | (standard-display-ascii 185 "{1}") ; superscript one | ||
| 69 | (standard-display-ascii 186 "{_o}") ; ordinal indicator, masculine | ||
| 70 | (standard-display-ascii 187 "{>>}") ; right angle quotation mark | ||
| 71 | (standard-display-ascii 188 "{1/4}") ; fraction one-quarter | ||
| 72 | (standard-display-ascii 189 "{1/2}") ; fraction one-half | ||
| 73 | (standard-display-ascii 190 "{3/4}") ; fraction three-quarters | ||
| 74 | (standard-display-ascii 191 "{?}") ; inverted question mark | ||
| 75 | (standard-display-ascii 192 "{`A}") ; A with grave accent | ||
| 76 | (standard-display-ascii 193 "{'A}") ; A with acute accent | ||
| 77 | (standard-display-ascii 194 "{^A}") ; A with circumflex accent | ||
| 78 | (standard-display-ascii 195 "{~A}") ; A with tilde | ||
| 79 | (standard-display-g1 196 ?[) ; A with diaeresis or umlaut mark | ||
| 80 | (standard-display-g1 197 ?]) ; A with ring | ||
| 81 | (standard-display-ascii 198 "{AE}") ; AE diphthong | ||
| 82 | (standard-display-ascii 199 "{,C}") ; C with cedilla | ||
| 83 | (standard-display-ascii 200 "{`E}") ; E with grave accent | ||
| 84 | (standard-display-g1 201 ?@) ; E with acute accent | ||
| 85 | (standard-display-ascii 202 "{^E}") ; E with circumflex accent | ||
| 86 | (standard-display-ascii 203 "{\"E}") ; E with diaeresis or umlaut mark | ||
| 87 | (standard-display-ascii 204 "{`I}") ; I with grave accent | ||
| 88 | (standard-display-ascii 205 "{'I}") ; I with acute accent | ||
| 89 | (standard-display-ascii 206 "{^I}") ; I with circumflex accent | ||
| 90 | (standard-display-ascii 207 "{\"I}") ; I with diaeresis or umlaut mark | ||
| 91 | (standard-display-ascii 208 "{-D}") ; D with stroke, Icelandic eth | ||
| 92 | (standard-display-ascii 209 "{~N}") ; N with tilde | ||
| 93 | (standard-display-ascii 210 "{`O}") ; O with grave accent | ||
| 94 | (standard-display-ascii 211 "{'O}") ; O with acute accent | ||
| 95 | (standard-display-ascii 212 "{^O}") ; O with circumflex accent | ||
| 96 | (standard-display-ascii 213 "{~O}") ; O with tilde | ||
| 97 | (standard-display-g1 214 ?\\) ; O with diaeresis or umlaut mark | ||
| 98 | (standard-display-ascii 215 "{x}") ; multiplication sign | ||
| 99 | (standard-display-ascii 216 "{/O}") ; O with slash | ||
| 100 | (standard-display-ascii 217 "{`U}") ; U with grave accent | ||
| 101 | (standard-display-ascii 218 "{'U}") ; U with acute accent | ||
| 102 | (standard-display-ascii 219 "{^U}") ; U with circumflex accent | ||
| 103 | (standard-display-g1 220 ?^) ; U with diaeresis or umlaut mark | ||
| 104 | (standard-display-ascii 221 "{'Y}") ; Y with acute accent | ||
| 105 | (standard-display-ascii 222 "{TH}") ; capital thorn, Icelandic | ||
| 106 | (standard-display-ascii 223 "{ss}") ; small sharp s, German | ||
| 107 | (standard-display-ascii 224 "{`a}") ; a with grave accent | ||
| 108 | (standard-display-ascii 225 "{'a}") ; a with acute accent | ||
| 109 | (standard-display-ascii 226 "{^a}") ; a with circumflex accent | ||
| 110 | (standard-display-ascii 227 "{~a}") ; a with tilde | ||
| 111 | (standard-display-g1 228 ?{) ; a with diaeresis or umlaut mark | ||
| 112 | (standard-display-g1 229 ?}) ; a with ring | ||
| 113 | (standard-display-ascii 230 "{ae}") ; ae diphthong | ||
| 114 | (standard-display-ascii 231 "{,c}") ; c with cedilla | ||
| 115 | (standard-display-ascii 232 "{`e}") ; e with grave accent | ||
| 116 | (standard-display-g1 233 ?`) ; e with acute accent | ||
| 117 | (standard-display-ascii 234 "{^e}") ; e with circumflex accent | ||
| 118 | (standard-display-ascii 235 "{\"e}") ; e with diaeresis or umlaut mark | ||
| 119 | (standard-display-ascii 236 "{`i}") ; i with grave accent | ||
| 120 | (standard-display-ascii 237 "{'i}") ; i with acute accent | ||
| 121 | (standard-display-ascii 238 "{^i}") ; i with circumflex accent | ||
| 122 | (standard-display-ascii 239 "{\"i}") ; i with diaeresis or umlaut mark | ||
| 123 | (standard-display-ascii 240 "{-d}") ; d with stroke, Icelandic eth | ||
| 124 | (standard-display-ascii 241 "{~n}") ; n with tilde | ||
| 125 | (standard-display-ascii 242 "{`o}") ; o with grave accent | ||
| 126 | (standard-display-ascii 243 "{'o}") ; o with acute accent | ||
| 127 | (standard-display-ascii 244 "{^o}") ; o with circumflex accent | ||
| 128 | (standard-display-ascii 245 "{~o}") ; o with tilde | ||
| 129 | (standard-display-g1 246 ?|) ; o with diaeresis or umlaut mark | ||
| 130 | (standard-display-ascii 247 "{/}") ; division sign | ||
| 131 | (standard-display-ascii 248 "{/o}") ; o with slash | ||
| 132 | (standard-display-ascii 249 "{`u}") ; u with grave accent | ||
| 133 | (standard-display-ascii 250 "{'u}") ; u with acute accent | ||
| 134 | (standard-display-ascii 251 "{^u}") ; u with circumflex accent | ||
| 135 | (standard-display-g1 252 ?~) ; u with diaeresis or umlaut mark | ||
| 136 | (standard-display-ascii 253 "{'y}") ; y with acute accent | ||
| 137 | (standard-display-ascii 254 "{th}") ; small thorn, Icelandic | ||
| 138 | (standard-display-ascii 255 "{\"y}") ; small y with diaeresis or umlaut mark | ||
| 139 | |||
| 140 | (provide 'iso8859-1-swedish) | ||
diff --git a/lisp/international/swedish.el b/lisp/international/swedish.el new file mode 100644 index 00000000000..bda8a7183a4 --- /dev/null +++ b/lisp/international/swedish.el | |||
| @@ -0,0 +1,145 @@ | |||
| 1 | ;; Miscellaneous functions for dealing with Swedish. | ||
| 2 | ;; Copyright (C) 1988 Free Software Foundation, Inc. | ||
| 3 | |||
| 4 | ;; This file is part of GNU Emacs. | ||
| 5 | |||
| 6 | ;; GNU Emacs is free software; you can redistribute it and/or modify | ||
| 7 | ;; it under the terms of the GNU General Public License as published by | ||
| 8 | ;; the Free Software Foundation; either version 1, or (at your option) | ||
| 9 | ;; any later version. | ||
| 10 | |||
| 11 | ;; GNU Emacs is distributed in the hope that it will be useful, | ||
| 12 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | ;; GNU General Public License for more details. | ||
| 15 | |||
| 16 | ;; You should have received a copy of the GNU General Public License | ||
| 17 | ;; along with GNU Emacs; see the file COPYING. If not, write to | ||
| 18 | ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 19 | |||
| 20 | |||
| 21 | ;; Written by Howard Gayle. See case-table.el for details. | ||
| 22 | |||
| 23 | ;; See iso-swed.el for a description of the character set. | ||
| 24 | |||
| 25 | (require 'iso-syntax) | ||
| 26 | |||
| 27 | (defvar swedish-re | ||
| 28 | "[ \t\n]\\(och\\|att\\|en\\|{r\\|\\[R\\|p}\\|P\\]\\|som\\|det\\|av\\|den\\|f|r\\|F\\\\R\\)[ \t\n.,?!:;'\")}]" | ||
| 29 | "Regular expression for common Swedish words.") | ||
| 30 | |||
| 31 | (defvar swascii-to-8859-trans | ||
| 32 | (let ((string (make-string 256 ? )) | ||
| 33 | (i 0)) | ||
| 34 | (while (< i 256) | ||
| 35 | (aset string i i) | ||
| 36 | (setq i (1+ i))) | ||
| 37 | (aset string ?\[ 196) | ||
| 38 | (aset string ?\] 197) | ||
| 39 | (aset string ?\\ 214) | ||
| 40 | (aset string ?^ 220) | ||
| 41 | (aset string ?\{ 228) | ||
| 42 | (aset string ?\} 229) | ||
| 43 | (aset string ?\` 233) | ||
| 44 | (aset string ?\| 246) | ||
| 45 | (aset string ?~ 252) | ||
| 46 | string) | ||
| 47 | "Trans table from SWASCII to 8859.") | ||
| 48 | |||
| 49 | ; $ is not converted because it almost always means US | ||
| 50 | ; dollars, not general currency sign. @ is not converted | ||
| 51 | ; because it is more likely to be an at sign in a mail address | ||
| 52 | ; than an E with acute accent. | ||
| 53 | |||
| 54 | (defun swascii-to-8859-buffer () | ||
| 55 | "Convert characters in buffer from Swedish/Finnish-ascii to ISO 8859/1. | ||
| 56 | Works even on read-only buffers. `$' and `@' are not converted." | ||
| 57 | (interactive) | ||
| 58 | (let ((buffer-read-only nil)) | ||
| 59 | (translate-region (point-min) (point-max) swascii-to-8859-trans))) | ||
| 60 | |||
| 61 | (defun swascii-to-8859-buffer-maybe () | ||
| 62 | "Call swascii-to-8859-buffer if the buffer looks like Swedish-ascii. | ||
| 63 | Leaves point just after the word that looks Swedish." | ||
| 64 | (interactive) | ||
| 65 | (let ((case-fold-search t)) | ||
| 66 | (if (re-search-forward swedish-re nil t) | ||
| 67 | (swascii-to-8859-buffer)))) | ||
| 68 | |||
| 69 | (setq rmail-show-message-hook 'swascii-to-8859-buffer-maybe) | ||
| 70 | |||
| 71 | (or (boundp 'news-group-hook-alist) (setq news-group-hook-alist nil)) | ||
| 72 | (setq news-group-hook-alist | ||
| 73 | (append '(("^swnet." . swascii-to-8859-buffer-maybe)) | ||
| 74 | news-group-hook-alist)) | ||
| 75 | |||
| 76 | (defvar 8859-to-swascii-trans | ||
| 77 | (let ((string (make-string 256 ? )) | ||
| 78 | (i 0)) | ||
| 79 | (while (< i 256) | ||
| 80 | (aset string i i) | ||
| 81 | (setq i (1+ i))) | ||
| 82 | (aset string 164 ?$) | ||
| 83 | (aset string 196 ?\[) | ||
| 84 | (aset string 197 ?\]) | ||
| 85 | (aset string 201 ?@) | ||
| 86 | (aset string 214 ?\\) | ||
| 87 | (aset string 220 ?^) | ||
| 88 | (aset string 228 ?\{) | ||
| 89 | (aset string 229 ?\}) | ||
| 90 | (aset string 233 ?\`) | ||
| 91 | (aset string 246 ?\|) | ||
| 92 | (aset string 252 ?~) | ||
| 93 | string) | ||
| 94 | "8859 to SWASCII trans table.") | ||
| 95 | |||
| 96 | (defun 8859-to-swascii-buffer () | ||
| 97 | "Convert characters in buffer from ISO 8859/1 to Swedish/Finnish-ascii." | ||
| 98 | (interactive "*") | ||
| 99 | (translate-region (point-min) (point-max) 8859-to-swascii-trans)) | ||
| 100 | |||
| 101 | (setq mail-send-hook '8859-to-swascii-buffer) | ||
| 102 | (setq news-inews-hook '8859-to-swascii-buffer) | ||
| 103 | |||
| 104 | ;; It's not clear what purpose is served by a separate | ||
| 105 | ;; Swedish mode that differs from Text mode only in having | ||
| 106 | ;; a separate abbrev table. Nothing says that the abbrevs you | ||
| 107 | ;; define in Text mode have to be English! | ||
| 108 | |||
| 109 | ;(defvar swedish-mode-abbrev-table nil | ||
| 110 | ; "Abbrev table used while in swedish mode.") | ||
| 111 | ;(define-abbrev-table 'swedish-mode-abbrev-table ()) | ||
| 112 | |||
| 113 | ;(defun swedish-mode () | ||
| 114 | ; "Major mode for editing Swedish text intended for humans to | ||
| 115 | ;read. Special commands:\\{text-mode-map} | ||
| 116 | ;Turning on swedish-mode calls the value of the variable | ||
| 117 | ;text-mode-hook, if that value is non-nil." | ||
| 118 | ; (interactive) | ||
| 119 | ; (kill-all-local-variables) | ||
| 120 | ; (use-local-map text-mode-map) | ||
| 121 | ; (setq mode-name "Swedish") | ||
| 122 | ; (setq major-mode 'swedish-mode) | ||
| 123 | ; (setq local-abbrev-table swedish-mode-abbrev-table) | ||
| 124 | ; (set-syntax-table text-mode-syntax-table) | ||
| 125 | ; (run-hooks 'text-mode-hook)) | ||
| 126 | |||
| 127 | ;(defun indented-swedish-mode () | ||
| 128 | ; "Major mode for editing indented Swedish text intended for | ||
| 129 | ;humans to read.\\{indented-text-mode-map} | ||
| 130 | ;Turning on indented-swedish-mode calls the value of the | ||
| 131 | ;variable text-mode-hook, if that value is non-nil." | ||
| 132 | ; (interactive) | ||
| 133 | ; (kill-all-local-variables) | ||
| 134 | ; (use-local-map text-mode-map) | ||
| 135 | ; (define-abbrev-table 'swedish-mode-abbrev-table ()) | ||
| 136 | ; (setq local-abbrev-table swedish-mode-abbrev-table) | ||
| 137 | ; (set-syntax-table text-mode-syntax-table) | ||
| 138 | ; (make-local-variable 'indent-line-function) | ||
| 139 | ; (setq indent-line-function 'indent-relative-maybe) | ||
| 140 | ; (use-local-map indented-text-mode-map) | ||
| 141 | ; (setq mode-name "Indented Swedish") | ||
| 142 | ; (setq major-mode 'indented-swedish-mode) | ||
| 143 | ; (run-hooks 'text-mode-hook)) | ||
| 144 | |||
| 145 | (provide 'swedish) | ||
diff --git a/lisp/rot13.el b/lisp/rot13.el new file mode 100644 index 00000000000..1a884d087de --- /dev/null +++ b/lisp/rot13.el | |||
| @@ -0,0 +1,41 @@ | |||
| 1 | ;; Display a buffer in rot13. | ||
| 2 | ;; Copyright (C) 1988 Free Software Foundation, Inc. | ||
| 3 | |||
| 4 | ;; This file is part of GNU Emacs. | ||
| 5 | |||
| 6 | ;; GNU Emacs is free software; you can redistribute it and/or modify | ||
| 7 | ;; it under the terms of the GNU General Public License as published by | ||
| 8 | ;; the Free Software Foundation; either version 1, or (at your option) | ||
| 9 | ;; any later version. | ||
| 10 | |||
| 11 | ;; GNU Emacs is distributed in the hope that it will be useful, | ||
| 12 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | ;; GNU General Public License for more details. | ||
| 15 | |||
| 16 | ;; You should have received a copy of the GNU General Public License | ||
| 17 | ;; along with GNU Emacs; see the file COPYING. If not, write to | ||
| 18 | ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 19 | |||
| 20 | |||
| 21 | ;; Written by Howard Gayle. See case-table.el for details. | ||
| 22 | |||
| 23 | ;; This hack is mainly to show off the char table stuff. | ||
| 24 | |||
| 25 | (defvar rot13-display-table | ||
| 26 | (let ((table (make-display-table)) | ||
| 27 | (i 0)) | ||
| 28 | (while (< i 26) | ||
| 29 | (aset table (+ i ?a) (make-rope (+ (% (+ i 13) 26) ?a))) | ||
| 30 | (aset table (+ i ?A) (make-rope (+ (% (+ i 13) 26) ?A))) | ||
| 31 | (setq i (1+ i))) | ||
| 32 | table) | ||
| 33 | "Char table for rot 13 display.") | ||
| 34 | |||
| 35 | (defun rot13-other-window () | ||
| 36 | "Display current buffer in rot 13 in another window." | ||
| 37 | (interactive) | ||
| 38 | (let ((w (display-buffer (current-buffer) t))) | ||
| 39 | (set-window-display-table w rot13-display-table))) | ||
| 40 | |||
| 41 | (provide 'rot13) | ||
diff --git a/lisp/vt100-led.el b/lisp/vt100-led.el new file mode 100644 index 00000000000..e8f370835f1 --- /dev/null +++ b/lisp/vt100-led.el | |||
| @@ -0,0 +1,61 @@ | |||
| 1 | ;; Functions for controlling the LEDs on VT-100 terminals & clones. | ||
| 2 | ;; Copyright (C) 1988 Free Software Foundation, Inc. | ||
| 3 | |||
| 4 | ;; This file is part of GNU Emacs. | ||
| 5 | |||
| 6 | ;; GNU Emacs is free software; you can redistribute it and/or modify | ||
| 7 | ;; it under the terms of the GNU General Public License as published by | ||
| 8 | ;; the Free Software Foundation; either version 1, or (at your option) | ||
| 9 | ;; any later version. | ||
| 10 | |||
| 11 | ;; GNU Emacs is distributed in the hope that it will be useful, | ||
| 12 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | ;; GNU General Public License for more details. | ||
| 15 | |||
| 16 | ;; You should have received a copy of the GNU General Public License | ||
| 17 | ;; along with GNU Emacs; see the file COPYING. If not, write to | ||
| 18 | ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 19 | |||
| 20 | |||
| 21 | ;; Written by Howard Gayle. | ||
| 22 | |||
| 23 | (defvar led-state (make-vector 5 nil) | ||
| 24 | "The internal state of the LEDs. Choices are nil, t, `flash. | ||
| 25 | Element 0 is not used.") | ||
| 26 | |||
| 27 | (defun led-flash (l) | ||
| 28 | "Flash LED l." | ||
| 29 | (aset led-state l 'flash) | ||
| 30 | (led-update)) | ||
| 31 | |||
| 32 | (defun led-off (&optional l) | ||
| 33 | "Turn off vt100 led number L. With no argument, turn them all off." | ||
| 34 | (interactive "P") | ||
| 35 | (if l | ||
| 36 | (aset led-state (prefix-numeric-value l) nil) | ||
| 37 | (fillarray led-state nil)) | ||
| 38 | (led-update)) | ||
| 39 | |||
| 40 | (defun led-on (l) | ||
| 41 | "Turn on LED l." | ||
| 42 | (aset led-state l t) | ||
| 43 | (led-update)) | ||
| 44 | |||
| 45 | (defun led-update () | ||
| 46 | "Update the terminal's LEDs to reflect the internal state." | ||
| 47 | (let ((f "\e[?0") ; String to flash. | ||
| 48 | (o "\e[0") ; String for steady on. | ||
| 49 | (l 1)) ; Current LED number. | ||
| 50 | (while (/= l 5) | ||
| 51 | (let ((s (aref led-state l))) | ||
| 52 | (cond | ||
| 53 | ((eq s 'flash) | ||
| 54 | (setq f (concat f ";" (int-to-string l)))) | ||
| 55 | (s | ||
| 56 | (setq o (concat o ";" (int-to-string l)))))) | ||
| 57 | (setq l (1+ l))) | ||
| 58 | (setq o (concat o "q" f "t")) | ||
| 59 | (send-string-to-terminal o))) | ||
| 60 | |||
| 61 | (provide 'vt100-led) | ||