aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard M. Stallman1997-01-02 20:41:58 +0000
committerRichard M. Stallman1997-01-02 20:41:58 +0000
commite8dd2298ce335ae59f2852790b60b7393378e741 (patch)
tree4aa8c9e74d9766f77f2042984605646a133d4477
parente6a6d6979915d526e72d2590dbf70cd742acb134 (diff)
downloademacs-e8dd2298ce335ae59f2852790b60b7393378e741.tar.gz
emacs-e8dd2298ce335ae59f2852790b60b7393378e741.zip
(word-help-mode-alist, reset-word-help)
(word-help-switch-help-file): Added support for completion. (word-help-complete, word-help-complete-list) (word-help-complete-index, word-help-extract-matches) (word-help-make-complete): New functions/variables for completion. (word-help-mode-alist): Enhanced search regexps. (word-help-index-mapper): Defaults now to extracting the first word. (word-help-mode-alist, word-help-index-mapper) (word-help-main-index, word-help-main-obarray) (reset-word-help, set-help-file, word-help-process-indexes) (word-help-goto-index-node): Doc fixes. (word-help-goto-index-node): Requires passing the keyword. Uses this in the a new and enhanced magic indexing routine. (set-help-file, word-help): Handle `completion-ignore-case' better. (word-help-extract-index): `case-fold-search' better handled. (word-help): Magic guessing of relevant help file put in new function word-help-find-help-file. (word-help-guess-all): New subroutine. (word-help-guess): Use word-help-guess-all. May optionally copy only upto the cursor, instead of the entire keyword.
-rw-r--r--lisp/word-help.el507
1 files changed, 380 insertions, 127 deletions
diff --git a/lisp/word-help.el b/lisp/word-help.el
index f442aef1a6a..f535fd9073c 100644
--- a/lisp/word-help.el
+++ b/lisp/word-help.el
@@ -3,7 +3,7 @@
3;; Copyright (c) 1996 Free Software Foundation, Inc. 3;; Copyright (c) 1996 Free Software Foundation, Inc.
4 4
5;; Maintainer: Jens T. Berger Thielemann, <jensthi@ifi.uio.no> 5;; Maintainer: Jens T. Berger Thielemann, <jensthi@ifi.uio.no>
6;; Keywords: help, keyword, languages 6;; Keywords: help, keyword, languages, completion
7 7
8;; This file is part of GNU Emacs. 8;; This file is part of GNU Emacs.
9 9
@@ -25,7 +25,7 @@
25;;; Commentary: 25;;; Commentary:
26 26
27;; This package provides a rather general interface for doing keyword 27;; This package provides a rather general interface for doing keyword
28;; help in most languages. In short, it'll determine which Texinfo 28;; help in most languages. In short, it'll determine which TeXinfo
29;; file which is relevant for the current mode; cache the index and 29;; file which is relevant for the current mode; cache the index and
30;; use regexps to give you help on the keyword you're looking at. 30;; use regexps to give you help on the keyword you're looking at.
31 31
@@ -61,6 +61,16 @@
61;; to an index topic; press return to accept this. If not, you may use 61;; to an index topic; press return to accept this. If not, you may use
62;; tab-completion to find the topic you're interested in. 62;; tab-completion to find the topic you're interested in.
63 63
64;; `word-help' is also able to do symbol completion via the
65;; `word-help-complete' function. Bind this function to C-TAB by
66;; adding the following line to your .emacs file:
67;;
68;; (global-set-key [?\M-\t] 'word-help-complete)
69;;
70;; Note that some modes automatically override this key; you may
71;; therefore wish to either put the above statement in a hook or
72;; associate the function with an other key.
73
64;; Usually, `word-help' is able to determine the relevant Texinfo 74;; Usually, `word-help' is able to determine the relevant Texinfo
65;; file from looking at the buffer's `mode-name'; if not, you can use 75;; file from looking at the buffer's `mode-name'; if not, you can use
66;; the interactive function `set-help-file' to set this. 76;; the interactive function `set-help-file' to set this.
@@ -84,6 +94,10 @@
84;; `alist' making `set-help-file' able to initialize the necessary 94;; `alist' making `set-help-file' able to initialize the necessary
85;; variable. 95;; variable.
86 96
97;; NOTE: If you have to customize the regexps, it is *CRUCIAL* that
98;; none of your regexps match the empty string! Not adhering to this
99;; restriction will make `word-help' enter an infinite loop.
100
87;; Contacting the author 101;; Contacting the author
88;; ********************* 102;; *********************
89;; 103;;
@@ -114,7 +128,7 @@
114If nil, we will just switch to it.") 128If nil, we will just switch to it.")
115 129
116(defvar word-help-magic-index t 130(defvar word-help-magic-index t
117"*Non-nil means that the keyword will be searched for in the requested node. 131 "*Non-nil means that the keyword will be searched for in the requested node.
118This is done by determining whether the line the point is positioned 132This is done by determining whether the line the point is positioned
119on after using `Info-goto-node', actually contains the keyword. If 133on after using `Info-goto-node', actually contains the keyword. If
120not, we will search for the first occurence of the keyword. This may 134not, we will search for the first occurence of the keyword. This may
@@ -127,17 +141,26 @@ help when the info file isn't correctly indexed.")
127;;;------------------------- 141;;;-------------------------
128 142
129(defvar word-help-mode-alist 143(defvar word-help-mode-alist
130 '(("autoconf" 144 '(
145 ("autoconf"
131 (("autoconf" "Macro Index") ("m4" "Macro index")) 146 (("autoconf" "Macro Index") ("m4" "Macro index"))
132 (("AC_\\([A-Za-z0-9_]+\\)" 1) 147 (("AC_\\([A-Za-z0-9_]+\\)" 1)
133 ("[a-z]+"))) 148 ("[a-z]+"))
149 nil
150 nil
151 (("AC_\\([A-Za-z0-9_]+\\)" 1 nil (("^[A-Z_]+$")))
152 ("[a-z_][a-z_]*" 0 nil (("^[a-z_]+$")))))
134 153
135 ("Bison" 154 ("Bison"
136 (("bison" "Index") 155 (("bison" "Index")
137 ("libc" "Type Index" "Function Index" "Variable Index")) 156 ("libc" "Type Index" "Function Index" "Variable Index"))
138 (("%[A-Za-z]+") 157 (("%[A-Za-z]*")
139 ("[A-Za-z]+") 158 ("[A-Za-z_][A-Za-z0-9_]*"))
140 ("[A-Za-z_][A-Za-z0-9_]+"))) 159 nil
160 nil
161 (("%[A-Za-z]*" nil nil (("^%")))
162 ("[A-Za-z_][A-Za-z0-9_]*" nil nil (("[A-Za-z_][A-Za-z0-9_]*")))))
163
141 ("YACC" . "Bison") 164 ("YACC" . "Bison")
142 165
143 ("C" (("libc" "Type Index" "Function Index" "Variable Index"))) 166 ("C" (("libc" "Type Index" "Function Index" "Variable Index")))
@@ -145,39 +168,72 @@ help when the info file isn't correctly indexed.")
145 168
146 ("Emacs-Lisp" 169 ("Emacs-Lisp"
147 (("elisp" "Index")) 170 (("elisp" "Index"))
148 (("[^][ ()\n\t.\"'#]+"))) 171 (("[^][ ()\n\t.\"'#]+"))
172 nil
173 nil
174 lisp-complete-symbol)
149 175
150 ("LaTeX" 176 ("LaTeX"
151 (("latex" "Command Index")) 177 (("latex" "Command Index"))
152 (("\\\\\\(begin\\|end\\){\\([^}\n]+\\)}" 2 0) 178 (("\\\\\\(begin\\|end\\){\\([^}\n]+\\)}" 2 0)
153 ("\\\\[A-Za-z]+") 179 ("\\\\[A-Za-z]+")
154 ("\\\\[^A-Za-z]") 180 ("\\\\[^A-Za-z]")
155 ("[A-Za-z]+"))) 181 ("[A-Za-z]+"))
182 nil
183 nil
184 (("\\\\begin{\\([A-Za-z]*\\)" 1 "}" (("^[A-Za-z]+$")))
185 ("\\\\end{\\([A-Za-z]*\\)" 1 "}" (("^[A-Za-z]+$")))
186 ("\\\\renewcommand{\\(\\\\?[A-Za-z]*\\)" 1 "}" (("^\\\\[A-Za-z]+")))
187 ("\\\\renewcommand\\(\\\\?[A-Za-z]*\\)" 1 "" (("^\\\\[A-Za-z]+")))
188 ("\\\\renewenvironment{?\\([A-Za-z]*\\)" 1 "}"(("^[A-Za-z]+$")))
189 ("\\\\[A-Za-z]*" 0 "" (("^\\\\[A-Za-z]+")))))
190
191 ("latex" . "LaTeX")
156 192
157 ("Nroff" 193 ("Nroff"
158 (("groff" "Macro Index" "Register Index" "Request Index")) 194 (("groff" "Macro Index" "Register Index" "Request Index"))
159 ((".[^A-Za-z]") 195 (("\\.[^A-Za-z]")
160 (".[A-Za-z]+") 196 ("\\.[A-Za-z]+")
161 (".\\([A-Za-z]+\\)" 1))) 197 ("\\.\\([A-Za-z]+\\)" 1))
198 nil
199 nil
200 (("\\.[A-Za-z]*" nil nil (("^\\.[A-Za-z]+$")))
201 ("\\.\\([A-Za-z]*\\)" 1 nil (("^[A-Za-z]+$")))))
202
162 ("Groff" . "Nroff") 203 ("Groff" . "Nroff")
163 204
164 ("m4" (("m4" "Macro index"))) 205 ("m4"
206 (("m4" "Macro index"))
207 (("\\([mM]4_\\)?\\([A-Za-z_][A-Za-z_0-9]*\\)" 2))
208 nil
209 nil
210 (("[mM]4_\\([A-Za-z_]?[A-Za-z_0-9]*\\)" 1)
211 ("[A-Za-z_][A-Za-z_0-9]*")))
165 212
166 ("Makefile" 213 ("Makefile"
167 (("make" "Name Index" "Concept Index")) 214 (("make" "Name Index"))
168 (("\\.[A-Za-z]+") 215 (("\\.[A-Za-z]+") ;; .SUFFIXES
169 ("\\$[^()]") 216 ("\\$[^()]") ;; $@
170 ("\\$([^()= \t]+)") 217 ("\\$([^A-Za-z].)") ;; $(<@)
171 ("[A-Za-z]+"))) 218 ("\\$[\(\{]\\([a-zA-Z+]\\)" 1) ;; $(wildcard)
219 ("[A-Za-z]+")) ;; foreach
220 nil
221 nil
222 (("\\.[A-Za-z]*" nil ":" (("^\\.[A-Za-z]+$")))
223 ("\\$(\\([A-Z]*\\)" 1 ")" (("^[A-Z]")))
224 ("[a-z]+" nil nil (("^[a-z]+$")))))
172 225
173 ("Perl" 226 ("Perl"
174 (("perl" "Variable Index" "Function Index")) 227 (("perl" "Variable Index" "Function Index"))
175 (("\\$[^A-Za-z^]") 228 (("\\$[^A-Za-z^]") ;; $@
176 ("\\$\\^[A-Za-z]?") 229 ("\\$\\^[A-Za-z]?") ;; $^D
177 ("\\$[A-Za-z][A-Za-z_0-9]+") 230 ("\\$[A-Za-z][A-Za-z_0-9]+") ;; $foobar
178 ("[A-Za-z_][A-Za-z_0-9]+")) 231 ("[A-Za-z_][A-Za-z_0-9]+")) ;; dbmopen
179 nil 232 nil
180 (("^\\([^ \t\n]+\\)" 1))) 233 nil
234 (("\\$[A-Za-z]*" nil nil (("^\\$[A-Za-z]+$"))) ;; $variable
235 ("[A-Za-z_][A-Za-z_0-9]*" nil nil
236 (("^[A-Za-z_][A-Za-z_0-9]*$"))))) ;; function
181 237
182 ("Simula" (("simula" "Index")) nil t) 238 ("Simula" (("simula" "Index")) nil t)
183 ("Ifi Simula" . "Simula") 239 ("Ifi Simula" . "Simula")
@@ -185,7 +241,10 @@ help when the info file isn't correctly indexed.")
185 241
186 ("Texinfo" 242 ("Texinfo"
187 (("texinfo" "Command and Variable Index")) 243 (("texinfo" "Command and Variable Index"))
188 (("@\\([A-Za-z]+\\)" 1))) 244 (("@\\([A-Za-z]+\\)" 1))
245 nil
246 nil
247 (("@\\([A-Za-z]*\\)" 1)))
189 248
190 ) 249 )
191 "Assoc list between `mode-name' and Texinfo files. 250 "Assoc list between `mode-name' and Texinfo files.
@@ -193,7 +252,8 @@ The variable should be initialized with a list of elements with the
193following form: 252following form:
194 253
195\(mode-name (word-help-info-files) (word-help-keyword-regexps) 254\(mode-name (word-help-info-files) (word-help-keyword-regexps)
196 word-help-ignore-case word-help-index-mapper) 255 word-help-ignore-case word-help-index-mapper
256 word-help-complete-list)
197 257
198where `word-help-info-files', `word-help-keyword-regexps' and so 258where `word-help-info-files', `word-help-keyword-regexps' and so
199forth of course are the values which should be put in these variables 259forth of course are the values which should be put in these variables
@@ -235,7 +295,7 @@ defining recursive aliases.")
235(make-variable-buffer-local 'word-help-ignore-case) 295(make-variable-buffer-local 'word-help-ignore-case)
236 296
237(defvar word-help-info-files nil 297(defvar word-help-info-files nil
238"List of infofiles with respective nodes for the current mode. 298 "List of info files with respective nodes, for the current mode.
239 299
240This should be a list of the following form: 300This should be a list of the following form:
241 301
@@ -305,11 +365,43 @@ Perl has index entries of the following form:
305We will thus try to extract the first word in the index entry - 365We will thus try to extract the first word in the index entry -
306\"abs\" from \"abs VALUE\", etc. This is done by the following entry: 366\"abs\" from \"abs VALUE\", etc. This is done by the following entry:
307 367
308\((\"^\\\\([^ \\t\\n]+\\\\)\" 1))") 368\((\"^\\\\([^ \\t\\n]+\\\\)\" 1))
369
370This value is btw. the default one, and works with most Texinfo files")
309(make-variable-buffer-local 'word-help-index-mapper) 371(make-variable-buffer-local 'word-help-index-mapper)
372(set-default 'word-help-index-mapper '(("^\\([^ \t\n]+\\)" 1)))
373
374
375(defvar word-help-complete-list nil
376 "Regexps or function to use for completion of symbols.
377The list should have the following format:
378
379 ((REGEXP SUBMATCH TEXT-APPEND (RE-FILTER-1 REG-FILTER-2 ...)
380 : : : : :
381 (REGEXP SUBMATCH TEXT-APPEND (RE-FILTER-1 REG-FILTER-2 ...))
382
383The two first entries are similar to `word-help-keyword-regexps',
384REGEXP is a regular expression which should match any relevant
385expression, and where SUBMATCH should be used for look up. By
386specifying non-nil REGEXP-FILTERs, we'll only include entries in the
387index which matches the regexp specified.
388
389If the contents of this variable is a symbol of a function, this
390function will be called instead. This is useful for modes providing
391a more intelligent function (like `lisp-complete-symbol' in Emacs Lisp mode).
392
393If you would like to use another function instead, you may.
394
395Non-nil TEXT-APPEND means that this text will be inserted after the
396completion, if we manage to do make a completion.")
397(make-variable-buffer-local 'word-help-complete-list)
398(set-default 'word-help-complete-list '(("[A-Za-z_][A-Za-z_0-9]*")))
399
400;;; Work variables
401
310 402
311(defvar word-help-main-index nil 403(defvar word-help-main-index nil
312"List of all index entries. 404 "List of all index entries.
313 405
314See `word-help-process-indexes' for structure formatting. 406See `word-help-process-indexes' for structure formatting.
315 407
@@ -317,8 +409,14 @@ Minor note: This variable is a list if it is initialized, t if
317initializing failed and nil if uninitialized.") 409initializing failed and nil if uninitialized.")
318(make-variable-buffer-local 'word-help-main-index) 410(make-variable-buffer-local 'word-help-main-index)
319 411
412(defvar word-help-complete-index nil
413 "List of regexps for completion, with matching index entries.
414Value is nil if uninitialized, t if initialized but not accessible,
415a list if we're feeling ok.")
416(make-variable-buffer-local 'word-help-complete-index)
417
320(defvar word-help-main-obarray nil 418(defvar word-help-main-obarray nil
321"Global work variable for `word-help' system. 419 "Global work variable for `word-help' system.
322Do Not mess with this!") 420Do Not mess with this!")
323 421
324(defvar word-help-history nil 422(defvar word-help-history nil
@@ -336,6 +434,9 @@ This means that `word-help-mode-index' can be init'ed faster.")
336 "Which mode the help system is bound to for the current mode.") 434 "Which mode the help system is bound to for the current mode.")
337(make-variable-buffer-local 'word-help-help-mode) 435(make-variable-buffer-local 'word-help-help-mode)
338 436
437;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
438;;;;;;;;;;;;;;;;;;;;;;;;;;; User Functions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
439;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
339 440
340;;; Debugging 441;;; Debugging
341 442
@@ -346,14 +447,16 @@ You should only need this when installing new info files, and/or
346adding more Texinfo files to the `word-help' system." 447adding more Texinfo files to the `word-help' system."
347 (interactive) 448 (interactive)
348 (setq word-help-index-alist nil 449 (setq word-help-index-alist nil
349 word-help-main-index nil)) 450 word-help-main-index nil
451 word-help-info-files nil
452 word-help-complete-index nil))
350 453
351 454
352;;; Changing help file 455;;; Changing help file
353 456
354;;;###autoload 457;;;###autoload
355(defun set-help-file () 458(defun set-help-file ()
356 "Change which set of Texinfo files used for word help. 459 "Change which set of Texinfo files used for word-help.
357 460
358`word-help' maintains a list over which Texinfo files which are 461`word-help' maintains a list over which Texinfo files which are
359relevant for each programming language (`word-help-mode-alist'). It 462relevant for each programming language (`word-help-mode-alist'). It
@@ -361,25 +464,22 @@ usually selects the correct one, based upon the value of `mode-name'.
361If this guess is incorrect, you may also use this function manually to 464If this guess is incorrect, you may also use this function manually to
362instruct future `word-help' calls which Texinfo files to use." 465instruct future `word-help' calls which Texinfo files to use."
363 (interactive) 466 (interactive)
364 (let (helpfile helpguess (case-comp completion-ignore-case)) 467 (let (helpfile helpguess (completion-ignore-case t))
468;; Try to make a guess
365 (setq helpguess (cond 469 (setq helpguess (cond
366 (word-help-current-help-file) 470 (word-help-current-help-file)
367 ((word-help-guess-help-file)))) 471 ((word-help-guess-help-file))))
368 472;; Ask the user
369 (setq completion-ignore-case t 473 (setq helpfile (completing-read
370 helpfile (completing-read
371 (if helpguess 474 (if helpguess
372 (format "Select help mode (default %s): " helpguess) 475 (format "Select help mode (default %s): " helpguess)
373 "Select help mode: ") 476 "Select help mode: ")
374 word-help-mode-alist 477 word-help-mode-alist
375 nil t nil nil)) 478 nil t nil nil))
376 (setq completion-ignore-case case-comp)
377 (if (equal "" helpfile) 479 (if (equal "" helpfile)
378 (setq helpfile helpguess)) 480 (setq helpfile helpguess))
379 (if helpfile 481 (if helpfile
380 (word-help-switch-help-file helpfile)) 482 (word-help-switch-help-file helpfile))))
381 )
382 )
383 483
384;;; Main user interface 484;;; Main user interface
385 485
@@ -397,12 +497,10 @@ interactively by the user.
397If the keyword you are looking at is not available in any index, no 497If the keyword you are looking at is not available in any index, no
398default suggestion will be presented. " 498default suggestion will be presented. "
399 (interactive) 499 (interactive)
400 (let (helpguess myguess guess index-info case-store) 500 (let (myguess guess index-info
501 (completion-ignore-case word-help-ignore-case))
401;; Set necessary variables for later lookup 502;; Set necessary variables for later lookup
402 (if (not word-help-info-files) 503 (word-help-find-help-file)
403 (if (setq helpguess (word-help-guess-help-file))
404 (word-help-switch-help-file helpguess)
405 (set-help-file)))
406;; Have we previously cached datas? 504;; Have we previously cached datas?
407 (word-help-process-indexes) 505 (word-help-process-indexes)
408 (if 506 (if
@@ -416,8 +514,6 @@ default suggestion will be presented. "
416 (car word-help-main-index))) 514 (car word-help-main-index)))
417 word-help-keyword-regexps)) 515 word-help-keyword-regexps))
418;; Ask the user himself 516;; Ask the user himself
419 (setq case-store completion-ignore-case
420 completion-ignore-case word-help-ignore-case)
421 (setq guess (completing-read 517 (setq guess (completing-read
422 ; Format string 518 ; Format string
423 (if myguess 519 (if myguess
@@ -426,7 +522,6 @@ default suggestion will be presented. "
426 ; Collection 522 ; Collection
427 (car word-help-main-index) 523 (car word-help-main-index)
428 nil t nil 'word-help-history)) 524 nil t nil 'word-help-history))
429 (setq completion-ignore-case case-store)
430 (if (equal guess "") 525 (if (equal guess "")
431 (setq guess myguess)) 526 (setq guess myguess))
432;; If we've got anything meaningful to lookup, do so 527;; If we've got anything meaningful to lookup, do so
@@ -437,16 +532,86 @@ default suggestion will be presented. "
437 word-help-main-index)) 532 word-help-main-index))
438 (if (not index-info) 533 (if (not index-info)
439 (message "Oops, I could not find \"%s\" anyway! Bug?" guess) 534 (message "Oops, I could not find \"%s\" anyway! Bug?" guess)
440 (word-help-goto-index-node index-info) 535 (word-help-goto-index-node (nconc index-info (list guess))))))))
441 ) 536
442 ) 537;;;###autoload
443 ) 538(defun word-help-complete ()
444 ) 539 "Perform completion on the symbol preceding the point.
445 ) 540The determination of which language the keyword belongs to, is based upon
541The relevant info file is selected by matching `mode-name' (the major
542mode) against the assoc list `word-help-mode-alist'.
543
544If this is not possible, `set-help-file' will be invoked for selecting
545the relevant info file. `set-help-file' may also be invoked
546interactively by the user.
547
548The keywords are extracted from the index of the info file defined for
549this mode, by using the `word-help-complete-list' variable."
550 (interactive)
551 (word-help-make-complete)
552 (cond
553 ((not word-help-complete-index)
554 (message "No completion available for this mode."))
555 ((symbolp word-help-complete-index)
556 (call-interactively word-help-complete-index))
557 ((listp word-help-complete-index)
558 (let ((all-match (word-help-guess-all (point)
559 word-help-complete-index t))
560 (completion-ignore-case word-help-ignore-case)
561 (c-list word-help-complete-index)
562 c-entry word-match completion completed)
563;; Loop over and try to find a match
564 (while (and all-match (not completed))
565 (setq word-match (car all-match)
566 c-entry (car c-list)
567 c-list (cdr c-list)
568 all-match (cdr all-match))
569;; Check whether the current pattern matched
570 (if word-match
571 (let ((close (nth 3 c-entry))
572 (words (nth 4 c-entry)))
573;; Find the maximum completion for this word
574; (print word-match)
575; (print c-entry)
576; (print close)
577 (setq completion (try-completion word-match words))
578;; Was the match exact
579 (cond ((eq completion t)
580 (and close
581 (not (looking-at (regexp-quote close)))
582 (insert close))
583 (setq completed t))
584;; Silently ignore non-matches
585 ((not completion))
586;; May we complete more unambiguously
587 ((not (string-equal completion word-match))
588 (delete-region (- (point) (length word-match))
589 (point))
590 (insert completion)
591 (if (eq t (try-completion completion words))
592 (progn
593 (and close
594 (not (looking-at (regexp-quote close)))
595 (insert close))))
596 (setq completed t))
597 (t
598 (message "Making completion list...")
599 (let ((list (all-completions word-match words nil)))
600 (setq completed list)
601 (with-output-to-temp-buffer "*Completions*"
602 (display-completion-list list)))
603 (message "Making completion list...done"))))))
604 (if (not completed) (message "No match."))))
605 (t (message "No completion available for this mode."))))
606
607;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
608;;;;;;;;;;;;;;;;;;;;;;;;;;; Index mapping ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
609;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
446 610
447;;; Index mappers
448 611
449(defun word-help-map-index-entries (str re-list) 612(defun word-help-map-index-entries (str re-list)
613 "Transform an Info index entry into a programming keyword.
614Uses this by mapping the entries through `word-help-index-mapper'."
450 (let ((regexp (car (car re-list))) 615 (let ((regexp (car (car re-list)))
451 (subexp (car (cdr (car re-list)))) 616 (subexp (car (cdr (car re-list))))
452 (next (cdr re-list))) 617 (next (cdr re-list)))
@@ -456,6 +621,9 @@ default suggestion will be presented. "
456 (next 621 (next
457 (word-help-map-index-entries str next))))) 622 (word-help-map-index-entries str next)))))
458 623
624;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
625;;;;;;;;;;;;;;;;;;;;;;;;; Switch mode files ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
626;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
459 627
460;;; Mode lookup 628;;; Mode lookup
461 629
@@ -483,28 +651,21 @@ Uses `word-help-mode-alist'."
483 'word-help-info-files 651 'word-help-info-files
484 'word-help-keyword-regexps 652 'word-help-keyword-regexps
485 'word-help-ignore-case 653 'word-help-ignore-case
486 'word-help-index-mapper)))) 654 'word-help-index-mapper
487 (setq word-help-main-index nil)))) 655 'word-help-complete-list))))
656 (setq word-help-main-index nil
657 word-help-complete-index nil))))
488 658
489;;; Default mapping 659;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
660;;;;;;;;;;;;;;;;;;;;;;;;;; Index collection ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
661;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
490 662
491(defun word-help-make-default-map (list vars)
492 "Makes a default mapping for `vars', which must be listed in order.
493vars is a list of quoted symbols. If the nth entry in the list is
494non-nil, the nth variable will be given this value. If nil, the var
495will be given the global default value."
496 (set (car vars) (cond ((car list)) ((default-value (car vars)))))
497 (if (cdr vars)
498 (word-help-make-default-map (cdr list) (cdr vars))))
499
500
501;;; Index collection
502 663
503(defun word-help-extract-index (file-name index-list index-map ignore-case) 664(defun word-help-extract-index (file-name index-list index-map ignore-case)
504 "Extract index from filename and the first node name in index list. 665 "Extract index from filename and the first node name in index list.
505`file-name' is the name of the info file, while `index-list' is a list 666`file-name' is the name of the info file, while `index-list' is a list
506of node-names to search." 667of node-names to search."
507 (let (cmd1 cmdlow nodename ob-array next) 668 (let (cmd1 cmdlow nodename ob-array next (case-fold-search word-help-ignore-case))
508 (setq nodename (car index-list)) 669 (setq nodename (car index-list))
509 (setq ob-array (make-vector 211 0)) 670 (setq ob-array (make-vector 211 0))
510 (message "Processing \"%s\" in %s..." nodename file-name) 671 (message "Processing \"%s\" in %s..." nodename file-name)
@@ -541,9 +702,7 @@ is an entry of the form
541 (nodes (cdr info-file))) 702 (nodes (cdr info-file)))
542 (nconc (list file) (word-help-extract-index file nodes 703 (nconc (list file) (word-help-extract-index file nodes
543 word-help-index-mapper 704 word-help-index-mapper
544 word-help-ignore-case)) 705 word-help-ignore-case))))
545 )
546 )
547 706
548(defun word-help-process-indexes () 707(defun word-help-process-indexes ()
549 "Process all the entries in the global variable `word-help-info-files'. 708 "Process all the entries in the global variable `word-help-info-files'.
@@ -588,48 +747,74 @@ This structure is then later searched by `word-help-find-index-node'."
588 word-help-index-alist))) 747 word-help-index-alist)))
589 (t (setq word-help-main-index t)))))) 748 (t (setq word-help-main-index t))))))
590 749
750(defun word-help-find-help-file ()
751 "Tries to find and set a relevant help file for the current mode."
752 (let (helpguess)
753 (if (not word-help-info-files)
754 (if (setq helpguess (word-help-guess-help-file))
755 (word-help-switch-help-file helpguess)
756 (set-help-file)))))
591 757
592;;; Keyword lookup
593 758
594(defun word-help-guess (cur-point cmd-array re-list) 759;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
595 "Guesses what keyword the user is looking at, and returns that. 760;;;;;;;;;;;;;;;;;;;;;;;;;;; Keyword guess ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
596CUR-POINT should be the current value of `point', CMD-ARRAY an obarray 761;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
597of all the keywords which are defined for the current mode, and 762
598RE-LIST a list of regexps use for the hunt. See also 763(defun word-help-guess-all (cur-point re-list
599`word-help-keyword-regexps'." 764 &optional copy-to-point)
600 (let (guess pre-guess regexp submatch cursmatch end-point) 765 "Guesses *all* keywords the user possibly may be looking at.
601 (setq regexp (car (car re-list)) 766Returns a list of all possible keywords. "
602 submatch (cond ((nth 1 (car re-list))) (0)) 767 (let ((regexp (car (car re-list)))
603 cursmatch (cond ((nth 2 (car re-list))) (0))) 768 (submatch (cond ((nth 1 (car re-list))) (0)))
604;; Store where the old point was 769 (cursmatch (cond ((nth 2 (car re-list))) (0)))
770 (guess nil)
771 (next-guess nil)
772 (case-fold-search word-help-ignore-case)
773 (end-point nil))
605 (save-excursion 774 (save-excursion
606 (end-of-line) 775 (end-of-line)
607;; We won't accept matches after the line
608 (setq end-point (point)) 776 (setq end-point (point))
609;; Start at the beginning 777 ;; Start at the beginning
610 (beginning-of-line) 778 (beginning-of-line)
611 (setq guess nil)
612 (while (and (not guess) (re-search-forward regexp end-point t)) 779 (while (and (not guess) (re-search-forward regexp end-point t))
613 (setq pre-guess (buffer-substring (match-beginning submatch) 780 ;; Look whether the cursor is within the match
614 (match-end submatch)))
615;; Look whether the cursor is within the match
616 (if (and (<= (match-beginning cursmatch) cur-point) 781 (if (and (<= (match-beginning cursmatch) cur-point)
617 (>= (match-end cursmatch) cur-point) 782 (>= (match-end cursmatch) cur-point))
618 (cond 783 (if (or (not copy-to-point) (<= cur-point (match-end submatch)))
619 (cmd-array (intern-soft (if word-help-ignore-case 784 (setq guess (buffer-substring (match-beginning submatch)
620 (downcase pre-guess) 785 (if copy-to-point
621 pre-guess) cmd-array)) 786 cur-point
622 (t))) 787 (match-end submatch)))))))
623 (setq guess pre-guess)) 788 ;; If we found anything, return it and call ourselves again
624 ) 789 (if (cdr re-list)
625;; If we found anything, return it, else call ourselves again 790 (setq next-guess (word-help-guess-all cur-point (cdr re-list)
626 (cond 791 copy-to-point))))
627 (guess) 792 (cons guess next-guess)))
628 ((cdr re-list) (word-help-guess cur-point cmd-array (cdr re-list))) 793
629 ) 794(defun word-help-guess-match (all-match cmd-array)
630 ) 795 (let ((sym (car all-match)))
631 ) 796 (cond
632 ) 797 ((and sym (intern-soft (if word-help-ignore-case
798 (downcase sym)
799 sym) cmd-array)
800 sym))
801 ((cdr all-match)
802 (word-help-guess-match (cdr all-match) cmd-array)))))
803
804
805(defun word-help-guess (cur-point cmd-array re-list)
806 "Guesses what keyword the user is looking at, and returns that.
807CUR-POINT should be the current value of `point', CMD-ARRAY an obarray
808of all the keywords which are defined for the current mode, and
809RE-LIST a list of regexps use for the hunt. See also
810`word-help-keyword-regexps'."
811 (let ((all-matches (word-help-guess-all cur-point re-list)))
812; (print all-matches)
813 (word-help-guess-match all-matches cmd-array)))
814
815;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
816;;;;;;;;;;;;;;;;;;;;;;; Show node for keyword ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
817;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
633 818
634;;; Find an index entry 819;;; Find an index entry
635 820
@@ -648,9 +833,7 @@ Returns nil if the entry can't be found."
648 (if (intern-soft node-name (car index-reg)) 833 (if (intern-soft node-name (car index-reg))
649 (setq file-info (word-help-index-search-file node-name 834 (setq file-info (word-help-index-search-file node-name
650 (cdr index-reg)))) 835 (cdr index-reg))))
651 file-info 836 file-info))
652 )
653 )
654 837
655(defun word-help-index-search-file (entry file-data) 838(defun word-help-index-search-file (entry file-data)
656 "Searches a cached file for the index-entry `entry'." 839 "Searches a cached file for the index-entry `entry'."
@@ -663,10 +846,7 @@ Returns nil if the entry can't be found."
663 (cond 846 (cond
664 (node 847 (node
665 (cons file-name node)) 848 (cons file-name node))
666 (next-files (word-help-index-search-file entry next-files)) 849 (next-files (word-help-index-search-file entry next-files)))))
667 )
668 )
669 )
670 850
671(defun word-help-index-search-nodes (entry node-info) 851(defun word-help-index-search-nodes (entry node-info)
672 "Searches a cached list of nodes for the entry `entry'." 852 "Searches a cached list of nodes for the entry `entry'."
@@ -687,31 +867,104 @@ Returns nil if the entry can't be found."
687 "Jumps to an index node. 867 "Jumps to an index node.
688`index-info' should be a list with the following format: 868`index-info' should be a list with the following format:
689 869
690\(FILE-NAME INDEX-NODE-NAME INDEX-ENTRY)" 870\(FILE-NAME INDEX-NODE-NAME INDEX-ENTRY KEYWORD)"
691 871
692 (let* ((file-name (car index-info)) 872 (let* ((file-name (car index-info))
693 (node-name (nth 1 index-info)) 873 (node-name (nth 1 index-info))
694 (entry-name (nth 2 index-info)) 874 (entry-name (nth 2 index-info))
695 (entry-regexp (concat "\\<" (regexp-quote (nth 2 index-info)) "\\>")) 875 (kw-name (nth 3 index-info))
696 (buffer (current-buffer)) 876 (buffer (current-buffer)))
697 end-point)
698 (if word-help-split-window 877 (if word-help-split-window
699 (pop-to-buffer nil)) 878 (pop-to-buffer nil))
700 (Info-goto-node (concat "(" file-name ")" node-name)) 879 (Info-goto-node (concat "(" file-name ")" node-name))
701 (Info-menu entry-name) 880 (Info-menu entry-name)
702;; Do magic keyword search 881;; Do magic keyword search
703 (cond 882 (if word-help-magic-index
704 (word-help-magic-index 883 (let (end-point regs this-re found entry-re)
705 (end-of-line) 884 (setq entry-re (regexp-quote kw-name)
706 (setq end-point (point)) 885 regs (list (concat
707 (beginning-of-line) 886 (if (string-match "^[A-Za-z]" entry-name)
708 (cond 887 "\\<" "")
709 ((not (re-search-forward entry-regexp end-point t)) 888 entry-re
710 (re-search-forward entry-regexp) 889 (if (string-match "[A-Za-z]$" entry-name)
711 (recenter 0))))) 890 "\\>" ""))
891 (concat "[`\"\(]" entry-re)
892 (concat "^" entry-re
893 (if (string-match "[A-Za-z]$" entry-name)
894 "\\>" ""))))
895 (end-of-line)
896 (setq end-point (point))
897 (beginning-of-line)
898 (if (not (re-search-forward (car regs) end-point t))
899 (while (and (not found) (car regs))
900 (setq this-re (car regs)
901 regs (cdr regs)
902 found (re-search-forward this-re nil t))))
903 (recenter 0)))
712 (if word-help-split-window 904 (if word-help-split-window
713 (pop-to-buffer buffer)))) 905 (pop-to-buffer buffer))))
714 906
907
908;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
909;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Completion ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
910;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
911
912
913
914(defun word-help-extract-matches (from-ob dest-ob re-list)
915 "Takes atoms from from-ob, and puts them in dest-ob if they match re-list."
916 (let ((regexp (car (car re-list))))
917 (mapatoms (lambda (x)
918 (if (or (not regexp) (string-match regexp (symbol-name x)))
919 (intern (symbol-name x) dest-ob)))
920 from-ob)
921 (if (cdr re-list)
922 (word-help-extract-matches from-ob dest-ob (cdr re-list))))
923 dest-ob)
924
925(defun word-help-make-complete ()
926 "Generates the `word-help-complete-index'."
927 (if word-help-complete-index
928 nil
929 (word-help-find-help-file)
930 (cond
931 ((symbolp word-help-complete-list)
932 (setq word-help-complete-index word-help-complete-list))
933 (t
934 (word-help-process-indexes)
935 (if (not (atom word-help-main-index))
936 (let ((from-ob (car word-help-main-index)))
937 (message "Processing keywords...")
938 (setq word-help-complete-index
939 (mapcar
940 (lambda (cmpl)
941 (let
942 ((regexp (car cmpl))
943 (subm (cond ((nth 1 cmpl)) (0)))
944 (app (cond ((nth 2 cmpl)) ("")))
945 (re-list (cond ((nth 3 cmpl)) ('((".")))))
946 (obarr (make-vector 47 0)))
947 (list regexp subm subm app
948 (word-help-extract-matches from-ob obarr
949 re-list))))
950 word-help-complete-list))))))))
951
952;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
953;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Misc. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
954;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
955
956
957;;; Default mapping
958
959(defun word-help-make-default-map (list vars)
960 "Makes a default mapping for `vars', which must be listed in order.
961vars is a list of quoted symbols. If the nth entry in the list is
962non-nil, the nth variable will be given this value. If nil, the var
963will be given the global default value."
964 (set (car vars) (cond ((car list)) ((default-value (car vars)))))
965 (if (cdr vars)
966 (word-help-make-default-map (cdr list) (cdr vars))))
967
715(provide 'word-help) 968(provide 'word-help)
716 969
717;;; word-help.el ends here 970;;; word-help.el ends here