Subject: Re: bug#5937: 23.1.95; why saving empty abbrev tables

From: Andreas Röhler <[email-masked]>
Date: Sun, 27 Mar 2011 19:34:36 +0200

Am 27.03.2011 07:09, schrieb Leo:
> On 2010-04-27 11:49 +0800, Stefan Monnier wrote:
>> Actually, having tried it now for a while I do have an objection: it
>> makes it harder to add entries to an abbrev-table if that table
>> is empty.
>>
>> So I think a better option is to sort the tables such that empty tables
>> are pushed to the end.
>>
>>
>>          Stefan
>
> Hello Stefan,
>
> I propose we allow C-u M-x edit-abbrevs to include all abbrev tables but
> default to include only nonempty tables.
>
> Here is an updated patch.
>
>
>
>
> === modified file 'lisp/abbrev.el'
> --- lisp/abbrev.el	2011-03-22 15:38:40 +0000
> +++ lisp/abbrev.el	2011-03-27 04:56:22 +0000
> @@ -104,7 +104,7 @@
>   prefix arg, display only local, i.e. mode-specific, abbrevs.
>   Otherwise display all abbrevs."
>     (interactive "P")
> -  (display-buffer (prepare-abbrev-list-buffer local)))
> +  (display-buffer (prepare-abbrev-list-buffer (and local 'local))))
>
>   (defun abbrev-table-name (table)
>     "Value is the name of abbrev table TABLE."
> @@ -116,14 +116,28 @@
>         (setq tables (cdr tables)))
>       found))
>
> -(defun prepare-abbrev-list-buffer (&optional local)
> -  (let ((local-table local-abbrev-table))
> +(defun abbrev-nonempty-table-names (&optional ignore-system)
> +  "Return a list of nonempty abbrev table names.
> +If IGNORE-SYSTEM is non-nil, system definitions are ignored."
> +  (delete nil
> +          (mapcar (lambda (tn)
> +                    (unless (abbrev-table-empty-p
> +                             (symbol-value tn) ignore-system)
> +                      tn))
> +                  abbrev-table-name-list)))
> +
> +;; HOW takes value: nil, local or all.
> +(defun prepare-abbrev-list-buffer (&optional how)
> +  (let ((local-table local-abbrev-table)
> +        (tables (if (eq how 'all)
> +                    abbrev-table-name-list
> +                  (abbrev-nonempty-table-names))))
>       (with-current-buffer (get-buffer-create "*Abbrevs*")
>         (erase-buffer)
> -      (if local
> +      (if (eq how 'local)
>             (insert-abbrev-table-description
>              (abbrev-table-name local-table) t)
> -        (dolist (table abbrev-table-name-list)
> +        (dolist (table tables)
>             (insert-abbrev-table-description table t)))
>         (goto-char (point-min))
>         (set-buffer-modified-p nil)
> @@ -140,10 +154,11 @@
>     (use-local-map edit-abbrevs-map)
>     (run-mode-hooks 'edit-abbrevs-mode-hook))
>
> -(defun edit-abbrevs ()
> +(defun edit-abbrevs (&optional all)
>     "Alter abbrev definitions by editing a list of them.
>   Selects a buffer containing a list of abbrev definitions.
> -You can edit them and type \\<edit-abbrevs-map>\\[edit-abbrevs-redefine] to redefine abbrevs
> +Use \\[universal-argument] to include empty abbrev tables.  You can edit
> +them and type \\<edit-abbrevs-map>\\[edit-abbrevs-redefine] to redefine abbrevs
>   according to your editing.
>   Buffer contains a header line for each abbrev table,
>    which is the abbrev table name in parentheses.
> @@ -152,8 +167,8 @@
>   where NAME and EXPANSION are strings with quotes,
>   USECOUNT is an integer, and HOOK is any valid function
>   or may be omitted (it is usually omitted)."
> -  (interactive)
> -  (switch-to-buffer (prepare-abbrev-list-buffer)))
> +  (interactive "P")
> +  (switch-to-buffer (prepare-abbrev-list-buffer (and all 'all))))
>
>   (defun edit-abbrevs-redefine ()
>     "Redefine abbrevs according to current buffer contents."
> @@ -225,7 +240,8 @@
>   		    abbrev-file-name)))
>     (or (and file (>  (length file) 0))
>         (setq file abbrev-file-name))
> -  (let ((coding-system-for-write 'utf-8))
> +  (let ((coding-system-for-write 'utf-8)
> +        (tables (abbrev-nonempty-table-names t)))
>       (with-temp-buffer
>         (dolist (table
>   	       ;; We sort the table in order to ease the automatic
> @@ -234,10 +250,9 @@
>   	       ;; user keeps their home directory in a revision
>   	       ;; control system, and is therefore keeping multiple
>   	       ;; slightly-differing copies loosely synchronized.
> -	       (sort (copy-sequence abbrev-table-name-list)
> -		     (lambda (s1 s2)
> -		       (string<  (symbol-name s1)
> -				(symbol-name s2)))))
> +	       (sort tables (lambda (s1 s2)
> +			      (string<  (symbol-name s1)
> +				       (symbol-name s2)))))
>   	(insert-abbrev-table-description table nil))
>         (when (unencodable-char-position (point-min) (point-max) 'utf-8)
>   	(setq coding-system-for-write
> @@ -420,6 +435,18 @@
>     (and (vectorp object)
>          (numberp (abbrev-table-get object :abbrev-table-modiff))))
>
> +(defun abbrev-table-empty-p (object&optional ignore-system)
> +  "Return nil if there are no abbrev symbols in OBJECT.
> +If IGNORE-SYSTEM is non-nil, system definitions are ignored."
> +  (unless (abbrev-table-p object)
> +    (error "Non abbrev table object"))
> +  (not (catch 'some
> +         (mapatoms (lambda (abbrev)
> +                     (unless (or (zerop (length (symbol-name abbrev)))
> +                                 (and ignore-system (abbrev-get abbrev :system)))
> +                       (throw 'some t)))
> +                   object))))
> +
>   (defvar global-abbrev-table (make-abbrev-table)
>     "The abbrev table whose abbrevs affect all buffers.
>   Each buffer may also have a local abbrev table.
>
>
>
>
>
> Leo

Hi Leo,

just an abstract reasoning: don't change things you are not compelled 
to. Or to say: unless there is a reason for it.

An empty table doesn't take considerable space nor time.

OTOH when changing a thing, always remains a certain risk to break 
something.

As said, just abtract reasoning. Don't see a real danger here.

Cheers

Andreas