Mercurial > emacs
changeset 85710:beb909dfc54d
Rewrite abbrev.c in Elisp.
* image.c (Qcount): Don't declare as extern.
(syms_of_image): Initialize and staticpro `Qcount'.
* puresize.h (BASE_PURESIZE): Increase for the new abbrev.el functions.
* emacs.c (main): Don't call syms_of_abbrev.
* Makefile.in (obj): Remove abbrev.o.
(abbrev.o): Remove.
* abbrev.c: Remove.
Rewrite abbrev.c in Elisp.
* abbrev.el (abbrev-mode): Move custom group from cus-edit.el.
(abbrev-table-get, abbrev-table-put, abbrev-get)
(abbrev-put, make-abbrev-table, abbrev-table-p, clear-abbrev-table)
(define-abbrev, abbrev--check-chars, define-global-abbrev)
(define-mode-abbrev, abbrev--active-tables, abbrev-symbol)
(abbrev-expansion, abbrev--before-point, expand-abbrev)
(unexpand-abbrev, abbrev--write, abbrev--describe)
(insert-abbrev-table-description, define-abbrev-table):
New funs, largely transcribed from abbrev.c.
(abbrev-with-wrapper-hook): New macro.
(abbrev-table-name-list, global-abbrev-table)
(abbrev-minor-mode-table-alist, fundamental-mode-abbrev-table)
(abbrevs-changed, abbrev-all-caps, abbrev-start-location)
(abbrev-start-location-buffer, last-abbrev, last-abbrev-text)
(last-abbrev-location, pre-abbrev-expand-hook, abbrev-expand-function):
New vars, largely transcribed from abbrev.c.
* cus-edit.el (abbrev-mode): Remove. Move to abbrev.el.
* cus-start.el: Remove abbrev-all-caps and pre-abbrev-expand-hook.
* loadup.el: Load "abbrev.el" before "lisp-mode.el".
author | Stefan Monnier <monnier@iro.umontreal.ca> |
---|---|
date | Sun, 28 Oct 2007 02:41:00 +0000 |
parents | 2dabdbde81e8 |
children | b6f5dc84b2e1 |
files | doc/lispref/abbrevs.texi etc/NEWS lisp/ChangeLog lisp/abbrev.el lisp/cus-edit.el lisp/cus-start.el lisp/loadup.el src/ChangeLog src/Makefile.in src/abbrev.c src/emacs.c src/image.c src/puresize.h |
diffstat | 13 files changed, 746 insertions(+), 873 deletions(-) [+] |
line wrap: on
line diff
--- a/doc/lispref/abbrevs.texi Sat Oct 27 22:15:27 2007 +0000 +++ b/doc/lispref/abbrevs.texi Sun Oct 28 02:41:00 2007 +0000 @@ -47,6 +47,10 @@ * Files: Abbrev Files. Saving abbrevs in files. * Expansion: Abbrev Expansion. Controlling expansion; expansion subroutines. * Standard Abbrev Tables:: Abbrev tables used by various major modes. +* Abbrev Properties:: How to read and set abbrev properties. + Which properties have which effect. +* Abbrev Table Properties:: How to read and set abbrev table properties. + Which properties have which effect. @end menu @node Abbrev Mode, Abbrev Tables, Abbrevs, Abbrevs @@ -75,9 +79,14 @@ This section describes how to create and manipulate abbrev tables. -@defun make-abbrev-table +@defun make-abbrev-table &rest props This function creates and returns a new, empty abbrev table---an obarray -containing no symbols. It is a vector filled with zeros. +containing no symbols. It is a vector filled with zeros. @var{props} +is a property list that is applied to the new table. +@end defun + +@defun abbrev-table-p table +Return non-@code{nil} is @var{table} is an abbrev table. @end defun @defun clear-abbrev-table table @@ -92,15 +101,18 @@ function sets the property lists of all copied abbrevs to 0. @end defun -@defun define-abbrev-table tabname definitions +@defun define-abbrev-table tabname definitions &optional docstring &rest props This function defines @var{tabname} (a symbol) as an abbrev table name, i.e., as a variable whose value is an abbrev table. It defines abbrevs in the table according to @var{definitions}, a list of elements of the form @code{(@var{abbrevname} @var{expansion} -@var{hook} @var{usecount} @var{system-flag})}. If an element of -@var{definitions} has length less than five, omitted elements default -to @code{nil}. A value of @code{nil} for @var{usecount} is equivalent -to zero. The return value is always @code{nil}. +[@var{hook}] [@var{props}...])}. These elements are passed as +arguments to @code{define-abbrev}. The return value is always +@code{nil}. + +The optional string @var{docstring} is the documentation string of the +variable @var{tabname}. The property list @var{props} is applied to +the abbrev table (@pxref{Abbrev Table Properties}). If this function is called more than once for the same @var{tabname}, subsequent calls add the definitions in @var{definitions} to @@ -132,20 +144,17 @@ @section Defining Abbrevs @code{define-abbrev} is the low-level basic function for defining an abbrev in a specified abbrev table. When major modes predefine standard -abbrevs, they should call @code{define-abbrev} and specify @code{t} for -@var{system-flag}. Be aware that any saved non-``system'' abbrevs are +abbrevs, they should call @code{define-abbrev} and specify a @code{t} for +the @code{system-flag} property. +Be aware that any saved non-``system'' abbrevs are restored at startup, i.e. before some major modes are loaded. Major modes should therefore not assume that when they are first loaded their abbrev tables are empty. -@defun define-abbrev table name expansion &optional hook count system-flag +@defun define-abbrev table name expansion &optional hook &rest props This function defines an abbrev named @var{name}, in @var{table}, to -expand to @var{expansion} and call @var{hook}. The return value is -@var{name}. - -The value of @var{count}, if specified, initializes the abbrev's -usage-count. If @var{count} is not specified or @code{nil}, the use -count is initialized to zero. +expand to @var{expansion} and call @var{hook}, with properties +@var{props} (@pxref{Abbrev Properties}). The return value is @var{name}. The argument @var{name} should be a string. The argument @var{expansion} is normally the desired expansion (a string), or @@ -167,12 +176,6 @@ returns @code{nil}, @code{expand-abbrev} also returns @code{nil}, as if expansion had not really occurred. -If @var{system-flag} is non-@code{nil}, that marks the abbrev as a -``system'' abbrev with the @code{system-type} property. Unless -@var{system-flag} has the value @code{force}, a ``system'' abbrev will -not overwrite an existing definition for a non-``system'' abbrev of the -same name. - Normally the function @code{define-abbrev} sets the variable @code{abbrevs-changed} to @code{t}, if it actually changes the abbrev. (This is so that some commands will offer to save the abbrevs.) It @@ -329,20 +332,19 @@ @code{expand-abbrev} for the sake of the @code{unexpand-abbrev} command. @end defvar -@c Emacs 19 feature -@defvar pre-abbrev-expand-hook -This is a normal hook whose functions are executed, in sequence, just -before any expansion of an abbrev. @xref{Hooks}. Since it is a normal -hook, the hook functions receive no arguments. However, they can find -the abbrev to be expanded by looking in the buffer before point. -Running the hook is the first thing that @code{expand-abbrev} does, and -so a hook function can be used to change the current abbrev table before -abbrev lookup happens. (Although you have to do this carefully. See -the example below.) +@defvar abbrev-expand-functions +This is a special hook run @emph{around} the @code{expand-abbrev} +function. Functions on this hook are called with a single argument +which is a function that performs the normal abbrev expansion. +The hook function can hence do anything it wants before and after +performing the expansion. It can also choose not to call its argument +and thus override the default behavior, or it may even call it +several times. The function should return the abbrev symbol if +expansion took place. @end defvar The following sample code shows a simple use of -@code{pre-abbrev-expand-hook}. It assumes that @code{foo-mode} is a +@code{abbrev-expand-functions}. It assumes that @code{foo-mode} is a mode for editing certain files in which lines that start with @samp{#} are comments. You want to use Text mode abbrevs for those lines. The regular local abbrev table, @code{foo-mode-abbrev-table} is @@ -351,30 +353,22 @@ definitions of @code{local-abbrev-table} and @code{text-mode-abbrev-table}. @smallexample -(defun foo-mode-pre-abbrev-expand () - (when (save-excursion (forward-line 0) (eq (char-after) ?#)) - (let ((local-abbrev-table text-mode-abbrev-table) - ;; Avoid infinite loop. - (pre-abbrev-expand-hook nil)) - (expand-abbrev)) - ;; We have already called `expand-abbrev' in this hook. - ;; Hence we want the "actual" call following this hook to be a no-op. - (setq abbrev-start-location (point-max) - abbrev-start-location-buffer (current-buffer)))) +(defun foo-mode-abbrev-expand-function (expand) + (if (not (save-excursion (forward-line 0) (eq (char-after) ?#))) + ;; Performs normal expansion. + (funcall expand) + ;; We're inside a comment: use the text-mode abbrevs. + (let ((local-abbrev-table text-mode-abbrev-table)) + (funcall expand)))) (add-hook 'foo-mode-hook #'(lambda () - (add-hook 'pre-abbrev-expand-hook - 'foo-mode-pre-abbrev-expand + (add-hook 'abbrev-expand-functions + 'foo-mode-abbrev-expand-function nil t))) @end smallexample -Note that @code{foo-mode-pre-abbrev-expand} just returns @code{nil} -without doing anything for lines not starting with @samp{#}. Hence -abbrevs expand normally using @code{foo-mode-abbrev-table} as local -abbrev table for such lines. - -@node Standard Abbrev Tables, , Abbrev Expansion, Abbrevs +@node Standard Abbrev Tables, Abbrev Properties, Abbrev Expansion, Abbrevs @comment node-name, next, previous, up @section Standard Abbrev Tables @@ -390,7 +384,16 @@ @defvar local-abbrev-table The value of this buffer-local variable is the (mode-specific) -abbreviation table of the current buffer. +abbreviation table of the current buffer. It can also be a list of +such tables. +@end defvar + +@defvar abbrev-minor-mode-table-alist +The value of this variable is a list of elements of the form +@code{(@var{mode} . @var{abbrev-table})} where @var{mode} is the name +of a variable: if the variable is bound to a non-@code{nil} value, +then the @var{abbrev-table} is active, otherwise it is ignored. +@var{abbrev-table} can also be a list of abbrev tables. @end defvar @defvar fundamental-mode-abbrev-table @@ -406,6 +409,105 @@ This is the local abbrev table used in Lisp mode and Emacs Lisp mode. @end defvar +@node Abbrev Properties, Abbrev Table Properties, Standard Abbrev Tables, Abbrevs +@section Abbrev Properties + +Abbrevs have properties, some of which influence the way they work. +They are usually set by providing the relevant arguments to +@code{define-abbrev} and can be manipulated with the functions: + +@defun abbrev-put abbrev prop val +Set the property @var{prop} of abbrev @var{abbrev} to value @var{val}. +@end defun + +@defun abbrev-get abbrev prop +Return the property @var{prop} of abbrev @var{abbrev}, or @code{nil} +if the abbrev has no such property. +@end defun + +The following properties have special meaning: + +@table @code +@item count +This property counts the number of times the abbrev has +been expanded. If not explicitly set, it is initialized to 0 by +@code{define-abbrev}. + +@item system-flag +If non-@code{nil}, this property marks the abbrev as a ``system'' +abbrev. Such abbrevs will not be saved to @var{abbrev-file-name}. +Also, unless @code{system-flag} has the value @code{force}, +a ``system'' abbrev will not overwrite an existing definition for +a non-``system'' abbrev of the same name. + +@item :enable-function +If non-@code{nil}, this property should be set to a function of no +arguments which returns @code{nil} if the abbrev should not be used +and @code{t} otherwise. + +@item :case-fixed +If non-@code{nil}, this property indicates that the case of the +abbrev's name is significant and should only match a text with the +same capitalization. It also disables the code that modifies the +capitalization of the expansion. + +@end table + +@node Abbrev Table Properties, , Abbrev Properties, Abbrevs +@section Abbrev Table Properties + +Like abbrevs, abble tables have properties, some of which influence +the way they work. They are usually set by providing the relevant +arguments to @code{define-abbrev-table} and can be manipulated with +the functions: + +@defun abbrev-table-put table prop val +Set the property @var{prop} of abbrev table @var{table} to value @var{val}. +@end defun + +@defun abbrev-table-get table prop +Return the property @var{prop} of abbrev table @var{table}, or @code{nil} +if the abbrev has no such property. +@end defun + +The following properties have special meaning: + +@table @code +@item :enable-function +If non-@code{nil}, this property should be set to a function of no +arguments which returns @code{nil} if the abbrev table should not be +used and @code{t} otherwise. This is like the @code{:enable-function} +abbrev property except that it applies to all abbrevs in the table and +is used even before trying to find the abbrev before point. + +@item :case-fixed +If non-@code{nil}, this property indicates that the case of the names +is significant for all abbrevs in the table and should only match +a text with the same capitalization. It also disables the code that +modifies the capitalization of the expansion. This is like the +@code{:case-fixed} abbrev property except that it applies to all +abbrevs in the table. + +@item :regexp +If non-@code{nil}, this property is a regular expression that +indicates how to extract the name of the abbrev before point before +looking it up in the table. When the regular expression matches +before point, the abbrev name is expected to be in submatch 1. +If this property is nil, @code{expand-function} defaults to +@code{"\\<\\(\\w+\\)\\W"}. This property allows the use of abbrevs +whose name contains characters of non-word syntax. + +@item :parents +This property holds the list of tables from which to inherit +other abbrevs. + +@item :abbrev-table-modiff +This property holds a counter incremented each time a new abbrev is +added to the table. + +@end table + + @ignore arch-tag: 5ffdbe08-2cd4-48ec-a5a8-080f95756eec @end ignore
--- a/etc/NEWS Sat Oct 27 22:15:27 2007 +0000 +++ b/etc/NEWS Sun Oct 28 02:41:00 2007 +0000 @@ -166,6 +166,20 @@ * Changes in Specialized Modes and Packages in Emacs 23.1 +** abbrev was rewritten in Elisp and extended with more flexibility. +*** New functions: abbrev-get, abbrev-put, abbrev-table-get, abbrev-table-put, + abbrev-table-p. +*** Special hook `abbrev-expand-functions' obsoletes `pre-abbrev-expand-hook'. +*** `make-abbrev-table', `define-abbrev', `define-abbrev-table' all take + extra arguments for arbitrary properties. +*** New variable `abbrev-minor-mode-table-alist'. +*** `local-abbrev-table' can hold a list of abbrev-tables. +*** Abbrevs have now the following special properties: + `count', `system-flag', `:enable-function', `:case-fixed'. +*** Abbrev-tables have now the following special properties: + `:parents', `:case-fixed', `:enable-function', `:regexp', + `abbrev-table-modiff'. + ** isearch can now search through multiple ChangeLog files. When running isearch in a ChangeLog file, if the search fails, then another C-s tries searching the previous ChangeLog,
--- a/lisp/ChangeLog Sat Oct 27 22:15:27 2007 +0000 +++ b/lisp/ChangeLog Sun Oct 28 02:41:00 2007 +0000 @@ -1,3 +1,26 @@ +2007-10-28 Stefan Monnier <monnier@iro.umontreal.ca> + + Rewrite abbrev.c in Elisp. + * abbrev.el (abbrev-mode): Move custom group from cus-edit.el. + (abbrev-table-get, abbrev-table-put, abbrev-get) + (abbrev-put, make-abbrev-table, abbrev-table-p, clear-abbrev-table) + (define-abbrev, abbrev--check-chars, define-global-abbrev) + (define-mode-abbrev, abbrev--active-tables, abbrev-symbol) + (abbrev-expansion, abbrev--before-point, expand-abbrev) + (unexpand-abbrev, abbrev--write, abbrev--describe) + (insert-abbrev-table-description, define-abbrev-table): + New funs, largely transcribed from abbrev.c. + (abbrev-with-wrapper-hook): New macro. + (abbrev-table-name-list, global-abbrev-table) + (abbrev-minor-mode-table-alist, fundamental-mode-abbrev-table) + (abbrevs-changed, abbrev-all-caps, abbrev-start-location) + (abbrev-start-location-buffer, last-abbrev, last-abbrev-text) + (last-abbrev-location, pre-abbrev-expand-hook, abbrev-expand-function): + New vars, largely transcribed from abbrev.c. + * cus-edit.el (abbrev-mode): Remove. Move to abbrev.el. + * cus-start.el: Remove abbrev-all-caps and pre-abbrev-expand-hook. + * loadup.el: Load "abbrev.el" before "lisp-mode.el". + 2007-10-27 Glenn Morris <rgm@gnu.org> * shell.el (shell-dirtrack-verbose, shell-directory-tracker): Doc fix.
--- a/lisp/abbrev.el Sat Oct 27 22:15:27 2007 +0000 +++ b/lisp/abbrev.el Sun Oct 28 02:41:00 2007 +0000 @@ -27,8 +27,20 @@ ;; This facility is documented in the Emacs Manual. +;; Todo: + +;; - Make abbrev-file-name obey user-emacs-directory. +;; - Cleanup name space. + ;;; Code: +(eval-when-compile (require 'cl)) + +(defgroup abbrev-mode nil + "Word abbreviations mode." + :link '(custom-manual "(emacs)Abbrevs") + :group 'abbrev) + (defcustom only-global-abbrevs nil "Non-nil means user plans to use global abbrevs only. This makes the commands that normally define mode-specific abbrevs @@ -363,6 +375,528 @@ (if (or noquery (y-or-n-p (format "Expand `%s'? " string))) (expand-abbrev))))))) +;;; Abbrev properties. + +(defun abbrev-table-get (table prop) + "Get the PROP property of abbrev table TABLE." + (let ((sym (intern-soft "" table))) + (if sym (get sym prop)))) + +(defun abbrev-table-put (table prop val) + "Set the PROP property of abbrev table TABLE to VAL." + (let ((sym (intern "" table))) + (set sym nil) ; Make sure it won't be confused for an abbrev. + (put sym prop val))) + +(defun abbrev-get (sym prop) + "Get the property PROP of abbrev SYM." + (let ((plist (symbol-plist sym))) + (if (listp plist) + (plist-get plist prop) + (if (eq 'count prop) plist)))) + +(defun abbrev-put (sym prop val) + "Set the property PROP of abbrev SYM to value VAL. +See `define-abbrev' for the effect of some special properties." + (let ((plist (symbol-plist sym))) + (if (consp plist) + (put sym prop val) + (setplist sym (if (eq 'count prop) val + (list 'count plist prop val)))))) + +(defmacro abbrev-with-wrapper-hook (var &rest body) + "Run BODY wrapped with the VAR hook. +VAR is a special hook: its functions are called with one argument which +is the \"original\" code (the BODY), so the hook function can wrap the +original function, can call it several times, or even not call it at all. +VAR is normally a symbol (a variable) in which case it is treated like a hook, +with a buffer-local and a global part. But it can also be an arbitrary expression. +This is similar to an `around' advice." + (declare (indent 1) (debug t)) + ;; We need those two gensyms because CL's lexical scoping is not available + ;; for function arguments :-( + (let ((funs (make-symbol "funs")) + (global (make-symbol "global"))) + ;; Since the hook is a wrapper, the loop has to be done via + ;; recursion: a given hook function will call its parameter in order to + ;; continue looping. + `(labels ((runrestofhook (,funs ,global) + ;; `funs' holds the functions left on the hook and `global' + ;; holds the functions left on the global part of the hook + ;; (in case the hook is local). + (lexical-let ((funs ,funs) + (global ,global)) + (if (consp funs) + (if (eq t (car funs)) + (runrestofhook (append global (cdr funs)) nil) + (funcall (car funs) + (lambda () (runrestofhook (cdr funs) global)))) + ;; Once there are no more functions on the hook, run + ;; the original body. + ,@body)))) + (runrestofhook ,var + ;; The global part of the hook, if any. + ,(if (symbolp var) + `(if (local-variable-p ',var) + (default-value ',var))))))) + + +;;; Code that used to be implemented in src/abbrev.c + +(defvar abbrev-table-name-list '(fundamental-mode-abbrev-table + global-abbrev-table) + "List of symbols whose values are abbrev tables.") + +(defun make-abbrev-table (&optional props) + "Create a new, empty abbrev table object. +PROPS is a " + ;; The value 59 is an arbitrary prime number. + (let ((table (make-vector 59 0))) + ;; Each abbrev-table has a `modiff' counter which can be used to detect + ;; when an abbreviation was added. An example of use would be to + ;; construct :regexp dynamically as the union of all abbrev names, so + ;; `modiff' can let us detect that an abbrev was added and hence :regexp + ;; needs to be refreshed. + ;; The presence of `modiff' entry is also used as a tag indicating this + ;; vector is really an abbrev-table. + (abbrev-table-put table :abbrev-table-modiff 0) + (while (consp props) + (abbrev-table-put table (pop props) (pop props))) + table)) + +(defun abbrev-table-p (object) + (and (vectorp object) + (numberp (abbrev-table-get object :abbrev-table-modiff)))) + +(defvar global-abbrev-table (make-abbrev-table) + "The abbrev table whose abbrevs affect all buffers. +Each buffer may also have a local abbrev table. +If it does, the local table overrides the global one +for any particular abbrev defined in both.") + +(defvar abbrev-minor-mode-table-alist nil + "Alist of abbrev tables to use for minor modes. +Each element looks like (VARIABLE . ABBREV-TABLE); +ABBREV-TABLE is active whenever VARIABLE's value is non-nil.") + +(defvar fundamental-mode-abbrev-table + (let ((table (make-abbrev-table))) + ;; Set local-abbrev-table's default to be fundamental-mode-abbrev-table. + (setq-default local-abbrev-table table) + table) + "The abbrev table of mode-specific abbrevs for Fundamental Mode.") + +(defvar abbrevs-changed nil + "Set non-nil by defining or altering any word abbrevs. +This causes `save-some-buffers' to offer to save the abbrevs.") + +(defcustom abbrev-all-caps nil + "Non-nil means expand multi-word abbrevs all caps if abbrev was so." + :type 'boolean + :group 'abbrev-mode) + +(defvar abbrev-start-location nil + "Buffer position for `expand-abbrev' to use as the start of the abbrev. +When nil, use the word before point as the abbrev. +Calling `expand-abbrev' sets this to nil.") + +(defvar abbrev-start-location-buffer nil + "Buffer that `abbrev-start-location' has been set for. +Trying to expand an abbrev in any other buffer clears `abbrev-start-location'.") + +(defvar last-abbrev nil + "The abbrev-symbol of the last abbrev expanded. See `abbrev-symbol'.") + +(defvar last-abbrev-text nil + "The exact text of the last abbrev expanded. +nil if the abbrev has already been unexpanded.") + +(defvar last-abbrev-location 0 + "The location of the start of the last abbrev expanded.") + +;; (defvar local-abbrev-table fundamental-mode-abbrev-table +;; "Local (mode-specific) abbrev table of current buffer.") +;; (make-variable-buffer-local 'local-abbrev-table) + +(defcustom pre-abbrev-expand-hook nil + "Function or functions to be called before abbrev expansion is done. +This is the first thing that `expand-abbrev' does, and so this may change +the current abbrev table before abbrev lookup happens." + :type 'hook + :group 'abbrev-mode) +(make-obsolete-variable 'pre-abbrev-expand-hook 'abbrev-expand-functions "23.1") + +(defun clear-abbrev-table (table) + "Undefine all abbrevs in abbrev table TABLE, leaving it empty." + (setq abbrevs-changed t) + (dotimes (i (length table)) + (aset table i 0))) + +(defun define-abbrev (table name expansion &optional hook &rest props) + "Define an abbrev in TABLE named NAME, to expand to EXPANSION and call HOOK. +NAME must be a string, and should be lower-case. +EXPANSION should usually be a string. +To undefine an abbrev, define it with EXPANSION = nil. +If HOOK is non-nil, it should be a function of no arguments; +it is called after EXPANSION is inserted. +If EXPANSION is not a string, the abbrev is a special one, + which does not expand in the usual way but only runs HOOK. + +PROPS is a property list. The following properties are special: +- `count': the value for the abbrev's usage-count, which is incremented each time + the abbrev is used (the default is zero). +- `system-flag': if non-nil, says that this is a \"system\" abbreviation + which should not be saved in the user's abbreviation file. + Unless `system-flag' is `force', a system abbreviation will not + overwrite a non-system abbreviation of the same name. +- `:case-fixed': non-nil means that abbreviations are looked up without + case-folding, and the expansion is not capitalized/upcased. +- `:enable-function': a function of no argument which returns non-nil iff the + abbrev should be used for a particular call of `expand-abbrev'. + +An obsolete but still supported calling form is: + +\(define-abbrev TABLE NAME EXPANSION &optional HOOK COUNT SYSTEM-FLAG)." + (when (and (consp props) (or (null (car props)) (numberp (car props)))) + ;; Old-style calling convention. + (setq props (list* 'count (car props) + (if (cadr props) (list 'system-flag (cadr props)))))) + (unless (plist-get props 'count) + (setq props (plist-put props 'count 0))) + (let ((system-flag (plist-get props 'system-flag)) + (sym (intern name table))) + ;; Don't override a prior user-defined abbrev with a system abbrev, + ;; unless system-flag is `force'. + (unless (and (not (memq system-flag '(nil force))) + (boundp sym) (symbol-value sym) + (not (abbrev-get sym 'system-flag))) + (unless (or system-flag + (and (boundp sym) (fboundp sym) + ;; load-file-name + (equal (symbol-value sym) expansion) + (equal (symbol-function sym) hook))) + (setq abbrevs-changed t)) + (set sym expansion) + (fset sym hook) + (setplist sym props) + (abbrev-table-put table :abbrev-table-modiff + (1+ (abbrev-table-get table :abbrev-table-modiff)))) + name)) + +(defun abbrev--check-chars (abbrev global) + "Check if the characters in ABBREV have word syntax in either the +current (if global is nil) or standard syntax table." + (with-syntax-table + (cond ((null global) (standard-syntax-table)) + ;; ((syntax-table-p global) global) + (t (syntax-table))) + (when (string-match "\\W" abbrev) + (let ((badchars ()) + (pos 0)) + (while (string-match "\\W" abbrev pos) + (pushnew (aref abbrev (match-beginning 0)) badchars) + (setq pos (1+ pos))) + (error "Some abbrev characters (%s) are not word constituents %s" + (apply 'string (nreverse badchars)) + (if global "in the standard syntax" "in this mode")))))) + +(defun define-global-abbrev (abbrev expansion) + "Define ABBREV as a global abbreviation for EXPANSION. +The characters in ABBREV must all be word constituents in the standard +syntax table." + (interactive "sDefine global abbrev: \nsExpansion for %s: ") + (abbrev--check-chars abbrev 'global) + (define-abbrev global-abbrev-table (downcase abbrev) expansion)) + +(defun define-mode-abbrev (abbrev expansion) + "Define ABBREV as a mode-specific abbreviation for EXPANSION. +The characters in ABBREV must all be word-constituents in the current mode." + (interactive "sDefine mode abbrev: \nsExpansion for %s: ") + (unless local-abbrev-table + (error "Major mode has no abbrev table")) + (abbrev--check-chars abbrev nil) + (define-abbrev local-abbrev-table (downcase abbrev) expansion)) + +(defun abbrev--active-tables (&optional tables) + "Return the list of abbrev tables currently active. +TABLES if non-nil overrides the usual rules. It can hold +either a single abbrev table or a list of abbrev tables." + ;; We could just remove the `tables' arg and let callers use + ;; (or table (abbrev--active-tables)) but then they'd have to be careful + ;; to treat the distinction between a single table and a list of tables. + (cond + ((consp tables) tables) + ((vectorp tables) (list tables)) + (t + (let ((tables (if (listp local-abbrev-table) + (append local-abbrev-table + (list global-abbrev-table)) + (list local-abbrev-table global-abbrev-table)))) + ;; Add the minor-mode abbrev tables. + (dolist (x abbrev-minor-mode-table-alist) + (when (and (symbolp (car x)) (boundp (car x)) (symbol-value (car x))) + (setq tables + (if (listp (cdr x)) + (append (cdr x) tables) (cons (cdr x) tables))))) + tables)))) + + +(defun abbrev-symbol (abbrev &optional table) + "Return the symbol representing abbrev named ABBREV. +This symbol's name is ABBREV, but it is not the canonical symbol of that name; +it is interned in an abbrev-table rather than the normal obarray. +The value is nil if that abbrev is not defined. +Optional second arg TABLE is abbrev table to look it up in. +The default is to try buffer's mode-specific abbrev table, then global table." + (let ((tables (abbrev--active-tables table)) + sym) + (while (and tables (not (symbol-value sym))) + (let ((table (pop tables)) + (case-fold (not (abbrev-table-get table :case-fixed)))) + (setq tables (append (abbrev-table-get table :parents) tables)) + ;; In case the table doesn't set :case-fixed but some of the + ;; abbrevs do, we have to be careful. + (setq sym + ;; First try without case-folding. + (or (intern-soft abbrev table) + (when case-fold + ;; We didn't find any abbrev, try case-folding. + (let ((sym (intern-soft (downcase abbrev) table))) + ;; Only use it if it doesn't require :case-fixed. + (and sym (not (abbrev-get sym :case-fixed)) + sym))))))) + (if (symbol-value sym) + sym))) + + +(defun abbrev-expansion (abbrev &optional table) + "Return the string that ABBREV expands into in the current buffer. +Optionally specify an abbrev table as second arg; +then ABBREV is looked up in that table only." + (symbol-value (abbrev-symbol abbrev table))) + + +(defun abbrev--before-point () + "Try and find an abbrev before point. Return it if found, nil otherwise." + (unless (eq abbrev-start-location-buffer (current-buffer)) + (setq abbrev-start-location nil)) + + (let ((tables (abbrev--active-tables)) + (pos (point)) + start end name res) + + (if abbrev-start-location + (progn + (setq start abbrev-start-location) + (setq abbrev-start-location nil) + ;; Remove the hyphen inserted by `abbrev-prefix-mark'. + (if (and (< start (point-max)) + (eq (char-after start) ?-)) + (delete-region start (1+ start))) + (skip-syntax-backward " ") + (setq end (point)) + (setq name (buffer-substring start end)) + (goto-char pos) ; Restore point. + (list (abbrev-symbol name tables) name start end)) + + (while (and tables (not (car res))) + (let* ((table (pop tables)) + (enable-fun (abbrev-table-get table :enable-function))) + (setq tables (append (abbrev-table-get table :parents) tables)) + (setq res + (and (or (not enable-fun) (funcall enable-fun)) + (looking-back (or (abbrev-table-get table :regexp) + "\\<\\(\\w+\\)\\W*") + (line-beginning-position)) + (setq start (match-beginning 1)) + (setq end (match-end 1)) + (setq name (buffer-substring start end)) + ;; This will also look it up in parent tables. + ;; This is not on purpose, but it seems harmless. + (list (abbrev-symbol name table) name start end))) + ;; Restore point. + (goto-char pos))) + res))) + +(defvar abbrev-expand-functions nil + "Wrapper hook around `expand-abbrev'. +The functions on this special hook are called with one argument: +a function that performs the abbrev expansion. It should return +the abbrev symbol if expansion took place.") + +(defun expand-abbrev () + "Expand the abbrev before point, if there is an abbrev there. +Effective when explicitly called even when `abbrev-mode' is nil. +Returns the abbrev symbol, if expansion took place." + (interactive) + (run-hooks 'pre-abbrev-expand-hook) + (abbrev-with-wrapper-hook abbrev-expand-functions + (destructuring-bind (&optional sym name wordstart wordend) + (abbrev--before-point) + (when sym + (let ((value sym)) + (unless (or ;; executing-kbd-macro + noninteractive + (window-minibuffer-p (selected-window))) + ;; Add an undo boundary, in case we are doing this for + ;; a self-inserting command which has avoided making one so far. + (undo-boundary)) + ;; Now sym is the abbrev symbol. + (setq last-abbrev-text name) + (setq last-abbrev sym) + (setq last-abbrev-location wordstart) + ;; Increment use count. + (abbrev-put sym 'count (1+ (abbrev-get sym 'count))) + ;; If this abbrev has an expansion, delete the abbrev + ;; and insert the expansion. + (when (stringp (symbol-value sym)) + (goto-char wordend) + (insert (symbol-value sym)) + (delete-region wordstart wordend) + (let ((case-fold-search nil)) + ;; If the abbrev's name is different from the buffer text (the + ;; only difference should be capitalization), then we may want + ;; to adjust the capitalization of the expansion. + (when (and (not (equal name (symbol-name sym))) + (string-match "[[:upper:]]" name)) + (if (not (string-match "[[:lower:]]" name)) + ;; Abbrev was all caps. If expansion is multiple words, + ;; normally capitalize each word. + (if (and (not abbrev-all-caps) + (save-excursion + (> (progn (backward-word 1) (point)) + (progn (goto-char wordstart) + (forward-word 1) (point))))) + (upcase-initials-region wordstart (point)) + (upcase-region wordstart (point))) + ;; Abbrev included some caps. Cap first initial of expansion. + (let ((end (point))) + ;; Find the initial. + (goto-char wordstart) + (skip-syntax-forward "^w" (1- end)) + ;; Change just that. + (upcase-initials-region (point) (1+ (point)))))))) + (when (symbol-function sym) + (let* ((hook (symbol-function sym)) + (expanded + ;; If the abbrev has a hook function, run it. + (funcall hook))) + ;; In addition, if the hook function is a symbol with + ;; a non-nil `no-self-insert' property, let the value it + ;; returned specify whether we consider that an expansion took + ;; place. If it returns nil, no expansion has been done. + (if (and (symbolp hook) + (null expanded) + (get hook 'no-self-insert)) + (setq value nil)))) + value))))) + +(defun unexpand-abbrev () + "Undo the expansion of the last abbrev that expanded. +This differs from ordinary undo in that other editing done since then +is not undone." + (interactive) + (save-excursion + (unless (or (< last-abbrev-location (point-min)) + (> last-abbrev-location (point-max))) + (goto-char last-abbrev-location) + (when (stringp last-abbrev-text) + ;; This isn't correct if last-abbrev's hook was used + ;; to do the expansion. + (let ((val (symbol-value last-abbrev))) + (unless (stringp val) + (error "value of abbrev-symbol must be a string")) + (delete-region (point) (+ (point) (length val))) + ;; Don't inherit properties here; just copy from old contents. + (insert last-abbrev-text) + (setq last-abbrev-text nil)))))) + +(defun abbrev--write (sym) + "Write the abbrev in a `read'able form. +Only writes the non-system abbrevs. +Presumes that `standard-output' points to `current-buffer'." + (unless (or (null (symbol-value sym)) (abbrev-get sym 'system-flag)) + (insert " (") + (prin1 name) + (insert " ") + (prin1 (symbol-value sym)) + (insert " ") + (prin1 (symbol-function sym)) + (insert " ") + (prin1 (abbrev-get sym 'count)) + (insert ")\n"))) + +(defun abbrev--describe (sym) + (when (symbol-value sym) + (prin1 (symbol-name sym)) + (if (null (abbrev-get sym 'system-flag)) + (indent-to 15 1) + (insert " (sys)") + (indent-to 20 1)) + (prin1 (abbrev-get sym 'count)) + (indent-to 20 1) + (prin1 (symbol-value sym)) + (when (symbol-function sym) + (indent-to 45 1) + (prin1 (symbol-function sym))) + (terpri))) + +(defun insert-abbrev-table-description (name &optional readable) + "Insert before point a full description of abbrev table named NAME. +NAME is a symbol whose value is an abbrev table. +If optional 2nd arg READABLE is non-nil, a human-readable description +is inserted. Otherwise the description is an expression, +a call to `define-abbrev-table', which would +define the abbrev table NAME exactly as it is currently defined. + +Abbrevs marked as \"system abbrevs\" are omitted." + (let ((table (symbol-value name)) + (symbols ())) + (mapatoms (lambda (sym) (if (symbol-value sym) (push sym symbols))) table) + (setq symbols (sort symbols 'string-lessp)) + (let ((standard-output (current-buffer))) + (if readable + (progn + (insert "(") + (prin1 name) + (insert ")\n\n") + (mapc 'abbrev--describe symbols) + (insert "\n\n")) + (insert "(define-abbrev-table '") + (prin1 name) + (insert " '(") + (mapc 'abbrev--write symbols) + (insert " ))\n\n")) + nil))) + +(defun define-abbrev-table (tablename definitions + &optional docstring &rest props) + "Define TABLENAME (a symbol) as an abbrev table name. +Define abbrevs in it according to DEFINITIONS, which is a list of elements +of the form (ABBREVNAME EXPANSION HOOK USECOUNT SYSTEMFLAG). +\(If the list is shorter than that, omitted elements default to nil). +PROPS is a property list to apply to the table. +Properties with special meaning: +- `:parents' contains a list of abbrev tables from which this table inherits + abbreviations. +- `:case-fixed' non-nil means that abbreviations are looked up without + case-folding, and the expansion is not capitalized/upcased. +- `:regexp' describes the form of abbrevs. It defaults to \\<\\(\\w+\\)\\W* which + means that an abbrev can only be a single word. The submatch 1 is treated + as the potential name of an abbrev. +- `:enable-function' can be set to a function of no argument which returns + non-nil iff the abbrevs in this table should be used for this instance + of `expand-abbrev'." + (let ((table (if (boundp tablename) (symbol-value tablename)))) + (unless table + (setq table (make-abbrev-table props)) + (set tablename table) + (push tablename abbrev-table-name-list)) + (when (stringp docstring) + (put tablename 'variable-documentation docstring)) + (dolist (elt definitions) + (apply 'define-abbrev table elt)))) + (provide 'abbrev) ;; arch-tag: dbd6f3ae-dfe3-40ba-b00f-f9e3ff960df5
--- a/lisp/cus-edit.el Sat Oct 27 22:15:27 2007 +0000 +++ b/lisp/cus-edit.el Sun Oct 28 02:41:00 2007 +0000 @@ -374,11 +374,6 @@ :prefix "custom-" :group 'customize) -(defgroup abbrev-mode nil - "Word abbreviations mode." - :link '(custom-manual "(emacs)Abbrevs") - :group 'abbrev) - (defgroup alloc nil "Storage allocation and gc for GNU Emacs Lisp interpreter." :tag "Storage Allocation"
--- a/lisp/cus-start.el Sat Oct 27 22:15:27 2007 +0000 +++ b/lisp/cus-start.el Sun Oct 28 02:41:00 2007 +0000 @@ -35,10 +35,7 @@ ;;; Code: -(let ((all '(;; abbrev.c - (abbrev-all-caps abbrev-mode boolean) - (pre-abbrev-expand-hook abbrev-mode hook) - ;; alloc.c +(let ((all '(;; alloc.c (gc-cons-threshold alloc integer) (garbage-collection-messages alloc boolean) ;; buffer.c
--- a/lisp/loadup.el Sat Oct 27 22:15:27 2007 +0000 +++ b/lisp/loadup.el Sun Oct 28 02:41:00 2007 +0000 @@ -160,6 +160,7 @@ (load "textmodes/page") (load "register") (load "textmodes/paragraphs") +(load "abbrev") ;lisp-mode.el uses define-abbrev-table. (load "emacs-lisp/lisp-mode") (load "textmodes/text-mode") (load "textmodes/fill") @@ -169,7 +170,6 @@ (if (eq system-type 'vax-vms) (progn (load "vmsproc"))) -(load "abbrev") (load "buff-menu") (if (fboundp 'x-create-frame)
--- a/src/ChangeLog Sat Oct 27 22:15:27 2007 +0000 +++ b/src/ChangeLog Sun Oct 28 02:41:00 2007 +0000 @@ -1,3 +1,14 @@ +2007-10-28 Stefan Monnier <monnier@iro.umontreal.ca> + + Rewrite abbrev.c in Elisp. + * image.c (Qcount): Don't declare as extern. + (syms_of_image): Initialize and staticpro `Qcount'. + * puresize.h (BASE_PURESIZE): Increase for the new abbrev.el functions. + * emacs.c (main): Don't call syms_of_abbrev. + * Makefile.in (obj): Remove abbrev.o. + (abbrev.o): Remove. + * abbrev.c: Remove. + 2007-10-26 Martin Rudalics <rudalics@gmx.at> * window.c (window_min_size_2): Don't count header-line.
--- a/src/Makefile.in Sat Oct 27 22:15:27 2007 +0000 +++ b/src/Makefile.in Sun Oct 28 02:41:00 2007 +0000 @@ -603,7 +603,7 @@ cmds.o casetab.o casefiddle.o indent.o search.o regex.o undo.o \ alloc.o data.o doc.o editfns.o callint.o \ eval.o floatfns.o fns.o print.o lread.o \ - abbrev.o syntax.o UNEXEC bytecode.o \ + syntax.o UNEXEC bytecode.o \ process.o callproc.o \ region-cache.o sound.o atimer.o \ doprnt.o strftime.o intervals.o textprop.o composite.o md5.o \ @@ -1094,8 +1094,6 @@ it is so often changed in ways that do not require any recompilation and so rarely changed in ways that do require any. */ -abbrev.o: abbrev.c buffer.h window.h dispextern.h commands.h charset.h \ - syntax.h $(config_h) buffer.o: buffer.c buffer.h region-cache.h commands.h window.h \ dispextern.h $(INTERVAL_SRC) blockinput.h atimer.h systime.h charset.h \ $(config_h) @@ -1279,7 +1277,7 @@ sunfns.o: sunfns.c buffer.h window.h dispextern.h termhooks.h $(config_h) #ifdef HAVE_CARBON -abbrev.o buffer.o callint.o cmds.o dispnew.o editfns.o fileio.o frame.o \ +buffer.o callint.o cmds.o dispnew.o editfns.o fileio.o frame.o \ fontset.o indent.o insdel.o keyboard.o macros.o minibuf.o msdos.o process.o \ scroll.o sysdep.o term.o terminal.o widget.o window.o xdisp.o xfaces.o xfns.o xmenu.o \ xterm.o xselect.o sound.o: macgui.h
--- a/src/abbrev.c Sat Oct 27 22:15:27 2007 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,803 +0,0 @@ -/* Primitives for word-abbrev mode. - Copyright (C) 1985, 1986, 1993, 1996, 1998, 2001, 2002, 2003, 2004, - 2005, 2006, 2007 Free Software Foundation, Inc. - -This file is part of GNU Emacs. - -GNU Emacs is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3, or (at your option) -any later version. - -GNU Emacs is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU Emacs; see the file COPYING. If not, write to -the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -Boston, MA 02110-1301, USA. */ - - -#include <config.h> -#include <stdio.h> - -#include "lisp.h" -#include "commands.h" -#include "buffer.h" -#include "window.h" -#include "charset.h" -#include "syntax.h" - -/* An abbrev table is an obarray. - Each defined abbrev is represented by a symbol in that obarray - whose print name is the abbreviation. - The symbol's value is a string which is the expansion. - If its function definition is non-nil, it is called - after the expansion is done. - The plist slot of the abbrev symbol is its usage count. */ - -/* List of all abbrev-table name symbols: - symbols whose values are abbrev tables. */ - -Lisp_Object Vabbrev_table_name_list; - -/* The table of global abbrevs. These are in effect - in any buffer in which abbrev mode is turned on. */ - -Lisp_Object Vglobal_abbrev_table; - -/* The local abbrev table used by default (in Fundamental Mode buffers) */ - -Lisp_Object Vfundamental_mode_abbrev_table; - -/* Set nonzero when an abbrev definition is changed */ - -int abbrevs_changed; - -int abbrev_all_caps; - -/* Non-nil => use this location as the start of abbrev to expand - (rather than taking the word before point as the abbrev) */ - -Lisp_Object Vabbrev_start_location; - -/* Buffer that Vabbrev_start_location applies to */ -Lisp_Object Vabbrev_start_location_buffer; - -/* The symbol representing the abbrev most recently expanded */ - -Lisp_Object Vlast_abbrev; - -/* A string for the actual text of the abbrev most recently expanded. - This has more info than Vlast_abbrev since case is significant. */ - -Lisp_Object Vlast_abbrev_text; - -/* Character address of start of last abbrev expanded */ - -EMACS_INT last_abbrev_point; - -/* Hook to run before expanding any abbrev. */ - -Lisp_Object Vpre_abbrev_expand_hook, Qpre_abbrev_expand_hook; - -Lisp_Object Qsystem_type, Qcount, Qforce; - -DEFUN ("make-abbrev-table", Fmake_abbrev_table, Smake_abbrev_table, 0, 0, 0, - doc: /* Create a new, empty abbrev table object. */) - () -{ - /* The value 59 is arbitrary chosen prime number. */ - return Fmake_vector (make_number (59), make_number (0)); -} - -DEFUN ("clear-abbrev-table", Fclear_abbrev_table, Sclear_abbrev_table, 1, 1, 0, - doc: /* Undefine all abbrevs in abbrev table TABLE, leaving it empty. */) - (table) - Lisp_Object table; -{ - int i, size; - - CHECK_VECTOR (table); - size = XVECTOR (table)->size; - abbrevs_changed = 1; - for (i = 0; i < size; i++) - XVECTOR (table)->contents[i] = make_number (0); - return Qnil; -} - -DEFUN ("define-abbrev", Fdefine_abbrev, Sdefine_abbrev, 3, 6, 0, - doc: /* Define an abbrev in TABLE named NAME, to expand to EXPANSION and call HOOK. -NAME must be a string, and should be lower-case. -EXPANSION should usually be a string. -To undefine an abbrev, define it with EXPANSION = nil. -If HOOK is non-nil, it should be a function of no arguments; -it is called after EXPANSION is inserted. -If EXPANSION is not a string, the abbrev is a special one, - which does not expand in the usual way but only runs HOOK. - -COUNT, if specified, gives the initial value for the abbrev's -usage-count, which is incremented each time the abbrev is used. -\(The default is zero.) - -SYSTEM-FLAG, if non-nil, says that this is a "system" abbreviation -which should not be saved in the user's abbreviation file. -Unless SYSTEM-FLAG is `force', a system abbreviation will not -overwrite a non-system abbreviation of the same name. */) - (table, name, expansion, hook, count, system_flag) - Lisp_Object table, name, expansion, hook, count, system_flag; -{ - Lisp_Object sym, oexp, ohook, tem; - CHECK_VECTOR (table); - CHECK_STRING (name); - - /* If defining a system abbrev, do not overwrite a non-system abbrev - of the same name, unless 'force is used. */ - if (!NILP (system_flag) && !EQ (system_flag, Qforce)) - { - sym = Fintern_soft (name, table); - - if (!NILP (SYMBOL_VALUE (sym)) && - NILP (Fplist_get (XSYMBOL (sym)->plist, Qsystem_type))) return Qnil; - } - - if (NILP (count)) - count = make_number (0); - else - CHECK_NUMBER (count); - - sym = Fintern (name, table); - - oexp = SYMBOL_VALUE (sym); - ohook = XSYMBOL (sym)->function; - if (!((EQ (oexp, expansion) - || (STRINGP (oexp) && STRINGP (expansion) - && (tem = Fstring_equal (oexp, expansion), !NILP (tem)))) - && - (EQ (ohook, hook) - || (tem = Fequal (ohook, hook), !NILP (tem)))) - && NILP (system_flag)) - abbrevs_changed = 1; - - Fset (sym, expansion); - Ffset (sym, hook); - - if (! NILP (system_flag)) - Fsetplist (sym, list4 (Qcount, count, Qsystem_type, system_flag)); - else - Fsetplist (sym, count); - - return name; -} - -/* Check if the characters in ABBREV have word syntax in either the - * current (if global == 0) or standard syntax table. */ -static void -abbrev_check_chars (abbrev, global) - Lisp_Object abbrev; - int global; -{ - int i, i_byte, len, nbad = 0; - int j, found, nuniq = 0; - char *badchars, *baduniq; - - CHECK_STRING (abbrev); - len = SCHARS (abbrev); - - badchars = (char *) alloca (len + 1); - - for (i = 0, i_byte = 0; i < len; ) - { - int c; - - FETCH_STRING_CHAR_ADVANCE (c, abbrev, i, i_byte); - - if (global) - { - /* Copied from SYNTAX in syntax.h, except using FOLLOW_PARENT. */ - Lisp_Object syntax_temp - = SYNTAX_ENTRY_FOLLOW_PARENT (Vstandard_syntax_table, c); - if ( (CONSP (syntax_temp) - ? (enum syntaxcode) (XINT (XCAR (syntax_temp)) & 0xff) - : Swhitespace) != Sword ) badchars[nbad++] = c; - } - else if (SYNTAX (c) != Sword) - badchars[nbad++] = c; - } - - if (nbad == 0) return; - - baduniq = (char *) alloca (nbad + 1); - - for (i = 0; i < nbad; i++) - { - found = 0; - - for (j = 0; j < nuniq; j++) - { - if (badchars[i] == baduniq[j]) - { - found = 1; - break; - } - } - - if (found) continue ; - - baduniq[nuniq++] = badchars[i]; - } - - baduniq[nuniq] = '\0'; - - error ("Some abbrev characters (%s) are not word constituents %s", - baduniq, global ? "in the standard syntax" : "in this mode" ); -} - -DEFUN ("define-global-abbrev", Fdefine_global_abbrev, Sdefine_global_abbrev, 2, 2, - "sDefine global abbrev: \nsExpansion for %s: ", - doc: /* Define ABBREV as a global abbreviation for EXPANSION. -The characters in ABBREV must all be word constituents in the standard -syntax table. */) - (abbrev, expansion) - Lisp_Object abbrev, expansion; -{ - abbrev_check_chars (abbrev, 1); - - Fdefine_abbrev (Vglobal_abbrev_table, Fdowncase (abbrev), - expansion, Qnil, make_number (0), Qnil); - return abbrev; -} - -DEFUN ("define-mode-abbrev", Fdefine_mode_abbrev, Sdefine_mode_abbrev, 2, 2, - "sDefine mode abbrev: \nsExpansion for %s: ", - doc: /* Define ABBREV as a mode-specific abbreviation for EXPANSION. -The characters in ABBREV must all be word-constituents in the current mode. */) - (abbrev, expansion) - Lisp_Object abbrev, expansion; -{ - if (NILP (current_buffer->abbrev_table)) - error ("Major mode has no abbrev table"); - - abbrev_check_chars (abbrev, 0); - - Fdefine_abbrev (current_buffer->abbrev_table, Fdowncase (abbrev), - expansion, Qnil, make_number (0), Qnil); - return abbrev; -} - -DEFUN ("abbrev-symbol", Fabbrev_symbol, Sabbrev_symbol, 1, 2, 0, - doc: /* Return the symbol representing abbrev named ABBREV. -This symbol's name is ABBREV, but it is not the canonical symbol of that name; -it is interned in an abbrev-table rather than the normal obarray. -The value is nil if that abbrev is not defined. -Optional second arg TABLE is abbrev table to look it up in. -The default is to try buffer's mode-specific abbrev table, then global table. */) - (abbrev, table) - Lisp_Object abbrev, table; -{ - Lisp_Object sym; - CHECK_STRING (abbrev); - if (!NILP (table)) - sym = Fintern_soft (abbrev, table); - else - { - sym = Qnil; - if (!NILP (current_buffer->abbrev_table)) - sym = Fintern_soft (abbrev, current_buffer->abbrev_table); - if (NILP (SYMBOL_VALUE (sym))) - sym = Qnil; - if (NILP (sym)) - sym = Fintern_soft (abbrev, Vglobal_abbrev_table); - } - if (NILP (SYMBOL_VALUE (sym))) - return Qnil; - return sym; -} - -DEFUN ("abbrev-expansion", Fabbrev_expansion, Sabbrev_expansion, 1, 2, 0, - doc: /* Return the string that ABBREV expands into in the current buffer. -Optionally specify an abbrev table as second arg; -then ABBREV is looked up in that table only. */) - (abbrev, table) - Lisp_Object abbrev, table; -{ - Lisp_Object sym; - sym = Fabbrev_symbol (abbrev, table); - if (NILP (sym)) return sym; - return Fsymbol_value (sym); -} - -/* Expand the word before point, if it is an abbrev. - Returns 1 if an expansion is done. */ - -DEFUN ("expand-abbrev", Fexpand_abbrev, Sexpand_abbrev, 0, 0, "", - doc: /* Expand the abbrev before point, if there is an abbrev there. -Effective when explicitly called even when `abbrev-mode' is nil. -Returns the abbrev symbol, if expansion took place. */) - () -{ - register char *buffer, *p; - int wordstart, wordend; - register int wordstart_byte, wordend_byte, idx, idx_byte; - int whitecnt; - int uccount = 0, lccount = 0; - register Lisp_Object sym; - Lisp_Object expansion, hook, tem; - Lisp_Object value; - int multibyte = ! NILP (current_buffer->enable_multibyte_characters); - - value = Qnil; - - Frun_hooks (1, &Qpre_abbrev_expand_hook); - - wordstart = 0; - if (!(BUFFERP (Vabbrev_start_location_buffer) - && XBUFFER (Vabbrev_start_location_buffer) == current_buffer)) - Vabbrev_start_location = Qnil; - if (!NILP (Vabbrev_start_location)) - { - tem = Vabbrev_start_location; - CHECK_NUMBER_COERCE_MARKER (tem); - wordstart = XINT (tem); - Vabbrev_start_location = Qnil; - if (wordstart < BEGV || wordstart > ZV) - wordstart = 0; - if (wordstart && wordstart != ZV) - { - wordstart_byte = CHAR_TO_BYTE (wordstart); - if (FETCH_BYTE (wordstart_byte) == '-') - del_range (wordstart, wordstart + 1); - } - } - if (!wordstart) - wordstart = scan_words (PT, -1); - - if (!wordstart) - return value; - - wordstart_byte = CHAR_TO_BYTE (wordstart); - wordend = scan_words (wordstart, 1); - if (!wordend) - return value; - - if (wordend > PT) - wordend = PT; - - wordend_byte = CHAR_TO_BYTE (wordend); - whitecnt = PT - wordend; - if (wordend <= wordstart) - return value; - - p = buffer = (char *) alloca (wordend_byte - wordstart_byte); - - for (idx = wordstart, idx_byte = wordstart_byte; idx < wordend; ) - { - register int c; - - if (multibyte) - { - FETCH_CHAR_ADVANCE (c, idx, idx_byte); - } - else - { - c = FETCH_BYTE (idx_byte); - idx++, idx_byte++; - } - - if (UPPERCASEP (c)) - c = DOWNCASE (c), uccount++; - else if (! NOCASEP (c)) - lccount++; - if (multibyte) - p += CHAR_STRING (c, p); - else - *p++ = c; - } - - if (VECTORP (current_buffer->abbrev_table)) - sym = oblookup (current_buffer->abbrev_table, buffer, - wordend - wordstart, p - buffer); - else - XSETFASTINT (sym, 0); - - if (INTEGERP (sym) || NILP (SYMBOL_VALUE (sym))) - sym = oblookup (Vglobal_abbrev_table, buffer, - wordend - wordstart, p - buffer); - if (INTEGERP (sym) || NILP (SYMBOL_VALUE (sym))) - return value; - - if (INTERACTIVE && !EQ (minibuf_window, selected_window)) - { - /* Add an undo boundary, in case we are doing this for - a self-inserting command which has avoided making one so far. */ - SET_PT (wordend); - Fundo_boundary (); - } - - Vlast_abbrev_text - = Fbuffer_substring (make_number (wordstart), make_number (wordend)); - - /* Now sym is the abbrev symbol. */ - Vlast_abbrev = sym; - value = sym; - last_abbrev_point = wordstart; - - /* Increment use count. */ - if (INTEGERP (XSYMBOL (sym)->plist)) - XSETINT (XSYMBOL (sym)->plist, - XINT (XSYMBOL (sym)->plist) + 1); - else if (INTEGERP (tem = Fget (sym, Qcount))) - Fput (sym, Qcount, make_number (XINT (tem) + 1)); - - /* If this abbrev has an expansion, delete the abbrev - and insert the expansion. */ - expansion = SYMBOL_VALUE (sym); - if (STRINGP (expansion)) - { - SET_PT (wordstart); - - insert_from_string (expansion, 0, 0, SCHARS (expansion), - SBYTES (expansion), 1); - del_range_both (PT, PT_BYTE, - wordend + (PT - wordstart), - wordend_byte + (PT_BYTE - wordstart_byte), - 1); - - SET_PT (PT + whitecnt); - - if (uccount && !lccount) - { - /* Abbrev was all caps */ - /* If expansion is multiple words, normally capitalize each word */ - /* This used to be if (!... && ... >= ...) Fcapitalize; else Fupcase - but Megatest 68000 compiler can't handle that */ - if (!abbrev_all_caps) - if (scan_words (PT, -1) > scan_words (wordstart, 1)) - { - Fupcase_initials_region (make_number (wordstart), - make_number (PT)); - goto caped; - } - /* If expansion is one word, or if user says so, upcase it all. */ - Fupcase_region (make_number (wordstart), make_number (PT)); - caped: ; - } - else if (uccount) - { - /* Abbrev included some caps. Cap first initial of expansion */ - int pos = wordstart_byte; - - /* Find the initial. */ - while (pos < PT_BYTE - && SYNTAX (*BUF_BYTE_ADDRESS (current_buffer, pos)) != Sword) - pos++; - - /* Change just that. */ - pos = BYTE_TO_CHAR (pos); - Fupcase_initials_region (make_number (pos), make_number (pos + 1)); - } - } - - hook = XSYMBOL (sym)->function; - if (!NILP (hook)) - { - Lisp_Object expanded, prop; - - /* If the abbrev has a hook function, run it. */ - expanded = call0 (hook); - - /* In addition, if the hook function is a symbol with - a non-nil `no-self-insert' property, let the value it returned - specify whether we consider that an expansion took place. If - it returns nil, no expansion has been done. */ - - if (SYMBOLP (hook) - && NILP (expanded) - && (prop = Fget (hook, intern ("no-self-insert")), - !NILP (prop))) - value = Qnil; - } - - return value; -} - -DEFUN ("unexpand-abbrev", Funexpand_abbrev, Sunexpand_abbrev, 0, 0, "", - doc: /* Undo the expansion of the last abbrev that expanded. -This differs from ordinary undo in that other editing done since then -is not undone. */) - () -{ - int opoint = PT; - int adjust = 0; - if (last_abbrev_point < BEGV - || last_abbrev_point > ZV) - return Qnil; - SET_PT (last_abbrev_point); - if (STRINGP (Vlast_abbrev_text)) - { - /* This isn't correct if Vlast_abbrev->function was used - to do the expansion */ - Lisp_Object val; - int zv_before; - - val = SYMBOL_VALUE (Vlast_abbrev); - if (!STRINGP (val)) - error ("Value of `abbrev-symbol' must be a string"); - zv_before = ZV; - del_range_byte (PT_BYTE, PT_BYTE + SBYTES (val), 1); - /* Don't inherit properties here; just copy from old contents. */ - insert_from_string (Vlast_abbrev_text, 0, 0, - SCHARS (Vlast_abbrev_text), - SBYTES (Vlast_abbrev_text), 0); - Vlast_abbrev_text = Qnil; - /* Total number of characters deleted. */ - adjust = ZV - zv_before; - } - SET_PT (last_abbrev_point < opoint ? opoint + adjust : opoint); - return Qnil; -} - -static void -write_abbrev (sym, stream) - Lisp_Object sym, stream; -{ - Lisp_Object name, count, system_flag; - - if (INTEGERP (XSYMBOL (sym)->plist)) - { - count = XSYMBOL (sym)->plist; - system_flag = Qnil; - } - else - { - count = Fget (sym, Qcount); - system_flag = Fget (sym, Qsystem_type); - } - - if (NILP (SYMBOL_VALUE (sym)) || ! NILP (system_flag)) - return; - - insert (" (", 5); - name = SYMBOL_NAME (sym); - Fprin1 (name, stream); - insert (" ", 1); - Fprin1 (SYMBOL_VALUE (sym), stream); - insert (" ", 1); - Fprin1 (XSYMBOL (sym)->function, stream); - insert (" ", 1); - Fprin1 (count, stream); - insert (")\n", 2); -} - -static void -describe_abbrev (sym, stream) - Lisp_Object sym, stream; -{ - Lisp_Object one, count, system_flag; - - if (INTEGERP (XSYMBOL (sym)->plist)) - { - count = XSYMBOL (sym)->plist; - system_flag = Qnil; - } - else - { - count = Fget (sym, Qcount); - system_flag = Fget (sym, Qsystem_type); - } - - if (NILP (SYMBOL_VALUE (sym))) - return; - - one = make_number (1); - Fprin1 (Fsymbol_name (sym), stream); - - if (!NILP (system_flag)) - { - insert_string (" (sys)"); - Findent_to (make_number (20), one); - } - else - Findent_to (make_number (15), one); - - Fprin1 (count, stream); - Findent_to (make_number (20), one); - Fprin1 (SYMBOL_VALUE (sym), stream); - if (!NILP (XSYMBOL (sym)->function)) - { - Findent_to (make_number (45), one); - Fprin1 (XSYMBOL (sym)->function, stream); - } - Fterpri (stream); -} - -static void -record_symbol (sym, list) - Lisp_Object sym, list; -{ - XSETCDR (list, Fcons (sym, XCDR (list))); -} - -DEFUN ("insert-abbrev-table-description", Finsert_abbrev_table_description, - Sinsert_abbrev_table_description, 1, 2, 0, - doc: /* Insert before point a full description of abbrev table named NAME. -NAME is a symbol whose value is an abbrev table. -If optional 2nd arg READABLE is non-nil, a human-readable description -is inserted. Otherwise the description is an expression, -a call to `define-abbrev-table', which would -define the abbrev table NAME exactly as it is currently defined. - -Abbrevs marked as "system abbrevs" are normally omitted. However, if -READABLE is non-nil, they are listed. */) - (name, readable) - Lisp_Object name, readable; -{ - Lisp_Object table; - Lisp_Object symbols; - Lisp_Object stream; - - CHECK_SYMBOL (name); - table = Fsymbol_value (name); - CHECK_VECTOR (table); - - XSETBUFFER (stream, current_buffer); - - symbols = Fcons (Qnil, Qnil); - map_obarray (table, record_symbol, symbols); - symbols = XCDR (symbols); - symbols = Fsort (symbols, Qstring_lessp); - - if (!NILP (readable)) - { - insert_string ("("); - Fprin1 (name, stream); - insert_string (")\n\n"); - while (! NILP (symbols)) - { - describe_abbrev (XCAR (symbols), stream); - symbols = XCDR (symbols); - } - - insert_string ("\n\n"); - } - else - { - insert_string ("(define-abbrev-table '"); - Fprin1 (name, stream); - insert_string (" '(\n"); - while (! NILP (symbols)) - { - write_abbrev (XCAR (symbols), stream); - symbols = XCDR (symbols); - } - insert_string (" ))\n\n"); - } - - return Qnil; -} - -DEFUN ("define-abbrev-table", Fdefine_abbrev_table, Sdefine_abbrev_table, - 2, 2, 0, - doc: /* Define TABLENAME (a symbol) as an abbrev table name. -Define abbrevs in it according to DEFINITIONS, which is a list of elements -of the form (ABBREVNAME EXPANSION HOOK USECOUNT SYSTEMFLAG). -\(If the list is shorter than that, omitted elements default to nil). */) - (tablename, definitions) - Lisp_Object tablename, definitions; -{ - Lisp_Object name, exp, hook, count; - Lisp_Object table, elt, sys; - - CHECK_SYMBOL (tablename); - table = Fboundp (tablename); - if (NILP (table) || (table = Fsymbol_value (tablename), NILP (table))) - { - table = Fmake_abbrev_table (); - Fset (tablename, table); - Vabbrev_table_name_list = Fcons (tablename, Vabbrev_table_name_list); - } - CHECK_VECTOR (table); - - for (; CONSP (definitions); definitions = XCDR (definitions)) - { - elt = XCAR (definitions); - name = Fcar (elt); elt = Fcdr (elt); - exp = Fcar (elt); elt = Fcdr (elt); - hook = Fcar (elt); elt = Fcdr (elt); - count = Fcar (elt); elt = Fcdr (elt); - sys = Fcar (elt); - Fdefine_abbrev (table, name, exp, hook, count, sys); - } - return Qnil; -} - -void -syms_of_abbrev () -{ - Qsystem_type = intern ("system-type"); - staticpro (&Qsystem_type); - - Qcount = intern ("count"); - staticpro (&Qcount); - - Qforce = intern ("force"); - staticpro (&Qforce); - - DEFVAR_LISP ("abbrev-table-name-list", &Vabbrev_table_name_list, - doc: /* List of symbols whose values are abbrev tables. */); - Vabbrev_table_name_list = Fcons (intern ("fundamental-mode-abbrev-table"), - Fcons (intern ("global-abbrev-table"), - Qnil)); - - DEFVAR_LISP ("global-abbrev-table", &Vglobal_abbrev_table, - doc: /* The abbrev table whose abbrevs affect all buffers. -Each buffer may also have a local abbrev table. -If it does, the local table overrides the global one -for any particular abbrev defined in both. */); - Vglobal_abbrev_table = Fmake_abbrev_table (); - - DEFVAR_LISP ("fundamental-mode-abbrev-table", &Vfundamental_mode_abbrev_table, - doc: /* The abbrev table of mode-specific abbrevs for Fundamental Mode. */); - Vfundamental_mode_abbrev_table = Fmake_abbrev_table (); - current_buffer->abbrev_table = Vfundamental_mode_abbrev_table; - buffer_defaults.abbrev_table = Vfundamental_mode_abbrev_table; - - DEFVAR_LISP ("last-abbrev", &Vlast_abbrev, - doc: /* The abbrev-symbol of the last abbrev expanded. See `abbrev-symbol'. */); - - DEFVAR_LISP ("last-abbrev-text", &Vlast_abbrev_text, - doc: /* The exact text of the last abbrev expanded. -A value of nil means the abbrev has already been unexpanded. */); - - DEFVAR_INT ("last-abbrev-location", &last_abbrev_point, - doc: /* The location of the start of the last abbrev expanded. */); - - Vlast_abbrev = Qnil; - Vlast_abbrev_text = Qnil; - last_abbrev_point = 0; - - DEFVAR_LISP ("abbrev-start-location", &Vabbrev_start_location, - doc: /* Buffer position for `expand-abbrev' to use as the start of the abbrev. -When nil, use the word before point as the abbrev. -Calling `expand-abbrev' sets this to nil. */); - Vabbrev_start_location = Qnil; - - DEFVAR_LISP ("abbrev-start-location-buffer", &Vabbrev_start_location_buffer, - doc: /* Buffer that `abbrev-start-location' has been set for. -Trying to expand an abbrev in any other buffer clears `abbrev-start-location'. */); - Vabbrev_start_location_buffer = Qnil; - - DEFVAR_BOOL ("abbrevs-changed", &abbrevs_changed, - doc: /* Set non-nil by defining or altering any word abbrevs. -This causes `save-some-buffers' to offer to save the abbrevs. */); - abbrevs_changed = 0; - - DEFVAR_BOOL ("abbrev-all-caps", &abbrev_all_caps, - doc: /* *Set non-nil means expand multi-word abbrevs all caps if abbrev was so. */); - abbrev_all_caps = 0; - - DEFVAR_LISP ("pre-abbrev-expand-hook", &Vpre_abbrev_expand_hook, - doc: /* Function or functions to be called before abbrev expansion is done. -This is the first thing that `expand-abbrev' does, and so this may change -the current abbrev table before abbrev lookup happens. */); - Vpre_abbrev_expand_hook = Qnil; - Qpre_abbrev_expand_hook = intern ("pre-abbrev-expand-hook"); - staticpro (&Qpre_abbrev_expand_hook); - - defsubr (&Smake_abbrev_table); - defsubr (&Sclear_abbrev_table); - defsubr (&Sdefine_abbrev); - defsubr (&Sdefine_global_abbrev); - defsubr (&Sdefine_mode_abbrev); - defsubr (&Sabbrev_expansion); - defsubr (&Sabbrev_symbol); - defsubr (&Sexpand_abbrev); - defsubr (&Sunexpand_abbrev); - defsubr (&Sinsert_abbrev_table_description); - defsubr (&Sdefine_abbrev_table); -} - -/* arch-tag: b721db69-f633-44a8-a361-c275acbdad7d - (do not change this comment) */
--- a/src/emacs.c Sat Oct 27 22:15:27 2007 +0000 +++ b/src/emacs.c Sun Oct 28 02:41:00 2007 +0000 @@ -1543,7 +1543,6 @@ syms_of_fns (); syms_of_floatfns (); - syms_of_abbrev (); syms_of_buffer (); syms_of_bytecode (); syms_of_callint ();
--- a/src/image.c Sat Oct 27 22:15:27 2007 +0000 +++ b/src/image.c Sun Oct 28 02:41:00 2007 +0000 @@ -733,9 +733,9 @@ /* Keywords. */ extern Lisp_Object QCwidth, QCheight, QCforeground, QCbackground, QCfile; -extern Lisp_Object QCdata, QCtype, Qcount; +extern Lisp_Object QCdata, QCtype; extern Lisp_Object Qcenter; -Lisp_Object QCascent, QCmargin, QCrelief; +Lisp_Object QCascent, QCmargin, QCrelief, Qcount; Lisp_Object QCconversion, QCcolor_symbols, QCheuristic_mask; Lisp_Object QCindex, QCmatrix, QCcolor_adjustment, QCmask; @@ -9089,6 +9089,9 @@ define_image_type (&xbm_type, 1); define_image_type (&pbm_type, 1); + Qcount = intern ("count"); + staticpro (&Qcount); + QCascent = intern (":ascent"); staticpro (&QCascent); QCmargin = intern (":margin");
--- a/src/puresize.h Sat Oct 27 22:15:27 2007 +0000 +++ b/src/puresize.h Sun Oct 28 02:41:00 2007 +0000 @@ -43,7 +43,7 @@ #endif #ifndef BASE_PURESIZE -#define BASE_PURESIZE (1170000 + SYSTEM_PURESIZE_EXTRA + SITELOAD_PURESIZE_EXTRA) +#define BASE_PURESIZE (1180000 + SYSTEM_PURESIZE_EXTRA + SITELOAD_PURESIZE_EXTRA) #endif /* Increase BASE_PURESIZE by a ratio depending on the machine's word size. */