Avoid writing empty abbrev tables

Fixes bug#29923

'insert-abbrev-table-description' with a non-nil READABLE inserts Lisp
forms suitable for evaluation to restore the defined abbrevs.  We
don't have to insert a form for tables that do not have any abbrevs.

To implement this, we need to filter out system abbrevs before
checking if a table is empty, because system abbrevs were previously
skipped in the 'abbrev--write' call, at which point we would already
have started inserting the beginning of a table definition form.

* lisp/abbrev.el (insert-abbrev-table-description):
Skip inserting empty tables when READABLE is non-nil.
Clarify behavior in documentation string.
(abbrev--write): Remove system abbrev check.

* doc/lispref/abbrevs.texi (Abbrev Tables): Document behavior
with empty tables.

* etc/NEWS: Mention the change in behavior of
'insert-abbrev-table-description'.
This commit is contained in:
Allen Li 2017-12-31 20:33:21 -08:00 committed by Eli Zaretskii
parent 48ff4c0b2f
commit 3bbe9e6091
3 changed files with 53 additions and 40 deletions

View file

@ -122,7 +122,9 @@ System abbrevs are listed and identified as such. Otherwise the
description is a Lisp expression---a call to @code{define-abbrev-table}
that would define @var{name} as it is currently defined, but without
the system abbrevs. (The mode or package using @var{name} is supposed
to add these to @var{name} separately.)
to add these to @var{name} separately.) If the Lisp expression would
not define any abbrevs (i.e.@: it defines an empty abbrev table), this
function inserts nothing.
@end defun
@node Defining Abbrevs

View file

@ -246,6 +246,12 @@ case does not match.
'write-abbrev-file' now writes special properties like ':case-fixed'
for abbrevs that have them.
+++
** 'insert-abbrev-table-description' skips empty tables.
'insert-abbrev-table-description' skips inserting empty tables when
inserting non-readable tables. By extension, this makes
'write-abbrev-file' skip writing empty tables.
+++
** The new functions and commands 'text-property-search-forward' and
'text-property-search-backward' have been added. These provide an

View file

@ -896,24 +896,22 @@ is not undone."
(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))
(insert " (")
(prin1 (symbol-name sym))
(insert " ")
(prin1 (symbol-value sym))
(insert " ")
(prin1 (symbol-function sym))
(insert " :count ")
(prin1 (abbrev-get sym :count))
(when (abbrev-get sym :case-fixed)
(insert " :case-fixed ")
(prin1 (abbrev-get sym :case-fixed)))
(when (abbrev-get sym :enable-function)
(insert " :enable-function ")
(prin1 (abbrev-get sym :enable-function)))
(insert ")\n")))
(insert " (")
(prin1 (symbol-name sym))
(insert " ")
(prin1 (symbol-value sym))
(insert " ")
(prin1 (symbol-function sym))
(insert " :count ")
(prin1 (abbrev-get sym :count))
(when (abbrev-get sym :case-fixed)
(insert " :case-fixed ")
(prin1 (abbrev-get sym :case-fixed)))
(when (abbrev-get sym :enable-function)
(insert " :enable-function ")
(prin1 (abbrev-get sym :enable-function)))
(insert ")\n"))
(defun abbrev--describe (sym)
(when (symbol-value sym)
@ -934,31 +932,38 @@ Presumes that `standard-output' points to `current-buffer'."
"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.
is inserted.
Abbrevs marked as \"system abbrevs\" are omitted."
If READABLE is nil, an expression is inserted. The expression is
a call to `define-abbrev-table' that when evaluated will define
the abbrev table NAME exactly as it is currently defined.
Abbrevs marked as \"system abbrevs\" are ignored. If the
resulting expression would not define any abbrevs, nothing is
inserted."
(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)
(if (null symbols)
(insert " '())\n\n")
(insert "\n '(\n")
(mapc 'abbrev--write symbols)
(insert " ))\n\n")))
nil)))
(mapatoms (lambda (sym)
(if (and (symbol-value sym) (or readable (not (abbrev-get sym :system))))
(push sym symbols)))
table)
(when symbols
(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)
(if (null symbols)
(insert " '())\n\n")
(insert "\n '(\n")
(mapc 'abbrev--write symbols)
(insert " ))\n\n")))
nil))))
(defun define-abbrev-table (tablename definitions
&optional docstring &rest props)