Mercurial > hg > xemacs-beta
comparison lisp/modes/two-column.el @ 0:376386a54a3c r19-14
Import from CVS: tag r19-14
author | cvs |
---|---|
date | Mon, 13 Aug 2007 08:45:50 +0200 |
parents | |
children | b82b59fe008d |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:376386a54a3c |
---|---|
1 ;;; two-column.el --- minor mode for editing of two-column text | |
2 | |
3 ;; Copyright (C) 1992, 1994 Free Software Foundation, Inc. | |
4 | |
5 ;; Author: Daniel Pfeiffer <pfeiffer@cix.cict.fr> | |
6 ;; Adapted-By: ESR | |
7 | |
8 ;; This file is part of GNU Emacs. | |
9 | |
10 ;; GNU Emacs is free software; you can redistribute it and/or modify | |
11 ;; it under the terms of the GNU General Public License as published by | |
12 ;; the Free Software Foundation; either version 2, or (at your option) | |
13 ;; any later version. | |
14 | |
15 ;; GNU Emacs is distributed in the hope that it will be useful, | |
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of | |
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
18 ;; GNU General Public License for more details. | |
19 | |
20 ;; You should have received a copy of the GNU General Public License | |
21 ;; along with GNU Emacs; see the file COPYING. If not, write to | |
22 ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. | |
23 | |
24 ;;; Commentary: | |
25 | |
26 ;; This package gives you the ability to edit text in a two-column format. | |
27 | |
28 ;; --8<---- two-column.el ----8<--------8<--------8<--------8<--------8<------- | |
29 ;; Esperanto: English: | |
30 | |
31 ;; Minora modalo por samtempa dukolumna Minor mode for simultaneous | |
32 ;; tajpado two-column editing | |
33 | |
34 ;; Tiu minora modalo ebligas al vi This minor mode allows you to | |
35 ;; tajpi sendepende en du apudaj independently edit two adjacent | |
36 ;; bufroj. Vi havas tri eblecojn por buffers. You have three ways to | |
37 ;; eki ^gin. ^Ciu donas al vi start it up. Each gives you a | |
38 ;; horizontale disigatan fenestron, horizontally split window similar to | |
39 ;; simila al fina apareco de via the final outcome of your text: | |
40 ;; teksto: | |
41 | |
42 ;; C-x 6 2 asocias novan bufron nomatan associates a new buffer called | |
43 ;; same, sed kun 2C/ anta^u. the same, but with 2C/ | |
44 ;; prepended. | |
45 | |
46 ;; C-x 6 b asocias alian bufron. Vi povas associates another buffer. | |
47 ;; anka^u asocii dataron, se vi This can be used to associate a | |
48 ;; ^jus anta^ue faris C-x C-f. file if you just did C-x C-f. | |
49 | |
50 ;; C-x 6 u disigas jam dukolumnan tekston unmerges a two-column text into | |
51 ;; en du bufroj ekde la nuna two buffers from the current | |
52 ;; linio, kaj je la nuna kolumno. line and at the current column. | |
53 ;; La anta^uaj signoj (ofte The preceding characters (often | |
54 ;; tabeligilo a^u |) estas la tab or |) are the column | |
55 ;; kolumna disiganto. Linioj kiuj separator. Lines that don't | |
56 ;; ne enhavas ilin ne estas have them won't be separated. | |
57 ;; disigitaj. Kiel la kvara kaj Like the fourth and fifth line | |
58 ;; la kvina linio se vi disigas if you unmerge this file from | |
59 ;; ^ci dataron ekde la unua angla the first english word. | |
60 ;; vorto. | |
61 | |
62 ;; Je ^cia flanko estas bufro, kiu On each side is a buffer that knows | |
63 ;; konas la alian. Kun la ordonoj C-x about the other. With the commands | |
64 ;; 6 SPC, C-x 6 DEL kaj C-x 6 RET oni C-x 6 SPC, C-x 6 DEL and C-x 6 RET | |
65 ;; povas suben- a^u supreniri unu you can simultaneously scroll up or | |
66 ;; ekranon, kaj subeniri linion, down by a screenfull and by a line | |
67 ;; samtempe en la du bufroj. Al la alia in both buffers. Empty lines are | |
68 ;; bufro estas aldonataj linioj se added to the other buffer if | |
69 ;; necesas, por ke vi vidu la saman necessary, so that you see the same | |
70 ;; parton. Per C-x 6 C-l vi povas part. With C-x 6 C-l you can | |
71 ;; recentrigi la linion. Kiam vi nur recenter the line. When you only | |
72 ;; plu havas unu el la du bufroj have one of the two buffers onscreen | |
73 ;; surekrane vi revidos la alian per you can get the other back with C-x | |
74 ;; denove C-x 6 2. 6 2 once more. | |
75 | |
76 ;; Se vi volas meti longajn liniojn If you include long lines, i.e which | |
77 ;; (ekz. programerojn) en la kunigotan will span both columns (eg. source | |
78 ;; tekston, ili devas esti en la code), they should be in what will | |
79 ;; estonte unua kolumno. La alia devas be the first column, with the | |
80 ;; havi malplenajn linion apud ili. associated buffer having empty lines | |
81 ;; next to them. | |
82 | |
83 ;; Averto: en Emacs kiam vi ^san^gas la Attention: in Emacs when you change | |
84 ;; ma^joran modalon, la minoraj modaloj the major mode, the minor modes are | |
85 ;; estas anka^u elmemorigitaj. Tiu- also purged from memory. In that | |
86 ;; okaze vi devas religi la du bufrojn case you must reassociate the two | |
87 ;; per iu C-x 6-ordono, ekz. C-x 6 b. buffers with any C-x 6-command, e.g. | |
88 ;; C-x 6 b. | |
89 | |
90 ;; Kiam vi estos kontenta de la When you have edited both buffers to | |
91 ;; rezulto, vi kunmetos la du kolumnojn your content, you merge them with | |
92 ;; per C-x 6 1. Se vi poste vidas C-x 6 1. If you then see a problem, | |
93 ;; problemon, vi neniigu la kunmeton you undo the merge with C-x u and | |
94 ;; per C-x u kaj plue modifu la du continue to edit the two buffers. | |
95 ;; bufrojn. Kiam vi ne plu volas tajpi When you no longer want to edit in | |
96 ;; dukolumne, vi eliru el la minora two columns, you turn off the minor | |
97 ;; modalo per C-x 6 k. mode with C-x 6 k. | |
98 | |
99 | |
100 ;; An^stata^u tri `autoload' kaj tri | Instead of three `autoload' and | |
101 ;; `global-set-key' vi povas uzi la | three `global-set-key' you can use | |
102 ;; jenon en via dataro ~/.emacs, por | the following in your file | |
103 ;; memstare ^sar^gi la modalon: | ~/.emacs, to automatically load | |
104 ;; | the mode: | |
105 | |
106 ;; (global-set-key "\C-x6" | |
107 ;; '(lambda () (interactive) | |
108 ;; (load-library "two-column") | |
109 ;; (call-interactively | |
110 ;; (cdr (assq (read-char) tc-mode-map))))) | |
111 | |
112 ;; Se vi ^satus havi la dukolumnajn | If you'd like to have the | |
113 ;; ordonojn je funkciklavo <f2>, vi | two-column commands on function | |
114 ;; povas uzi la jenon en via dataro | key <f2>, you can use the | |
115 ;; ~/.emacs: | following in your file ~/.emacs: | |
116 | |
117 ;; (global-set-key [f2] (function | |
118 ;; (lambda () | |
119 ;; (interactive) | |
120 ;; (load-library "two-column") | |
121 ;; (global-set-key [f2] tc-mode-map) | |
122 ;; (call-interactively | |
123 ;; (cdr (assq (read-char) tc-mode-map)))))) | |
124 | |
125 ;; In addition to two-column editing of text, for example for writing a | |
126 ;; bilingual text side-by-side as shown below in the file's prolog, other | |
127 ;; interesting uses have been found for this minor mode: | |
128 ;; | |
129 ;; | |
130 ;; You can separate the columns with {+} C-x 6 u or <f2> u if you prefer | |
131 ;; any string that pleases you, by {+} handles these with a prefix argument | |
132 ;; setting tc-separator. For {+} that enables you to declare the | |
133 ;; example "{+} " if you like to {+} desired length of such a string. | |
134 ;; amuse yourself. | |
135 ;; | |
136 ;; | |
137 ;; keyword You can write any text corresponding to a | |
138 ;; given keyword in a filled paragraph next to | |
139 ;; it. Note that the width of the first column | |
140 ;; may be less than window-min-width in the | |
141 ;; result, but will be displayed at that width. | |
142 ;; | |
143 ;; another This is not a three- or multi-column mode. | |
144 ;; The example in the file's prolog required | |
145 ;; working on two columns and then treating the | |
146 ;; result as one column in order to add the | |
147 ;; third. | |
148 ;; | |
149 ;; | |
150 ;; Programmers might like the ability to split off the comment column of | |
151 ;; a file that looks like the following. The advantage is that with | |
152 ;; (setq fill-prefix "-- ") you can run M-q (fill-paragraph) on the | |
153 ;; comment. The problem is, code quickly gets rather wide, so you need | |
154 ;; to use a narrower comment column, which is less interesting, unless | |
155 ;; you have a 132-column screen. Code lines that reach beyond | |
156 ;; comment-column are no problem, except that you won't always see their | |
157 ;; end during editing. | |
158 ;; | |
159 ;; BEGIN -- This is just some meaningless | |
160 ;; FOR i IN 1..10 LOOP -- code in Ada, that runs foobar | |
161 ;; foobar( i ); -- once for each argument from one | |
162 ;; END LOOP; -- to ten, and then we're already | |
163 ;; END; -- through with it. | |
164 ;; | |
165 ;; Better yet, you can put the point before "This", type M-3 C-x 6 u | |
166 ;; which makes "-- " the separator between a no-comments Ada buffer, and | |
167 ;; a plain text comment buffer. When you put them back together, every | |
168 ;; non-empty line of the 2nd column will again be preceded by "-- ". | |
169 ;; | |
170 ;; | |
171 ;; The <f2> function key hack (which is one of the rare times when | |
172 ;; function keys are mnemonic) at the end of the file's prolog requires | |
173 ;; that the lisp/term/*.el for your terminal use the standard | |
174 ;; conventions. Too bad that some don't (at least not in version 18.55). | |
175 ;; The Sun one is hopelessly non-standard, and vt2[024]0 somehow forgot | |
176 ;; to define <f1> thru <f5>. (It defines <pf1> thru <pf4> instead, but | |
177 ;; that is not what we need on an X terminal.) If you want to use those, | |
178 ;; you'll need another hack something like: | |
179 ;; | |
180 ;; (if (string= (system-name) "cix") | |
181 ;; (progn | |
182 ;; (load-library "term/vt200.el") | |
183 ;; (define-key CSI-map "12~" (cons function-keymap ?\^b))) | |
184 ;; (global-unset-key "\e[") | |
185 ;; (define-key esc-map "[225z" (cons function-keymap ?\^b))) | |
186 ;; | |
187 ;; where "cix" is the non-sun machine I use. Actually I use the same X | |
188 ;; terminal to connect to both machines, and I want to keep my ~/.emacs | |
189 ;; identical on both. Bother, the two Emacses don't recognize the same | |
190 ;; keys and assign different sequences to those they do! I sure hope all | |
191 ;; this nonsense will stop with version 19 (or preferably soon) where I'd | |
192 ;; like to be able to say (define-key some-map '<f2> some-cmd), and see | |
193 ;; <f2> rather than some unintelligible ESC-sequence in command key | |
194 ;; sequences. | |
195 | |
196 ;;; Code: | |
197 | |
198 ;;;;; Set up keymap ;;;;; | |
199 | |
200 ;;;###autoload | |
201 (defvar tc-mode-map nil | |
202 "Keymap for commands for two-column mode.") | |
203 | |
204 ;;;###autoload | |
205 (if tc-mode-map | |
206 () | |
207 (setq tc-mode-map (make-sparse-keymap)) | |
208 (define-key tc-mode-map "1" 'tc-merge) | |
209 (define-key tc-mode-map "2" 'tc-two-columns) | |
210 (define-key tc-mode-map "b" 'tc-associate-buffer) | |
211 (define-key tc-mode-map "d" 'tc-dissociate) | |
212 (define-key tc-mode-map "\C-l" 'tc-recenter) | |
213 (define-key tc-mode-map "o" 'tc-associated-buffer) | |
214 (define-key tc-mode-map "s" 'tc-split) | |
215 (define-key tc-mode-map "{" 'shrink-window-horizontally) | |
216 (define-key tc-mode-map "}" 'enlarge-window-horizontally) | |
217 (define-key tc-mode-map " " 'tc-scroll-up) | |
218 (define-key tc-mode-map "\^?" 'tc-scroll-down) | |
219 (define-key tc-mode-map "\C-m" 'tc-scroll-line)) | |
220 | |
221 ;;;###autoload | |
222 (global-set-key "\C-x6" tc-mode-map) | |
223 | |
224 ;;;;; variable declarations ;;;;; | |
225 | |
226 ;; markers seem to be the only buffer-id not affected by renaming | |
227 ;; a buffer. This nevertheless loses when a buffer is killed. | |
228 ;;;###autoload | |
229 (defvar tc-other nil | |
230 "Marker to the associated buffer, if non-nil.") | |
231 ;;;###autoload | |
232 (make-variable-buffer-local 'tc-other) | |
233 ;;;###autoload | |
234 (put 'tc-other 'permanent-local t) | |
235 | |
236 ;(setq minor-mode-alist (cons '(tc-other " 2C") minor-mode-alist)) | |
237 ;; XEmacs: moved after def of tc-two-columns. | |
238 | |
239 ;; rearranged, so that the pertinent info will show in 40 columns | |
240 (defvar tc-mode-line-format | |
241 '("-%*- %15b --" (-3 . "%p") "--%[(" mode-name | |
242 minor-mode-alist mode-line-process "%n" ")%]%-") | |
243 "*Value of mode-line-format for a buffer in two-column minor mode.") | |
244 | |
245 (defvar tc-separator "" | |
246 "*A string inserted between the two columns when merging. | |
247 This gets set locally by \\[tc-split].") | |
248 (put 'tc-separator 'permanent-local t) | |
249 | |
250 (defvar tc-window-width 40 | |
251 "*The width of the first column. (Must be at least `window-min-width') | |
252 This value is local for every buffer that sets it.") | |
253 (make-variable-buffer-local 'tc-window-width) | |
254 (put 'tc-window-width 'permanent-local t) | |
255 | |
256 (defvar tc-beyond-fill-column 4 | |
257 "*Base for calculating `fill-column' for a buffer in two-column minor mode. | |
258 The value of `fill-column' becomes `tc-window-width' for this buffer | |
259 minus this value.") | |
260 | |
261 (defvar tc-mode-hook nil | |
262 "Function called, if non-nil, whenever turning on two-column minor mode. | |
263 It can get called by \\[tc-two-columns] (tc-two-columns), \\[tc-split] (tc-split) | |
264 and \\[tc-associate-buffer] (tc-associate-buffer), on both buffers.") | |
265 | |
266 ;;;;; base functions ;;;;; | |
267 | |
268 ;; the access method for the other buffer. this tries to remedy against | |
269 ;; lost local variables and lost buffers. | |
270 (defun tc-other () | |
271 (if tc-other | |
272 (or (prog1 | |
273 (marker-buffer tc-other) | |
274 (setq mode-line-format tc-mode-line-format )) | |
275 ; The associated buffer somehow got killed. | |
276 (progn | |
277 ; The other variables may later be useful if the user | |
278 ; reestablishes the association. | |
279 (kill-local-variable 'tc-other) | |
280 (kill-local-variable 'mode-line-format) | |
281 nil)))) | |
282 | |
283 ;;;###autoload | |
284 (defun tc-two-columns (&optional buffer) | |
285 "Split current window vertically for two-column editing. | |
286 | |
287 When called the first time, associates a buffer with the current | |
288 buffer. Both buffers are put in two-column minor mode and | |
289 tc-mode-hook gets called on both. These buffers remember | |
290 about one another, even when renamed. | |
291 | |
292 When called again, restores the screen layout with the current buffer | |
293 first and the associated buffer to it's right. | |
294 | |
295 If you include long lines, i.e which will span both columns (eg. | |
296 source code), they should be in what will be the first column, with | |
297 the associated buffer having empty lines next to them. | |
298 | |
299 You have the following commands at your disposal: | |
300 | |
301 \\[tc-two-columns] Rearrange screen | |
302 \\[tc-associate-buffer] Reassociate buffer after changing major mode | |
303 \\[tc-scroll-up] Scroll both buffers up by a screenfull | |
304 \\[tc-scroll-down] Scroll both buffers down by a screenful | |
305 \\[tc-scroll-line] Scroll both buffers up by one or more lines | |
306 \\[tc-recenter] Recenter and realign other buffer | |
307 \\[shrink-window-horizontally], \\[enlarge-window-horizontally] Shrink, enlarge current column | |
308 \\[tc-associated-buffer] Switch to associated buffer | |
309 \\[tc-merge] Merge both buffers | |
310 | |
311 These keybindings can be customized in your ~/.emacs by `tc-prefix' | |
312 and `tc-mode-map'. | |
313 | |
314 The appearance of the screen can be customized by the variables | |
315 `tc-window-width', `tc-beyond-fill-column', | |
316 `tc-mode-line-format' and `truncate-partial-width-windows'." | |
317 | |
318 (interactive "P") | |
319 ; first go to full width, so that we can certainly split into | |
320 ; two windows | |
321 (if (< (window-width) (frame-width)) | |
322 (enlarge-window 99999 t)) | |
323 (split-window-horizontally | |
324 (max window-min-width (min tc-window-width | |
325 (- (frame-width) window-min-width)))) | |
326 (if (tc-other) | |
327 (progn | |
328 (other-window 1) | |
329 (switch-to-buffer (tc-other)) | |
330 (other-window -1) | |
331 ; align buffers if necessary | |
332 (tc-scroll-line 0)) | |
333 | |
334 ; set up minor mode linking two buffers | |
335 (setq fill-column (- tc-window-width | |
336 tc-beyond-fill-column) | |
337 mode-line-format tc-mode-line-format) | |
338 (run-hooks tc-mode-hook) | |
339 (let ((other (point-marker))) | |
340 (other-window 1) | |
341 (switch-to-buffer | |
342 (or buffer | |
343 (generate-new-buffer | |
344 (concat "2C/" (buffer-name))))) | |
345 (or buffer | |
346 (text-mode)) | |
347 (setq fill-column (- tc-window-width | |
348 tc-beyond-fill-column) | |
349 mode-line-format tc-mode-line-format | |
350 tc-other other | |
351 other (point-marker)) | |
352 (run-hooks tc-mode-hook) | |
353 (other-window -1) | |
354 (setq tc-other other)))) | |
355 | |
356 ;; XEmacs: do it right. | |
357 ;;;###autoload | |
358 (add-minor-mode 'tc-other " 2C" nil nil 'tc-two-columns) | |
359 | |
360 (defalias 'tc-mode 'tc-two-columns) | |
361 | |
362 ;;;###autoload | |
363 (defun tc-associate-buffer () | |
364 "Associate another buffer with this one in two-column minor mode. | |
365 Can also be used to associate a just previously visited file, by | |
366 accepting the proposed default buffer. | |
367 | |
368 See \\[tc-two-columns] and `lisp/two-column.el' for further details." | |
369 (interactive) | |
370 (let ((b1 (current-buffer)) | |
371 (b2 (or (tc-other) | |
372 (read-buffer "Associate buffer: " (other-buffer))))) | |
373 (save-excursion | |
374 (setq tc-other nil) | |
375 (set-buffer b2) | |
376 (and (tc-other) | |
377 (not (eq b1 (tc-other))) | |
378 (error "Buffer already associated with buffer `%s'." | |
379 (buffer-name (tc-other)))) | |
380 (setq b1 (and (assq 'tc-window-width (buffer-local-variables)) | |
381 tc-window-width))) | |
382 ; if other buffer has a local width, adjust here too | |
383 (if b1 (setq tc-window-width (- (frame-width) b1))) | |
384 (tc-two-columns b2))) | |
385 | |
386 ;;;###autoload | |
387 (defun tc-split (arg) | |
388 "Unmerge a two-column text into two buffers in two-column minor mode. | |
389 The text is unmerged at the cursor's column which becomes the local | |
390 value of `tc-window-width'. Only lines that have the ARG same | |
391 preceding characters at that column get split. The ARG preceding | |
392 characters without any leading whitespace become the local value for | |
393 `tc-separator'. This way lines that continue across both | |
394 columns remain untouched in the first buffer. | |
395 | |
396 This function can be used with a prototype line, to set up things as | |
397 you like them. You write the first line of each column with the | |
398 separator you like and then unmerge that line. E.g.: | |
399 | |
400 First column's text sSs Second columns text | |
401 \\___/\\ | |
402 / \\ | |
403 5 character Separator You type M-5 \\[tc-split] with the point here | |
404 | |
405 See \\[tc-two-columns] and `lisp/two-column.el' for further details." | |
406 (interactive "p") | |
407 (and (tc-other) | |
408 (if (y-or-n-p (concat "Overwrite associated buffer `" | |
409 (buffer-name (tc-other)) | |
410 "'? ")) | |
411 (save-excursion | |
412 (set-buffer (tc-other)) | |
413 (erase-buffer)) | |
414 (signal 'quit nil))) | |
415 (let ((point (point)) | |
416 ; make next-line always come back to same column | |
417 (goal-column (current-column)) | |
418 ; a counter for empty lines in other buffer | |
419 (n (1- (count-lines (point-min) (point)))) | |
420 chars other) | |
421 (save-excursion | |
422 (backward-char arg) | |
423 (setq chars (buffer-substring (point) point)) | |
424 (skip-chars-forward " \t" point) | |
425 (make-local-variable 'tc-separator) | |
426 (setq tc-separator (buffer-substring (point) point) | |
427 tc-window-width (current-column))) | |
428 (tc-two-columns) | |
429 (setq other (tc-other)) | |
430 ; now we're ready to actually unmerge | |
431 (save-excursion | |
432 (while (not (eobp)) | |
433 (if (not (and (= (current-column) goal-column) | |
434 (string= chars | |
435 (buffer-substring (point) | |
436 (save-excursion | |
437 (backward-char arg) | |
438 (point)))))) | |
439 (setq n (1+ n)) | |
440 (setq point (point)) | |
441 (backward-char arg) | |
442 (skip-chars-backward " \t") | |
443 (delete-region point (point)) | |
444 (setq point (point)) | |
445 (insert-char ?\n n) | |
446 (append-to-buffer other point (progn (end-of-line) | |
447 (if (eobp) | |
448 (point) | |
449 (1+ (point))))) | |
450 (delete-region point (point)) | |
451 (setq n 0)) | |
452 (next-line 1))))) | |
453 | |
454 ;;;###autoload | |
455 (defun tc-dissociate () | |
456 "Turn off two-column minor mode in current and associated buffer. | |
457 If the associated buffer is unmodified and empty, it is killed." | |
458 (interactive) | |
459 (let ((buffer (current-buffer))) | |
460 (save-excursion | |
461 (and (tc-other) | |
462 (set-buffer (tc-other)) | |
463 (or (not (tc-other)) | |
464 (eq buffer (tc-other))) | |
465 (if (and (not (buffer-modified-p)) | |
466 (eobp) (bobp)) | |
467 (kill-buffer nil) | |
468 (kill-local-variable 'tc-other) | |
469 (kill-local-variable 'tc-window-width) | |
470 (kill-local-variable 'tc-separator) | |
471 (kill-local-variable 'mode-line-format) | |
472 (kill-local-variable 'fill-column)))) | |
473 (kill-local-variable 'tc-other) | |
474 (kill-local-variable 'tc-window-width) | |
475 (kill-local-variable 'tc-separator) | |
476 (kill-local-variable 'mode-line-format) | |
477 (kill-local-variable 'fill-column))) | |
478 | |
479 | |
480 ;; this doesn't use yank-rectangle, so that the first column can | |
481 ;; contain long lines | |
482 ;;;###autoload | |
483 (defun tc-merge () | |
484 "Merges the associated buffer with the current buffer. | |
485 They get merged at the column, which is the value of | |
486 `tc-window-width', i.e. usually at the vertical window | |
487 separator. This separator gets replaced with white space. Beyond | |
488 that the value of gets inserted on merged lines. The two columns are | |
489 thus pasted side by side, in a single text. If the other buffer is | |
490 not displayed to the left of this one, then this one becomes the left | |
491 column. | |
492 | |
493 If you want `tc-separator' on empty lines in the second column, | |
494 you should put just one space in them. In the final result, you can strip | |
495 off trailing spaces with \\[beginning-of-buffer] \\[replace-regexp] [ SPC TAB ] + $ RET RET" | |
496 | |
497 (interactive) | |
498 (or (tc-other) | |
499 (error "You must first set two-column minor mode.")) | |
500 (and (> (car (window-pixel-edges)) 0) ; not touching left edge of screen | |
501 (eq (window-buffer (previous-window)) | |
502 (tc-other)) | |
503 (other-window -1)) | |
504 (save-excursion | |
505 (let ((b1 (current-buffer)) | |
506 (b2 (tc-other)) | |
507 string) | |
508 (goto-char (point-min)) | |
509 (set-buffer b2) | |
510 (goto-char (point-min)) | |
511 (while (not (eobp)) | |
512 (setq string (buffer-substring (point) | |
513 (progn (end-of-line) (point)))) | |
514 (or (eobp) | |
515 (forward-char)) ; next line | |
516 (set-buffer b1) | |
517 (if (string= string "") | |
518 () | |
519 (end-of-line) | |
520 (indent-to-column tc-window-width) | |
521 (insert tc-separator string)) | |
522 (next-line 1) ; add one if necessary | |
523 (set-buffer b2)))) | |
524 (if (< (window-width) (frame-width)) | |
525 (enlarge-window 99999 t))) | |
526 | |
527 ;;;;; utility functions ;;;;; | |
528 | |
529 ;;;###autoload | |
530 (defun tc-associated-buffer () | |
531 "Switch to associated buffer." | |
532 (interactive) | |
533 (or (tc-other) | |
534 (error "You must set two-column minor mode.")) | |
535 (if (get-buffer-window (tc-other)) | |
536 (select-window (get-buffer-window (tc-other))) | |
537 (switch-to-buffer (tc-other)))) | |
538 | |
539 ;; It would be desirable to intercept anything that causes the current | |
540 ;; window to scroll. Maybe a `scroll-hook'? | |
541 ;;;###autoload | |
542 (defun tc-scroll-line (arg) | |
543 "Scroll current window upward by ARG lines. | |
544 The associated window gets scrolled to the same line." | |
545 (interactive "p") | |
546 (or (tc-other) | |
547 (error "You must set two-column minor mode.")) | |
548 ; scroll-up has a bug on arg 0 at end of buffer | |
549 (or (zerop arg) | |
550 (scroll-up arg)) | |
551 (setq arg (count-lines (point-min) (window-start))) | |
552 ; too bad that pre 18.57 Emacs makes save-window-excursion restore | |
553 ; the point. When it becomes extinct, we can simplify this. | |
554 (if (get-buffer-window (tc-other)) | |
555 (let ((window (selected-window))) | |
556 (select-window (get-buffer-window (tc-other))) | |
557 (setq arg (- arg (count-lines (point-min) (window-start)))) | |
558 ; make sure that other buffer has enough lines | |
559 (save-excursion | |
560 (goto-char (point-max)) | |
561 (insert-char ?\n | |
562 (- arg (count-lines (window-start) (point-max)) -1))) | |
563 (or (zerop arg) | |
564 (scroll-up arg)) | |
565 (select-window window)))) | |
566 | |
567 ;;;###autoload | |
568 (defun tc-scroll-up (arg) | |
569 "Scroll current window upward by ARG screens. | |
570 The associated window gets scrolled to the same line." | |
571 (interactive "p") | |
572 (tc-scroll-line (* arg (- (window-height) | |
573 next-screen-context-lines 1)))) | |
574 | |
575 ;;;###autoload | |
576 (defun tc-scroll-down (arg) | |
577 "Scroll current window downward by ARG screens. | |
578 The associated window gets scrolled to the same line." | |
579 (interactive "p") | |
580 (tc-scroll-line (* arg (- next-screen-context-lines | |
581 (window-height) -1)))) | |
582 | |
583 ;;;###autoload | |
584 (defun tc-recenter (arg) | |
585 "Center point in window. With ARG, put point on line ARG. | |
586 This counts from bottom if ARG is negative. The associated window | |
587 gets scrolled to the same line." | |
588 (interactive "P") | |
589 (setq arg (and arg (prefix-numeric-value arg))) | |
590 (tc-scroll-line (- (count-lines (window-start) (point)) | |
591 (cond ((null arg) (/ (window-height) 2)) | |
592 ((< arg 0) (+ (window-height) arg)) | |
593 ( arg))))) | |
594 | |
595 (defun enlarge-window-horizontally (arg) | |
596 "Make current window ARG columns wider." | |
597 (interactive "p") | |
598 (enlarge-window arg t) | |
599 (and (tc-other) | |
600 (setq tc-window-width (+ tc-window-width arg)) | |
601 (set-buffer (tc-other)) | |
602 (setq tc-window-width (- tc-window-width arg)))) | |
603 | |
604 (defun shrink-window-horizontally (arg) | |
605 "Make current window ARG columns narrower." | |
606 (interactive "p") | |
607 (enlarge-window-horizontally (- arg))) | |
608 | |
609 (provide 'two-column) | |
610 | |
611 ;;; two-column.el ends here |