| 1 |
|
|---|
| 2 |
|
|---|
| 3 |
|
|---|
| 4 |
|
|---|
| 5 |
|
|---|
| 6 |
|
|---|
| 7 |
|
|---|
| 8 |
|
|---|
| 9 |
|
|---|
| 10 |
|
|---|
| 11 |
|
|---|
| 12 |
|
|---|
| 13 |
|
|---|
| 14 |
|
|---|
| 15 |
|
|---|
| 16 |
|
|---|
| 17 |
|
|---|
| 18 |
|
|---|
| 19 |
|
|---|
| 20 |
|
|---|
| 21 |
|
|---|
| 22 |
|
|---|
| 23 |
|
|---|
| 24 |
|
|---|
| 25 |
|
|---|
| 26 |
|
|---|
| 27 |
|
|---|
| 28 |
|
|---|
| 29 |
|
|---|
| 30 |
|
|---|
| 31 |
|
|---|
| 32 |
(defcustom only-global-abbrevs nil |
|---|
| 33 |
"Non-nil means user plans to use global abbrevs only. |
|---|
| 34 |
This makes the commands that normally define mode-specific abbrevs |
|---|
| 35 |
define global abbrevs instead." |
|---|
| 36 |
:type 'boolean |
|---|
| 37 |
:group 'abbrev-mode |
|---|
| 38 |
:group 'convenience) |
|---|
| 39 |
|
|---|
| 40 |
(defun abbrev-mode (&optional arg) |
|---|
| 41 |
"Toggle Abbrev mode in the current buffer. |
|---|
| 42 |
With optional argument ARG, turn abbrev mode on if ARG is |
|---|
| 43 |
positive, otherwise turn it off. In Abbrev mode, inserting an |
|---|
| 44 |
abbreviation causes it to expand and be replaced by its expansion." |
|---|
| 45 |
(interactive "P") |
|---|
| 46 |
(setq abbrev-mode |
|---|
| 47 |
(if (null arg) (not abbrev-mode) |
|---|
| 48 |
(> (prefix-numeric-value arg) 0))) |
|---|
| 49 |
(force-mode-line-update)) |
|---|
| 50 |
|
|---|
| 51 |
(defcustom abbrev-mode nil |
|---|
| 52 |
"Enable or disable Abbrev mode. |
|---|
| 53 |
Non-nil means automatically expand abbrevs as they are inserted. |
|---|
| 54 |
|
|---|
| 55 |
Setting this variable with `setq' changes it for the current buffer. |
|---|
| 56 |
Changing it with \\[customize] sets the default value. |
|---|
| 57 |
Interactively, use the command `abbrev-mode' |
|---|
| 58 |
to enable or disable Abbrev mode in the current buffer." |
|---|
| 59 |
:type 'boolean |
|---|
| 60 |
:group 'abbrev-mode) |
|---|
| 61 |
|
|---|
| 62 |
|
|---|
| 63 |
|
|---|
| 64 |
(defvar edit-abbrevs-map |
|---|
| 65 |
(let ((map (make-sparse-keymap))) |
|---|
| 66 |
(define-key map "\C-x\C-s" 'edit-abbrevs-redefine) |
|---|
| 67 |
(define-key map "\C-c\C-c" 'edit-abbrevs-redefine) |
|---|
| 68 |
map) |
|---|
| 69 |
"Keymap used in `edit-abbrevs'.") |
|---|
| 70 |
|
|---|
| 71 |
(defun kill-all-abbrevs () |
|---|
| 72 |
"Undefine all defined abbrevs." |
|---|
| 73 |
(interactive) |
|---|
| 74 |
(let ((tables abbrev-table-name-list)) |
|---|
| 75 |
(while tables |
|---|
| 76 |
(clear-abbrev-table (symbol-value (car tables))) |
|---|
| 77 |
(setq tables (cdr tables))))) |
|---|
| 78 |
|
|---|
| 79 |
(defun copy-abbrev-table (table) |
|---|
| 80 |
"Make a new abbrev-table with the same abbrevs as TABLE." |
|---|
| 81 |
(let ((new-table (make-abbrev-table))) |
|---|
| 82 |
(mapatoms |
|---|
| 83 |
(lambda (symbol) |
|---|
| 84 |
(define-abbrev new-table |
|---|
| 85 |
(symbol-name symbol) |
|---|
| 86 |
(symbol-value symbol) |
|---|
| 87 |
(symbol-function symbol))) |
|---|
| 88 |
table) |
|---|
| 89 |
new-table)) |
|---|
| 90 |
|
|---|
| 91 |
(defun insert-abbrevs () |
|---|
| 92 |
"Insert after point a description of all defined abbrevs. |
|---|
| 93 |
Mark is set after the inserted text." |
|---|
| 94 |
(interactive) |
|---|
| 95 |
(push-mark |
|---|
| 96 |
(save-excursion |
|---|
| 97 |
(let ((tables abbrev-table-name-list)) |
|---|
| 98 |
(while tables |
|---|
| 99 |
(insert-abbrev-table-description (car tables) t) |
|---|
| 100 |
(setq tables (cdr tables)))) |
|---|
| 101 |
(point)))) |
|---|
| 102 |
|
|---|
| 103 |
(defun list-abbrevs (&optional local) |
|---|
| 104 |
"Display a list of defined abbrevs. |
|---|
| 105 |
If LOCAL is non-nil, interactively when invoked with a |
|---|
| 106 |
prefix arg, display only local, i.e. mode-specific, abbrevs. |
|---|
| 107 |
Otherwise display all abbrevs." |
|---|
| 108 |
(interactive "P") |
|---|
| 109 |
(display-buffer (prepare-abbrev-list-buffer local))) |
|---|
| 110 |
|
|---|
| 111 |
(defun abbrev-table-name (table) |
|---|
| 112 |
"Value is the name of abbrev table TABLE." |
|---|
| 113 |
(let ((tables abbrev-table-name-list) |
|---|
| 114 |
found) |
|---|
| 115 |
(while (and (not found) tables) |
|---|
| 116 |
(when (eq (symbol-value (car tables)) table) |
|---|
| 117 |
(setq found (car tables))) |
|---|
| 118 |
(setq tables (cdr tables))) |
|---|
| 119 |
found)) |
|---|
| 120 |
|
|---|
| 121 |
(defun prepare-abbrev-list-buffer (&optional local) |
|---|
| 122 |
(save-excursion |
|---|
| 123 |
(let ((table local-abbrev-table)) |
|---|
| 124 |
(set-buffer (get-buffer-create "*Abbrevs*")) |
|---|
| 125 |
(erase-buffer) |
|---|
| 126 |
(if local |
|---|
| 127 |
(insert-abbrev-table-description (abbrev-table-name table) t) |
|---|
| 128 |
(dolist (table abbrev-table-name-list) |
|---|
| 129 |
(insert-abbrev-table-description table t))) |
|---|
| 130 |
(goto-char (point-min)) |
|---|
| 131 |
(set-buffer-modified-p nil) |
|---|
| 132 |
(edit-abbrevs-mode) |
|---|
| 133 |
(current-buffer)))) |
|---|
| 134 |
|
|---|
| 135 |
(defun edit-abbrevs-mode () |
|---|
| 136 |
"Major mode for editing the list of abbrev definitions. |
|---|
| 137 |
\\{edit-abbrevs-map}" |
|---|
| 138 |
(interactive) |
|---|
| 139 |
(kill-all-local-variables) |
|---|
| 140 |
(setq major-mode 'edit-abbrevs-mode) |
|---|
| 141 |
(setq mode-name "Edit-Abbrevs") |
|---|
| 142 |
(use-local-map edit-abbrevs-map) |
|---|
| 143 |
(run-mode-hooks 'edit-abbrevs-mode-hook)) |
|---|
| 144 |
|
|---|
| 145 |
(defun edit-abbrevs () |
|---|
| 146 |
"Alter abbrev definitions by editing a list of them. |
|---|
| 147 |
Selects a buffer containing a list of abbrev definitions. |
|---|
| 148 |
You can edit them and type \\<edit-abbrevs-map>\\[edit-abbrevs-redefine] to redefine abbrevs |
|---|
| 149 |
according to your editing. |
|---|
| 150 |
Buffer contains a header line for each abbrev table, |
|---|
| 151 |
which is the abbrev table name in parentheses. |
|---|
| 152 |
This is followed by one line per abbrev in that table: |
|---|
| 153 |
NAME USECOUNT EXPANSION HOOK |
|---|
| 154 |
where NAME and EXPANSION are strings with quotes, |
|---|
| 155 |
USECOUNT is an integer, and HOOK is any valid function |
|---|
| 156 |
or may be omitted (it is usually omitted)." |
|---|
| 157 |
(interactive) |
|---|
| 158 |
(switch-to-buffer (prepare-abbrev-list-buffer))) |
|---|
| 159 |
|
|---|
| 160 |
(defun edit-abbrevs-redefine () |
|---|
| 161 |
"Redefine abbrevs according to current buffer contents." |
|---|
| 162 |
(interactive) |
|---|
| 163 |
(save-restriction |
|---|
| 164 |
(widen) |
|---|
| 165 |
(define-abbrevs t) |
|---|
| 166 |
(set-buffer-modified-p nil))) |
|---|
| 167 |
|
|---|
| 168 |
(defun define-abbrevs (&optional arg) |
|---|
| 169 |
"Define abbrevs according to current visible buffer contents. |
|---|
| 170 |
See documentation of `edit-abbrevs' for info on the format of the |
|---|
| 171 |
text you must have in the buffer. |
|---|
| 172 |
With argument, eliminate all abbrev definitions except |
|---|
| 173 |
the ones defined from the buffer now." |
|---|
| 174 |
(interactive "P") |
|---|
| 175 |
(if arg (kill-all-abbrevs)) |
|---|
| 176 |
(save-excursion |
|---|
| 177 |
(goto-char (point-min)) |
|---|
| 178 |
(while (and (not (eobp)) (re-search-forward "^(" nil t)) |
|---|
| 179 |
(let* ((buf (current-buffer)) |
|---|
| 180 |
(table (read buf)) |
|---|
| 181 |
abbrevs name hook exp count sys) |
|---|
| 182 |
(forward-line 1) |
|---|
| 183 |
(while (progn (forward-line 1) |
|---|
| 184 |
(not (eolp))) |
|---|
| 185 |
(setq name (read buf) count (read buf)) |
|---|
| 186 |
(if (equal count '(sys)) |
|---|
| 187 |
(setq sys t count (read buf))) |
|---|
| 188 |
(setq exp (read buf)) |
|---|
| 189 |
(skip-chars-backward " \t\n\f") |
|---|
| 190 |
(setq hook (if (not (eolp)) (read buf))) |
|---|
| 191 |
(skip-chars-backward " \t\n\f") |
|---|
| 192 |
(setq abbrevs (cons (list name exp hook count sys) abbrevs))) |
|---|
| 193 |
(define-abbrev-table table abbrevs))))) |
|---|
| 194 |
|
|---|
| 195 |
(defun read-abbrev-file (&optional file quietly) |
|---|
| 196 |
"Read abbrev definitions from file written with `write-abbrev-file'. |
|---|
| 197 |
Optional argument FILE is the name of the file to read; |
|---|
| 198 |
it defaults to the value of `abbrev-file-name'. |
|---|
| 199 |
Optional second argument QUIETLY non-nil means don't display a message." |
|---|
| 200 |
(interactive |
|---|
| 201 |
(list |
|---|
| 202 |
(read-file-name (format "Read abbrev file (default %s): " |
|---|
| 203 |
abbrev-file-name) |
|---|
| 204 |
nil abbrev-file-name t))) |
|---|
| 205 |
(load (or file abbrev-file-name) nil quietly) |
|---|
| 206 |
(setq abbrevs-changed nil)) |
|---|
| 207 |
|
|---|
| 208 |
(defun quietly-read-abbrev-file (&optional file) |
|---|
| 209 |
"Read abbrev definitions from file written with `write-abbrev-file'. |
|---|
| 210 |
Optional argument FILE is the name of the file to read; |
|---|
| 211 |
it defaults to the value of `abbrev-file-name'. |
|---|
| 212 |
Does not display any message." |
|---|
| 213 |
|
|---|
| 214 |
(read-abbrev-file file t)) |
|---|
| 215 |
|
|---|
| 216 |
(defun write-abbrev-file (&optional file) |
|---|
| 217 |
"Write all user-level abbrev definitions to a file of Lisp code. |
|---|
| 218 |
This does not include system abbrevs; it includes only the abbrev tables |
|---|
| 219 |
listed in listed in `abbrev-table-name-list'. |
|---|
| 220 |
The file written can be loaded in another session to define the same abbrevs. |
|---|
| 221 |
The argument FILE is the file name to write. If omitted or nil, the file |
|---|
| 222 |
specified in `abbrev-file-name' is used." |
|---|
| 223 |
(interactive |
|---|
| 224 |
(list |
|---|
| 225 |
(read-file-name "Write abbrev file: " |
|---|
| 226 |
(file-name-directory (expand-file-name abbrev-file-name)) |
|---|
| 227 |
abbrev-file-name))) |
|---|
| 228 |
(or (and file (> (length file) 0)) |
|---|
| 229 |
(setq file abbrev-file-name)) |
|---|
| 230 |
(let ((coding-system-for-write 'emacs-mule)) |
|---|
| 231 |
(with-temp-file file |
|---|
| 232 |
(insert ";;-*-coding: emacs-mule;-*-\n") |
|---|
| 233 |
(dolist (table |
|---|
| 234 |
|
|---|
| 235 |
|
|---|
| 236 |
|
|---|
| 237 |
|
|---|
| 238 |
|
|---|
| 239 |
|
|---|
| 240 |
(sort (copy-sequence abbrev-table-name-list) |
|---|
| 241 |
(lambda (s1 s2) |
|---|
| 242 |
(string< (symbol-name s1) |
|---|
| 243 |
(symbol-name s2))))) |
|---|
| 244 |
(insert-abbrev-table-description table nil))))) |
|---|
| 245 |
|
|---|
| 246 |
(defun add-mode-abbrev (arg) |
|---|
| 247 |
"Define mode-specific abbrev for last word(s) before point. |
|---|
| 248 |
Argument is how many words before point form the expansion; |
|---|
| 249 |
or zero means the region is the expansion. |
|---|
| 250 |
A negative argument means to undefine the specified abbrev. |
|---|
| 251 |
Reads the abbreviation in the minibuffer. |
|---|
| 252 |
|
|---|
| 253 |
Don't use this function in a Lisp program; use `define-abbrev' instead." |
|---|
| 254 |
(interactive "p") |
|---|
| 255 |
(add-abbrev |
|---|
| 256 |
(if only-global-abbrevs |
|---|
| 257 |
global-abbrev-table |
|---|
| 258 |
(or local-abbrev-table |
|---|
| 259 |
(error "No per-mode abbrev table"))) |
|---|
| 260 |
"Mode" arg)) |
|---|
| 261 |
|
|---|
| 262 |
(defun add-global-abbrev (arg) |
|---|
| 263 |
"Define global (all modes) abbrev for last word(s) before point. |
|---|
| 264 |
The prefix argument specifies the number of words before point that form the |
|---|
| 265 |
expansion; or zero means the region is the expansion. |
|---|
| 266 |
A negative argument means to undefine the specified abbrev. |
|---|
| 267 |
This command uses the minibuffer to read the abbreviation. |
|---|
| 268 |
|
|---|
| 269 |
Don't use this function in a Lisp program; use `define-abbrev' instead." |
|---|
| 270 |
(interactive "p") |
|---|
| 271 |
(add-abbrev global-abbrev-table "Global" arg)) |
|---|
| 272 |
|
|---|
| 273 |
(defun add-abbrev (table type arg) |
|---|
| 274 |
(let ((exp (and (>= arg 0) |
|---|
| 275 |
(buffer-substring-no-properties |
|---|
| 276 |
(point) |
|---|
| 277 |
(if (= arg 0) (mark) |
|---|
| 278 |
(save-excursion (forward-word (- arg)) (point)))))) |
|---|
| 279 |
name) |
|---|
| 280 |
(setq name |
|---|
| 281 |
(read-string (format (if exp "%s abbrev for \"%s\": " |
|---|
| 282 |
"Undefine %s abbrev: ") |
|---|
| 283 |
type exp))) |
|---|
| 284 |
(set-text-properties 0 (length name) nil name) |
|---|
| 285 |
(if (or (null exp) |
|---|
| 286 |
(not (abbrev-expansion name table)) |
|---|
| 287 |
(y-or-n-p (format "%s expands to \"%s\"; redefine? " |
|---|
| 288 |
name (abbrev-expansion name table)))) |
|---|
| 289 |
(define-abbrev table (downcase name) exp)))) |
|---|
| 290 |
|
|---|
| 291 |
(defun inverse-add-mode-abbrev (n) |
|---|
| 292 |
"Define last word before point as a mode-specific abbrev. |
|---|
| 293 |
With prefix argument N, defines the Nth word before point. |
|---|
| 294 |
This command uses the minibuffer to read the expansion. |
|---|
| 295 |
Expands the abbreviation after defining it." |
|---|
| 296 |
(interactive "p") |
|---|
| 297 |
(inverse-add-abbrev |
|---|
| 298 |
(if only-global-abbrevs |
|---|
| 299 |
global-abbrev-table |
|---|
| 300 |
(or local-abbrev-table |
|---|
| 301 |
(error "No per-mode abbrev table"))) |
|---|
| 302 |
"Mode" n)) |
|---|
| 303 |
|
|---|
| 304 |
(defun inverse-add-global-abbrev (n) |
|---|
| 305 |
"Define last word before point as a global (mode-independent) abbrev. |
|---|
| 306 |
With prefix argument N, defines the Nth word before point. |
|---|
| 307 |
This command uses the minibuffer to read the expansion. |
|---|
| 308 |
Expands the abbreviation after defining it." |
|---|
| 309 |
(interactive "p") |
|---|
| 310 |
(inverse-add-abbrev global-abbrev-table "Global" n)) |
|---|
| 311 |
|
|---|
| 312 |
(defun inverse-add-abbrev (table type arg) |
|---|
| 313 |
(let (name exp start end) |
|---|
| 314 |
(save-excursion |
|---|
| 315 |
(forward-word (1+ (- arg))) |
|---|
| 316 |
(setq end (point)) |
|---|
| 317 |
(backward-word 1) |
|---|
| 318 |
(setq start (point) |
|---|
| 319 |
name (buffer-substring-no-properties start end))) |
|---|
| 320 |
|
|---|
| 321 |
(setq exp (read-string (format "%s expansion for \"%s\": " type name) |
|---|
| 322 |
nil nil nil t)) |
|---|
| 323 |
(when (or (not (abbrev-expansion name table)) |
|---|
| 324 |
(y-or-n-p (format "%s expands to \"%s\"; redefine? " |
|---|
| 325 |
name (abbrev-expansion name table)))) |
|---|
| 326 |
(define-abbrev table (downcase name) exp) |
|---|
| 327 |
(save-excursion |
|---|
| 328 |
(goto-char end) |
|---|
| 329 |
(expand-abbrev))))) |
|---|
| 330 |
|
|---|
| 331 |
(defun abbrev-prefix-mark (&optional arg) |
|---|
| 332 |
"Mark current point as the beginning of an abbrev. |
|---|
| 333 |
Abbrev to be expanded starts here rather than at beginning of word. |
|---|
| 334 |
This way, you can expand an abbrev with a prefix: insert the prefix, |
|---|
| 335 |
use this command, then insert the abbrev. This command inserts a |
|---|
| 336 |
temporary hyphen after the prefix \(until the intended abbrev |
|---|
| 337 |
expansion occurs). |
|---|
| 338 |
If the prefix is itself an abbrev, this command expands it, unless |
|---|
| 339 |
ARG is non-nil. Interactively, ARG is the prefix argument." |
|---|
| 340 |
(interactive "P") |
|---|
| 341 |
(or arg (expand-abbrev)) |
|---|
| 342 |
(setq abbrev-start-location (point-marker) |
|---|
| 343 |
abbrev-start-location-buffer (current-buffer)) |
|---|
| 344 |
(insert "-")) |
|---|
| 345 |
|
|---|
| 346 |
(defun expand-region-abbrevs (start end &optional noquery) |
|---|
| 347 |
"For abbrev occurrence in the region, offer to expand it. |
|---|
| 348 |
The user is asked to type `y' or `n' for each occurrence. |
|---|
| 349 |
A prefix argument means don't query; expand all abbrevs." |
|---|
| 350 |
(interactive "r\nP") |
|---|
| 351 |
(save-excursion |
|---|
| 352 |
(goto-char start) |
|---|
| 353 |
(let ((lim (- (point-max) end)) |
|---|
| 354 |
pnt string) |
|---|
| 355 |
(while (and (not (eobp)) |
|---|
| 356 |
(progn (forward-word 1) |
|---|
| 357 |
(<= (setq pnt (point)) (- (point-max) lim)))) |
|---|
| 358 |
(if (abbrev-expansion |
|---|
| 359 |
(setq string |
|---|
| 360 |
(buffer-substring-no-properties |
|---|
| 361 |
(save-excursion (forward-word -1) (point)) |
|---|
| 362 |
pnt))) |
|---|
| 363 |
(if (or noquery (y-or-n-p (format "Expand `%s'? " string))) |
|---|
| 364 |
(expand-abbrev))))))) |
|---|
| 365 |
|
|---|
| 366 |
(provide 'abbrev) |
|---|
| 367 |
|
|---|
| 368 |
|
|---|
| 369 |
|
|---|
| 370 |
|
|---|