0
|
1 ;;!emacs
|
|
2 ;;
|
|
3 ;; FILE: hactypes.el
|
|
4 ;; SUMMARY: Default action types for Hyperbole.
|
|
5 ;; USAGE: GNU Emacs Lisp Library
|
|
6 ;; KEYWORDS: extensions, hypermedia
|
|
7 ;;
|
|
8 ;; AUTHOR: Bob Weiner
|
|
9 ;; ORG: Brown U.
|
|
10 ;;
|
|
11 ;; ORIG-DATE: 23-Sep-91 at 20:34:36
|
|
12 ;; LAST-MOD: 28-Oct-95 at 02:33:45 by Bob Weiner
|
|
13 ;;; ************************************************************************
|
|
14 ;;; Other required Elisp libraries
|
|
15 ;;; ************************************************************************
|
|
16
|
|
17 (mapcar 'require '(hbut hpath hargs hact hmail))
|
|
18
|
|
19 ;;; ************************************************************************
|
|
20 ;;; Standard Hyperbole action types
|
|
21 ;;; ************************************************************************
|
|
22
|
|
23 (defact annot-bib (key)
|
|
24 "Follows internal ref KEY within an annotated bibliography, delimiters=[]."
|
|
25 (interactive "sReference key (no []): ")
|
|
26 (let ((opoint (point)))
|
|
27 (goto-char 1)
|
|
28 (if (re-search-forward
|
|
29 (concat "^[*]*[ \t]*\\\[" (ebut:key-to-label key) "\\\]") nil t)
|
|
30 (progn
|
|
31 (beginning-of-line)
|
|
32 (delete-other-windows)
|
|
33 (split-window-vertically nil)
|
|
34 (goto-char opoint))
|
|
35 (beep))
|
|
36 (goto-char opoint)))
|
|
37
|
|
38 (defact completion ()
|
|
39 "Inserts completion at point into minibuffer or other window.
|
|
40 Unless at end of buffer or if completion has already been inserted, then
|
|
41 deletes completions window."
|
|
42 (interactive)
|
|
43 (if (eobp)
|
|
44 (progn (bury-buffer nil)
|
|
45 (delete-window))
|
|
46 (hargs:completion)))
|
|
47
|
|
48 (defact eval-elisp (lisp-expr)
|
|
49 "Evaluates a Lisp expression LISP-EXPR."
|
|
50 (interactive "xLisp to eval: ")
|
|
51 (eval lisp-expr))
|
|
52
|
|
53 (defact exec-kbd-macro (kbd-macro &optional repeat-count)
|
|
54 "Executes KBD-MACRO REPEAT-COUNT times.
|
|
55 KBD-MACRO may be a string of editor command characters, a function symbol or
|
|
56 nil to use the last defined keyboard macro.
|
|
57 Optional REPEAT-COUNT nil means execute once, zero means repeat until
|
|
58 error."
|
|
59 (interactive
|
|
60 (let (macro repeat)
|
|
61 (setq macro (intern-soft
|
|
62 (hargs:read-match
|
|
63 "Unquoted macro name or nil for last one defined: "
|
|
64 obarray (function
|
|
65 (lambda (sym)
|
|
66 (and (fboundp sym)
|
|
67 (stringp (hypb:indirect-function sym)))))
|
|
68 nil "nil" 'symbol)))
|
|
69 (cond ((fboundp macro))
|
|
70 ((null last-kbd-macro)
|
|
71 (hypb:error
|
|
72 "(exec-kbd-macro): Define a keyboard macro first."))
|
|
73 (t (fset 'zzz last-kbd-macro)
|
|
74 (setq macro 'zzz)))
|
|
75 (save-excursion
|
|
76 (let ((standard-output (get-buffer-create "*macro-def*")))
|
|
77 (unwind-protect
|
|
78 (progn (set-buffer standard-output)
|
|
79 (setq buffer-read-only nil)
|
|
80 (erase-buffer)
|
|
81 (insert-kbd-macro macro)
|
|
82 (goto-char (point-min))
|
|
83 (setq macro (car (cdr (cdr (read (current-buffer)))))))
|
|
84 (kill-buffer standard-output))))
|
|
85 (fmakunbound 'zzz)
|
|
86 (setq repeat (hargs:read "Repeat count: "
|
|
87 (function
|
|
88 (lambda (repeat)
|
|
89 (or (null repeat)
|
|
90 (and (integerp repeat) (>= repeat 0)))))
|
|
91 1))
|
|
92 (list macro repeat)))
|
|
93 (if (interactive-p)
|
|
94 nil
|
|
95 (or (and kbd-macro (or (stringp kbd-macro)
|
|
96 (and (symbolp kbd-macro) (fboundp kbd-macro))))
|
|
97 (hypb:error "(exec-kbd-macro): Bad macro: %s" kbd-macro))
|
|
98 (or (null repeat-count) (and (integerp repeat-count) (<= 0 repeat-count))
|
|
99 (hypb:error "(exec-kbd-macro): Bad repeat count: %s" repeat-count)))
|
|
100 (execute-kbd-macro kbd-macro repeat-count))
|
|
101
|
|
102 ;;; Support next two actypes on systems which use the 'comint' shell package
|
|
103 ;;; rather than Emacs V18 shell.el.
|
|
104 ;;;
|
|
105 (if (or hyperb:lemacs-p hyperb:emacs19-p)
|
|
106 (require 'comint))
|
|
107 (and (fboundp 'comint-send-input) (not (fboundp 'shell-send-input))
|
|
108 (fset 'shell-send-input 'comint-send-input))
|
|
109 (and (fboundp 'comint-kill-output) (not (fboundp 'kill-output-from-shell))
|
|
110 (fset 'kill-output-from-shell 'comint-kill-output))
|
|
111 (and (fboundp 'comint-show-output) (not (fboundp 'show-output-from-shell))
|
|
112 (fset 'show-output-from-shell 'comint-show-output))
|
|
113
|
|
114 (defact exec-shell-cmd (shell-cmd &optional internal-cmd kill-prev)
|
|
115 "Executes a SHELL-CMD string asynchronously.
|
|
116 Optional non-nil second argument INTERNAL-CMD means do not display the shell
|
|
117 command line executed. Optional non-nil third argument KILL-PREV means
|
|
118 kill last output to shell buffer before executing SHELL-CMD."
|
|
119 (interactive
|
|
120 (let ((default (car defaults))
|
|
121 (default1 (nth 1 defaults))
|
|
122 (default2 (nth 2 defaults)))
|
|
123 (list (hargs:read "Shell cmd: "
|
|
124 (function
|
|
125 (lambda (cmd) (not (string= cmd ""))))
|
|
126 default "Enter a shell command." 'string)
|
|
127 (y-or-n-p (format "Omit cmd from output (default = %s): "
|
|
128 default1))
|
|
129 (y-or-n-p (format "Kill prior cmd's output (default = %s): "
|
|
130 default2)))))
|
|
131 (let ((buf-name "*Hypb Shell*")
|
|
132 (owind (selected-window)))
|
|
133 (unwind-protect
|
|
134 (progn
|
|
135 (if (not (hpath:ange-ftp-p default-directory))
|
|
136 (setq shell-cmd
|
|
137 (concat "cd " default-directory "; " shell-cmd)))
|
|
138 (if (not (get-buffer buf-name))
|
|
139 (save-excursion
|
|
140 ;; Ensure shell displays in other window unless in the
|
|
141 ;; OO-Browser, then use selected window.
|
|
142 (if (br-in-browser)
|
|
143 nil
|
|
144 (if (= (length (hypb:window-list)) 1)
|
|
145 (split-window-vertically))
|
|
146 (other-window 1))
|
|
147 (if (eq (minibuffer-window) (selected-window))
|
|
148 (other-window 1))
|
|
149 (shell) (rename-buffer buf-name)
|
|
150 (setq last-input-start (point-marker)
|
|
151 last-input-end (point-marker))
|
|
152 (if (fboundp 'comint-kill-output)
|
|
153 (setq comint-last-input-start last-input-start
|
|
154 comint-last-input-end last-input-end)
|
|
155 )))
|
|
156 (or (equal (buffer-name (current-buffer)) buf-name)
|
|
157 (if (br-in-browser) (switch-to-buffer buf-name)
|
|
158 (pop-to-buffer buf-name)))
|
|
159 (goto-char (point-max))
|
|
160 (and kill-prev last-input-end
|
|
161 (not (equal last-input-start last-input-end))
|
|
162 (kill-output-from-shell))
|
|
163 (insert shell-cmd)
|
|
164 (shell-send-input)
|
|
165 (show-output-from-shell)
|
|
166 (or internal-cmd (scroll-down 1)))
|
|
167 (select-window owind))))
|
|
168
|
|
169 (defact exec-window-cmd (shell-cmd)
|
|
170 "Executes an external window-based SHELL-CMD string asynchronously."
|
|
171 (interactive
|
|
172 (let ((default (car defaults)))
|
|
173 (list (hargs:read "Shell cmd: "
|
|
174 (function
|
|
175 (lambda (cmd) (not (string= cmd ""))))
|
|
176 default "Enter a shell command." 'string))))
|
|
177 (let ((buf-name "*Hypb Shell*")
|
|
178 (cmd (if (hpath:ange-ftp-p default-directory)
|
|
179 (concat "(" shell-cmd ") &")
|
|
180 (concat "(cd " default-directory "; " shell-cmd ") &")))
|
|
181 (msg (format "Executing: %s" shell-cmd))
|
|
182 (shell-buf))
|
|
183 (message msg)
|
|
184 (save-excursion
|
|
185 (save-window-excursion
|
|
186 (if (not (get-buffer buf-name))
|
|
187 (progn (save-excursion
|
|
188 (save-window-excursion
|
|
189 (shell)
|
|
190 (setq shell-buf (current-buffer))))
|
|
191 (message msg)
|
|
192 ;; Wait for shell to startup before sending it input.
|
|
193 (sit-for 1)
|
|
194 (set-buffer shell-buf)
|
|
195 (rename-buffer buf-name)
|
|
196 (setq last-input-start (point-marker)
|
|
197 last-input-end (point-marker))
|
|
198 (if (fboundp 'comint-kill-output)
|
|
199 (setq comint-last-input-start last-input-start
|
|
200 comint-last-input-end last-input-end)
|
|
201 )))
|
|
202 (or (equal (buffer-name (current-buffer)) buf-name)
|
|
203 (set-buffer buf-name))
|
|
204 (goto-char (point-max))
|
|
205 (insert cmd)
|
|
206 (shell-send-input)))
|
|
207 (message msg)))
|
|
208
|
|
209 (defact hyp-config (&optional out-buf)
|
|
210 "Inserts Hyperbole configuration info at end of optional OUT-BUF or current."
|
|
211 (hypb:configuration out-buf))
|
|
212
|
|
213 (defact hyp-request (&optional out-buf)
|
|
214 "Inserts Hyperbole mail list request help into optional OUT-BUF or current."
|
|
215 (save-excursion
|
|
216 (and out-buf (set-buffer out-buf))
|
|
217 (goto-char (point-max))
|
|
218 (delete-blank-lines) (delete-blank-lines)
|
|
219 (insert "Use one of the following formats on your subject line:\n
|
|
220 Subject: Subscribe <joe@any.com> (Joe Williams).
|
|
221 Subject: Unsubscribe <joe@any.com>.
|
|
222
|
|
223 To change your address, first unsubscribe by sending an unsubscribe
|
|
224 request from your old address. Then subscribe by sending a subscribe
|
|
225 request from your new address.
|
|
226
|
|
227 Possible mail lists are:
|
|
228 hyperbole - discussion of Hyperbole
|
|
229 hyperbole-announce - Hyperbole announcements only\n")))
|
|
230
|
|
231 (defact hyp-source (buf-str-or-file)
|
|
232 "Displays a buffer or file from a line beginning with 'hbut:source-prefix'."
|
|
233 (interactive
|
|
234 (list (prin1-to-string (get-buffer-create
|
|
235 (read-buffer "Buffer to link to: ")))))
|
|
236 (if (stringp buf-str-or-file)
|
|
237 (cond ((string-match "\\`#<buffer \"?\\([^ \n\"]+\\)\"?>" buf-str-or-file)
|
|
238 (pop-to-buffer (substring buf-str-or-file
|
|
239 (match-beginning 1) (match-end 1))))
|
|
240 (t (hpath:find-other-window buf-str-or-file)))
|
|
241 (hypb:error "(hyp-source): Non-string argument: %s" buf-str-or-file)))
|
|
242
|
|
243 (defact link-to-buffer-tmp (buffer)
|
|
244 "Displays a BUFFER in another window.
|
|
245 Link is generally only good for current Emacs session.
|
|
246 Use 'link-to-file' instead for a permanent link."
|
|
247 (interactive "bBuffer to link to: ")
|
|
248 (if (or (stringp buffer) (bufferp buffer))
|
|
249 (pop-to-buffer buffer)
|
|
250 (hypb:error "(link-to-buffer-tmp): Not a current buffer: %s" buffer)))
|
|
251
|
|
252 (defact link-to-directory (directory)
|
|
253 "Displays a DIRECTORY in Dired mode in another window."
|
|
254 (interactive "DDirectory to link to: ")
|
|
255 (hpath:find-other-window directory))
|
|
256
|
|
257 (defact link-to-ebut (key-file key)
|
|
258 "Performs action given by another button, specified by KEY-FILE and KEY."
|
|
259 (interactive
|
|
260 (let (but-file but-lbl)
|
|
261 (while (cond ((setq but-file
|
|
262 (read-file-name
|
|
263 "File of button to link to: " nil nil t))
|
|
264 (if (string= but-file "")
|
|
265 (progn (beep) t)))
|
|
266 ((not (file-readable-p but-file))
|
|
267 (message "(link-to-ebut): You cannot read '%s'."
|
|
268 but-file)
|
|
269 (beep) (sit-for 3))))
|
|
270 (list but-file
|
|
271 (progn
|
|
272 (find-file-noselect but-file)
|
|
273 (while (string= "" (setq but-lbl
|
|
274 (hargs:read-match
|
|
275 "Button to link to: "
|
|
276 (ebut:alist but-file)
|
|
277 nil nil nil 'ebut)))
|
|
278 (beep))
|
|
279 (ebut:label-to-key but-lbl)))))
|
|
280 (or (interactive-p)
|
|
281 (setq key-file (hpath:validate (hpath:substitute-value key-file))))
|
|
282 (let ((but (ebut:get key (find-file-noselect key-file))))
|
|
283 (if but (hbut:act but)
|
|
284 (hypb:error "(link-to-ebut): No button '%s' in '%s'." (ebut:key-to-label key)
|
|
285 key-file))))
|
|
286
|
|
287 (defact link-to-elisp-doc (func-symbol)
|
|
288 "Displays documentation for FUNC-SYMBOL."
|
|
289 (interactive "aFunction to display doc for: ")
|
|
290 (cond ((not (symbolp func-symbol))
|
|
291 (hypb:error "(link-to-elisp-doc): '%s' not a symbol."
|
|
292 func-symbol))
|
|
293 ((not (fboundp func-symbol))
|
|
294 (hypb:error "(link-to-elisp-doc): '%s' not defined as a function."
|
|
295 func-symbol))
|
|
296 ((not (documentation func-symbol))
|
|
297 (hypb:error "(link-to-elisp-doc): '%s' has no documentation."
|
|
298 func-symbol))
|
|
299 ((describe-function func-symbol))))
|
|
300
|
|
301 (defact link-to-file (path &optional point)
|
|
302 "Displays a PATH in another window scrolled to optional POINT.
|
|
303 With POINT, buffer is displayed with POINT at the top of the window."
|
|
304 (interactive
|
|
305 (let ((prev-reading-p hargs:reading-p))
|
|
306 (unwind-protect
|
|
307 (let* ((default (car defaults))
|
|
308 (hargs:reading-p 'file)
|
|
309 (path (read-file-name "Path to link to: " default default))
|
|
310 (path-buf (get-file-buffer path)))
|
|
311 (if path-buf
|
|
312 (save-excursion
|
|
313 (set-buffer path-buf)
|
|
314 (setq hargs:reading-p 'character)
|
|
315 (if (y-or-n-p
|
|
316 (format "y = Display at present position (line %d); n = no position: "
|
|
317 (count-lines 1 (point))))
|
|
318 (list path (point))
|
|
319 (list path)))
|
|
320 (list path)))
|
|
321 (setq hargs:reading-p prev-reading-p))))
|
|
322 (and (hpath:find-other-window path)
|
|
323 (integerp point)
|
|
324 (progn (goto-char (min (point-max) point))
|
|
325 (recenter 0))))
|
|
326
|
|
327 (defact link-to-file-line (path line-num)
|
|
328 "Displays a PATH in another window scrolled to LINE-NUM."
|
|
329 (interactive "fPath to link to: \nnDisplay at line number: ")
|
|
330 (and (setq path (smart-tags-file-path path))
|
|
331 (hpath:find-other-window path)
|
|
332 (integerp line-num)
|
|
333 (progn (widen)
|
|
334 (goto-line line-num))))
|
|
335
|
|
336 (defact link-to-Info-node (node)
|
|
337 "Displays an Info NODE in another window.
|
|
338 NODE must be a string of the form `(file)nodename'."
|
|
339 (interactive "+IInfo (file)nodename to link to: ")
|
|
340 (require 'info)
|
|
341 (if (and (stringp node) (string-match "^(\\([^\)]+\\))\\(.*\\)" node))
|
|
342 (let ((nodename (substring node (match-beginning 2) (match-end 2)))
|
|
343 (file (hpath:absolute-to
|
|
344 (substring node (match-beginning 1) (match-end 1))
|
|
345 (if (boundp 'Info-directory-list)
|
|
346 Info-directory-list
|
|
347 Info-directory))))
|
|
348 (if (and file (setq file (hpath:substitute-value file)))
|
|
349 (let ((wind (get-buffer-window "*info*")))
|
|
350 (if wind (select-window wind)
|
|
351 (pop-to-buffer (other-buffer)))
|
|
352 (info) (Info-goto-node (concat "(" file ")" nodename)))
|
|
353 (hypb:error "(link-to-Info-node): Bad node spec: '%s'" node)))))
|
|
354
|
|
355 (defact link-to-kcell (file cell-ref)
|
|
356 "Displays FILE with kcell given by CELL-REF at the top of the window.
|
|
357 See documentation for 'kcell:ref-to-id' for valid cell-ref formats.
|
|
358
|
|
359 If FILE is nil, the current buffer is used.
|
|
360 If CELL-REF is nil, the first cell in the view is shown."
|
|
361 (interactive "fKotl file to link to: \n+KKcell to link to: ")
|
|
362 (require 'kfile)
|
|
363 (cond ((and (stringp cell-ref) (= ?| (aref cell-ref 0)))
|
|
364 ;; Activate view spec in current window.
|
|
365 (kotl-mode:goto-cell cell-ref))
|
|
366 ((if file
|
|
367 (hpath:find-other-window file)
|
|
368 (pop-to-buffer (current-buffer) t))
|
|
369 (if cell-ref
|
|
370 (kotl-mode:goto-cell cell-ref)
|
|
371 (kotl-mode:beginning-of-buffer))
|
|
372 (recenter 0))))
|
|
373
|
|
374 (defact link-to-mail (mail-msg-id &optional mail-file)
|
|
375 "Displays mail msg with MAIL-MSG-ID from optional MAIL-FILE in other window.
|
|
376 See documentation for the variable 'hmail:init-function' for information on
|
|
377 how to specify a mail reader to use."
|
|
378 (interactive "+MMail Msg: ")
|
|
379 (if (not (fboundp 'rmail:msg-to-p))
|
|
380 (hypb:error "(link-to-mail): Invoke mail reader before trying to follow a mail link.")
|
|
381 (if (and (listp mail-msg-id) (null mail-file))
|
|
382 (setq mail-file (car (cdr mail-msg-id))
|
|
383 mail-msg-id (car mail-msg-id)))
|
|
384 (let ((wind (selected-window))
|
|
385 (wconfig (current-window-configuration)))
|
|
386 (other-window 1)
|
|
387 (if (eq wind (selected-window))
|
|
388 (progn (split-window-vertically nil) (other-window 1)))
|
|
389 ;; Initialize user-specified mail reader if need be.
|
|
390 (if (and (symbolp hmail:init-function)
|
|
391 (fboundp hmail:init-function)
|
|
392 (listp (symbol-function hmail:init-function))
|
|
393 (eq 'autoload (car (symbol-function hmail:init-function))))
|
|
394 (funcall hmail:init-function))
|
|
395 (if (rmail:msg-to-p mail-msg-id mail-file)
|
|
396 nil
|
|
397 ;; Couldn't find message, restore old window config, report error
|
|
398 (set-window-configuration wconfig)
|
|
399 (hypb:error "(link-to-mail): No msg '%s' in file \"%s\"."
|
|
400 mail-msg-id mail-file)))))
|
|
401
|
|
402 (defact link-to-regexp-match (regexp n source &optional buffer-p)
|
|
403 "Finds REGEXP's Nth occurrence in SOURCE and displays location at window top.
|
|
404 SOURCE is a pathname unless optional BUFFER-P is non-nil, then SOURCE must be
|
|
405 a buffer name or buffer.
|
|
406 Returns t if found, signals an error if not."
|
|
407 (interactive "sRegexp to match: \nnOccurrence number: \nfFile to search: ")
|
|
408 (let ((orig-src source))
|
|
409 (if buffer-p
|
|
410 (if (stringp source)
|
|
411 (setq source (get-buffer source)))
|
|
412 ;; Source is a pathname.
|
|
413 (if (not (stringp source))
|
|
414 (hypb:error
|
|
415 "(link-to-regexp-match): Source parameter is not a filename: '%s'"
|
|
416 orig-src)
|
|
417 (setq source (find-file-noselect (hpath:substitute-value source)))))
|
|
418 (if (not (bufferp source))
|
|
419 (hypb:error
|
|
420 "(link-to-regexp-match): Invalid source parameter: '%s'" orig-src)
|
|
421 (switch-to-buffer-other-window source)
|
|
422 (widen)
|
|
423 (goto-char (point-min))
|
|
424 (if (re-search-forward regexp nil t n)
|
|
425 (progn (beginning-of-line) (recenter 0) t)
|
|
426 (hypb:error
|
|
427 "(link-to-regexp-match): Pattern not found: '%s'" regexp)))))
|
|
428
|
|
429 (defact link-to-rfc (rfc-num)
|
|
430 "Retrieves and displays an Internet rfc given by RFC-NUM.
|
|
431 RFC-NUM may be a string or an integer. Requires ange-ftp or efs for
|
|
432 remote retrievals."
|
|
433 (interactive "nRFC number to retrieve: ")
|
|
434 (if (or (stringp rfc-num) (integerp rfc-num))
|
|
435 (hpath:find-other-window (hpath:rfc rfc-num))))
|
|
436
|
|
437 (defact link-to-string-match (string n source &optional buffer-p)
|
|
438 "Finds STRING's Nth occurrence in SOURCE and displays location at window top.
|
|
439 SOURCE is a pathname unless optional BUFFER-P is non-nil, then SOURCE must be
|
|
440 a buffer name or buffer.
|
|
441 Returns t if found, nil if not."
|
|
442 (interactive "sString to match: \nnOccurrence number: \nfFile to search: ")
|
|
443 (funcall (actype:action 'link-to-regexp-match)
|
|
444 (regexp-quote string) n source buffer-p))
|
|
445
|
|
446 (defact man-show (topic)
|
|
447 "Displays man page on TOPIC, which may be of the form <command>(<section>)."
|
|
448 (interactive "sManual topic: ")
|
|
449 (manual-entry topic))
|
|
450
|
|
451 (defact rfc-toc (&optional buf-name opoint)
|
|
452 "Computes and displays summary of an Internet rfc in BUF-NAME.
|
|
453 Assumes point has already been moved to start of region to summarize.
|
|
454 Optional OPOINT is point to return to in BUF-NAME after displaying summary."
|
|
455 (interactive)
|
|
456 (if buf-name
|
|
457 (cond ((get-buffer buf-name)
|
|
458 (switch-to-buffer buf-name))
|
|
459 ((let ((buf (get-file-buffer buf-name)))
|
|
460 (if buf
|
|
461 (progn (switch-to-buffer (setq buf-name buf))
|
|
462 t))))
|
|
463 (t (if opoint (goto-char opoint))
|
|
464 (hypb:error "(rfc-toc): Invalid buffer name: %s" buf-name))))
|
|
465 (let ((sect-regexp "^[ \t]*[1-9][0-9]*\\.[0-9.]*[ \t]+[^ \t\n]"))
|
|
466 (occur sect-regexp)
|
|
467 (set-buffer "*Occur*")
|
|
468 (rename-buffer (format "*%s toc*" buf-name))
|
|
469 (re-search-forward "^[ ]*[0-9]+:" nil t)
|
|
470 (beginning-of-line)
|
|
471 (delete-region (point-min) (point))
|
|
472 (insert "Contents of " (buffer-name occur-buffer) ":\n")
|
|
473 (set-buffer-modified-p nil)
|
|
474 (set-buffer buf-name)
|
|
475 (if opoint (goto-char opoint))))
|
|
476
|
|
477 (defact text-toc (section)
|
|
478 "Jumps to the text file SECTION referenced by a table of contents entry at point."
|
|
479 (interactive "sGo to section named: ")
|
|
480 (if (stringp section)
|
|
481 (progn
|
|
482 (actypes::link-to-regexp-match
|
|
483 (concat "^\\*+[ \t]*" (regexp-quote section))
|
|
484 1 (current-buffer) t)
|
|
485 (while (and (= (forward-line -1) 0)
|
|
486 (looking-at "[ \t]*[-=][-=]")))
|
|
487 (forward-line 1)
|
|
488 (recenter 0))))
|
|
489
|
|
490 (provide 'hactypes)
|