GENTZEL@CPWSCU.PSC.EDU (Dave Gentzel) (07/28/89)
ABBREV.C FIXES (expand-abbrevs): 1. Contrary to the documentation, define-abbrev blows up if passed nil for expansion. 2. expand-abbrev refuses to expand any abbrev with > 199 characters in length. Not a major restriction, but one of the few arbitrary limits in emacs and easy to fix. (While changing the code I've made a few other minor improvements...) 3. There were several unnecessary checks such as point <= scan_word(point, -1) which is always false provided scan_word doesn't return 0 (it doesn't). These have been removed. 4. Allow whitespace after the word to expand, i.e. tom ^point here expand-abbrev will expand tom (assuming it is an abbrev, of course). *** abbrev.c;-0 Fri May 5 15:43:53 1989 --- abbrev.c Thu Jul 27 15:20:46 1989 *************** *** 110,116 Lisp_Object sym, oexp, ohook, tem; CHECK_VECTOR (table, 0); CHECK_STRING (name, 1); ! CHECK_STRING (expansion, 2); if (NULL (count)) count = make_number (0); else --- 110,117 ----- Lisp_Object sym, oexp, ohook, tem; CHECK_VECTOR (table, 0); CHECK_STRING (name, 1); ! if (!NULL (expansion)) ! CHECK_STRING (expansion, 2); if (NULL (count)) count = make_number (0); else *************** *** 207,215 Returns t if expansion took place.") () { ! char buffer[200]; ! register char *p = buffer; ! register int wordstart, idx; int uccount = 0, lccount = 0; register Lisp_Object sym; Lisp_Object expansion, hook, tem; --- 208,216 ----- Returns t if expansion took place.") () { ! register char *buffer, *p; ! register int wordstart, wordend, idx; ! int whitecnt; int uccount = 0, lccount = 0; register Lisp_Object sym; Lisp_Object expansion, hook, tem; *************** *** 227,234 } else wordstart = scan_words (point, -1); ! ! if (!wordstart || point - wordstart >= sizeof buffer || point <= wordstart) return Qnil; for (idx = wordstart; idx < point; idx++) --- 228,235 ----- } else wordstart = scan_words (point, -1); ! ! if (!wordstart) return Qnil; wordend = scan_words (wordstart, 1); *************** *** 230,237 if (!wordstart || point - wordstart >= sizeof buffer || point <= wordstart) return Qnil; ! ! for (idx = wordstart; idx < point; idx++) { register int c = CharAt (idx); if (UPPERCASEP (c)) --- 231,245 ----- if (!wordstart) return Qnil; ! ! wordend = scan_words (wordstart, 1); ! if (wordend > point) ! wordend = point; ! whitecnt = point - wordend; ! ! p = buffer = alloca (wordend - wordstart); ! ! for (idx = wordstart; idx < wordend; idx++) { register int c = CharAt (idx); if (UPPERCASEP (c)) *************** *** 245,252 sym = oblookup (bf_cur->abbrev_table, buffer, p - buffer); else XFASTINT (sym) = 0; ! if (XTYPE (sym) == Lisp_Int || ! NULL (XSYMBOL (sym)->value)) sym = oblookup (Vglobal_abbrev_table, buffer, p - buffer); if (XTYPE (sym) == Lisp_Int || NULL (XSYMBOL (sym)->value)) --- 253,259 ----- sym = oblookup (bf_cur->abbrev_table, buffer, p - buffer); else XFASTINT (sym) = 0; ! if (XTYPE (sym) == Lisp_Int || NULL (XSYMBOL (sym)->value)) sym = oblookup (Vglobal_abbrev_table, buffer, p - buffer); if (XTYPE (sym) == Lisp_Int || NULL (XSYMBOL (sym)->value)) return Qnil; *************** *** 248,255 if (XTYPE (sym) == Lisp_Int || NULL (XSYMBOL (sym)->value)) sym = oblookup (Vglobal_abbrev_table, buffer, p - buffer); ! if (XTYPE (sym) == Lisp_Int || ! NULL (XSYMBOL (sym)->value)) return Qnil; if (INTERACTIVE && !EQ (minibuf_window, selected_window)) --- 255,261 ----- XFASTINT (sym) = 0; if (XTYPE (sym) == Lisp_Int || NULL (XSYMBOL (sym)->value)) sym = oblookup (Vglobal_abbrev_table, buffer, p - buffer); ! if (XTYPE (sym) == Lisp_Int || NULL (XSYMBOL (sym)->value)) return Qnil; if (INTERACTIVE && !EQ (minibuf_window, selected_window)) *************** *** 254,260 if (INTERACTIVE && !EQ (minibuf_window, selected_window)) { ! SetPoint (wordstart + p - buffer); Fundo_boundary (); } SetPoint (wordstart); --- 260,266 ----- if (INTERACTIVE && !EQ (minibuf_window, selected_window)) { ! SetPoint (wordend); Fundo_boundary (); } SetPoint (wordstart); *************** *** 259,267 } SetPoint (wordstart); Vlast_abbrev_text ! = Fbuffer_substring (make_number (point), ! make_number (point + (p - buffer))); ! del_range (point, point + (p - buffer)); /* Now sym is the abbrev symbol. */ Vlast_abbrev = sym; --- 265,272 ----- } SetPoint (wordstart); Vlast_abbrev_text ! = Fbuffer_substring (make_number (wordstart), make_number (wordend)); ! del_range (wordstart, wordend); /* Now sym is the abbrev symbol. */ Vlast_abbrev = sym; *************** *** 265,271 /* Now sym is the abbrev symbol. */ Vlast_abbrev = sym; ! last_abbrev_point = point; if (XTYPE (XSYMBOL (sym)->plist) == Lisp_Int) XSETINT (XSYMBOL (sym)->plist, --- 270,276 ----- /* Now sym is the abbrev symbol. */ Vlast_abbrev = sym; ! last_abbrev_point = wordstart; if (XTYPE (XSYMBOL (sym)->plist) == Lisp_Int) /* Increment use count */ *************** *** 268,275 last_abbrev_point = point; if (XTYPE (XSYMBOL (sym)->plist) == Lisp_Int) ! XSETINT (XSYMBOL (sym)->plist, ! XINT (XSYMBOL (sym)->plist) + 1); /* Increment use count */ expansion = XSYMBOL (sym)->value; InsCStr (XSTRING (expansion)->data, XSTRING (expansion)->size); --- 273,280 ----- last_abbrev_point = wordstart; if (XTYPE (XSYMBOL (sym)->plist) == Lisp_Int) ! /* Increment use count */ ! XSETINT (XSYMBOL (sym)->plist, XINT (XSYMBOL (sym)->plist) + 1); expansion = XSYMBOL (sym)->value; InsCStr (XSTRING (expansion)->data, XSTRING (expansion)->size); *************** *** 273,278 --- 278,284 ----- expansion = XSYMBOL (sym)->value; InsCStr (XSTRING (expansion)->data, XSTRING (expansion)->size); + SetPoint (point + whitecnt); if (uccount && !lccount) { ABBREV.EL FIXES (expand-region-abbrevs): 1. Ignores its prefix argument (missing `P' from the interactive spec). 2. Does unnecessary fiddling to get the region args in the right order. The `r' interactive spec already does this. 3. Uses expand-abbrev to determine whether a word has an abbrev defined. This has the very undesirable side-effect of munging the undo information (especially buffer-modified) which makes undoing a very verbose operation! Just pick up the word from the buffer and use abbrev-expansion instead. 4. Make file argument to read-abbrev-file and quietly-read-abbrev-file optional (default to abbrev-file-name). 5. Make write-abbrev-file default file to abbrev-file-name rather than the current visited file name! 6. Fix the prompt for add-abbrev when undefining (arg < 0). *** abbrev.el;-0 Fri May 5 15:42:42 1989 --- abbrev.el Thu Jul 27 15:21:52 1989 *************** *** 129,136 (skip-chars-backward " \t\n\f") (setq abbrevs (cons (list name exp hook count) abbrevs))) (define-abbrev-table table abbrevs))))) ! ! (defun read-abbrev-file (file &optional quietly) "Read abbrev definitions from file written with write-abbrev-file. Takes file name as argument. Optional second argument non-nil means don't print anything." --- 129,136 ----- (skip-chars-backward " \t\n\f") (setq abbrevs (cons (list name exp hook count) abbrevs))) (define-abbrev-table table abbrevs))))) ! ! (defun read-abbrev-file (&optional file quietly) "Read abbrev definitions from file written with write-abbrev-file. Takes file name as argument. Optional second argument non-nil means don't print anything." *************** *** 138,145 (load (if (and file (> (length file) 0)) file abbrev-file-name) nil quietly) (setq save-abbrevs t abbrevs-changed nil)) ! ! (defun quietly-read-abbrev-file (file) "Read abbrev definitions from file written with write-abbrev-file. Takes file name as argument. Does not print anything." ;(interactive "fRead abbrev file: ") --- 138,145 ----- (load (if (and file (> (length file) 0)) file abbrev-file-name) nil quietly) (setq save-abbrevs t abbrevs-changed nil)) ! ! (defun quietly-read-abbrev-file (&optional file) "Read abbrev definitions from file written with write-abbrev-file. Takes file name as argument. Does not print anything." (interactive "fRead abbrev file: ") *************** *** 142,148 (defun quietly-read-abbrev-file (file) "Read abbrev definitions from file written with write-abbrev-file. Takes file name as argument. Does not print anything." ! ;(interactive "fRead abbrev file: ") (read-abbrev-file file t)) (defun write-abbrev-file (file) --- 142,148 ----- (defun quietly-read-abbrev-file (&optional file) "Read abbrev definitions from file written with write-abbrev-file. Takes file name as argument. Does not print anything." ! (interactive "fRead abbrev file: ") (read-abbrev-file file t)) (defun write-abbrev-file (file) *************** *** 148,154 (defun write-abbrev-file (file) "Write all abbrev definitions to file of Lisp code. The file can be loaded to define the same abbrevs." ! (interactive "FWrite abbrev file: ") (or (and file (> (length file) 0)) (setq file abbrev-file-name)) (save-excursion --- 148,158 ----- (defun write-abbrev-file (file) "Write all abbrev definitions to file of Lisp code. The file can be loaded to define the same abbrevs." ! (interactive ! (list ! (read-file-name "Write abbrev file: " ! (file-name-directory (expand-file-name abbrev-file-name)) ! abbrev-file-name))) (or (and file (> (length file) 0)) (setq file abbrev-file-name)) (save-excursion *************** *** 191,198 (if (= arg 0) (mark) (save-excursion (forward-word (- arg)) (point)))))) name) ! (setq name (read-string (format "%s abbrev for \"%s\": " ! type exp))) (if (or (null exp) (not (abbrev-expansion name table)) (y-or-n-p (format "%s expands to \"%s\"; redefine? " --- 195,204 ----- (if (= arg 0) (mark) (save-excursion (forward-word (- arg)) (point)))))) name) ! (setq name (read-string ! (if exp ! (format "%s abbrev for \"%s\": " type exp) ! (format "Undefine %s abbrev: " type)))) (if (or (null exp) (not (abbrev-expansion name table)) (y-or-n-p (format "%s expands to \"%s\"; redefine? " *************** *** 254,260 The user is asked to type y or n for each occurrence. A numeric argument means don't query; expand all abbrevs. Calling from a program, arguments are START END &optional NOQUERY." ! (interactive "r") (save-excursion (goto-char (min start end)) (let ((lim (- (point-max) (max start end)))) --- 260,266 ----- The user is asked to type y or n for each occurrence. A numeric argument means don't query; expand all abbrevs. Calling from a program, arguments are START END &optional NOQUERY." ! (interactive "r\nP") (save-excursion (goto-char start) (let ((lim (- (point-max) end)) pnt) *************** *** 256,263 Calling from a program, arguments are START END &optional NOQUERY." (interactive "r") (save-excursion ! (goto-char (min start end)) ! (let ((lim (- (point-max) (max start end)))) (while (and (not (eobp)) (progn (forward-word 1) (<= (point) (- (point-max) lim)))) --- 262,269 ----- Calling from a program, arguments are START END &optional NOQUERY." (interactive "r\nP") (save-excursion ! (goto-char start) ! (let ((lim (- (point-max) end)) pnt) (while (and (not (eobp)) (forward-word 1) (<= (setq pnt (point)) (- (point-max) lim))) *************** *** 259,270 (goto-char (min start end)) (let ((lim (- (point-max) (max start end)))) (while (and (not (eobp)) ! (progn (forward-word 1) ! (<= (point) (- (point-max) lim)))) ! (let ((modp (buffer-modified-p))) ! (if (expand-abbrev) ! (progn ! (set-buffer-modified-p modp) ! (unexpand-abbrev) ! (if (or noquery (y-or-n-p "Expand this? ")) ! (expand-abbrev))))))))) --- 265,275 ----- (goto-char start) (let ((lim (- (point-max) end)) pnt) (while (and (not (eobp)) ! (forward-word 1) ! (<= (setq pnt (point)) (- (point-max) lim))) ! (if (abbrev-expansion ! (prog1 ! (buffer-substring (progn (forward-word -1) (point)) pnt) ! (goto-char pnt))) ! (if (or noquery (y-or-n-p "Expand this? ")) ! (expand-abbrev)))))))