0
|
1 ;;!emacs
|
|
2 ;;
|
|
3 ;; FILE: kotl-mode.el
|
|
4 ;; SUMMARY: Major mode for editing koutlines and associated commands.
|
|
5 ;; USAGE: GNU Emacs Lisp Library
|
|
6 ;; KEYWORDS: data, hypermedia, outlines, wp
|
|
7 ;;
|
|
8 ;; AUTHOR: Bob Weiner & Kellie Clark
|
|
9 ;;
|
|
10 ;; ORIG-DATE: 6/30/93
|
114
|
11 ;; LAST-MOD: 6-Mar-97 at 01:15:42 by Bob Weiner
|
0
|
12 ;;
|
|
13 ;; This file is part of Hyperbole.
|
|
14 ;; Available for use and distribution under the same terms as GNU Emacs.
|
|
15 ;;
|
|
16 ;; Copyright (C) 1993, 1994, 1995 Free Software Foundation, Inc.
|
|
17 ;; Developed with support from Motorola Inc.
|
|
18 ;;
|
|
19 ;; DESCRIPTION:
|
|
20 ;; DESCRIP-END.
|
|
21
|
|
22 ;;; ************************************************************************
|
|
23 ;;; Other required Lisp Libraries
|
|
24 ;;; ************************************************************************
|
|
25
|
|
26 (mapcar 'require '(hsite hmail kview kimport kvspec kotl))
|
|
27
|
|
28 ;;; ************************************************************************
|
|
29 ;;; Public variables
|
|
30 ;;; ************************************************************************
|
|
31
|
|
32 (defvar kotl-mode:refill-flag nil
|
|
33 "*Automatically refill cells during move, copy, promotion and demotion operations when non-nil.
|
|
34 Default value is nil. Cells with a `no-fill' attribute are never refilled
|
|
35 during such operations, regardless of the value of this flag.")
|
|
36
|
|
37 ;;; ************************************************************************
|
|
38 ;;; Public functions
|
|
39 ;;; ************************************************************************
|
|
40
|
|
41 ;;;###autoload
|
|
42 (defun kotl-mode ()
|
|
43 "The major mode used to edit and view koutlines.
|
|
44 It provides the following keys:
|
|
45 \\{kotl-mode-map}"
|
|
46 (interactive)
|
|
47 (use-local-map kotl-mode-map)
|
|
48 (set-syntax-table text-mode-syntax-table)
|
|
49 ;; Turn off filladapt minor mode if on, so that it does not interfere with
|
|
50 ;; the filling code in "kfill.el".
|
|
51 (and (boundp 'filladapt-mode) filladapt-mode (filladapt-mode -1))
|
|
52 (if (/= 3 (length (action:params (symbol-function 'fill-paragraph))))
|
|
53 ;; Some package such as filladapt has overwritten the primitives
|
|
54 ;; defined in kfill.el, so reload it.
|
|
55 (load "kfill"))
|
|
56 ;; Ensure that outline structure data is saved when save-buffer is called
|
|
57 ;; from save-some-buffers, {C-x s}.
|
|
58 (add-hook 'local-write-file-hooks 'kotl-mode:update-buffer)
|
|
59 (mapcar 'make-local-variable
|
|
60 '(kotl-previous-mode indent-line-function indent-region-function
|
|
61 minor-mode-alist selective-display-ellipses))
|
|
62 ;; Used by kimport.el functions.
|
|
63 (if (and (boundp 'kotl-previous-mode) kotl-previous-mode)
|
|
64 nil
|
|
65 (setq kotl-previous-mode major-mode
|
|
66 ;; Remove outline indication due to selective-display.
|
|
67 minor-mode-alist (copy-sequence minor-mode-alist)
|
|
68 minor-mode-alist (set:remove '(selective-display " Outline")
|
|
69 minor-mode-alist)
|
|
70 minor-mode-alist (set:remove '(selective-display " Otl")
|
|
71 minor-mode-alist)
|
100
|
72 ;; Remove indication that buffer is narrowed.
|
0
|
73 mode-line-format (copy-sequence mode-line-format)
|
|
74 mode-line-format (set:remove "%n" mode-line-format)))
|
|
75 ;;
|
|
76 (setq indent-line-function 'kotl-mode:indent-line
|
|
77 indent-region-function 'kotl-mode:indent-region
|
|
78 local-abbrev-table text-mode-abbrev-table
|
|
79 selective-display t
|
|
80 selective-display-ellipses t
|
|
81 paragraph-start "^[ \t]*$\\|^\^L"
|
|
82 paragraph-separate "^[ \t]*$\\|^\^L")
|
|
83 ;;
|
|
84 ;; This major-mode setting must come after the local variable settings but
|
|
85 ;; before the koutline is formatted.
|
|
86 (setq major-mode 'kotl-mode
|
|
87 mode-name "Kotl"
|
|
88 indent-tabs-mode nil)
|
|
89 ;; If buffer has not yet been formatted for editing, format it.
|
|
90 (cond
|
|
91 ;; Koutline file that has been loaded and formatted for editing.
|
|
92 ((kview:is-p kview)
|
|
93 ;; The buffer might have been widened for inspection, so narrow to cells
|
|
94 ;; only.
|
|
95 (kfile:narrow-to-kcells))
|
|
96 ;; Koutline file that has been loaded but not yet formatted for editing.
|
|
97 ((kfile:is-p)
|
|
98 (kfile:read
|
|
99 (current-buffer)
|
|
100 (and buffer-file-name (file-exists-p buffer-file-name)))
|
|
101 (kvspec:activate))
|
|
102 ;; New koutline buffer or a foreign text buffer that must be converted to
|
|
103 ;; koutline format.
|
|
104 (t
|
|
105 (kfile:create (current-buffer))
|
|
106 (kvspec:activate)))
|
|
107 ;; We have been converting a buffer from a foreign format to a koutline.
|
|
108 ;; Now that it is converted, ensure that kotl-previous-mode is set to
|
|
109 ;; koutline now.
|
|
110 (setq kotl-previous-mode 'kotl-mode)
|
|
111 (run-hooks 'kotl-mode-hook))
|
|
112
|
|
113 (defun kotl-mode:find-file-hook ()
|
|
114 (if (kview:is-p kview)
|
|
115 (kotl-mode:to-valid-position))
|
|
116 nil)
|
|
117
|
|
118 ;;; Ensure that point ends up at a valid position whenever a find-file
|
|
119 ;;; is done on a kotl-file.
|
|
120 (add-hook 'find-file-hooks 'kotl-mode:find-file-hook)
|
|
121
|
|
122 ;;; Ensure that outline structure data is hidden from view after a file save.
|
|
123 (add-hook 'after-save-hook 'kfile:narrow-to-kcells)
|
|
124
|
|
125 ;;; ------------------------------------------------------------------------
|
|
126 ;;; Editing within a single kotl
|
|
127 ;;; ------------------------------------------------------------------------
|
|
128
|
|
129 (fset 'kotl-mode:backward-delete-char-untabify
|
|
130 'kotl-mode:delete-backward-char)
|
|
131 (fset 'kotl-mode:backward-delete-char
|
|
132 'kotl-mode:delete-backward-char)
|
|
133
|
|
134 (defun kotl-mode:backward-kill-word (arg)
|
|
135 "Kill up to prefix ARG words preceding point within a single cell."
|
|
136 (interactive "*p")
|
|
137 (or arg (setq arg 1))
|
|
138 (cond ((< arg 0)
|
|
139 (if (kotl-mode:eocp)
|
|
140 (error "(kotl-mode:backward-kill-word): End of cell")))
|
|
141 ((> arg 0)
|
|
142 (if (kotl-mode:bocp)
|
|
143 (error "(kotl-mode:backward-kill-word): Beginning of cell"))))
|
|
144 (if (= arg 0)
|
|
145 nil
|
|
146 (save-restriction
|
|
147 (narrow-to-region (kcell-view:start) (kcell-view:end-contents))
|
|
148 (backward-kill-word arg))))
|
|
149
|
|
150 (defun kotl-mode:center-line ()
|
|
151 "Center the line point is on, within the width specified by `fill-column'.
|
|
152 This means adjusting the indentation so that it equals the distance between
|
|
153 the end of the text and `fill-column'."
|
|
154 (interactive "*")
|
|
155 (setq zmacs-region-stays t) ;; Maintain region highlight for XEmacs.
|
|
156 (let ((indent (kcell-view:indent))
|
|
157 (opoint (point-marker))
|
|
158 (bocp)
|
|
159 start)
|
114
|
160 (setq start (kotl-mode:start-of-line))
|
0
|
161 (if (setq bocp (kotl-mode:bocp))
|
|
162 (progn
|
|
163 ;; Add a temporary fill-prefix since this is the 1st line of the cell
|
|
164 ;; where label could interfere with centering.
|
|
165 (insert "\n\n") (insert-char ?\ indent)))
|
|
166 (center-line)
|
|
167 (if bocp
|
|
168 ;; Delete temporary fill prefix.
|
|
169 (delete-region start (+ start indent 2)))
|
|
170 (goto-char opoint)
|
|
171 ;; Move to editable point if need be.
|
|
172 (kotl-mode:to-valid-position)))
|
|
173
|
|
174 (defun kotl-mode:center-paragraph ()
|
|
175 "Center each nonblank line in the paragraph at or after point.
|
|
176 See `center-line' for more info."
|
|
177 (interactive "*")
|
|
178 (setq zmacs-region-stays t) ;; Maintain region highlight for XEmacs.
|
|
179 (let ((indent (kcell-view:indent))
|
|
180 (opoint (point-marker))
|
|
181 start)
|
|
182 (backward-paragraph)
|
|
183 (kotl-mode:to-valid-position)
|
|
184 (setq start (point))
|
|
185 ;; Add a temporary fill-prefix for 1st line in cell which contains a
|
|
186 ;; label, so is centered properly.
|
|
187 (insert "\n\n") (insert-char ?\ indent)
|
|
188 (kcell-view:operate 'center-paragraph)
|
|
189 ;; Delete temporary fill prefix.
|
|
190 (delete-region start (+ start indent 2))
|
|
191 ;; Return to original point.
|
|
192 (goto-char (min opoint (kcell-view:end-contents)))
|
|
193 ;; Move to editable point if need be.
|
|
194 (kotl-mode:to-valid-position)))
|
|
195
|
|
196 (defun kotl-mode:copy-region-as-kill (start end)
|
|
197 "Copy region between START and END within a single kcell to kill ring."
|
|
198 (interactive "r")
|
|
199 (kotl-mode:kill-region start end t))
|
|
200
|
|
201 (defun kotl-mode:copy-to-register (register start end &optional delete-flag)
|
|
202 "Copy into REGISTER the region START to END.
|
|
203 With optional prefix arg DELETE-FLAG, delete region."
|
|
204 (interactive "cCopy to register: \nr\nP")
|
|
205 (let ((indent (kcell-view:indent)))
|
|
206 (set-register register
|
|
207 (hypb:replace-match-string
|
|
208 (concat "^" (make-string indent ?\ ))
|
|
209 (buffer-substring start end)
|
|
210 "" t)))
|
|
211 (if delete-flag (delete-region start end)))
|
|
212
|
|
213 (defun kotl-mode:delete-backward-char (arg &optional kill-flag)
|
|
214 "Delete up to the preceding prefix ARG characters.
|
|
215 Return number of characters deleted.
|
|
216 Optional KILL-FLAG non-nil means save in kill ring instead of deleting.
|
|
217 Does not delete across cell boundaries."
|
|
218 (interactive "*P")
|
|
219 (if (interactive-p)
|
|
220 (if current-prefix-arg
|
|
221 (setq kill-flag t
|
|
222 arg (prefix-numeric-value current-prefix-arg))))
|
|
223 (or arg (setq arg 1))
|
|
224 (kotl-mode:delete-char (- arg) kill-flag))
|
|
225
|
|
226 (defun kotl-mode:delete-blank-lines ()
|
|
227 "On blank line within a cell, delete all surrounding blank lines, leaving just one.
|
|
228 On isolated blank line, delete that one.
|
|
229 On nonblank line, delete all blank lines that follow it.
|
|
230
|
|
231 If nothing but whitespace follows point until the end of a cell, delete all
|
|
232 whitespace at the end of the cell."
|
|
233 (interactive "*")
|
|
234 ;; If nothing but whitespace from point until the end of cell, remove all
|
|
235 ;; cell trailing whitespace.
|
|
236 (let ((end (kcell-view:end-contents))
|
|
237 start)
|
|
238 (if (save-excursion
|
|
239 (skip-chars-forward " \t\n\r" end)
|
|
240 (not (kotl-mode:eocp)))
|
|
241 (kcell-view:operate (function (lambda () (delete-blank-lines))))
|
|
242 (setq start (kcell-view:start))
|
|
243 (goto-char end)
|
|
244 ;; delete any preceding whitespace
|
|
245 (skip-chars-backward " \t\n\r" start)
|
|
246 (delete-region (max start (point)) end)))
|
|
247 (kotl-mode:to-valid-position))
|
|
248
|
|
249 (defun kotl-mode:delete-char (arg &optional kill-flag)
|
|
250 "Delete up to prefix ARG characters following point.
|
|
251 Return number of characters deleted.
|
|
252 Optional KILL-FLAG non-nil means save in kill ring instead of deleting.
|
|
253 Does not delete across cell boundaries."
|
|
254 (interactive "*P")
|
|
255 (if (interactive-p)
|
|
256 (if current-prefix-arg
|
|
257 (setq kill-flag t
|
|
258 arg (prefix-numeric-value current-prefix-arg))))
|
|
259 (or arg (setq arg 1))
|
|
260 (let ((del-count 0)
|
|
261 (indent (kcell-view:indent))
|
|
262 count start end)
|
|
263 (cond ((> arg 0)
|
|
264 (if (kotl-mode:eocp)
|
|
265 (error "(kotl-mode:delete-char): End of cell")
|
|
266 (setq end (kcell-view:end)
|
|
267 arg (min arg (- end (point))))
|
|
268 (while (> arg 0)
|
|
269 (if (kotl-mode:eolp)
|
|
270 (if (/= ?\ (char-syntax (following-char)))
|
|
271 (setq arg 0
|
|
272 del-count (1- del-count))
|
|
273 (delete-char 1 kill-flag)
|
|
274 ;; There may be non-whitespace characters in the
|
|
275 ;; indent area. Don't delete them.
|
|
276 (setq count indent)
|
|
277 (while (and (> count 0)
|
|
278 (= ?\ (char-syntax (following-char))))
|
|
279 (delete-char 1)
|
|
280 (setq count (1- count))))
|
|
281 (delete-char 1 kill-flag))
|
|
282 (setq arg (1- arg)
|
|
283 del-count (1+ del-count)))
|
|
284 ))
|
|
285 ((< arg 0)
|
|
286 (if (kotl-mode:bocp)
|
|
287 (error "(kotl-mode:delete-char): Beginning of cell")
|
|
288 (setq start (kcell-view:start)
|
|
289 arg (max arg (- start (point))))
|
|
290 (while (< arg 0)
|
|
291 (if (kotl-mode:bolp)
|
|
292 (if (/= ?\ (char-syntax (preceding-char)))
|
|
293 (setq arg 0
|
|
294 del-count (1- del-count))
|
|
295 ;; There may be non-whitespace characters in the
|
|
296 ;; indent area. Don't delete them.
|
|
297 (setq count indent)
|
|
298 (while (and (> count 0)
|
|
299 (= ?\ (char-syntax (preceding-char))))
|
|
300 (delete-char -1)
|
|
301 (setq count (1- count)))
|
|
302 (if (zerop count)
|
|
303 (delete-char -1 kill-flag)))
|
|
304 (delete-char -1 kill-flag))
|
|
305 (setq arg (1+ arg)
|
|
306 del-count (1+ del-count))))))
|
|
307 del-count))
|
|
308
|
|
309 (defun kotl-mode:delete-horizontal-space ()
|
|
310 "Delete all spaces and tabs around point."
|
|
311 (interactive "*")
|
|
312 (save-restriction
|
|
313 (narrow-to-region
|
|
314 (save-excursion
|
|
315 (kotl-mode:start-of-line))
|
|
316 (save-excursion
|
|
317 (kotl-mode:finish-of-line)))
|
|
318 (delete-horizontal-space)))
|
|
319
|
|
320 (defun kotl-mode:delete-indentation (&optional arg)
|
|
321 "Join this line to previous and fix up whitespace at join.
|
|
322 If there is a fill prefix, delete it from the beginning of this line.
|
|
323 With argument, join this line to following line."
|
|
324 (interactive "*P")
|
|
325 (kcell-view:operate
|
|
326 (function
|
|
327 (lambda ()
|
|
328 (let ((opoint (point)))
|
|
329 (beginning-of-line)
|
|
330 (if arg (forward-line 1))
|
|
331 (if (eq (preceding-char) ?\n)
|
|
332 (progn
|
|
333 (delete-region (point) (1- (point)))
|
|
334 ;; If the second line started with the fill prefix,
|
|
335 ;; delete the prefix.
|
|
336 (if (and fill-prefix
|
|
337 (<= (+ (point) (length fill-prefix)) (point-max))
|
|
338 (string= fill-prefix
|
|
339 (buffer-substring
|
|
340 (point) (+ (point) (length fill-prefix)))))
|
|
341 (delete-region (point) (+ (point) (length fill-prefix))))
|
|
342 (fixup-whitespace))
|
|
343 (goto-char opoint)))))))
|
|
344
|
|
345 (defun kotl-mode:fill-cell (&optional justify ignore-collapsed-p)
|
|
346 "Fill current cell within current view if it does not have a non-nil `no-fill' attribute.
|
|
347 With optional JUSTIFY, justify cell as well.
|
|
348 IGNORE-COLLAPSED-P is used when caller has already expanded cell, indicating
|
|
349 it is not collapsed."
|
|
350 (interactive "*P")
|
|
351 (cond ((kcell-view:get-attr 'no-fill)
|
|
352 (if (interactive-p)
|
|
353 (progn (beep)
|
|
354 (message "Current cell has a `do not fill' attribute.")
|
|
355 nil)))
|
|
356 ((string-match "\\`[ \t\n\r]*\\'" (kcell-view:contents))
|
|
357 ;; Cell content is all whitespace.
|
|
358 nil)
|
|
359 (t (let* ((indent (kcell-view:indent))
|
|
360 (opoint (set-marker (make-marker) (point)))
|
|
361 (start (kcell-view:start))
|
|
362 (collapsed-p)
|
|
363 (end (kcell-view:end-contents))
|
|
364 temp-prefix prev-point)
|
|
365 (goto-char start)
|
|
366 ;; Expand cell if collapsed so that filling is done properly.
|
|
367 (if (and (not ignore-collapsed-p)
|
|
368 (setq collapsed-p (search-forward "\r" end t)))
|
|
369 (subst-char-in-region start end ?\r ?\n t))
|
|
370 (goto-char start)
|
|
371 ;; Add a temporary fill-prefix for first labeled line, so is
|
|
372 ;; filled properly.
|
|
373 (insert (setq temp-prefix
|
|
374 (concat "\n\n" (make-string indent ?\ ))))
|
|
375 (while (progn (fill-paragraph justify)
|
|
376 (setq prev-point (point))
|
|
377 (forward-paragraph)
|
|
378 (and (/= (point) prev-point)
|
|
379 (< (point) (kcell-view:end-contents))
|
|
380 (if (memq (preceding-char) '(?\n ?\r))
|
|
381 (not (looking-at "[\n\r]"))
|
|
382 t))))
|
|
383 ;; Delete temporary fill prefix.
|
|
384 (goto-char start)
|
|
385 (if (looking-at temp-prefix)
|
|
386 (replace-match "" t t))
|
|
387 ;; Return to original point.
|
|
388 (setq end (kcell-view:end-contents))
|
|
389 (goto-char (min opoint end))
|
|
390 ;;
|
|
391 ;; If cell was collapsed before filling, collapse it again.
|
|
392 (if collapsed-p
|
|
393 (subst-char-in-region start end ?\n ?\r t))
|
|
394 ;;
|
|
395 ;; Remove markers
|
|
396 (set-marker opoint nil))
|
|
397 ;; Move to editable point if need be.
|
|
398 (kotl-mode:to-valid-position))))
|
|
399
|
|
400 (defun kotl-mode:fill-paragraph (&optional justify)
|
|
401 "Fill the current paragraph within the cell.
|
|
402 With optional JUSTIFY, justify the paragraph as well.
|
|
403 Ignore any non-nil no-fill attribute attached to the cell."
|
|
404 (interactive "*P")
|
|
405 (let ((indent (kcell-view:indent))
|
|
406 (opoint (point-marker))
|
|
407 start end)
|
|
408 (backward-paragraph)
|
|
409 (kotl-mode:to-valid-position)
|
|
410 (setq start (point-marker))
|
|
411 ;; Add a temporary fill-prefix for 1st line in cell which contains a
|
|
412 ;; label, so is filled properly.
|
|
413 (insert "\n\n") (insert-char ?\ indent)
|
|
414 (setq end (point-marker))
|
|
415 ;; Return to original paragraph point. This is the correct formula,
|
|
416 ;; considering the fill prefix that was just added.
|
|
417 (goto-char (min (max opoint (point)) (kcell-view:end-contents)))
|
|
418 (fill-paragraph justify)
|
|
419 ;; Delete temporary fill prefix.
|
|
420 (delete-region start end)
|
|
421 ;; Return to original point.
|
|
422 (goto-char (min opoint (kcell-view:end-contents)))
|
|
423 ;; Move to editable point if need be.
|
|
424 (kotl-mode:to-valid-position)
|
|
425 ;; Remove markers
|
|
426 (set-marker opoint nil)
|
|
427 (set-marker start nil)
|
|
428 (set-marker end nil)))
|
|
429
|
|
430 ;; XEmacs binds this to {M-q}.
|
|
431 (fset 'kotl-mode:fill-paragraph-or-region 'kotl-mode:fill-paragraph)
|
|
432
|
|
433 (defun kotl-mode:fill-tree (&optional top-p)
|
|
434 "Refill each cell within the tree whose root is at point.
|
|
435 Skip cells with a non-nil no-fill attribute.
|
|
436 With optional prefix argument TOP-P non-nil, refill all cells in the outline."
|
|
437 (interactive "P")
|
|
438 ;; Store list of which cells are presently collapsed.
|
|
439 (let ((collapsed-cells
|
|
440 (kview:map-tree
|
|
441 (function (lambda (view)
|
|
442 ;; Use free variable label-sep-len bound in
|
|
443 ;; kview:map-tree for speed.
|
|
444 (kcell-view:collapsed-p nil label-sep-len)))
|
|
445 kview top-p)))
|
|
446 ;;
|
|
447 ;; Expand all cells in tree.
|
|
448 (if top-p
|
|
449 (subst-char-in-region (point-min) (point-max) ?\r ?\n t)
|
|
450 (save-excursion
|
|
451 (kotl-mode:end-of-tree)
|
|
452 (subst-char-in-region
|
|
453 (point) (kcell-view:end-contents) ?\r ?\n t)))
|
|
454 ;;
|
|
455 ;; Refill cells without no-fill property.
|
|
456 (kview:map-tree (function (lambda (view) (kotl-mode:fill-cell)))
|
|
457 kview top-p)
|
|
458 ;;
|
|
459 ;; Collapse temporarily expanded cells.
|
|
460 (if (delq nil collapsed-cells)
|
|
461 (kview:map-tree
|
|
462 (function
|
|
463 (lambda (view)
|
|
464 (if (car collapsed-cells)
|
|
465 ;; Use free variable label-sep-len bound in
|
|
466 ;; kview:map-tree for speed.
|
|
467 (kcell-view:collapse nil label-sep-len))
|
|
468 (setq collapsed-cells (cdr collapsed-cells))))
|
|
469 kview top-p))))
|
|
470
|
|
471 (defun kotl-mode:insert-buffer (buffer)
|
|
472 "Insert after point the contents of BUFFER.
|
|
473 Puts mark after the inserted text.
|
|
474 BUFFER may be a buffer or a buffer name."
|
|
475 (interactive "*bInsert buffer: ")
|
|
476 (insert-buffer buffer)
|
|
477 (kotl-mode:add-indent-to-region))
|
|
478
|
|
479 (defun kotl-mode:insert-file (import-from children-p)
|
|
480 "Insert each element in IMPORT-FROM as a separate cell in the current view.
|
|
481 Insert as sibling cells following the current cell unless prefix arg,
|
|
482 CHILDREN-P is non-nil, then insert as the initial children of the current
|
|
483 cell.
|
|
484
|
|
485 IMPORT-FROM may be a buffer name or file name (file name completion is
|
|
486 provided).
|
|
487
|
|
488 See documentation for `kimport:file' for information on how the type of
|
|
489 importation is determined."
|
|
490 (interactive
|
|
491 (list (read-file-name
|
|
492 (if current-prefix-arg
|
|
493 "Buffer or file to insert as children of current cell: "
|
|
494 "Buffer or file to insert as siblings of current cell: "))
|
|
495 current-prefix-arg))
|
|
496 (kimport:file import-from (current-buffer) children-p))
|
|
497
|
|
498 (defun kotl-mode:insert-file-contents (filename)
|
|
499 "Insert contents of file FILENAME into current cell after point.
|
|
500 Set mark after the inserted text."
|
|
501 (interactive "*fInsert file: ")
|
|
502 (let ((tem (insert-file-contents filename)))
|
|
503 (push-mark (+ (point) (car (cdr tem)))))
|
|
504 (kotl-mode:add-indent-to-region))
|
|
505
|
|
506 (defun kotl-mode:insert-register (register &optional arg)
|
|
507 "Insert contents of register REGISTER at point in current cell.
|
|
508 REGISTER is a character naming the register to insert.
|
|
509 Normally puts point before and mark after the inserted text.
|
|
510 If optional second arg is non-nil, puts mark before and point after.
|
|
511 Interactively, second arg is non-nil if prefix arg is supplied."
|
|
512 (interactive "*cInsert register: \nP")
|
|
513 (push-mark)
|
|
514 (let ((val (get-register register)))
|
|
515 (cond ((consp val)
|
|
516 (insert-rectangle val))
|
|
517 ((stringp val)
|
|
518 (insert val)
|
|
519 (kotl-mode:add-indent-to-region))
|
|
520 ((integerp val)
|
|
521 (princ val (current-buffer)))
|
|
522 ((and (markerp val) (marker-position val))
|
|
523 (princ (marker-position val) (current-buffer)))
|
|
524 (t
|
114
|
525 (error "Register `%c' does not contain text" register))))
|
0
|
526 (if (not arg) (exchange-point-and-mark)))
|
|
527
|
|
528 (defun kotl-mode:just-one-space ()
|
|
529 "Delete all spaces and tabs around point and leave one space."
|
|
530 (interactive "*")
|
|
531 (save-restriction
|
|
532 (narrow-to-region
|
|
533 (save-excursion
|
|
534 (kotl-mode:start-of-line))
|
|
535 (save-excursion
|
|
536 (kotl-mode:finish-of-line)))
|
|
537 (just-one-space)))
|
|
538
|
|
539 (defun kotl-mode:kill-line (&optional arg)
|
|
540 "Kill ARG lines from point."
|
|
541 (interactive "*P")
|
|
542 (if (and (null arg)
|
|
543 (kotl-mode:bolp)
|
|
544 (boundp 'kill-whole-line) kill-whole-line)
|
|
545 (let ((indent (kcell-view:indent)))
|
|
546 ;; Kill whole line including newline, if any.
|
|
547 (kcell-view:operate
|
|
548 (function
|
|
549 (lambda ()
|
|
550 (let ((no-newline))
|
|
551 (kill-region (point)
|
|
552 (progn (setq no-newline
|
|
553 (not (search-forward "\n" nil 'stay)))
|
|
554 (point)))
|
|
555 (or no-newline (delete-char indent)))))))
|
|
556 ;; Kill part of a line or multiple lines.
|
|
557 (let ((num-arg (prefix-numeric-value arg)))
|
|
558 (cond
|
|
559 ((and (null arg) (not (kotl-mode:eolp)))
|
|
560 ;; kill to eol but not newline
|
|
561 (kill-region (point) (setq arg (kotl-mode:finish-of-line))))
|
|
562 ((= num-arg 0)
|
|
563 ;; kill to bol
|
|
564 (kill-region (point) (setq arg (kotl-mode:start-of-line))))
|
|
565 (t;; (/= num-arg 0)
|
|
566 ;; Find start and end of region to kill
|
|
567 (let ((start (point))
|
|
568 (end (min (kcell-view:end-contents)
|
|
569 (save-excursion (forward-line num-arg) (point)))))
|
|
570 (kotl-mode:kill-region start end))))))
|
|
571 (setq last-command 'kill-region))
|
|
572
|
|
573 (defun kotl-mode:kill-region (start end &optional copy-p)
|
|
574 "Kill region between START and END within a single kcell.
|
|
575 With optional COPY-P equal to 't, copy region to kill ring but does not
|
|
576 kill it. With COPY-P any other non-nil value, return region as a
|
|
577 string without affecting kill ring.
|
|
578
|
|
579 If the buffer is read-only and COPY-P is nil, the region will not be deleted
|
|
580 but it will be copied to the kill ring and then an error will be signaled."
|
|
581 (interactive "*r")
|
|
582 (let ((read-only (and (not copy-p) buffer-read-only)))
|
|
583 (if read-only (setq copy-p t))
|
|
584 (if (and (number-or-marker-p start)
|
|
585 (number-or-marker-p end)
|
|
586 (eq (kcell-view:cell start)
|
|
587 (kcell-view:cell end)))
|
|
588 (save-excursion
|
|
589 (goto-char start)
|
|
590 (let ((indent (kcell-view:indent))
|
|
591 killed subst-str)
|
|
592 ;; Convert region to string
|
|
593 ;; Convert all occurrences of newline + indent
|
|
594 ;; to just newline, eliminating indent.
|
|
595 ;; Then save to kill ring.
|
|
596 (setq subst-str (concat "\\([\n\r]\\)" (make-string indent ?\ ))
|
|
597 killed
|
|
598 (hypb:replace-match-string
|
|
599 subst-str (buffer-substring start end) "\\1"))
|
|
600 (if copy-p
|
|
601 nil
|
|
602 ;; If last char of region is a newline, then delete indent in
|
|
603 ;; following line.
|
|
604 (delete-region
|
|
605 start (+ end (if (memq (char-after (1- (max start end)))
|
|
606 '(?\n ?\r))
|
|
607 indent
|
|
608 0))))
|
|
609 (if (and copy-p (not (eq copy-p t)))
|
|
610 ;; Return killed region as a string.
|
|
611 killed
|
|
612 (if (eq last-command 'kill-region)
|
|
613 (kill-append killed (< end start))
|
|
614 (kill-new killed))
|
|
615 (setq this-command 'kill-region)
|
|
616 (if read-only (barf-if-buffer-read-only))
|
|
617 )))
|
|
618 (error
|
|
619 "(kotl-mode:kill-region): Bad region or not within a single kcell."))))
|
|
620
|
|
621 (fset 'kotl-mode:kill-ring-save 'kotl-mode:copy-region-as-kill)
|
|
622
|
|
623 (defun kotl-mode:kill-sentence (&optional arg)
|
|
624 "Kill up to prefix ARG (or 1) sentences following point within a single cell."
|
|
625 (interactive "*p")
|
|
626 (or arg (setq arg 1))
|
|
627 (cond ((> arg 0)
|
|
628 (if (kotl-mode:eocp)
|
|
629 (error "(kotl-mode:kill-sentence): End of cell")))
|
|
630 ((< arg 0)
|
|
631 (if (kotl-mode:bocp)
|
|
632 (error "(kotl-mode:kill-sentence): Beginning of cell"))))
|
|
633 (if (= arg 0)
|
|
634 nil
|
|
635 (kotl-mode:kill-region (point)
|
|
636 (save-excursion
|
|
637 (kotl-mode:forward-sentence arg)))))
|
|
638
|
|
639 (defun kotl-mode:kill-word (arg)
|
|
640 "Kill up to prefix ARG words following point within a single cell."
|
|
641 (interactive "*p")
|
|
642 (or arg (setq arg 1))
|
|
643 (cond ((> arg 0)
|
|
644 (if (kotl-mode:eocp)
|
|
645 (error "(kotl-mode:kill-word): End of cell")))
|
|
646 ((< arg 0)
|
|
647 (if (kotl-mode:bocp)
|
|
648 (error "(kotl-mode:kill-word): Beginning of cell"))))
|
|
649 (if (= arg 0)
|
|
650 nil
|
|
651 (save-restriction
|
|
652 (narrow-to-region (kcell-view:start) (kcell-view:end-contents))
|
|
653 (kill-word arg))))
|
|
654
|
|
655 (defun kotl-mode:newline (arg)
|
|
656 "Insert a newline. With ARG, insert ARG newlines.
|
|
657 In Auto Fill mode, if no numeric arg, break the preceding line if it is
|
|
658 too long."
|
|
659 (interactive "*p")
|
|
660 (let ((indent (kcell-view:indent)))
|
|
661 (if (equal arg 1)
|
|
662 (progn
|
|
663 (save-excursion
|
|
664 (insert ?\n)
|
|
665 (insert-char ?\ indent))
|
|
666 (do-auto-fill)
|
|
667 (forward-line 1)
|
|
668 (kotl-mode:start-of-line)
|
|
669 )
|
|
670 (while (> arg 0)
|
|
671 (insert ?\n)
|
|
672 (insert-char ?\ indent)
|
|
673 (setq arg (1- arg))))))
|
|
674
|
|
675 (fset 'kotl-mode:newline-and-indent 'kotl-mode:newline)
|
|
676
|
|
677 (defun kotl-mode:open-line (arg)
|
|
678 "Insert a newline and leave point before it.
|
|
679 With arg N, insert N newlines."
|
|
680 (interactive "*p")
|
|
681 (let* ((bolp (and (kotl-mode:bolp) (not (kotl-mode:bocp))))
|
|
682 (indent (kcell-view:indent)))
|
|
683 (while (> arg 0)
|
|
684 (save-excursion
|
|
685 (insert ?\n)
|
|
686 (if (and (not bolp) fill-prefix)
|
|
687 (insert fill-prefix)
|
|
688 (insert-char ?\ indent)))
|
|
689 (setq arg (1- arg)))
|
|
690 (if (and bolp fill-prefix)
|
|
691 (progn (delete-horizontal-space)
|
|
692 (insert fill-prefix)))
|
|
693 ))
|
|
694
|
|
695 (defun kotl-mode:set-fill-prefix (turn-off)
|
|
696 "Sets fill prefix to line up to point.
|
|
697 With prefix arg TURN-OFF or at begin of line, turns fill prefix off."
|
|
698 (interactive "P")
|
|
699 (set-fill-prefix (or turn-off (kotl-mode:bolp))))
|
|
700
|
|
701 (defun kotl-mode:transpose-chars (arg)
|
|
702 "Interchange characters around point, moving forward one character.
|
|
703 With prefix ARG, take character before point and drag it forward past ARG
|
|
704 other characters (backward if ARG negative).
|
|
705 If no prefix ARG and at end of line, the previous two characters are
|
|
706 exchanged."
|
|
707 (interactive "*P")
|
|
708 (and (null arg) (kotl-mode:eolp) (kotl-mode:forward-char -1))
|
|
709 (transpose-subr 'kotl-mode:forward-char (prefix-numeric-value arg)))
|
|
710
|
|
711 (defun kotl-mode:transpose-lines (arg)
|
|
712 "Exchange current line and previous line, leaving point after both.
|
|
713 If no previous line, exchange current with next line.
|
|
714 With prefix ARG, take previous line and move it past ARG lines.
|
|
715 With prefix ARG = 0, interchange the line that contains point with the line
|
|
716 that contains mark."
|
|
717 (interactive "*p")
|
|
718 (cond
|
|
719 ((and (kotl-mode:first-line-p) (kotl-mode:last-line-p))
|
|
720 (error "(kotl-mode:transpose-lines): Only one line in outline"))
|
|
721 ;;
|
|
722 ;; Transpose current and previous lines or current and next lines, if no
|
|
723 ;; previous line. Leave point after both exchanged lines.
|
|
724 ((= arg 1)
|
|
725 (let* ((point (point-marker))
|
|
726 (mark (set-marker (make-marker)
|
|
727 (if (kotl-mode:first-line-p)
|
|
728 (kotl-mode:next-line 1)
|
|
729 (kotl-mode:previous-line 1)))))
|
|
730 (kotl-mode:transpose-lines-internal point mark)
|
|
731 (goto-char (max point mark))
|
|
732 (kotl-mode:next-line 1)
|
|
733 (set-marker mark nil)))
|
|
734 ;;
|
|
735 ;; Transpose point and mark lines, leaving point on the line of text that
|
|
736 ;; originally contained point.
|
|
737 ((= arg 0)
|
|
738 (kotl-mode:transpose-lines-internal (point-marker) (hypb:mark-marker t))
|
|
739 ;; This is like exchange-point-and-mark, but doesn't activate the
|
|
740 ;; mark.
|
|
741 (goto-char (prog1 (hypb:mark t)
|
|
742 (set-marker (hypb:mark-marker t) (point)))))
|
|
743 ;;
|
|
744 ;; Move previous line past ARG next lines and leave point after previous
|
|
745 ;; line text.
|
|
746 (t
|
|
747 (if (kotl-mode:first-line-p)
|
|
748 (error "(kotl-mode:transpose-lines): No previous line to transpose"))
|
|
749 (kotl-mode:previous-line 1)
|
|
750 (let* ((mark (set-marker (make-marker)
|
|
751 (save-excursion (kotl-mode:next-line arg))))
|
|
752 (line-to-move (kotl-mode:delete-line)))
|
|
753 (condition-case ()
|
|
754 ;; Delete trailing newline if any, ignoring error.
|
|
755 (kotl-mode:delete-char 1)
|
|
756 (error nil))
|
|
757 (goto-char mark)
|
|
758 (set-marker mark nil)
|
|
759 (kotl-mode:finish-of-line)
|
|
760 (insert "\n")
|
|
761 (insert-char ?\ (kcell-view:indent))
|
|
762 (insert line-to-move)
|
|
763 (kotl-mode:start-of-line)))))
|
|
764
|
|
765 (defun kotl-mode:transpose-paragraphs (arg)
|
|
766 "Interchange this (or next) paragraph with previous one."
|
|
767 (interactive "*p")
|
|
768 (transpose-subr 'kotl-mode:forward-paragraph (prefix-numeric-value arg)))
|
|
769
|
|
770 (defun kotl-mode:transpose-sentences (arg)
|
|
771 "Interchange this (next) and previous sentence."
|
|
772 (interactive "*p")
|
|
773 (transpose-subr 'kotl-mode:forward-sentence (prefix-numeric-value arg)))
|
|
774
|
|
775 (defun kotl-mode:transpose-words (arg)
|
|
776 "Interchange words around point, leaving point after both words.
|
|
777 With prefix ARG, take word before or around point and drag it forward past
|
|
778 ARG other words (backward if ARG negative). If ARG is zero, the words around
|
|
779 or after point and around or after mark are interchanged."
|
|
780 (interactive "*p")
|
|
781 (transpose-subr 'kotl-mode:forward-word (prefix-numeric-value arg)))
|
|
782
|
|
783 (defun kotl-mode:zap-to-char (arg char)
|
|
784 "Kill up to and including prefix ARG'th occurrence of CHAR.
|
|
785 Goes backward if ARG is negative; error if CHAR not found."
|
|
786 (interactive "*p\ncZap to char within current cell: ")
|
|
787 (kcell-view:operate
|
|
788 (function (lambda () (zap-to-char arg char)))))
|
|
789
|
|
790 ;;; ------------------------------------------------------------------------
|
|
791 ;;; Editing across kotls
|
|
792 ;;; ------------------------------------------------------------------------
|
|
793
|
|
794 (defun kotl-mode:append-cell (contents-cell append-to-cell)
|
|
795 "Append CONTENTS-CELL to APPEND-TO-CELL.
|
|
796 APPEND-TO-CELL is refilled if neither cell has a no-fill property and
|
|
797 kotl-mode:refill-flag is enabled."
|
|
798 (interactive
|
|
799 (let* ((label (kcell-view:label))
|
|
800 (hargs:defaults (list label label)))
|
|
801 (hargs:iform-read
|
|
802 '(interactive
|
|
803 "*+KAppend contents of cell: \n+KAppend contents of cell <%s> to cell: "))))
|
|
804 (save-excursion
|
|
805 (kotl-mode:goto-cell contents-cell)
|
|
806 (let ((contents (kcell-view:contents))
|
|
807 (no-fill (kcell-view:get-attr 'no-fill)))
|
|
808 (kotl-mode:goto-cell append-to-cell)
|
|
809 (if no-fill nil (setq no-fill (kcell-view:get-attr 'no-fill)))
|
|
810 (goto-char (kcell-view:end-contents))
|
|
811 (let ((fill-prefix (make-string (kcell-view:indent) ?\ )))
|
|
812 (if (kotl-mode:bolp)
|
|
813 nil
|
|
814 ;; Append contents of cell beginning on its own line.
|
|
815 (insert "\n" fill-prefix))
|
|
816 (kview:insert-contents (kcell-view:cell) contents
|
|
817 (or no-fill (null kotl-mode:refill-flag))
|
|
818 fill-prefix)))))
|
|
819
|
|
820 (defun kotl-mode:copy-after (from-cell-ref to-cell-ref child-p)
|
|
821 "Copy tree rooted at FROM-CELL-REF to follow tree rooted at TO-CELL-REF.
|
|
822 If prefix arg CHILD-P is non-nil, make FROM-CELL-REF the first child of
|
|
823 TO-CELL-REF, otherwise make it the sibling following TO-CELL-REF.
|
|
824
|
|
825 Leave point at the start of the root cell of the new tree."
|
|
826 (interactive
|
|
827 (let* ((label (kcell-view:label))
|
|
828 (hargs:defaults (list label label)))
|
|
829 (append
|
|
830 (hargs:iform-read
|
|
831 (list
|
|
832 'interactive
|
|
833 (format "*+KCopy tree: \n+KCopy tree <%%s> to follow as %s of cell: "
|
|
834 (if current-prefix-arg "child" "sibling"))))
|
|
835 (list current-prefix-arg))))
|
|
836 ;;
|
|
837 ;; Copy tree in current view and leave point at the start of the copy.
|
|
838 (goto-char (kotl-mode:move-after from-cell-ref to-cell-ref child-p t))
|
|
839 ;; Alter the copied tree so each cell appears to be newly created.
|
|
840 (kview:map-tree
|
|
841 (function
|
|
842 (lambda (view)
|
|
843 (kcell-view:set-cell
|
|
844 (kcell:create nil (kview:id-increment view)))))
|
|
845 kview))
|
|
846
|
|
847 (defun kotl-mode:copy-before (from-cell-ref to-cell-ref parent-p)
|
|
848 "Copy tree rooted at FROM-CELL-REF to precede tree rooted at TO-CELL-REF.
|
|
849 If prefix arg PARENT-P is non-nil, make FROM-CELL-REF the first child of
|
|
850 TO-CELL-REF's parent, otherwise make it the preceding sibling of TO-CELL-REF.
|
|
851
|
|
852 Leave point at the start of the root cell of the new tree."
|
|
853 (interactive
|
|
854 (let* ((label (kcell-view:label))
|
|
855 (hargs:defaults (list label label)))
|
|
856 (append
|
|
857 (hargs:iform-read
|
|
858 (list 'interactive
|
|
859 (format "*+KCopy tree: \n+KCopy tree <%%s> to be %s of cell: "
|
|
860 (if current-prefix-arg "first child of parent"
|
|
861 "preceding sibling"))))
|
|
862 (list current-prefix-arg))))
|
|
863 ;;
|
|
864 ;; Copy tree in current view and leave point at the start of the copy.
|
|
865 (goto-char (kotl-mode:move-before from-cell-ref to-cell-ref parent-p t))
|
|
866 ;; Alter the copied tree so each cell appears to be newly created.
|
|
867 (kview:map-tree
|
|
868 (function
|
|
869 (lambda (view)
|
|
870 (kcell-view:set-cell
|
|
871 (kcell:create nil (kview:id-increment view)))))
|
|
872 kview))
|
|
873
|
|
874 (defun kotl-mode:copy-to-buffer (cell-ref buffer invisible-flag)
|
|
875 "Copy outline tree rooted at CELL-REF to a non-koutline BUFFER.
|
|
876 Invisible text is expanded and included in the copy only if INVISIBLE-FLAG is
|
|
877 non-nil. The tree is inserted before point in BUFFER. Use \"0\" to copy the
|
|
878 whole outline buffer."
|
|
879 (interactive
|
|
880 (let ((label-default (kcell-view:label)))
|
|
881 (hargs:iform-read
|
|
882 '(interactive
|
|
883 (list
|
|
884 (hargs:read "Copy tree without attributes: (0 for whole outline) "
|
|
885 nil label-default nil 'kcell)
|
|
886 (read-buffer "To buffer: "
|
|
887 (save-window-excursion
|
|
888 (if (one-window-p)
|
|
889 (select-frame (next-frame))
|
|
890 (other-window 1))
|
|
891 (buffer-name))
|
|
892 t)
|
|
893 (y-or-n-p "Copy invisible text? "))))))
|
|
894 (message "") ;; Erase last interactive prompt, if any.
|
|
895 (setq buffer (get-buffer-create buffer))
|
|
896 (if (equal cell-ref "0")
|
|
897 (hypb:insert-region buffer (point-min) (point-max) invisible-flag)
|
|
898 (let (start end)
|
|
899 (save-excursion
|
|
900 (kotl-mode:goto-cell cell-ref t)
|
|
901 (save-excursion (beginning-of-line) (setq start (point)))
|
|
902 (setq end (kotl-mode:tree-end)))
|
|
903 (hypb:insert-region buffer start end invisible-flag))))
|
|
904
|
|
905 (defun kotl-mode:move-after (from-cell-ref to-cell-ref child-p
|
|
906 &optional copy-p fill-p)
|
|
907 "Move tree rooted at FROM-CELL-REF to follow tree rooted at TO-CELL-REF.
|
|
908 If prefix arg CHILD-P is non-nil, make FROM-CELL-REF the first child of
|
|
909 TO-CELL-REF, otherwise make it the sibling following TO-CELL-REF.
|
|
910 With optional COPY-P, copies tree rather than moving it.
|
|
911
|
|
912 Leave point at original location but return the tree's new start point."
|
|
913 (interactive
|
|
914 (let* ((label (kcell-view:label))
|
|
915 (hargs:defaults (list label label)))
|
|
916 (append
|
|
917 (hargs:iform-read
|
|
918 (list
|
|
919 'interactive
|
|
920 (format "*+KMove tree: \n+KMove tree <%%s> to follow as %s of cell: "
|
|
921 (if current-prefix-arg "child" "sibling"))))
|
|
922 (list current-prefix-arg))))
|
|
923 (if (and (not copy-p) (equal from-cell-ref to-cell-ref))
|
|
924 (error "(kotl-mode:move-after): Can't move tree after itself"))
|
|
925 (let* ((orig (set-marker (make-marker) (point)))
|
|
926 (label-sep-len (kview:label-separator-length kview))
|
|
927 (move-to-point (set-marker
|
|
928 (make-marker)
|
|
929 (kotl-mode:goto-cell to-cell-ref t)))
|
|
930 (to-label (kcell-view:label))
|
|
931 (to-indent (kcell-view:indent nil label-sep-len))
|
|
932 (from-label (progn (kotl-mode:goto-cell from-cell-ref t)
|
|
933 (kcell-view:label)))
|
|
934 (from-indent (kcell-view:indent nil label-sep-len))
|
|
935 (start (kotl-mode:tree-start))
|
|
936 (end (kotl-mode:tree-end))
|
|
937 (sib-id (if (= 0 (kotl-mode:forward-cell 1))
|
|
938 (kcell-view:idstamp)))
|
|
939 new-tree-start)
|
|
940 ;;
|
|
941 ;; We can't move a tree to a point within itself, so if that is the case
|
|
942 ;; and this is not a copy operation, signal an error.
|
|
943 (if (and (not copy-p) (>= move-to-point start) (<= move-to-point end))
|
|
944 (error "(kotl-mode:move-after): Can't move tree <%s> to within itself"
|
|
945 from-label))
|
|
946 ;;
|
|
947 ;; If tree to move has a sibling, point is now at the start of the
|
|
948 ;; sibling cell. Mark its label with a property which will be deleted
|
|
949 ;; whenever the cell label is renumbered. This tells us whether or not
|
|
950 ;; to renumber the sibling separately from the tree to move.
|
|
951 (if sib-id
|
|
952 ;; Move to middle of label and insert klabel-original temp property.
|
|
953 (progn (goto-char (- (point) label-sep-len 3))
|
|
954 (kproperty:set 'klabel-original t)))
|
|
955 ;;
|
|
956 ;; Position for insertion before deletion of tree-to-move from old
|
|
957 ;; position, in case old position precedes new one.
|
|
958 ;; Skip past either cell or tree at move-to-point.
|
|
959 (goto-char move-to-point)
|
|
960 (if child-p
|
|
961 ;; Move to insert position for first child of to-cell-ref.
|
|
962 (progn (goto-char (kcell-view:end))
|
|
963 (setq to-label (klabel:child to-label)
|
|
964 to-indent (+ to-indent (kview:level-indent kview))))
|
|
965 ;; Move to after to-cell-ref's tree for insertion as following sibling.
|
|
966 (goto-char (kotl-mode:tree-end))
|
|
967 (setq to-label (klabel:increment to-label)))
|
|
968 ;;
|
|
969 ;; Insert tree-to-move at new location
|
|
970 ;;
|
|
971 (kview:move start end (point) from-indent to-indent copy-p
|
|
972 (or fill-p kotl-mode:refill-flag))
|
|
973 ;;
|
|
974 ;; Ensure that point is within editable region of cell with to-label.
|
|
975 (kotl-mode:to-valid-position)
|
|
976 (setq new-tree-start (point))
|
|
977 ;;
|
|
978 ;; Update current cell and new siblings' labels within view.
|
|
979 (klabel-type:update-labels to-label)
|
|
980 ;;
|
|
981 (if copy-p
|
|
982 nil
|
|
983 ;;
|
|
984 ;; Move to sibling of tree-to-move within view and update labels within
|
|
985 ;; view of tree-to-move's original siblings.
|
|
986 (if sib-id
|
|
987 (progn (kotl-mode:goto-cell sib-id t)
|
|
988 ;; Sibling labels may have already been updated if tree was
|
|
989 ;; moved somewhere preceding its siblings.
|
|
990 (let ((label-middle (- (point) label-sep-len 2)))
|
|
991 (if (kproperty:get label-middle 'klabel-original)
|
|
992 (klabel-type:update-labels from-label))))))
|
|
993 ;;
|
|
994 (goto-char orig)
|
|
995 ;;
|
|
996 ;; Ensure that point is within editable region of a cell.
|
|
997 (kotl-mode:to-valid-position)
|
|
998 ;;
|
|
999 (set-marker orig nil)
|
|
1000 (set-marker move-to-point nil)
|
|
1001 new-tree-start))
|
|
1002
|
|
1003 (defun kotl-mode:move-before (from-cell-ref to-cell-ref parent-p
|
|
1004 &optional copy-p fill-p)
|
|
1005 "Move tree rooted at FROM-CELL-REF to precede tree rooted at TO-CELL-REF.
|
|
1006 If prefix arg PARENT-P is non-nil, make FROM-CELL-REF the first child of
|
|
1007 TO-CELL-REF's parent, otherwise make it the preceding sibling of TO-CELL-REF.
|
|
1008 With optional COPY-P, copies tree rather than moving it.
|
|
1009
|
|
1010 Leave point at original location but return the tree's new start point."
|
|
1011 (interactive
|
|
1012 (let* ((label (kcell-view:label))
|
|
1013 (hargs:defaults (list label label)))
|
|
1014 (append
|
|
1015 (hargs:iform-read
|
|
1016 (list 'interactive
|
|
1017 (format "*+KMove tree: \n+KMove tree <%%s> to be %s of cell: "
|
|
1018 (if current-prefix-arg "first child of parent"
|
|
1019 "preceding sibling"))))
|
|
1020 (list current-prefix-arg))))
|
|
1021 (if (and (not copy-p) (equal from-cell-ref to-cell-ref))
|
|
1022 (error "(kotl-mode:move-before): Can't move tree before itself"))
|
|
1023 (let* ((orig (set-marker (make-marker) (point)))
|
|
1024 (label-sep-len (kview:label-separator-length kview))
|
|
1025 (move-to-point (set-marker
|
|
1026 (make-marker)
|
|
1027 (kotl-mode:goto-cell to-cell-ref t)))
|
|
1028 (to-label (kcell-view:label))
|
|
1029 (to-indent (kcell-view:indent nil label-sep-len))
|
|
1030 (from-label (progn (kotl-mode:goto-cell from-cell-ref t)
|
|
1031 (kcell-view:label)))
|
|
1032 (from-indent (kcell-view:indent nil label-sep-len))
|
|
1033 (start (kotl-mode:tree-start))
|
|
1034 (end (kotl-mode:tree-end))
|
|
1035 (sib-id (if (= 0 (kotl-mode:forward-cell 1))
|
|
1036 (kcell-view:idstamp)))
|
|
1037 new-tree-start)
|
|
1038 ;;
|
|
1039 ;; We can't move a tree to a point within itself, so if that is the case
|
|
1040 ;; and this is not a copy operation, signal an error.
|
|
1041 (if (and (not copy-p) (>= move-to-point start) (<= move-to-point end))
|
|
1042 (error "(kotl-mode:move-before): Can't move tree <%s> to within itself"
|
|
1043 from-label))
|
|
1044 ;;
|
|
1045 ;; If tree to move has a sibling, point is now at the start of the
|
|
1046 ;; sibling cell. Mark its label with a property which will be deleted
|
|
1047 ;; whenever the cell label is renumbered. This tells us whether or not
|
|
1048 ;; to renumber the sibling separately from the tree to move.
|
|
1049 (if sib-id
|
|
1050 ;; Move to middle of label and insert klabel-original temp property.
|
|
1051 (progn (goto-char (- (point) label-sep-len 3))
|
|
1052 (kproperty:set 'klabel-original t)))
|
|
1053 ;;
|
|
1054 ;; Position for insertion at succeeding-tree, before deletion of
|
|
1055 ;; tree-to-move from old position, in case old position precedes new one.
|
|
1056 (goto-char move-to-point)
|
|
1057 (if parent-p
|
|
1058 ;; Move to insert position for first child of to-cell-ref's parent.
|
|
1059 (if (kcell-view:parent nil label-sep-len)
|
|
1060 (progn (setq to-label (klabel:child (kcell-view:label)))
|
|
1061 (goto-char (kcell-view:end)))
|
|
1062 (error "(kotl-mode:move-before): to-cell-ref's parent not in current view"))
|
|
1063 ;; Move to before to-cell-ref for insertion as preceding sibling.
|
|
1064 (goto-char (kotl-mode:tree-start)))
|
|
1065 ;;
|
|
1066 ;; Insert tree-to-move at new location
|
|
1067 ;;
|
|
1068 (kview:move start end (point) from-indent to-indent copy-p
|
|
1069 (or fill-p kotl-mode:refill-flag))
|
|
1070 ;;
|
|
1071 ;; Ensure that point is within editable region of root of tree just moved.
|
|
1072 (kotl-mode:to-valid-position)
|
|
1073 (setq new-tree-start (point))
|
|
1074 ;;
|
|
1075 ;; Update current cell and new siblings' labels within view.
|
|
1076 (klabel-type:update-labels to-label)
|
|
1077 ;;
|
|
1078 (if copy-p
|
|
1079 nil
|
|
1080 ;;
|
|
1081 ;; Move to sibling of tree-to-move within view and update labels within
|
|
1082 ;; view of tree-to-move's original siblings.
|
|
1083 (if sib-id
|
|
1084 (progn
|
|
1085 (kotl-mode:goto-cell sib-id t)
|
|
1086 ;; Sibling labels may have already been updated if tree was
|
|
1087 ;; moved somewhere preceding its siblings.
|
|
1088 (let ((label-middle (- (point) label-sep-len 2)))
|
|
1089 (if (kproperty:get label-middle 'klabel-original)
|
|
1090 (klabel-type:update-labels from-label))))))
|
|
1091 ;;
|
|
1092 (goto-char orig)
|
|
1093 ;;
|
|
1094 ;; Ensure that point is within editable region of a cell.
|
|
1095 (kotl-mode:to-valid-position)
|
|
1096 ;;
|
|
1097 (set-marker orig nil)
|
|
1098 (set-marker move-to-point nil)
|
|
1099 new-tree-start))
|
|
1100
|
|
1101 (defun kotl-mode:yank (&optional arg)
|
|
1102 "Reinsert the last stretch of killed text.
|
|
1103 More precisely, reinsert the stretch of killed text most recently
|
|
1104 killed OR yanked. Put point at end, and set mark at beginning.
|
|
1105 With just C-u as argument, same but put point at beginning (and mark at end).
|
|
1106 With argument N, reinsert the Nth most recently killed stretch of killed
|
|
1107 text.
|
|
1108 See also the command \\[kotl-mode:yank-pop]."
|
|
1109 (interactive "*P")
|
|
1110 (push-mark (point))
|
|
1111 (let* ((yank-text (current-kill (cond
|
|
1112 ((listp arg) 0)
|
|
1113 ((eq arg '-) -1)
|
|
1114 (t (1- arg)))))
|
|
1115 (indent (kcell-view:indent))
|
|
1116 (indent-str (make-string indent ?\ )))
|
|
1117 ;; Convert all occurrences of newline to newline + cell indent.
|
|
1118 ;; Then insert into buffer.
|
|
1119 (insert (hypb:replace-match-string
|
|
1120 "[\n\r]" yank-text (concat "\\0" indent-str))))
|
|
1121 (if (consp arg)
|
|
1122 ;; This is like exchange-point-and-mark, but doesn't activate the mark.
|
|
1123 ;; It is cleaner to avoid activation, even though the command
|
|
1124 ;; loop would deactivate the mark because we inserted text.
|
|
1125 (goto-char (prog1 (mark t)
|
|
1126 (set-marker (hypb:mark-marker t) (point)))))
|
|
1127 nil)
|
|
1128
|
|
1129 (defun kotl-mode:yank-pop (arg)
|
|
1130 "Replace just-yanked stretch of killed text with a different stretch.
|
|
1131 This command is allowed only immediately after a `yank' or a `yank-pop'.
|
|
1132 At such a time, the region contains a stretch of reinserted
|
|
1133 previously-killed text. `yank-pop' deletes that text and inserts in its
|
|
1134 place a different stretch of killed text.
|
|
1135
|
|
1136 With no argument, the previous kill is inserted.
|
|
1137 With argument N, insert the Nth previous kill.
|
|
1138 If N is negative, this is a more recent kill.
|
|
1139
|
|
1140 The sequence of kills wraps around, so that after the oldest one
|
|
1141 comes the newest one."
|
|
1142 (interactive "*p")
|
|
1143 (if (not (eq last-command 'kotl-mode:yank))
|
|
1144 (error "Previous command was not a yank"))
|
|
1145 (setq this-command 'kotl-mode:yank)
|
|
1146 (let ((before (< (point) (mark t))))
|
|
1147 (delete-region (point) (mark t))
|
|
1148 (set-marker (hypb:mark-marker t) (point) (current-buffer))
|
|
1149 (let* ((yank-text (current-kill arg))
|
|
1150 (indent (kcell-view:indent))
|
|
1151 (indent-str (make-string indent ?\ )))
|
|
1152 ;; Convert all occurrences of newline to newline + cell indent.
|
|
1153 ;; Then insert into buffer.
|
|
1154 (insert (hypb:replace-match-string
|
|
1155 "[\n\r]" yank-text (concat "\\0" indent-str))))
|
|
1156 (if before
|
|
1157 ;; This is like exchange-point-and-mark, but doesn't activate the mark.
|
|
1158 ;; It is cleaner to avoid activation, even though the command
|
|
1159 ;; loop would deactivate the mark because we inserted text.
|
|
1160 (goto-char (prog1 (mark t)
|
|
1161 (set-marker (hypb:mark-marker t) (point) (current-buffer))))))
|
|
1162 nil)
|
|
1163
|
|
1164 ;;; ------------------------------------------------------------------------
|
|
1165 ;;; Movement
|
|
1166 ;;; ------------------------------------------------------------------------
|
|
1167
|
|
1168 ;;; Cursor and keypad key functions aliases for XEmacs.
|
|
1169 (if (not (string-match "XEmacs\\|Lucid" emacs-version))
|
|
1170 nil
|
|
1171 (fset 'kotl-mode:fkey-backward-char 'kotl-mode:backward-char)
|
|
1172 (fset 'kotl-mode:fkey-forward-char 'kotl-mode:forward-char)
|
|
1173 (fset 'kotl-mode:fkey-next-line 'kotl-mode:next-line)
|
|
1174 (fset 'kotl-mode:fkey-previous-line 'kotl-mode:previous-line)
|
|
1175 (fset 'kotl-mode:deprecated-scroll-down 'kotl-mode:scroll-down)
|
|
1176 (fset 'kotl-mode:deprecated-scroll-up 'kotl-mode:scroll-up)
|
|
1177 (fset 'kotl-mode:deprecated-bob 'kotl-mode:beginning-of-buffer)
|
|
1178 (fset 'kotl-mode:deprecated-eob 'kotl-mode:end-of-buffer))
|
|
1179
|
|
1180 (defun kotl-mode:back-to-indentation ()
|
|
1181 "Move point to the first non-read-only non-whitespace character on this line."
|
|
1182 (interactive)
|
|
1183 (setq zmacs-region-stays t) ;; Maintain region highlight for XEmacs.
|
|
1184 (back-to-indentation)
|
|
1185 (kotl-mode:to-valid-position))
|
|
1186
|
|
1187 (defun kotl-mode:backward-cell (arg)
|
|
1188 "Move to prefix ARGth prior visible cell (same level) within current view.
|
|
1189 Return number of cells left to move."
|
|
1190 (interactive "p")
|
|
1191 (setq zmacs-region-stays t) ;; Maintain region highlight for XEmacs.
|
|
1192 (if (< arg 0)
|
|
1193 (kotl-mode:forward-cell (- arg))
|
|
1194 (let ((prior (= arg 0))
|
|
1195 (label-sep-len (kview:label-separator-length kview)))
|
|
1196 (while (and (> arg 0) (setq prior (kcell-view:backward t label-sep-len)))
|
|
1197 (setq arg (1- arg)))
|
|
1198 (if (or prior (not (interactive-p)))
|
|
1199 arg
|
|
1200 (error "(kotl-mode:backward-cell): No prior cell at same level")))))
|
|
1201
|
|
1202 (defun kotl-mode:backward-char (&optional arg)
|
|
1203 "Move point backward ARG (or 1) characters and return point."
|
|
1204 (interactive "p")
|
|
1205 (setq zmacs-region-stays t) ;; Maintain region highlight for XEmacs.
|
|
1206 (or arg (setq arg 1))
|
|
1207 (if (>= arg 0)
|
|
1208 (while (> arg 0)
|
|
1209 (cond ((kotl-mode:bobp)
|
|
1210 (error "(kotl-mode:backward-char): Beginning of buffer"))
|
|
1211 ((kotl-mode:bocp)
|
|
1212 (if (kcell-view:previous)
|
|
1213 (kotl-mode:end-of-cell)))
|
|
1214 ((kotl-mode:bolp)
|
|
1215 (if (re-search-backward "[\n\r]" nil t)
|
|
1216 (kotl-mode:to-valid-position t)))
|
|
1217 (t (backward-char)))
|
|
1218 (setq arg (1- arg)))
|
|
1219 (kotl-mode:forward-char (- arg)))
|
|
1220 (point))
|
|
1221
|
|
1222 (defun kotl-mode:backward-paragraph (&optional arg)
|
|
1223 "Move backward to start of paragraph.
|
|
1224 With arg N, do it N times; negative arg -N means move forward N paragraphs.
|
|
1225 Return point.
|
|
1226
|
|
1227 A paragraph start is the beginning of a line which is a
|
|
1228 `first-line-of-paragraph' or which is ordinary text and follows a
|
|
1229 paragraph-separating line.
|
|
1230
|
|
1231 See `forward-paragraph' for more information."
|
|
1232 (interactive "p")
|
|
1233 (setq arg (prefix-numeric-value arg)
|
|
1234 zmacs-region-stays t);; Maintain region highlight for XEmacs.
|
|
1235 (kotl-mode:forward-paragraph (- arg)))
|
|
1236
|
|
1237 (fset 'kotl-mode:backward-para 'kotl-mode:backward-paragraph)
|
|
1238
|
|
1239 (defun kotl-mode:backward-sentence (&optional arg)
|
|
1240 "Move point backward ARG (or 1) sentences and return point."
|
|
1241 (interactive "p")
|
|
1242 (setq zmacs-region-stays t) ;; Maintain region highlight for XEmacs.
|
|
1243 (let* ((label-sep-len (kview:label-separator-length kview))
|
|
1244 ;; Setting fill prefix makes sentence commands properly recognize
|
|
1245 ;; indented paragraphs.
|
|
1246 (fill-prefix (make-string (kcell-view:indent nil label-sep-len) ?\ )))
|
|
1247 (if (kotl-mode:bobp)
|
|
1248 (error "(kotl-mode:backward-sentence): First sentence")
|
|
1249 (if (and (kotl-mode:bocp) (kcell-view:previous nil label-sep-len))
|
|
1250 (goto-char (kcell-view:end-contents)))
|
|
1251 (or arg (setq arg 1))
|
|
1252 (save-restriction
|
|
1253 (if (= arg 1)
|
|
1254 (narrow-to-region
|
|
1255 (- (kcell-view:start nil label-sep-len)
|
|
1256 (kcell-view:indent nil label-sep-len))
|
|
1257 (kcell-view:end-contents)))
|
|
1258 (unwind-protect
|
|
1259 (let ((opoint (point)))
|
|
1260 (backward-sentence arg)
|
|
1261 (if (= opoint (point))
|
|
1262 (progn (kcell-view:previous nil label-sep-len)
|
|
1263 (backward-sentence arg))))
|
|
1264 (kotl-mode:to-valid-position t)))))
|
|
1265 (point))
|
|
1266
|
|
1267 (defun kotl-mode:backward-word (&optional arg)
|
|
1268 "Move point backward ARG (or 1) words and return point."
|
|
1269 (interactive "p")
|
|
1270 (setq zmacs-region-stays t) ;; Maintain region highlight for XEmacs.
|
|
1271 (or arg (setq arg 1))
|
|
1272 (if (>= arg 0)
|
|
1273 (while (> arg 0)
|
|
1274 (cond ((kotl-mode:bobp) (setq arg 0))
|
|
1275 ((kotl-mode:bocp)
|
|
1276 (beginning-of-line)
|
|
1277 (kotl-mode:to-valid-position t)))
|
|
1278 (unwind-protect
|
|
1279 (backward-word 1)
|
|
1280 (kotl-mode:to-valid-position t))
|
|
1281 (setq arg (1- arg)))
|
|
1282 (kotl-mode:forward-word (- arg)))
|
|
1283 (point))
|
|
1284
|
|
1285 (defun kotl-mode:beginning-of-buffer ()
|
|
1286 "Move point to beginning of buffer and return point."
|
|
1287 (interactive)
|
|
1288 (setq zmacs-region-stays t) ;; Maintain region highlight for XEmacs.
|
|
1289 (goto-char (point-min))
|
|
1290 ;; To move to cell start.
|
|
1291 (goto-char (kcell-view:start)))
|
|
1292
|
|
1293 (defun kotl-mode:beginning-of-cell (&optional arg)
|
|
1294 "Move point to beginning of current or ARGth - 1 prior cell and return point."
|
|
1295 (interactive "p")
|
|
1296 (setq zmacs-region-stays t) ;; Maintain region highlight for XEmacs.
|
|
1297 (or arg (setq arg 1))
|
|
1298 (or (integer-or-marker-p arg)
|
114
|
1299 (error "(kotl-mode:beginning-of-cell): Wrong type arg, integer-or-marker, `%s'" arg))
|
0
|
1300 (if (= arg 1)
|
|
1301 (goto-char (kcell-view:start))
|
|
1302 (kotl-mode:backward-cell (1- arg)))
|
|
1303 (point))
|
|
1304
|
|
1305 ;;; Avoid XEmacs byte-compiler bug which inserts nil for calls to this
|
|
1306 ;;; function if named kotl-mode:beginning-of-line.
|
|
1307 ;;;
|
|
1308 (defun kotl-mode:start-of-line (&optional arg)
|
|
1309 "Move point to beginning of current or ARGth - 1 line and return point."
|
|
1310 (interactive "p")
|
|
1311 (setq zmacs-region-stays t) ;; Maintain region highlight for XEmacs.
|
|
1312 (or arg (setq arg 1))
|
|
1313 (or (integer-or-marker-p arg)
|
114
|
1314 (error "(kotl-mode:start-of-line): Wrong type arg, integer-or-marker, `%s'" arg))
|
0
|
1315 (forward-line (1- arg))
|
|
1316 (if (eolp)
|
|
1317 nil
|
|
1318 (forward-char (prog1 (kcell-view:indent)
|
|
1319 (beginning-of-line))))
|
|
1320 (point))
|
|
1321
|
114
|
1322 ;;; This ensures that the key bound to `beginning-of-line' is replaced in
|
|
1323 ;;; kotl-mode.
|
|
1324 (fset 'kotl-mode:beginning-of-line 'kotl-mode:start-of-line)
|
0
|
1325
|
|
1326 (defun kotl-mode:beginning-of-tree ()
|
|
1327 "Move point to the level 1 root of the current cell's tree.
|
|
1328 Leave point at the start of the cell."
|
|
1329 (interactive)
|
|
1330 (setq zmacs-region-stays t) ;; Maintain region highlight for XEmacs.
|
|
1331 (let ((label-sep-len (kview:label-separator-length kview)))
|
|
1332 (if (/= (kcell-view:level nil label-sep-len) 1)
|
|
1333 ;; Enable user to return to this previous position if desired.
|
|
1334 (push-mark nil 'no-msg))
|
|
1335 (while (and (/= (kcell-view:level nil label-sep-len) 1)
|
|
1336 (kcell-view:parent nil label-sep-len)))
|
|
1337 (kotl-mode:beginning-of-cell)))
|
|
1338
|
|
1339 (defun kotl-mode:down-level (arg)
|
|
1340 "Move down prefix ARG levels lower within current tree."
|
|
1341 (interactive "p")
|
|
1342 (setq zmacs-region-stays t) ;; Maintain region highlight for XEmacs.
|
|
1343 (if (< arg 0)
|
|
1344 (kotl-mode:up-level (- arg))
|
|
1345 ;; Enable user to return to this previous position if desired.
|
|
1346 (push-mark nil 'no-msg)
|
|
1347 (let ((child))
|
|
1348 (while (and (> arg 0) (kcell-view:child))
|
|
1349 (or child (setq child t))
|
|
1350 (setq arg (1- arg)))
|
|
1351 ;; Signal an error if couldn't move down at least 1 child level.
|
|
1352 (or child
|
|
1353 (progn
|
|
1354 (goto-char (hypb:mark t))
|
|
1355 (pop-mark)
|
|
1356 (error "(kotl-mode:down-level): No child level to which to move")
|
|
1357 )))))
|
|
1358
|
|
1359 (defun kotl-mode:end-of-buffer ()
|
|
1360 "Move point to end of buffer and return point."
|
|
1361 (interactive)
|
|
1362 (setq zmacs-region-stays t) ;; Maintain region highlight for XEmacs.
|
|
1363 (goto-char (point-max))
|
|
1364 ;; To move to cell end.
|
|
1365 (kotl-mode:to-valid-position t)
|
|
1366 (point))
|
|
1367
|
|
1368 (defun kotl-mode:end-of-cell (&optional arg)
|
|
1369 "Move point to end of current or ARGth - 1 succeeding cell and return point."
|
|
1370 (interactive "p")
|
|
1371 (setq zmacs-region-stays t) ;; Maintain region highlight for XEmacs.
|
|
1372 (or arg (setq arg 1))
|
|
1373 (or (integer-or-marker-p arg)
|
114
|
1374 (error "(kotl-mode:end-of-cell): Wrong type arg, integer-or-marker, `%s'" arg))
|
0
|
1375 (if (= arg 1)
|
|
1376 (goto-char (kcell-view:end-contents))
|
|
1377 (kotl-mode:forward-cell (1- arg)))
|
|
1378 (point))
|
|
1379
|
|
1380 ;;; Avoid XEmacs byte-compiler bug which inserts nil for calls to this
|
|
1381 ;;; function if named kotl-mode:end-of-line.
|
|
1382 ;;;
|
|
1383 (defun kotl-mode:finish-of-line (&optional arg)
|
|
1384 "Move point to end of current or ARGth - 1 line and return point."
|
|
1385 (interactive "p")
|
|
1386 (setq zmacs-region-stays t) ;; Maintain region highlight for XEmacs.
|
|
1387 (or arg (setq arg 1))
|
|
1388 (or (integer-or-marker-p arg)
|
114
|
1389 (error "(kotl-mode:finish-of-line): Wrong type arg, integer-or-marker, `%s'" arg))
|
0
|
1390 (forward-line (1- arg))
|
|
1391 (end-of-line)
|
|
1392 ;; May have to move backwards to before label if support labels
|
|
1393 ;; at end of cells.
|
|
1394 (point))
|
|
1395
|
|
1396 (defalias 'kotl-mode:end-of-line 'kotl-mode:finish-of-line)
|
|
1397
|
|
1398 (defun kotl-mode:end-of-tree ()
|
|
1399 "Move point to the last cell in tree rooted at the current cell.
|
|
1400 Leave point at the start of the cell."
|
|
1401 (interactive)
|
|
1402 (setq zmacs-region-stays t) ;; Maintain region highlight for XEmacs.
|
|
1403 ;; Enable user to return to this previous position if desired.
|
|
1404 (push-mark nil 'no-msg)
|
|
1405 (let ((label-sep-len (kview:label-separator-length kview)))
|
|
1406 (if (kcell-view:forward nil label-sep-len)
|
|
1407 ;; Move to cell preceding start of next tree.
|
|
1408 (kcell-view:previous nil label-sep-len)
|
|
1409 ;; Otherwise, no next tree, so move until find last cell in tree.
|
|
1410 (let ((cell-indent (kcell-view:indent nil label-sep-len))
|
|
1411 (end-point (point)))
|
|
1412 ;; Terminate when no further cells or when reach a cell at an equal
|
|
1413 ;; or higher level in the outline than the first cell that we
|
|
1414 ;; processed.
|
|
1415 (while (and (kcell-view:next nil label-sep-len)
|
|
1416 (> (kcell-view:indent nil label-sep-len) cell-indent))
|
|
1417 (setq end-point (point)))
|
|
1418 (goto-char end-point)))
|
|
1419 (kotl-mode:beginning-of-cell)))
|
|
1420
|
|
1421 (defun kotl-mode:first-sibling ()
|
|
1422 "Move point to the first sibling of the present cell.
|
|
1423 Leave point at the start of the cell or at its present position if it is
|
|
1424 already within the first sibling cell."
|
|
1425 (interactive)
|
|
1426 (setq zmacs-region-stays t) ;; Maintain region highlight for XEmacs.
|
|
1427 (let ((label-sep-len (kview:label-separator-length kview)))
|
|
1428 (if (save-excursion (kcell-view:backward nil label-sep-len))
|
|
1429 ;; Enable user to return to this previous position if desired.
|
|
1430 (push-mark nil 'no-msg))
|
|
1431 (while (kcell-view:backward nil label-sep-len))))
|
|
1432
|
|
1433 (defun kotl-mode:forward-cell (arg)
|
|
1434 "Move to prefix ARGth following cell (same level) within current view.
|
|
1435 Return number of cells left to move."
|
|
1436 (interactive "p")
|
|
1437 (setq zmacs-region-stays t) ;; Maintain region highlight for XEmacs.
|
|
1438 (if (< arg 0)
|
|
1439 (kotl-mode:backward-cell (- arg))
|
|
1440 (let ((next (= arg 0))
|
|
1441 (label-sep-len (kview:label-separator-length kview)))
|
|
1442 (while (and (> arg 0) (setq next (kcell-view:forward t label-sep-len)))
|
|
1443 (setq arg (1- arg)))
|
|
1444 (if (or next (not (interactive-p)))
|
|
1445 arg
|
|
1446 (error "(kotl-mode:forward-cell): No following cell at same level")))))
|
|
1447
|
|
1448 (defun kotl-mode:forward-char (&optional arg)
|
|
1449 "Move point forward ARG (or 1) characters and return point."
|
|
1450 (interactive "p")
|
|
1451 (setq zmacs-region-stays t) ;; Maintain region highlight for XEmacs.
|
|
1452 (or arg (setq arg 1))
|
|
1453 (if (>= arg 0)
|
|
1454 (while (> arg 0)
|
|
1455 (cond ((and (kotl-mode:eolp) (kotl-mode:last-line-p))
|
|
1456 (error "(kotl-mode:forward-char): End of buffer"))
|
|
1457 ((kotl-mode:eocp)
|
|
1458 (skip-chars-forward "\n\r")
|
|
1459 (kotl-mode:start-of-line))
|
|
1460 ((kotl-mode:eolp)
|
|
1461 (forward-char)
|
|
1462 (kotl-mode:start-of-line))
|
|
1463 (t (forward-char)))
|
|
1464 (setq arg (1- arg)))
|
|
1465 (kotl-mode:backward-char (- arg)))
|
|
1466 (point))
|
|
1467
|
|
1468 (defun kotl-mode:forward-paragraph (&optional arg)
|
|
1469 "Move point forward until after the last character of the current paragraph.
|
|
1470 With arg N, do it N times; negative arg -N means move backward N paragraphs.
|
|
1471 Return point.
|
|
1472
|
|
1473 A line which `paragraph-start' matches either separates paragraphs
|
|
1474 \(if `paragraph-separate' matches it also) or is the first line of a paragraph.
|
|
1475 A paragraph end is one character before the beginning of a line which is not
|
|
1476 part of the paragraph, or the end of the buffer."
|
|
1477 (interactive "p")
|
|
1478 (setq arg (prefix-numeric-value arg)
|
|
1479 zmacs-region-stays t);; Maintain region highlight for XEmacs.
|
|
1480 (if (< arg 0)
|
|
1481 (progn
|
|
1482 (if (kotl-mode:bocp) (setq arg (1- arg)))
|
|
1483 (while (< arg 0)
|
|
1484 (start-of-paragraph-text)
|
|
1485 (setq arg (1+ arg))))
|
|
1486 (while (> arg 0)
|
|
1487 (end-of-paragraph-text)
|
|
1488 (setq arg (1- arg))))
|
|
1489 (kotl-mode:to-valid-position)
|
|
1490 (point))
|
|
1491
|
|
1492 (fset 'kotl-mode:forward-para 'kotl-mode:forward-paragraph)
|
|
1493
|
|
1494 (defun kotl-mode:forward-sentence (&optional arg)
|
|
1495 "Move point forward ARG (or 1) sentences and return point."
|
|
1496 (interactive "P")
|
|
1497 (setq zmacs-region-stays t) ;; Maintain region highlight for XEmacs.
|
|
1498 (let* ((label-sep-len (kview:label-separator-length kview))
|
|
1499 ;; Setting fill prefix makes sentence commands properly recognize
|
|
1500 ;; indented paragraphs.
|
|
1501 (fill-prefix (make-string (kcell-view:indent nil label-sep-len) ?\ )))
|
|
1502 (if (kotl-mode:eobp)
|
|
1503 (error "(kotl-mode:forward-sentence): Last sentence")
|
|
1504 (if (kotl-mode:eocp) (kcell-view:next nil label-sep-len))
|
|
1505 (or arg (setq arg 1))
|
|
1506 (save-restriction
|
|
1507 (if (= arg 1)
|
|
1508 (narrow-to-region
|
|
1509 (- (kcell-view:start nil label-sep-len)
|
|
1510 (kcell-view:indent nil label-sep-len))
|
|
1511 (kcell-view:end-contents)))
|
|
1512 (unwind-protect
|
|
1513 (let ((opoint (point)))
|
|
1514 (forward-sentence arg)
|
|
1515 (if (= opoint (point))
|
|
1516 (progn (kcell-view:next nil label-sep-len)
|
|
1517 (forward-sentence arg))))
|
|
1518 (kotl-mode:to-valid-position)))))
|
|
1519 (point))
|
|
1520
|
|
1521 (defun kotl-mode:forward-word (&optional arg)
|
|
1522 "Move point forward ARG (or 1) words and return point."
|
|
1523 (interactive "p")
|
|
1524 (setq zmacs-region-stays t) ;; Maintain region highlight for XEmacs.
|
|
1525 (or arg (setq arg 1))
|
|
1526 (if (>= arg 0)
|
|
1527 (while (> arg 0)
|
|
1528 (cond ((kotl-mode:eobp) (setq arg 0))
|
|
1529 ((kotl-mode:eocp)
|
|
1530 (skip-chars-forward "\n\r")
|
|
1531 (kotl-mode:start-of-line)))
|
|
1532 (unwind-protect
|
|
1533 (forward-word 1)
|
|
1534 (kotl-mode:to-valid-position))
|
|
1535 ;; If point is at beginning of a cell after moving forward a word,
|
|
1536 ;; then we moved over something other than a word (some
|
|
1537 ;; punctuation or an outline autonumber); therefore, leave counter as
|
|
1538 ;; is in order to move forward over next word.
|
|
1539 (or (kotl-mode:bocp)
|
|
1540 (setq arg (1- arg))))
|
|
1541 (kotl-mode:backward-word (- arg)))
|
|
1542 (point))
|
|
1543
|
|
1544 (defun kotl-mode:goto-cell (cell-ref &optional error-p)
|
114
|
1545 "Move point to start of cell given by CELL-REF. (See `kcell:ref-to-id'.)
|
0
|
1546 Return point iff CELL-REF is found within current view.
|
|
1547 With a prefix argument, CELL-REF is assigned the argument value for use
|
|
1548 as an idstamp.
|
|
1549
|
|
1550 Optional second arg, ERROR-P, non-nil means signal an error if CELL-REF is
|
|
1551 not found within current view. Will signal same error if called
|
|
1552 interactively when CELL-REF is not found."
|
|
1553 (interactive
|
|
1554 (list (if current-prefix-arg
|
|
1555 (format "0%d" (prefix-numeric-value current-prefix-arg))
|
|
1556 (read-string "Goto cell label or id: "))))
|
|
1557 (setq cell-ref
|
|
1558 (or (kcell:ref-to-id cell-ref)
|
114
|
1559 (error "(kotl-mode:goto-cell): Invalid cell reference, `%s'" cell-ref)))
|
0
|
1560 (let* ((opoint (point))
|
|
1561 (found)
|
|
1562 cell-id kvspec)
|
|
1563 (if (= ?| (aref cell-ref 0))
|
|
1564 ;; This is a standalone view spec, not a cell reference.
|
|
1565 (progn (kvspec:activate cell-ref) (setq found (point)))
|
|
1566
|
|
1567 ;; !! Remove any relative specs and view specs from
|
|
1568 ;; cell-ref to form cell-id. Really should account for relative
|
|
1569 ;; specs here, but we don't yet support them.
|
|
1570 (if (string-match "\\(\\.[a-zA-Z]+\\)?\\([|:].*\\)\\|\\.[a-zA-Z]+"
|
|
1571 cell-ref)
|
|
1572 (setq cell-id (substring cell-ref 0 (match-beginning 0))
|
|
1573 kvspec (if (match-beginning 2)
|
|
1574 (substring
|
|
1575 cell-ref (match-beginning 2) (match-end 2))))
|
|
1576 (setq cell-id cell-ref kvspec nil))
|
|
1577
|
|
1578 (goto-char (point-min))
|
|
1579 (cond ((= ?0 (aref cell-id 0))
|
|
1580 ;; is an idstamp
|
|
1581 (if (kview:goto-cell-id cell-id)
|
|
1582 (setq found (point))))
|
|
1583 ;; is a label
|
|
1584 ((re-search-forward
|
|
1585 (format "\\([\n\r][\n\r]\\|\\`\\)[ ]*%s%s"
|
|
1586 (regexp-quote cell-id)
|
|
1587 (regexp-quote (kview:label-separator kview)))
|
|
1588 nil t)
|
|
1589 (setq found (point)))
|
|
1590 ;; no match
|
|
1591 (t (goto-char opoint)
|
|
1592 nil))
|
|
1593 (if (and (not found) (or error-p (interactive-p)))
|
114
|
1594 (error "(kotl-mode:goto-cell): No `%s' cell in this view" cell-ref)
|
0
|
1595 ;; Activate any viewspec associated with cell-ref.
|
|
1596 (if kvspec (kvspec:activate kvspec))))
|
|
1597 found))
|
|
1598
|
|
1599 (defun kotl-mode:head-cell ()
|
|
1600 "Move point to the start of the first visible cell at the same level as current cell.
|
|
1601 If at head cell already, do nothing and return nil."
|
|
1602 (interactive "p")
|
|
1603 (setq zmacs-region-stays t) ;; Maintain region highlight for XEmacs.
|
|
1604 (let ((moved)
|
|
1605 (label-sep-len (kview:label-separator-length kview)))
|
|
1606 (while (kcell-view:backward t label-sep-len)
|
|
1607 (setq moved t))
|
|
1608 moved))
|
|
1609
|
|
1610 (defun kotl-mode:last-sibling ()
|
|
1611 "Move point to the last sibling of the present cell.
|
|
1612 Leave point at the start of the cell or at its present position if it is
|
|
1613 already within the last sibling cell."
|
|
1614 (interactive)
|
|
1615 (setq zmacs-region-stays t) ;; Maintain region highlight for XEmacs.
|
|
1616 (let ((label-sep-len (kview:label-separator-length kview)))
|
|
1617 (if (save-excursion (kcell-view:forward nil label-sep-len))
|
|
1618 ;; Enable user to return to this previous position if desired.
|
|
1619 (push-mark nil 'no-msg))
|
|
1620 (while (kcell-view:forward nil label-sep-len))))
|
|
1621
|
|
1622 (defun kotl-mode:mark-paragraph ()
|
|
1623 "Put point at beginning of this paragraph, mark at end.
|
|
1624 The paragraph marked is the one that contains point or follows point."
|
|
1625 (interactive)
|
|
1626 (forward-paragraph 1)
|
|
1627 (kotl-mode:to-valid-position t)
|
|
1628 (hypb:push-mark nil t t)
|
|
1629 (backward-paragraph 1)
|
|
1630 (kotl-mode:to-valid-position))
|
|
1631
|
|
1632 (defun kotl-mode:mark-whole-buffer ()
|
|
1633 "Put point at first editable character in buffer and mark at the last such character."
|
|
1634 (interactive)
|
|
1635 (hypb:push-mark (point))
|
|
1636 (kotl-mode:end-of-buffer)
|
|
1637 (hypb:push-mark (point) nil t)
|
|
1638 (kotl-mode:beginning-of-buffer))
|
|
1639
|
|
1640 (defun kotl-mode:next-cell (arg)
|
|
1641 "Move to prefix ARGth next cell (any level) within current view."
|
|
1642 (interactive "p")
|
|
1643 (setq zmacs-region-stays t) ;; Maintain region highlight for XEmacs.
|
|
1644 (if (< arg 0)
|
|
1645 (kotl-mode:previous-cell (- arg))
|
|
1646 (let ((next (= arg 0))
|
|
1647 (label-sep-len (kview:label-separator-length kview)))
|
|
1648 (while (and (> arg 0) (setq next (kcell-view:next t label-sep-len)))
|
|
1649 (setq arg (1- arg)))
|
|
1650 (if next
|
|
1651 arg
|
|
1652 (error "(kotl-mode:next-cell): Last cell")))))
|
|
1653
|
|
1654 (defun kotl-mode:next-line (arg)
|
|
1655 "Move point to ARGth next line and return point."
|
|
1656 (interactive "p")
|
|
1657 (setq zmacs-region-stays t) ;; Maintain region highlight for XEmacs.
|
|
1658 (kotl-mode:set-temp-goal-column)
|
|
1659 (let ((orig-arg arg))
|
|
1660 (cond ((> arg 0)
|
|
1661 (while (and (> arg 0) (= 0 (forward-line 1)))
|
|
1662 (cond ((kotl-mode:eobp)
|
|
1663 (forward-line -1)
|
|
1664 (goto-char (kcell-view:end-contents))
|
|
1665 (and (interactive-p) (= orig-arg arg)
|
|
1666 (message "(kotl-mode:next-line): Last line") (beep))
|
|
1667 (setq arg 0)
|
|
1668 )
|
|
1669 ((looking-at "^$");; blank line between cells
|
|
1670 nil);; Don't count this line.
|
|
1671 (t (setq arg (1- arg)))))
|
|
1672 (kotl-mode:line-move 0)
|
|
1673 (kotl-mode:to-valid-position)
|
|
1674 )
|
|
1675 ((< arg 0)
|
|
1676 (kotl-mode:previous-line (- arg)))
|
|
1677 (t)))
|
|
1678 (setq this-command 'next-line)
|
|
1679 (point))
|
|
1680
|
|
1681 (defun kotl-mode:next-tree ()
|
|
1682 "Move past current tree to next tree, or to last cell in tree if no next tree.
|
|
1683 Return non-nil iff there is a next tree within this koutline."
|
|
1684 (let ((start-indent (kcell-view:indent))
|
|
1685 (label-sep-len (kview:label-separator-length kview))
|
|
1686 (same-tree t))
|
|
1687 (while (and (kcell-view:next nil label-sep-len)
|
|
1688 (setq same-tree (< start-indent
|
|
1689 (kcell-view:indent nil label-sep-len)))))
|
|
1690 (not same-tree)))
|
|
1691
|
|
1692 (defun kotl-mode:previous-line (arg)
|
|
1693 "Move point to ARGth previous line and return point."
|
|
1694 (interactive "p")
|
|
1695 (setq zmacs-region-stays t) ;; Maintain region highlight for XEmacs.
|
|
1696 (kotl-mode:set-temp-goal-column)
|
|
1697 (cond ((> arg 0)
|
|
1698 (while (and (> arg 0) (= 0 (forward-line -1)))
|
|
1699 (cond ((kotl-mode:bobp)
|
|
1700 (kotl-mode:beginning-of-cell)
|
|
1701 (setq arg 0))
|
|
1702 ((looking-at "^$") ;; blank line between cells
|
|
1703 nil) ;; Don't count this line.
|
|
1704 (t (setq arg (1- arg)))))
|
|
1705 (kotl-mode:line-move 0)
|
|
1706 (kotl-mode:to-valid-position)
|
|
1707 )
|
|
1708 ((< arg 0)
|
|
1709 (kotl-mode:next-line (- arg)))
|
|
1710 (t))
|
|
1711 (setq this-command 'previous-line)
|
|
1712 (point))
|
|
1713
|
|
1714 (defun kotl-mode:previous-cell (arg)
|
|
1715 "Move to prefix ARGth previous cell (any level) within current view."
|
|
1716 (interactive "p")
|
|
1717 (setq zmacs-region-stays t) ;; Maintain region highlight for XEmacs.
|
|
1718 (if (< arg 0)
|
|
1719 (kotl-mode:next-cell (- arg))
|
|
1720 (let ((previous (= arg 0))
|
|
1721 (label-sep-len (kview:label-separator-length kview)))
|
|
1722 (while (and (> arg 0) (setq previous
|
|
1723 (kcell-view:previous t label-sep-len)))
|
|
1724 (setq arg (1- arg)))
|
|
1725 (if previous
|
|
1726 arg
|
|
1727 (error "(kotl-mode:previous-cell): First cell")))))
|
|
1728
|
|
1729 (defun kotl-mode:scroll-down (arg)
|
|
1730 "Scroll text of current window downward ARG lines; or a windowful if no ARG."
|
|
1731 (interactive "P")
|
|
1732 (setq zmacs-region-stays t) ;; Maintain region highlight for XEmacs.
|
|
1733 (scroll-down arg)
|
|
1734 (kotl-mode:to-valid-position t))
|
|
1735
|
|
1736 (defun kotl-mode:scroll-up (arg)
|
|
1737 "Scroll text of current window upward ARG lines; or a windowful if no ARG."
|
|
1738 (interactive "P")
|
|
1739 (setq zmacs-region-stays t) ;; Maintain region highlight for XEmacs.
|
|
1740 (scroll-up arg)
|
|
1741 (kotl-mode:to-valid-position))
|
|
1742
|
|
1743 (defun kotl-mode:tail-cell ()
|
|
1744 "Move point to the start of the last visible cell at the same level as current cell and return t.
|
|
1745 If at tail cell already, do nothing and return nil."
|
|
1746 (interactive "p")
|
|
1747 (setq zmacs-region-stays t) ;; Maintain region highlight for XEmacs.
|
|
1748 (let ((moved)
|
|
1749 (label-sep-len (kview:label-separator-length kview)))
|
|
1750 (while (kcell-view:forward t label-sep-len)
|
|
1751 (setq moved t))
|
|
1752 moved))
|
|
1753
|
|
1754 (defun kotl-mode:up-level (arg)
|
|
1755 "Move up prefix ARG levels higher in current outline view."
|
|
1756 (interactive "p")
|
|
1757 (setq zmacs-region-stays t) ;; Maintain region highlight for XEmacs.
|
|
1758 (if (< arg 0)
|
|
1759 (kotl-mode:down-level (- arg))
|
|
1760 ;; Enable user to return to this previous position if desired.
|
|
1761 (push-mark nil 'no-msg)
|
|
1762 (let ((parent)
|
|
1763 (label-sep-len (kview:label-separator-length kview))
|
|
1764 result)
|
|
1765 (while (and (> arg 0) (setq result (kcell-view:parent t label-sep-len)))
|
|
1766 (or parent (setq parent result))
|
|
1767 (setq arg (if (eq result 0) 0 (1- arg))))
|
|
1768 ;; Signal an error if couldn't move up at least 1 parent level.
|
|
1769 (or (and parent (not (eq parent 0)))
|
|
1770 (progn
|
|
1771 (goto-char (hypb:mark t))
|
|
1772 (pop-mark)
|
|
1773 (error "(kotl-mode:up-level): No parent level to which to move")
|
|
1774 )))))
|
|
1775
|
|
1776 ;;; ------------------------------------------------------------------------
|
|
1777 ;;; Predicates
|
|
1778 ;;; ------------------------------------------------------------------------
|
|
1779
|
|
1780 (defun kotl-mode:bobp ()
|
|
1781 "Return point if at the start of the first cell in kview, else nil."
|
|
1782 (interactive)
|
|
1783 (or (bobp)
|
|
1784 (and (not (save-excursion (re-search-backward "[\n\r]" nil t)))
|
|
1785 (kotl-mode:bolp))))
|
|
1786
|
|
1787 (defun kotl-mode:bocp ()
|
|
1788 "Return point if at beginning of a kcell, else nil."
|
|
1789 (and (kotl-mode:bolp)
|
|
1790 (let ((begin-point (kcell-view:plist-point))
|
|
1791 (bol))
|
|
1792 (and begin-point
|
|
1793 (save-excursion
|
|
1794 ;; If first line-begin is less than cell begin point,
|
|
1795 ;; then we know we are on the first line of the cell.
|
|
1796 (if (setq bol (re-search-backward "^" nil t))
|
|
1797 (<= bol begin-point)))))
|
|
1798 (point)))
|
|
1799
|
|
1800 (defun kotl-mode:bolp ()
|
|
1801 "Return point if at beginning of a kview line, else nil."
|
|
1802 (if (= (current-column) (kcell-view:indent))
|
|
1803 (point)))
|
|
1804
|
|
1805 (defun kotl-mode:buffer-empty-p ()
|
|
1806 "Return non-nil iff there are no outline cells within current buffer."
|
|
1807 (save-excursion
|
|
1808 (goto-char (point-min))
|
|
1809 (looking-at "[\n\r]*\\'")))
|
|
1810
|
|
1811 (defun kotl-mode:eobp ()
|
|
1812 "Return point if after the end of the last cell in kview, else nil."
|
|
1813 (interactive)
|
|
1814 (if (looking-at "^[\n\r]*\\'") (point)))
|
|
1815
|
|
1816 (defun kotl-mode:eocp ()
|
|
1817 "Return point if at the end of a kview cell, else nil."
|
|
1818 (or (eobp)
|
|
1819 (looking-at "[\n\r]+\\'")
|
|
1820 (and (eolp)
|
|
1821 (save-excursion
|
|
1822 (skip-chars-forward "\n\r")
|
|
1823 (kotl-mode:start-of-line)
|
|
1824 (kotl-mode:bocp)))))
|
|
1825
|
|
1826 (fset 'kotl-mode:eolp 'eolp)
|
|
1827
|
|
1828 (defun kotl-mode:first-cell-p ()
|
|
1829 "Return t iff point is on the first cell of the outline."
|
|
1830 (save-excursion (not (kcell-view:previous))))
|
|
1831
|
|
1832 (fset 'kotl-mode:first-line-p 'first-line-p)
|
|
1833
|
|
1834 (defun kotl-mode:last-cell-p ()
|
|
1835 "Return t iff point is on the last cell of the outline."
|
|
1836 (save-excursion (not (kcell-view:next))))
|
|
1837
|
|
1838 (defun kotl-mode:last-line-p ()
|
|
1839 "Return t iff point is on the last line of the outline."
|
|
1840 (save-excursion
|
|
1841 (kotl-mode:finish-of-line)
|
|
1842 (looking-at "\n*\\'")))
|
|
1843
|
|
1844 ;;; ------------------------------------------------------------------------
|
|
1845 ;;; Smart Key Support
|
|
1846 ;;; ------------------------------------------------------------------------
|
|
1847
|
|
1848
|
|
1849 (defun kotl-mode:action-key ()
|
|
1850 "Collapses, expands, links to, and scrolls through koutline cells.
|
|
1851 Invoked via a key press when in kotl-mode. It assumes that its caller has
|
|
1852 already checked that the key was pressed in an appropriate buffer and has
|
|
1853 moved the cursor to the selected buffer.
|
|
1854
|
|
1855 If key is pressed:
|
|
1856 (1) at the end of buffer, uncollapse and unhide all cells in view;
|
|
1857 (2) within a cell, if its subtree is hidden then show it,
|
|
1858 otherwise hide it;
|
|
1859 (3) between cells or within the read-only indentation region to the left of
|
|
1860 a cell, then move point to prior location and begin creation of a
|
|
1861 klink to some other outline cell; hit the Action Key twice to select the
|
|
1862 link referent cell;
|
|
1863 (4) anywhere else, scroll up a windowful."
|
|
1864 (interactive)
|
|
1865 (cond ((kotl-mode:eobp) (kotl-mode:show-all))
|
|
1866 ((kotl-mode:eolp) (smart-scroll-up))
|
|
1867 ((not (kview:valid-position-p))
|
|
1868 (if (markerp action-key-depress-prev-point)
|
|
1869 (progn (select-window
|
|
1870 (get-buffer-window
|
|
1871 (marker-buffer action-key-depress-prev-point)))
|
|
1872 (goto-char (marker-position action-key-depress-prev-point))
|
|
1873 (call-interactively 'klink:create))
|
|
1874 (kotl-mode:to-valid-position)
|
|
1875 (error "(kotl-mode:action-key): Action Key released at invalid position")))
|
|
1876 (t ;; On a cell line (not at the end of line).
|
|
1877 (if (smart-outline-subtree-hidden-p)
|
|
1878 (kotl-mode:show-tree (kcell-view:label))
|
|
1879 (kotl-mode:hide-tree (kcell-view:label)))))
|
|
1880 (kotl-mode:to-valid-position))
|
|
1881
|
|
1882 (defun kotl-mode:help-key ()
|
|
1883 "Displays properties of koutline cells, collapses all cells, and scrolls back.
|
|
1884 Invoked via an assist-key press when in kotl-mode. It assumes that its caller
|
|
1885 has already checked that the assist-key was pressed in an appropriate buffer
|
|
1886 and has moved the cursor to the selected buffer.
|
|
1887
|
|
1888 If assist-key is pressed:
|
|
1889 (1) at the end of buffer, collapse all cells and hide all non-level-one
|
|
1890 cells;
|
|
1891 (2) on a header line but not at the beginning or end, display properties of
|
|
1892 each cell in tree beginning at point;
|
|
1893 (3) between cells or within the read-only indentation region to the left of
|
|
1894 a cell, then move point to prior location and prompt to move one tree to
|
|
1895 a new location in the outline; hit the Action Key twice to select the
|
|
1896 tree to move and where to move it;
|
|
1897 (4) anywhere else, scroll down a windowful."
|
|
1898 (interactive)
|
|
1899 (cond ((kotl-mode:eobp) (kotl-mode:overview))
|
|
1900 ((kotl-mode:eolp) (smart-scroll-down))
|
|
1901 ((not (kview:valid-position-p))
|
|
1902 (if (markerp assist-key-depress-prev-point)
|
|
1903 (progn (select-window
|
|
1904 (get-buffer-window
|
|
1905 (marker-buffer assist-key-depress-prev-point)))
|
|
1906 (goto-char (marker-position
|
|
1907 assist-key-depress-prev-point))
|
|
1908 (call-interactively 'kotl-mode:move-after))
|
|
1909 (kotl-mode:to-valid-position)
|
|
1910 (error "(kotl-mode:help-key): Help Key released at invalid position")))
|
|
1911 ((not (bolp))
|
|
1912 ;; On an outline header line but not at the start/end of line,
|
|
1913 ;; show attributes for tree at point.
|
|
1914 (kotl-mode:cell-help (kcell-view:label) (or current-prefix-arg 2)))
|
|
1915 ((smart-scroll-down)))
|
|
1916 (kotl-mode:to-valid-position))
|
|
1917
|
|
1918 ;;; ------------------------------------------------------------------------
|
|
1919 ;;; Structure Editing
|
|
1920 ;;; ------------------------------------------------------------------------
|
|
1921
|
|
1922 (defun kotl-mode:add-child ()
|
|
1923 "Add a new cell to current kview as first child of current cell."
|
|
1924 (interactive "*")
|
|
1925 (kotl-mode:add-cell '(4)))
|
|
1926
|
|
1927 (defun kotl-mode:add-parent ()
|
|
1928 "Add a new cell to current kview as sibling of current cell's parent."
|
|
1929 (interactive "*")
|
|
1930 (kotl-mode:add-cell -1))
|
|
1931
|
|
1932 (defun kotl-mode:add-cell (&optional relative-level contents plist no-fill)
|
|
1933 "Add a cell following current cell at optional RELATIVE-LEVEL with CONTENTS string, attributes in PLIST, a property list, and NO-FILL flag to prevent any filling of CONTENTS.
|
|
1934
|
|
1935 Optional prefix arg RELATIVE-LEVEL means add as sibling if nil or >= 0, as
|
|
1936 child if equal to universal argument, {C-u}, and as sibling of current cell's
|
|
1937 parent, otherwise. If added as sibling of current level, RELATIVE-LEVEL is
|
|
1938 used as a repeat count for the number of cells to add.
|
|
1939
|
|
1940 Return last newly added cell."
|
|
1941 (interactive "*P")
|
|
1942 (or (stringp contents) (setq contents nil))
|
|
1943 (let ((klabel (kcell-view:label))
|
|
1944 (label-sep-len (kview:label-separator-length kview))
|
|
1945 cell-level new-cell sibling-p child-p start parent
|
|
1946 cells-to-add)
|
|
1947 (setq cell-level (kcell-view:level nil label-sep-len)
|
|
1948 child-p (equal relative-level '(4))
|
|
1949 sibling-p (and (not child-p)
|
|
1950 (cond ((not relative-level) 1)
|
|
1951 ((>= (prefix-numeric-value relative-level) 0)
|
|
1952 (prefix-numeric-value relative-level))))
|
|
1953 cells-to-add (or sibling-p 1))
|
|
1954 (if child-p
|
|
1955 (setq cell-level (1+ cell-level))
|
|
1956 (if sibling-p
|
|
1957 nil
|
|
1958 ;; Add as following sibling of current cell's parent.
|
|
1959 ;; Move to parent.
|
|
1960 (setq cell-level (1- cell-level)
|
|
1961 start (point)
|
|
1962 parent (kcell-view:parent nil label-sep-len))
|
|
1963 (if (not (eq parent t))
|
|
1964 (progn
|
|
1965 (goto-char start)
|
|
1966 (error
|
|
1967 "(kotl-mode:add-cell): No higher level at which to add cell.")
|
|
1968 )))
|
|
1969 ;; Skip from point past any children to next cell.
|
|
1970 (if (kotl-mode:next-tree)
|
|
1971 ;; If found a new tree, then move back to prior cell so can add
|
|
1972 ;; new cell after it.
|
|
1973 (kcell-view:previous nil label-sep-len)))
|
|
1974 (goto-char (kcell-view:end))
|
|
1975 ;;
|
|
1976 ;; Insert new cells into view.
|
|
1977 (if (= cells-to-add 1)
|
|
1978 (setq klabel
|
|
1979 (cond (sibling-p
|
|
1980 (klabel:increment klabel))
|
|
1981 (child-p (klabel:child klabel))
|
|
1982 ;; add as sibling of parent of current cell
|
|
1983 (t (klabel:increment (klabel:parent klabel))))
|
|
1984 new-cell (kview:add-cell klabel cell-level contents plist
|
|
1985 (or no-fill sibling-p
|
|
1986 (not kotl-mode:refill-flag))))
|
|
1987 ;;
|
|
1988 ;; sibling-p must be true if we are looping here so there is no need to
|
|
1989 ;; conditionalize how to increment the labels.
|
|
1990 (while (>= (setq cells-to-add (1- cells-to-add)) 0)
|
|
1991 (setq klabel (klabel:increment klabel)
|
|
1992 ;; Since new cells are at the same level as old one, don't fill
|
|
1993 ;; any of their intial contents.
|
|
1994 new-cell (kview:add-cell klabel cell-level contents plist t))))
|
|
1995 ;;
|
|
1996 ;; Move back to last inserted cell and then move to its following
|
|
1997 ;; sibling if any.
|
|
1998 (kotl-mode:to-valid-position t)
|
|
1999 (save-excursion
|
|
2000 (if (kcell-view:forward t label-sep-len)
|
|
2001 ;; Update the labels of these siblings and their subtrees.
|
|
2002 (klabel-type:update-labels (klabel:increment klabel))))
|
|
2003 ;;
|
|
2004 ;; Leave point within last newly added cell and return this cell.
|
|
2005 (kotl-mode:beginning-of-cell)
|
|
2006 new-cell))
|
|
2007
|
|
2008 (defun kotl-mode:demote-tree (arg)
|
|
2009 "Move current tree a maximum of prefix ARG levels lower in current view.
|
|
2010 Each cell is refilled iff its `no-fill' attribute is nil and
|
|
2011 kotl-mode:refill-flag is non-nil. With prefix ARG = 0, cells are demoted up
|
|
2012 to one level and kotl-mode:refill-flag is treated as true."
|
|
2013 (interactive "*p")
|
|
2014 (if (< arg 0)
|
|
2015 (kotl-mode:promote-tree (- arg))
|
|
2016 (let* ((label-sep-len (kview:label-separator-length kview))
|
|
2017 (orig-level (kcell-view:level nil label-sep-len))
|
|
2018 (orig-point (point))
|
|
2019 (orig-id (kcell-view:idstamp))
|
|
2020 (fill-p (= arg 0))
|
|
2021 (orig-pos-in-cell
|
|
2022 (- (point) (kcell-view:start nil label-sep-len)))
|
|
2023 prev prev-level)
|
|
2024 (if fill-p (setq arg 1))
|
|
2025 (unwind-protect
|
|
2026 (progn
|
|
2027 (backward-char 1)
|
|
2028 (while (and (> arg 0)
|
|
2029 (setq prev
|
|
2030 (kcell-view:previous nil label-sep-len)))
|
|
2031 (if prev
|
|
2032 (progn (setq prev-level
|
|
2033 (kcell-view:level nil label-sep-len))
|
|
2034 (cond ((> prev-level (+ orig-level arg))
|
|
2035 ;; Don't want to demote this far
|
|
2036 ;; so keep looking at prior nodes.
|
|
2037 nil)
|
|
2038 ((= arg (- prev-level orig-level))
|
|
2039 ;; Demote to be sibling of this kcell.
|
|
2040 (setq arg -1))
|
|
2041 ((< prev-level orig-level)
|
|
2042 ;; prev is at higher level then
|
|
2043 ;; orig, so can't demote
|
|
2044 (setq prev nil
|
|
2045 arg 0))
|
|
2046 (t
|
|
2047 ;; Demote below this kcell. This is
|
|
2048 ;; as far we can demote, though it may
|
|
2049 ;; not be the full amount of arg.
|
|
2050 (setq arg 0))))))
|
|
2051 (if prev
|
|
2052 (kotl-mode:move-after
|
|
2053 (kcell-view:label orig-point)
|
|
2054 (kcell-view:label) (= arg 0)
|
|
2055 nil fill-p)))
|
|
2056 ;; Move to start of original cell
|
|
2057 (kotl-mode:goto-cell orig-id)
|
|
2058 ;; Move to original pos within cell
|
|
2059 (forward-char orig-pos-in-cell)
|
|
2060 (kotl-mode:to-valid-position))
|
|
2061 (if (not prev)
|
|
2062 (error "(kotl-mode:demote-tree): Cannot demote any further")))))
|
|
2063
|
|
2064 (defun kotl-mode:exchange-cells (cell-ref-1 cell-ref-2)
|
|
2065 "Exchange CELL-REF-1 with CELL-REF-2 in current view. Don't move point."
|
|
2066 (interactive
|
|
2067 (let ((hargs:defaults
|
|
2068 (save-excursion
|
|
2069 (list (kcell-view:label)
|
|
2070 (cond
|
|
2071 ((kcell-view:previous t)
|
|
2072 (kcell-view:label))
|
|
2073 ((kcell-view:next t)
|
|
2074 (kcell-view:label))
|
|
2075 (t (error
|
|
2076 "(kotl-mode:exchange-cells): No 2 visible cells")))))))
|
|
2077 (hargs:iform-read
|
|
2078 '(interactive "*+KExchange cell: \n+KExchange cell <%s> with cell: "))))
|
|
2079 (save-excursion
|
|
2080 (let (kcell-1 contents-1
|
|
2081 kcell-2 contents-2)
|
|
2082 ;;
|
|
2083 ;; Save cell-1 attributes
|
|
2084 (kotl-mode:goto-cell cell-ref-1 t)
|
|
2085 (setq kcell-1 (kcell-view:cell)
|
|
2086 contents-1 (kcell-view:contents))
|
|
2087 ;;
|
|
2088 ;; Save cell-2 attributes
|
|
2089 (kotl-mode:goto-cell cell-ref-2 t)
|
|
2090 (setq kcell-2 (kcell-view:cell)
|
|
2091 contents-2 (kcell-view:contents))
|
|
2092 ;;
|
|
2093 ;; Substitute cell-1 attributes into cell-2 location.
|
|
2094 ;;
|
|
2095 ;; Set kcell properties.
|
|
2096 (kcell-view:set-cell kcell-1)
|
|
2097 ;; If idstamp labels are on, then must exchange labels in view.
|
|
2098 (if (eq (kview:label-type kview) 'id)
|
|
2099 (klabel:set (kcell-view:idstamp)))
|
|
2100 ;; Exchange cell contents.
|
|
2101 (delete-region (kcell-view:start) (kcell-view:end-contents))
|
|
2102 (insert
|
|
2103 (hypb:replace-match-string
|
|
2104 "\\([\n\r]\\)"
|
|
2105 contents-1 (concat "\\1" (make-string (kcell-view:indent) ?\ ))))
|
|
2106 (if kotl-mode:refill-flag (kotl-mode:fill-cell))
|
|
2107 ;;
|
|
2108 ;; Substitute cell-2 attributes into cell-1 location.
|
|
2109 ;;
|
|
2110 ;; Set kcell properties.
|
|
2111 (kotl-mode:goto-cell cell-ref-1 t)
|
|
2112 (kcell-view:set-cell kcell-2)
|
|
2113 ;; If idstamp labels are on, then must exchange labels in view.
|
|
2114 (if (eq (kview:label-type kview) 'id)
|
|
2115 (klabel:set (kcell-view:idstamp)))
|
|
2116 ;; Exchange cell contents.
|
|
2117 (delete-region (kcell-view:start) (kcell-view:end-contents))
|
|
2118 ;; Add indentation to all but first line.
|
|
2119 (insert
|
|
2120 (hypb:replace-match-string
|
|
2121 "\\([\n\r]\\)"
|
|
2122 contents-2 (concat "\\1" (make-string (kcell-view:indent) ?\ ))))
|
|
2123 (if kotl-mode:refill-flag (kotl-mode:fill-cell)))))
|
|
2124
|
|
2125 (defun kotl-mode:kill-contents (arg)
|
|
2126 "Kill contents of cell from point to cell end.
|
|
2127 With prefix ARG, kill entire cell contents."
|
|
2128 (interactive "*P")
|
|
2129 (kotl-mode:kill-region
|
|
2130 (if arg (kcell-view:start) (point))
|
|
2131 (kcell-view:end-contents)))
|
|
2132
|
|
2133 (defun kotl-mode:kill-tree (&optional arg)
|
|
2134 "Kill ARG following trees starting with tree rooted at point.
|
|
2135 If ARG is not a non-positive number, nothing is done."
|
|
2136 (interactive "*p")
|
|
2137 (or (integerp arg) (setq arg 1))
|
|
2138 (let ((killed) (label (kcell-view:label))
|
|
2139 (label-sep-len (kview:label-separator-length kview))
|
|
2140 start end sib)
|
|
2141 (while (> arg 0)
|
|
2142 (setq start (kotl-mode:tree-start)
|
|
2143 end (kotl-mode:tree-end)
|
|
2144 sib (kcell-view:sibling-p nil nil label-sep-len)
|
|
2145 arg (1- arg)
|
|
2146 killed t)
|
|
2147 ;; Don't want to delete any prior cells, so if on last cell, ensure
|
|
2148 ;; this is the last one killed.
|
|
2149 (if (kotl-mode:last-cell-p)
|
|
2150 (progn (setq arg 0)
|
|
2151 (kview:delete-region start end))
|
|
2152 (kview:delete-region start end)
|
|
2153 (kotl-mode:to-valid-position)))
|
|
2154 (if killed
|
|
2155 (progn
|
|
2156 (cond (sib (klabel-type:update-labels label))
|
|
2157 ((kotl-mode:buffer-empty-p)
|
|
2158 ;; Always leave at least 1 visible cell within a view.
|
|
2159 (kview:add-cell "1" 1)))
|
|
2160 (kotl-mode:to-valid-position)))))
|
|
2161
|
|
2162 (defun kotl-mode:mail-tree (cell-ref invisible-flag)
|
|
2163 "Mail outline tree rooted at CELL-REF. Use \"0\" for whole outline buffer.
|
|
2164 Invisible text is expanded and included in the mail only if INVISIBLE-FLAG is
|
|
2165 non-nil."
|
|
2166 (interactive
|
|
2167 (let ((label-default (kcell-view:label)))
|
|
2168 (hargs:iform-read
|
|
2169 '(interactive
|
|
2170 (list
|
|
2171 (hargs:read "Mail tree: (0 for whole outline) "
|
|
2172 nil label-default nil 'kcell)
|
|
2173 (y-or-n-p "Include invisible text? "))))))
|
|
2174 (if (equal cell-ref "0")
|
|
2175 (hmail:buffer nil invisible-flag)
|
|
2176 (let (start end)
|
|
2177 (save-excursion
|
|
2178 (kotl-mode:goto-cell cell-ref t)
|
|
2179 (beginning-of-line)
|
|
2180 (setq start (point))
|
|
2181 (or (= (kotl-mode:forward-cell 1) 0) (goto-char (point-max)))
|
|
2182 (forward-line -1)
|
|
2183 (setq end (point)))
|
|
2184 (hmail:region start end nil invisible-flag))))
|
|
2185
|
|
2186 (defun kotl-mode:promote-tree (arg)
|
|
2187 "Move current tree a maximum of prefix ARG levels higher in current view.
|
|
2188 Each cell is refilled iff its `no-fill' attribute is nil and
|
|
2189 kotl-mode:refill-flag is non-nil. With prefix ARG = 0, cells are promoted up
|
|
2190 to one level and kotl-mode:refill-flag is treated as true."
|
|
2191 (interactive "*p")
|
|
2192 (if (< arg 0)
|
|
2193 (kotl-mode:demote-tree (- arg))
|
|
2194 (let* ((parent) (result)
|
|
2195 (label-sep-len (kview:label-separator-length kview))
|
|
2196 (orig-point (point))
|
|
2197 (orig-id (kcell-view:idstamp))
|
|
2198 (fill-p (= arg 0))
|
|
2199 (orig-pos-in-cell
|
|
2200 (- (point) (kcell-view:start nil label-sep-len))))
|
|
2201 (if fill-p (setq arg 1))
|
|
2202 (unwind-protect
|
|
2203 (progn
|
|
2204 (backward-char 1)
|
|
2205 (while (and (> arg 0)
|
|
2206 (setq result (kcell-view:parent
|
|
2207 nil label-sep-len))
|
|
2208 (not (eq result 0)))
|
|
2209 (setq parent result
|
|
2210 arg (1- arg)))
|
|
2211 (if parent
|
|
2212 (kotl-mode:move-after
|
|
2213 (kcell-view:label orig-point)
|
|
2214 (kcell-view:label) nil
|
|
2215 nil fill-p)))
|
|
2216 ;; Move to start of original cell
|
|
2217 (kotl-mode:goto-cell orig-id)
|
|
2218 ;; Move to original pos within cell
|
|
2219 (forward-char orig-pos-in-cell)
|
|
2220 (kotl-mode:to-valid-position))
|
|
2221 (if (not parent)
|
|
2222 (error "(kotl-mode:promote-tree): Cannot promote any further")))))
|
|
2223
|
|
2224 (defun kotl-mode:set-cell-attribute (attribute value &optional pos)
|
|
2225 "Include ATTRIBUTE VALUE with the current cell or the cell at optional POS.
|
|
2226 Replaces any existing value that ATTRIBUTE has.
|
|
2227 When called interactively, it displays the setting in the minibuffer as
|
|
2228 confirmation."
|
|
2229 (interactive
|
|
2230 (let* ((plist (copy-sequence (kcell-view:plist)))
|
|
2231 (existing-attributes plist)
|
|
2232 attribute value)
|
|
2233 (barf-if-buffer-read-only)
|
|
2234 ;; Remove attribute values
|
|
2235 (while plist
|
|
2236 (setcdr plist (cdr (cdr plist)))
|
|
2237 (setq plist (cdr plist)))
|
|
2238 ;; Remove read-only attributes
|
|
2239 (setq existing-attributes (set:create existing-attributes)
|
|
2240 existing-attributes (set:difference
|
|
2241 existing-attributes
|
|
2242 kcell:read-only-attributes))
|
|
2243
|
|
2244 (while (zerop (length (setq attribute
|
|
2245 (completing-read
|
|
2246 "Current cell attribute to set: "
|
|
2247 (mapcar 'list
|
|
2248 (mapcar 'symbol-name
|
|
2249 existing-attributes))))))
|
|
2250 (beep))
|
|
2251 (setq attribute (intern attribute)
|
|
2252 value (kcell-view:get-attr attribute))
|
|
2253 (if value
|
114
|
2254 (setq value (read-minibuffer
|
0
|
2255 (format "Change value of \"%s\" to: " attribute)
|
|
2256 (prin1-to-string value)))
|
114
|
2257 (setq value (read-minibuffer
|
0
|
2258 (format "Set value of \"%s\" to: " attribute))))
|
|
2259 (list attribute value nil)))
|
|
2260 (kcell-view:set-attr attribute value pos)
|
|
2261 ;; Note that buffer needs to be saved to store new attribute value.
|
|
2262 (set-buffer-modified-p t)
|
|
2263 (if (interactive-p)
|
|
2264 (message "Attribute \"%s\" set to `%s' in cell <%s>."
|
|
2265 attribute value (kcell-view:label pos))))
|
|
2266
|
|
2267 (defun kotl-mode:split-cell (&optional arg)
|
|
2268 "Split the current cell into two cells and move to the new cell.
|
|
2269 The cell contents after point become part of the newly created cell.
|
|
2270 The default is to create the new cell as a sibling of the current cell.
|
|
2271 With optional universal ARG, {C-u}, the new cell is added as the child of
|
|
2272 the current cell."
|
|
2273 (interactive "*P")
|
|
2274 (let ((new-cell-contents (kotl-mode:kill-region
|
|
2275 (point) (kcell-view:end-contents) 'string))
|
|
2276 (start (kcell-view:start)))
|
|
2277 ;; delete any preceding whitespace
|
|
2278 (skip-chars-backward " \t\n\r" start)
|
|
2279 (delete-region (max start (point)) (kcell-view:end-contents))
|
|
2280 (kotl-mode:add-cell arg new-cell-contents (kcell-view:plist))))
|
|
2281
|
|
2282 (defun kotl-mode:transpose-cells (arg)
|
|
2283 "Exchange current and previous visible cells, leaving point after both.
|
|
2284 If no previous cell, exchange current with next cell.
|
|
2285 With prefix ARG, take current tree and move it past ARG visible cells.
|
|
2286 With prefix ARG = 0, interchange the cell that contains point with the cell
|
|
2287 that contains mark."
|
|
2288 (interactive "*p")
|
|
2289 (let ((label-sep-len (kview:label-separator-length kview)))
|
|
2290 (cond
|
|
2291 ((save-excursion (not (or (kcell-view:next t label-sep-len)
|
|
2292 (kcell-view:previous t label-sep-len))))
|
|
2293 (error "(kotl-mode:transpose-cells): Only one visible cell in outline"))
|
|
2294 ;;
|
|
2295 ;; Transpose current and previous cells or current and next cells, if no
|
|
2296 ;; previous cell. Leave point after both exchanged cells or within last
|
|
2297 ;; visible cell.
|
|
2298 ((= arg 1)
|
|
2299 (let ((label-1 (kcell-view:label))
|
|
2300 (prev (kcell-view:previous t label-sep-len))
|
|
2301 label-2)
|
|
2302 (or prev (kcell-view:next t label-sep-len))
|
|
2303 (setq label-2 (kcell-view:label))
|
|
2304 (kotl-mode:exchange-cells label-1 label-2)
|
|
2305 (kcell-view:next t label-sep-len)
|
|
2306 (if prev (kcell-view:next t label-sep-len))))
|
|
2307 ;;
|
|
2308 ;; Transpose point and mark cells, moving point to the new location of the
|
|
2309 ;; cell which originally contained point.
|
|
2310 ((= arg 0)
|
|
2311 (let ((label-1 (kcell-view:label))
|
|
2312 label-2)
|
|
2313 ;; This is like exchange-point-and-mark, but doesn't activate the
|
|
2314 ;; mark.
|
|
2315 (goto-char (prog1 (hypb:mark t)
|
|
2316 (set-marker (hypb:mark-marker t) (point))))
|
|
2317 (setq label-2 (kcell-view:label))
|
|
2318 (kotl-mode:exchange-cells label-1 label-2)))
|
|
2319 ;;
|
|
2320 ;; Move current tree past ARG next visible cells and leave point after
|
|
2321 ;; original cell text.
|
|
2322 (t
|
|
2323 (let ((mark (set-marker (make-marker)
|
|
2324 (save-excursion (kotl-mode:next-line arg)))))
|
|
2325 (kotl-mode:move-after
|
|
2326 (kcell-view:label)
|
|
2327 (progn (while (and (> arg 0) (kcell-view:next t label-sep-len))
|
|
2328 (setq arg (1- arg)))
|
|
2329 (kcell-view:label))
|
|
2330 nil)
|
|
2331 (goto-char mark)
|
|
2332 (set-marker mark nil))))))
|
|
2333
|
|
2334 ;;; ------------------------------------------------------------------------
|
|
2335 ;;; Structure Viewing
|
|
2336 ;;; ------------------------------------------------------------------------
|
|
2337
|
|
2338 (defun kotl-mode:collapse-tree (&optional all-flag)
|
|
2339 "Collapse to one line each visible cell of tree rooted at point.
|
|
2340 With optional ALL-FLAG non-nil, collapse all cells visible within the current
|
|
2341 view."
|
|
2342 (interactive "P")
|
|
2343 (kotl-mode:is-p)
|
|
2344 (let (buffer-read-only)
|
|
2345 (if all-flag
|
|
2346 (progn (kvspec:show-lines-per-cell 1)
|
|
2347 (kvspec:update t))
|
|
2348 (kview:map-tree
|
|
2349 (function
|
|
2350 (lambda (kview)
|
|
2351 ;; Use free variable label-sep-len bound in kview:map-tree for speed.
|
|
2352 (goto-char (kcell-view:start nil label-sep-len))
|
|
2353 (subst-char-in-region (point) (kcell-view:end-contents) ?\n ?\r t)))
|
|
2354 kview nil t))))
|
|
2355
|
|
2356 (defun kotl-mode:expand-tree (&optional all-flag)
|
|
2357 "Expand each visible cell of tree rooted at point.
|
|
2358 With optional ALL-FLAG non-nil, expand all cells visible within the current
|
|
2359 view."
|
|
2360 (interactive "P")
|
|
2361 (kotl-mode:is-p)
|
|
2362 (let (buffer-read-only)
|
|
2363 (if all-flag
|
|
2364 (progn (kvspec:show-lines-per-cell 0)
|
|
2365 (kvspec:update t))
|
|
2366 (kview:map-tree
|
|
2367 (function
|
|
2368 (lambda (kview)
|
|
2369 ;; Use free variable label-sep-len bound in kview:map-tree for speed.
|
|
2370 (goto-char (kcell-view:start nil label-sep-len))
|
|
2371 (subst-char-in-region (point) (kcell-view:end-contents) ?\r ?\n t)))
|
|
2372 kview nil t))))
|
|
2373
|
|
2374 (defun kotl-mode:toggle-tree-expansion (&optional all-flag)
|
|
2375 "Collapse or expand each cell of tree rooted at point or all visible cells if optional prefix arg ALL-FLAG is given.
|
|
2376 If current cell is collapsed, cells will be expanded, otherwise they will be
|
|
2377 collapsed."
|
|
2378 (interactive "P")
|
|
2379 (if (kcell-view:collapsed-p)
|
|
2380 ;; expand cells
|
|
2381 (kotl-mode:expand-tree all-flag)
|
|
2382 (kotl-mode:collapse-tree all-flag)))
|
|
2383
|
|
2384 ;;;
|
|
2385 (defun kotl-mode:overview ()
|
|
2386 "Show the first line of each cell without blank line separators."
|
|
2387 (interactive)
|
|
2388 (kotl-mode:show-all)
|
|
2389 (if (string-match "b" kvspec:current)
|
|
2390 (kvspec:toggle-blank-lines))
|
|
2391 (kotl-mode:collapse-tree t))
|
|
2392
|
|
2393 (defun kotl-mode:show-all ()
|
|
2394 "Show (expand) all cells in current view."
|
|
2395 (interactive)
|
|
2396 (if (kotl-mode:is-p)
|
|
2397 (progn (kview:set-attr kview 'levels-to-show 0)
|
|
2398 (kview:set-attr kview 'lines-to-show 0)
|
|
2399 (show-all)
|
|
2400 (kvspec:update t))))
|
|
2401
|
|
2402 (defun kotl-mode:top-cells ()
|
|
2403 "Collapse all level 1 cells in view and hide any deeper sublevels."
|
|
2404 (interactive)
|
|
2405 (kotl-mode:is-p)
|
|
2406 (let ((modified-p (buffer-modified-p))
|
|
2407 (buffer-read-only))
|
|
2408 (kvspec:levels-to-show 1)
|
|
2409 (kvspec:show-lines-per-cell 1)
|
|
2410 (kvspec:update t)
|
|
2411 ;; Restore buffer modification status
|
|
2412 (set-buffer-modified-p modified-p)))
|
|
2413
|
|
2414 ;;;
|
|
2415 (defun kotl-mode:hide-sublevels (levels-to-keep)
|
|
2416 "Hide all cells in outline at levels deeper than LEVELS-TO-KEEP (a number).
|
|
2417 Shows any hidden cells within LEVELS-TO-KEEP. 1 is the first level. 0 means
|
|
2418 display all levels of cells."
|
|
2419 (interactive "P")
|
|
2420 (kvspec:levels-to-show levels-to-keep)
|
|
2421 ;; The prior call might have shown more lines per cell than the current
|
|
2422 ;; viewspec supports, so reset lines per cell.
|
|
2423 (kvspec:lines-to-show)
|
|
2424 (kvspec:update t))
|
|
2425
|
|
2426 (defun kotl-mode:hide-subtree (&optional cell-ref show-flag)
|
|
2427 "Hide subtree, ignoring root, at optional CELL-REF (defaults to cell at point)."
|
|
2428 (interactive)
|
|
2429 (kotl-mode:is-p)
|
|
2430 (save-excursion
|
|
2431 (if cell-ref
|
|
2432 (kotl-mode:goto-cell cell-ref t)
|
|
2433 (kotl-mode:beginning-of-cell))
|
|
2434 (let ((start (kcell-view:end-contents))
|
|
2435 (end (kotl-mode:tree-end t))
|
|
2436 (buffer-read-only))
|
|
2437 (if show-flag
|
|
2438 (subst-char-in-region start end ?\r ?\n t)
|
|
2439 (subst-char-in-region start end ?\n ?\r t)))))
|
|
2440
|
|
2441 (defun kotl-mode:show-subtree (&optional cell-ref)
|
|
2442 "Show subtree, ignoring root, at optional CELL-REF (defaults to cell at point)."
|
|
2443 (interactive)
|
|
2444 (kotl-mode:hide-subtree cell-ref t))
|
|
2445
|
|
2446 (defun kotl-mode:hide-tree (&optional cell-ref show-flag)
|
|
2447 "Collapse tree rooted at optional CELL-REF (defaults to cell at point)."
|
|
2448 (interactive)
|
|
2449 (kotl-mode:is-p)
|
|
2450 (save-excursion
|
|
2451 (let ((start (if cell-ref
|
|
2452 (kotl-mode:goto-cell cell-ref t)
|
|
2453 (kotl-mode:beginning-of-cell)))
|
|
2454 (end (kotl-mode:tree-end t))
|
|
2455 (buffer-read-only))
|
|
2456 (if show-flag
|
|
2457 (subst-char-in-region start end ?\r ?\n t)
|
|
2458 (subst-char-in-region start end ?\n ?\r t)))))
|
|
2459
|
|
2460 (defun kotl-mode:show-tree (&optional cell-ref)
|
|
2461 "Display fully expanded tree rooted at CELL-REF."
|
|
2462 (interactive)
|
|
2463 (kotl-mode:hide-tree cell-ref t))
|
|
2464
|
|
2465 ;;;
|
|
2466 (defun kotl-mode:cell-attributes (all-flag)
|
|
2467 "Display a temporary buffer with the attributes of the current kcell.
|
|
2468 With prefix arg ALL-FLAG non-nil, display the attributes of all visible
|
|
2469 kcells in the current buffer.
|
|
2470
|
|
2471 See also the documentation for `kotl-mode:cell-help'."
|
|
2472 (interactive "P")
|
|
2473 (with-output-to-temp-buffer
|
|
2474 (hypb:help-buf-name "Kotl")
|
|
2475 (save-excursion
|
|
2476 (if (not all-flag)
|
|
2477 (kotl-mode:print-attributes kview)
|
|
2478 (let ((label-sep-len (kview:label-separator-length kview)))
|
|
2479 (kotl-mode:beginning-of-buffer)
|
|
2480 (while (progn (kotl-mode:print-attributes kview)
|
|
2481 (kcell-view:next t label-sep-len))))))))
|
|
2482
|
|
2483 (defun kotl-mode:cell-help (&optional cell-ref cells-flag)
|
|
2484 "Display a temporary buffer with CELL-REF's attributes.
|
|
2485 CELL-REF defaults to current cell.
|
|
2486 Optional prefix arg CELLS-FLAG selects the cells to print:
|
|
2487 If = 1, print CELL-REF's cell only;
|
|
2488 If > 1, print CELL-REF's visible tree (the tree rooted at CELL-REF);
|
|
2489 If < 1, print all visible cells in current view (CELL-REF is not used).
|
|
2490
|
|
2491 See also the documentation for `kotl-mode:cell-attributes'."
|
|
2492 (interactive
|
|
2493 (let* ((label (kcell-view:label))
|
|
2494 (hargs:defaults (list label label)))
|
|
2495 (append
|
|
2496 (let ((arg (prefix-numeric-value current-prefix-arg)))
|
|
2497 (if (< arg 1)
|
|
2498 0
|
|
2499 (hargs:iform-read
|
|
2500 (list 'interactive
|
|
2501 (format "+KDisplay properties of koutline %s: "
|
|
2502 (if (= arg 1) "cell" "tree"))))))
|
|
2503 (list current-prefix-arg))))
|
|
2504 (or (integerp cells-flag)
|
|
2505 (setq cells-flag (prefix-numeric-value cells-flag)))
|
|
2506 (or (stringp cell-ref) (setq cell-ref (kcell-view:label)))
|
|
2507 (with-output-to-temp-buffer
|
|
2508 (hypb:help-buf-name "Koutline")
|
|
2509 (save-excursion
|
|
2510 (if (equal cell-ref "0")
|
|
2511 (progn
|
|
2512 (hattr:report (kcell:plist (kview:top-cell kview)))
|
|
2513 (terpri)
|
|
2514 (cond ((= cells-flag 1) nil)
|
|
2515 ((> cells-flag 1)
|
|
2516 (kview:map-tree 'kotl-mode:print-attributes kview t t))
|
|
2517 ;; (< cells-flag 1)
|
|
2518 (t (kotl-mode:cell-attributes t))))
|
|
2519 (cond ((= cells-flag 1)
|
|
2520 (kotl-mode:goto-cell cell-ref)
|
|
2521 (kotl-mode:print-attributes kview))
|
|
2522 ((> cells-flag 1)
|
|
2523 (kotl-mode:goto-cell cell-ref)
|
|
2524 (kview:map-tree 'kotl-mode:print-attributes kview nil t))
|
|
2525 ;; (< cells-flag 1)
|
|
2526 (t (kotl-mode:cell-attributes t)))))))
|
|
2527
|
|
2528 (defun kotl-mode:get-cell-attribute (attribute &optional pos)
|
|
2529 "Return ATTRIBUTE's value for the current cell or the cell at optional POS.
|
|
2530 When called interactively, it displays the value in the minibuffer."
|
|
2531 (interactive "SCurrent cell attribute to get: ")
|
|
2532 (let ((value (kcell-view:get-attr attribute pos)))
|
|
2533 (if (interactive-p)
|
|
2534 (message "Attribute \"%s\" = `%s' in cell <%s>."
|
|
2535 attribute value (kcell-view:label pos)))
|
|
2536 value))
|
|
2537
|
|
2538 ;;; ************************************************************************
|
|
2539 ;;; Private functions
|
|
2540 ;;; ************************************************************************
|
|
2541
|
|
2542 (defun kotl-mode:add-indent-to-region (&optional indent start end)
|
|
2543 "Add current cell's indent to current region.
|
|
2544 Optionally, INDENT and region START and END may be given."
|
|
2545 (or (integerp indent) (setq indent (kcell-view:indent)))
|
|
2546 (save-excursion
|
|
2547 (save-restriction
|
|
2548 (narrow-to-region (or start (point)) (or end (hypb:mark t)))
|
|
2549 (goto-char (point-min))
|
|
2550 (replace-regexp "\n" (concat "\n" (make-string indent ?\ ))))))
|
|
2551
|
|
2552 (defun kotl-mode:delete-line (&optional pos)
|
|
2553 "Delete and return contents of cell line at point or optional POS as a string.
|
|
2554 Does not delete newline at end of line."
|
|
2555 (save-excursion
|
|
2556 (if pos (goto-char pos))
|
|
2557 (if (kview:valid-position-p)
|
|
2558 (let ((bol (kotl-mode:start-of-line))
|
|
2559 (eol (kotl-mode:finish-of-line)))
|
|
2560 (prog1
|
|
2561 (buffer-substring bol eol)
|
|
2562 (delete-region bol eol)))
|
114
|
2563 (error "(kotl-mode:delete-line): Invalid position, `%d'" (point)))))
|
0
|
2564
|
|
2565 (defun kotl-mode:indent-line (arg)
|
|
2566 ;; Disallow the indent-line command.
|
|
2567 (error "(kotl-mode:indent-line): Insert spaces to indent each line."))
|
|
2568
|
|
2569 (defun kotl-mode:indent-region (start end)
|
|
2570 ;; User might try to indent across cells. This would be bad, so disallow
|
|
2571 ;; the indent-region command.
|
|
2572 (error "(kotl-mode:indent-region): Insert spaces to indent each line."))
|
|
2573
|
|
2574 (defun kotl-mode:is-p ()
|
|
2575 "Signal an error if current buffer is not a Hyperbole outline, else return t."
|
|
2576 (if (kview:is-p kview)
|
|
2577 t
|
|
2578 (hypb:error
|
|
2579 "(kotl-mode:is-p): Command requires a current Hyperbole outline.")))
|
|
2580
|
|
2581 (defun kotl-mode:tree-end (&optional omit-end-newlines)
|
|
2582 "Return end point of current cell's tree within this view.
|
|
2583 If optional OMIT-END-NEWLINES is non-nil, point returned precedes any
|
|
2584 newlines at end of tree."
|
|
2585 (let* ((label-sep-len (kview:label-separator-length kview))
|
|
2586 (start-indent (kcell-view:indent nil label-sep-len))
|
|
2587 (next))
|
|
2588 (save-excursion
|
|
2589 (while (and (setq next (kcell-view:next nil label-sep-len))
|
|
2590 (< start-indent (kcell-view:indent nil label-sep-len))))
|
|
2591 (cond (next
|
|
2592 (goto-char (progn (kcell-view:previous nil label-sep-len)
|
|
2593 (kcell-view:end))))
|
|
2594 ;; Avoid skipping too far at end of file.
|
|
2595 ((re-search-forward "[\n\r][\n\r]" nil t))
|
|
2596 (t (goto-char (point-max))))
|
|
2597 (if omit-end-newlines (skip-chars-backward "\n\r"))
|
|
2598 (point))))
|
|
2599
|
|
2600 (defun kotl-mode:tree-start ()
|
|
2601 "Return beginning of line position preceding current cell's start point."
|
|
2602 (save-excursion (goto-char (kcell-view:start)) (beginning-of-line)
|
|
2603 (point)))
|
|
2604
|
|
2605 (defun kotl-mode:line-move (arg)
|
|
2606 "Move point ARG visible lines forward within an outline."
|
|
2607 (if (not (integerp selective-display))
|
|
2608 (forward-line arg)
|
|
2609 ;; Move by arg lines, but ignore invisible ones.
|
|
2610 (while (> arg 0)
|
|
2611 (vertical-motion 1)
|
|
2612 (forward-char -1)
|
|
2613 (forward-line 1)
|
|
2614 (setq arg (1- arg)))
|
|
2615 (while (< arg 0)
|
|
2616 (vertical-motion -1)
|
|
2617 (beginning-of-line)
|
|
2618 (setq arg (1+ arg))))
|
|
2619 (move-to-column (or goal-column temporary-goal-column))
|
|
2620 nil)
|
|
2621
|
|
2622 (defun kotl-mode:print-attributes (kview)
|
|
2623 "Print to the `standard-output' stream the attributes of the current visible kcell.
|
114
|
2624 Takes argument KVIEW (so it can be used with `kview:map-tree' and so that
|
0
|
2625 KVIEW is bound correctly) but always operates upon the current view."
|
|
2626 ;; Move to start of visible cell to avoid printing attributes for an
|
|
2627 ;; invisible kcell which point may be over.
|
|
2628 ;; Print first line of cell for reference.
|
|
2629 (save-excursion
|
|
2630 (princ
|
|
2631 (buffer-substring (progn (beginning-of-line) (point))
|
|
2632 (progn (kview:end-of-actual-line)
|
|
2633 (point)))))
|
|
2634 (terpri)
|
|
2635 (hattr:report (kcell:plist (kcell-view:cell)))
|
|
2636 (terpri))
|
|
2637
|
|
2638 (defun kotl-mode:set-temp-goal-column ()
|
|
2639 (if (not (or (eq last-command 'next-line)
|
|
2640 (eq last-command 'previous-line)))
|
|
2641 (setq temporary-goal-column
|
|
2642 (if (and track-eol (eolp)
|
|
2643 ;; Don't count beg of empty line as end of line
|
|
2644 ;; unless we just did explicit end-of-line.
|
|
2645 (or (not (bolp)) (eq last-command 'end-of-line)))
|
|
2646 9999
|
|
2647 (current-column)))))
|
|
2648
|
|
2649 (defun kotl-mode:to-valid-position (&optional backward-p)
|
|
2650 "Move point to the nearest non-read-only position within current koutline view.
|
|
2651 With optional BACKWARD-P, move backward if possible to get to valid position."
|
|
2652 (if (kview:valid-position-p)
|
|
2653 nil
|
|
2654 (let ((label-sep-len (kview:label-separator-length kview)))
|
|
2655 (cond ((kotl-mode:bobp)
|
|
2656 (goto-char (kcell-view:start nil label-sep-len)))
|
|
2657 ((kotl-mode:eobp)
|
|
2658 (skip-chars-backward "\n\r"))
|
|
2659 (t (let ((indent (kcell-view:indent nil label-sep-len)))
|
|
2660 (if (bolp)
|
|
2661 (if backward-p
|
|
2662 (skip-chars-backward "\n\r")
|
|
2663 (skip-chars-forward "\n\r")))
|
|
2664 (setq indent (kcell-view:indent nil label-sep-len))
|
|
2665 (if (< (current-column) indent)
|
|
2666 (move-to-column indent))))))))
|
|
2667
|
|
2668 (defun kotl-mode:transpose-lines-internal (start end)
|
|
2669 "Transpose lines at START and END markers within an outline.
|
|
2670 Leave point at end of line now residing at START."
|
|
2671 (if (and start end
|
|
2672 (kview:valid-position-p start)
|
|
2673 (kview:valid-position-p end))
|
|
2674 (let* ((pline (kotl-mode:delete-line start))
|
|
2675 mline)
|
|
2676 (goto-char end)
|
|
2677 (setq mline (kotl-mode:delete-line))
|
|
2678 (insert pline)
|
|
2679 (goto-char start)
|
|
2680 (insert mline))
|
|
2681 ;; Set non-point and non-mark markers to point nowhere before signalling
|
|
2682 ;; an error.
|
|
2683 (or (eq start (point-marker))
|
|
2684 (eq start (hypb:mark-marker t))
|
|
2685 (set-marker start nil))
|
|
2686 (or (eq end (point-marker))
|
|
2687 (eq end (hypb:mark-marker t))
|
|
2688 (set-marker start nil))
|
|
2689 (error "(kotl-mode:transpose-lines): Point or mark is at an invalid position")))
|
|
2690
|
|
2691 (defun kotl-mode:update-buffer ()
|
|
2692 "Update current view buffer in preparation for saving."
|
|
2693 (if (kview:is-p kview)
|
|
2694 (let ((mod-p (buffer-modified-p))
|
|
2695 (start (window-start)))
|
|
2696 (save-excursion
|
|
2697 (kfile:update)
|
|
2698 (set-buffer-modified-p mod-p))
|
|
2699 (set-window-start nil (max (point-min) start) t)
|
|
2700 nil)))
|
|
2701
|
|
2702 ;;; ------------------------------------------------------------------------
|
|
2703
|
|
2704 (defvar kotl-mode-map nil
|
|
2705 "Keymap containing koutliner editing and viewing commands.")
|
|
2706 (if kotl-mode-map
|
|
2707 nil
|
|
2708 (setq kotl-mode-map
|
|
2709 (if (string-match "XEmacs\\|Lucid" emacs-version)
|
|
2710 (make-keymap)
|
|
2711 (copy-keymap indented-text-mode-map)))
|
|
2712 ;; Overload edit keys to deal with structure and labels.
|
|
2713 (let (local-cmd)
|
|
2714 (mapcar
|
|
2715 (if (string-match "XEmacs\\|Lucid" emacs-version)
|
|
2716 ;; XEmacs
|
|
2717 (function
|
|
2718 (lambda (cmd)
|
|
2719 (setq local-cmd (intern-soft
|
|
2720 (concat "kotl-mode:" (symbol-name cmd))))
|
|
2721 ;; Only bind key locally if kotl-mode local-cmd has already
|
|
2722 ;; been defined and cmd is a valid function.
|
|
2723 (if (and local-cmd (fboundp cmd))
|
|
2724 (progn
|
|
2725 ;; Make local-cmd have the same property list as cmd,
|
|
2726 ;; e.g. so pending-delete property is the same.
|
|
2727 (setplist local-cmd (symbol-plist cmd))
|
|
2728 (mapcar
|
|
2729 (function
|
|
2730 (lambda (key) (define-key kotl-mode-map key local-cmd)))
|
|
2731 (where-is-internal cmd))))))
|
|
2732 ;; GNU Emacs 19
|
|
2733 (function
|
|
2734 (lambda (cmd)
|
|
2735 (setq local-cmd (intern-soft
|
|
2736 (concat "kotl-mode:" (symbol-name cmd))))
|
|
2737 ;; Only bind key locally if kotl-mode local-cmd has already
|
|
2738 ;; been defined and cmd is a valid function.
|
|
2739 (if (and local-cmd (fboundp cmd))
|
|
2740 (progn
|
|
2741 ;; Make local-cmd have the same property list as cmd,
|
|
2742 ;; e.g. so pending-delete property is the same.
|
|
2743 (setplist local-cmd (symbol-plist cmd))
|
|
2744 (substitute-key-definition
|
|
2745 cmd local-cmd kotl-mode-map global-map))))))
|
|
2746 '(
|
|
2747 back-to-indentation
|
|
2748 backward-char
|
|
2749 backward-delete-char
|
|
2750 backward-delete-char-untabify
|
|
2751 backward-kill-word
|
|
2752 backward-para
|
|
2753 backward-paragraph
|
|
2754 backward-sentence
|
|
2755 backward-word
|
|
2756 beginning-of-buffer
|
|
2757 beginning-of-line
|
|
2758 copy-region-as-kill
|
|
2759 copy-to-register
|
|
2760 delete-blank-lines
|
|
2761 delete-backward-char
|
|
2762 delete-char
|
|
2763 delete-horizontal-space
|
|
2764 delete-indentation
|
|
2765 end-of-buffer
|
|
2766 end-of-line
|
|
2767 fill-paragraph
|
|
2768 fill-paragraph-or-region
|
|
2769 ;; cursor keys
|
|
2770 fkey-backward-char
|
|
2771 fkey-forward-char
|
|
2772 fkey-next-line
|
|
2773 fkey-previous-line
|
|
2774 ;;
|
|
2775 forward-char
|
|
2776 forward-word
|
|
2777 forward-para
|
|
2778 forward-paragraph
|
|
2779 forward-sentence
|
|
2780 insert-buffer
|
|
2781 insert-file
|
|
2782 insert-register
|
|
2783 just-one-space
|
|
2784 kill-word
|
|
2785 kill-line
|
|
2786 kill-region
|
|
2787 kill-ring-save
|
|
2788 kill-sentence
|
|
2789 mark-paragraph
|
|
2790 mark-whole-buffer
|
|
2791 newline
|
|
2792 newline-and-indent
|
|
2793 next-line
|
|
2794 open-line
|
|
2795 previous-line
|
|
2796 scroll-down
|
|
2797 scroll-up
|
|
2798 set-fill-prefix
|
|
2799 transpose-chars
|
|
2800 transpose-lines
|
|
2801 transpose-paragraphs
|
|
2802 transpose-sentences
|
|
2803 transpose-words
|
|
2804 yank
|
|
2805 yank-pop
|
|
2806 zap-to-char
|
|
2807 )))
|
|
2808
|
|
2809
|
|
2810 ;; kotl-mode keys
|
|
2811 (define-key kotl-mode-map "\C-c@" 'kotl-mode:mail-tree)
|
|
2812 (define-key kotl-mode-map "\C-c+" 'kotl-mode:append-cell)
|
|
2813 (define-key kotl-mode-map "\C-c," 'kotl-mode:beginning-of-cell)
|
|
2814 (define-key kotl-mode-map "\C-c." 'kotl-mode:end-of-cell)
|
|
2815 (define-key kotl-mode-map "\C-c<" 'kotl-mode:first-sibling)
|
|
2816 (define-key kotl-mode-map "\C-c>" 'kotl-mode:last-sibling)
|
|
2817 (define-key kotl-mode-map "\C-c^" 'kotl-mode:beginning-of-tree)
|
|
2818 (define-key kotl-mode-map "\C-c$" 'kotl-mode:end-of-tree)
|
|
2819 (define-key kotl-mode-map "\C-ca" 'kotl-mode:add-child)
|
|
2820 (define-key kotl-mode-map "\C-c\C-a" 'kotl-mode:show-all)
|
|
2821 (define-key kotl-mode-map "\C-cb" 'kvspec:toggle-blank-lines)
|
|
2822 (define-key kotl-mode-map "\C-c\C-b" 'kotl-mode:backward-cell)
|
|
2823 (define-key kotl-mode-map "\C-cc" 'kotl-mode:copy-after)
|
|
2824 (define-key kotl-mode-map "\C-c\C-c" 'kotl-mode:copy-before)
|
|
2825 (define-key kotl-mode-map "\C-c\M-c" 'kotl-mode:copy-to-buffer)
|
|
2826 (define-key kotl-mode-map "\C-cd" 'kotl-mode:down-level)
|
|
2827 (define-key kotl-mode-map "\C-c\C-d" 'kotl-mode:down-level)
|
|
2828 (define-key kotl-mode-map "\C-ce" 'kotl-mode:exchange-cells)
|
|
2829 (define-key kotl-mode-map "\C-c\C-f" 'kotl-mode:forward-cell)
|
|
2830 (define-key kotl-mode-map "\C-cg" 'kotl-mode:goto-cell)
|
|
2831 (define-key kotl-mode-map "\C-ch" 'kotl-mode:cell-help)
|
|
2832 (define-key kotl-mode-map "\C-c\C-h" 'kotl-mode:hide-tree)
|
|
2833 (define-key kotl-mode-map "\M-\C-h" 'kotl-mode:hide-subtree)
|
|
2834 ;; Override this global binding for set-selective-display with a similar
|
|
2835 ;; function appropriate for kotl-mode.
|
|
2836 (define-key kotl-mode-map "\C-x$" 'kotl-mode:hide-sublevels)
|
|
2837 (define-key kotl-mode-map "\C-i" 'kotl-mode:demote-tree)
|
|
2838 (define-key kotl-mode-map "\M-\C-i" 'kotl-mode:promote-tree)
|
|
2839 (define-key kotl-mode-map "\C-j" 'kotl-mode:add-cell)
|
|
2840 (define-key kotl-mode-map "\M-j" 'kotl-mode:fill-paragraph)
|
|
2841 (define-key kotl-mode-map "\C-c\M-j" 'kotl-mode:fill-cell)
|
|
2842 (define-key kotl-mode-map "\M-\C-j" 'kotl-mode:fill-tree)
|
|
2843 (define-key kotl-mode-map "\C-c\C-k" 'kotl-mode:kill-tree)
|
|
2844 (define-key kotl-mode-map "\C-ck" 'kotl-mode:kill-contents)
|
|
2845 (define-key kotl-mode-map "\C-c\C-i" 'kotl-mode:set-cell-attribute)
|
|
2846 (define-key kotl-mode-map "\C-cl" 'klink:create)
|
|
2847 (define-key kotl-mode-map "\C-c\C-l" 'kview:set-label-type)
|
|
2848 (define-key kotl-mode-map "\C-c\M-l" 'kview:set-label-separator)
|
|
2849 (define-key kotl-mode-map "\C-m" 'kotl-mode:newline)
|
|
2850 (define-key kotl-mode-map "\C-cm" 'kotl-mode:move-after)
|
|
2851 (define-key kotl-mode-map "\C-c\C-m" 'kotl-mode:move-before)
|
|
2852 (define-key kotl-mode-map "\C-c\C-n" 'kotl-mode:next-cell)
|
|
2853 (define-key kotl-mode-map "\C-c\C-o" 'kotl-mode:overview)
|
|
2854 (define-key kotl-mode-map "\C-c\C-p" 'kotl-mode:previous-cell)
|
|
2855 (define-key kotl-mode-map "\C-cp" 'kotl-mode:add-parent)
|
|
2856 (if (memq (global-key-binding "\M-q") '(fill-paragraph
|
|
2857 fill-paragraph-or-region))
|
|
2858 (progn
|
|
2859 (define-key kotl-mode-map "\C-c\M-q" 'kotl-mode:fill-cell)
|
|
2860 (define-key kotl-mode-map "\M-\C-q" 'kotl-mode:fill-tree)))
|
|
2861 (define-key kotl-mode-map "\C-cs" 'kotl-mode:split-cell)
|
|
2862 (define-key kotl-mode-map "\C-c\C-s" 'kotl-mode:show-tree)
|
|
2863 (define-key kotl-mode-map "\C-c\C-\\" 'kotl-mode:show-tree)
|
|
2864 (define-key kotl-mode-map "\M-s" 'kotl-mode:center-line)
|
|
2865 (define-key kotl-mode-map "\M-S" 'kotl-mode:center-paragraph)
|
|
2866 (define-key kotl-mode-map "\C-ct" 'kotl-mode:transpose-cells)
|
|
2867 (define-key kotl-mode-map "\C-c\C-t" 'kotl-mode:top-cells)
|
|
2868 (define-key kotl-mode-map "\C-cu" 'kotl-mode:up-level)
|
|
2869 (define-key kotl-mode-map "\C-c\C-u" 'kotl-mode:up-level)
|
|
2870 (define-key kotl-mode-map "\C-c\C-v" 'kvspec:activate)
|
|
2871 (define-key kotl-mode-map "\C-x\C-w" 'kfile:write))
|
|
2872
|
|
2873 (provide 'kotl-mode)
|