lopsidedcroc · 2022-04-05 15:52
Lisp noob here, apologies in advance for the rudimentary question.
To add a multi-word phrase to the abbrev list, I have to count how many words there are in it, use that number as a prefix, then do Ctl-x a +.
I would like to modify this so I can simply highlight (I'm using evil mode) the whole phrase and hit Ctl-x a +.
Thanks!
[deleted] · 2022-04-05 19:32
[deleted]
geza42 · 2022-04-05 22:18
You can create a function for this. Here's the solution I'm using. If you call it when visual mode is active, then it uses the selection as the expansion. If visual mode is not active and the cursor is on a word, then it will use the word as the expansion. Otherwise it will ask for the expansion string. If the expansion already exists, then it will remove the corresponding abbreviation. Otherwise it will ask for the abbreviation. So this works a little bit differently than `C-x a +`, but you can use it as a starting point to develop your own solution. I like this solution because I can define and remove an abbreviation with the same keybinding.
Here's the code:
(defun my-handle-abbrev (table table-name)
(let* (beg name existing-abbrevs (expansion-from-buffer
(if (eq evil-state 'visual)
(buffer-substring-no-properties (region-beginning) (region-end))
(save-excursion
(skip-syntax-backward "w_")
(setq beg (point))
(skip-syntax-forward "w_")
(buffer-substring-no-properties beg (point)))))
(expansion (if (> (length expansion-from-buffer) 0) expansion-from-buffer (read-string "Expansion: "))))
(obarray-map (lambda (sym) (when (equal (symbol-value sym) expansion) (add-to-list 'existing-abbrevs sym))) table)
(if existing-abbrevs
(dolist (a existing-abbrevs)
(obarray-remove table a)
(message "Abbreviation \"%s\" removed from %s" a table-name))
(setq name (read-string (format "%s abbrev for \"%s\": " table-name expansion)))
(set-text-properties 0 (length name) nil name)
(define-abbrev table name expansion))))
As an example, if you'd like to add/remove a local abbreviation, you can do it with `(my-handle-abbrev local-abbrev-table "Local")`.
lopsidedcroc · 2022-04-08 15:25
Thanks for this.
For some reason I can't call it. Ctl-x-e produces the expected result (the function name in the mini-buffer) but when I try to M-x it, it's not found ("match required"). (I haven't set up a key binding yet.)
Any idea what might be happening?
geza42 · 2022-04-08 15:45
I believe `M-x` only lists interactive functions. Create a little wrapper function around `my-handle-abbrev`, like this:
(defun my-local-abbrev ()
(interactive)
(my-handle-abbrev local-abbrev-table "Local"))
With this, `my-local-abbrev` will be listed by `M-x`.
lopsidedcroc · 2022-04-08 19:09
This works like a charm. I bound it to a key combination for visual mode and it works flawlessly. Thank you!