How do you find all available abbrevs in elisp? - emacs

For kinda goofy reasons I want to write a completing-read function to read Emacs abbrevs.
(defun ivy-abbrev (abbrev-name)
(interactive
(list
(ivy-completing-read "Insert abbrev: " (...get abbrev names here...))))
(progn
(abbrev-insert (abbrev-symbol abbrev-name ..appropriate abbrev-table...))))
Unfortunately there's nothing in the documentation that makes ...get abbrev names... look do-able:
https://www.gnu.org/software/emacs/manual/html_node/elisp/Abbrevs.html#Abbrevs
Looking in the source at abbrev--before-point it looks as though there's a recursive search through abbrev--active-tables on each invocation.
Is there a helper method in this abbrev API to make this easier?

You could use something like the following,
(cl-loop for table in (abbrev--active-tables)
unless (abbrev-table-empty-p table)
append (append (delete 0 table) ()))
Note that appending nil to a vector is a trick to create a list.

Related

How to add extra math to org-cdlatex-mode when starting emacs?

The org-cdlatex-mode helps to insert math latex symbols/tempelates in org-mode.
I would like to add some extra symbols/accents to it. I realized that the math accents are stored in the variable cdlatex-math-modify-alist-comb and if I add to that list in the scrach buffer, I will get the extra short key for the new symbol, for example running:
(add-to-list 'cdlatex-math-modify-alist-comb '(?o "\\operatorname" nil t t nil))
works as expected. However if I add the same line in the init file, the new key won't be added to the list and emacs complains with warning that the list variable is free!
I probably need to add to the list after it has been loaded, however I couldn't find any source of how to do it.
The variable that needs to be set in your case is cdlatex-math-modify-alist. The documentation of that variable says: Any entries in this variable will be added to the default.
The workaround I did is to create a function that adds them every time I call my math minor mode
(define-minor-mode org-math-mode
"Some config to write math on `org-mode'."
:lighter "org-math-mode"
(org-fragtog-mode 1)
(org-cdlatex-mode 1)
(lauremacs-cdlatex-add-math-symbols))
(defun lauremacs-cdlatex-add-math-symbols ()
(add-multiple-into-list
'cdlatex-math-symbol-alist-comb
'(
(?. "\\cdot" "\\dots")
(?\; "\\;")
(?C "" "\\mathbb{C}" "\\arccos")
(?N "\\nabla" "\\mathbb{N}" "\\exp")
(?Q "\\Theta" "\\mathbb{Q}")
(?R "\\Re" "\\mathbb{R}")
(?Z "" "\\mathbb{Z}")
)))
where add to multiple is just a helper function that uses add-to-list
(defun add-multiple-into-list (lst items)
"Add each item from ITEMS into LST."
(throw-unless (symbolp lst) "List should be a symbol.")
(dolist (item items)
(add-to-list lst item)))
This might lead to a very big 'cdlatex-math-symbol-alist-comb but it didn't bothered me yet, a solution to this is adding to list if element is not there or something like this
Just edit cdlatex.el and compile it. For example, I add sum with this piece of code:
("sum" "Insert \\sum_{i=1}{n}"
"\\sum_{i=1}{n}?" cdlatex-position-cursor nil nil t)
and it works.

Insert yasnippet by name

I want to insert a specific yasnippet as part of a function in emacs-lisp. Is there a way to do that?
The only command that seems related is yas/insert-snippet, but it simply opens a popup with all the options and the documentation doesn't say anything about bypassing the popup by specifing the snippet name.
yas/insert-snippet is indeed just a thin wrapper around yas/expand-snippet for interactive use. However, the internal structures are... interesting. Judging from the source code the following does work for me when I want to expand the "defun" snippet in elisp-mode:
(yas/expand-snippet
(yas/template-content (cdar (mapcan #'(lambda (table)
(yas/fetch table "defun"))
(yas/get-snippet-tables)))))
As the author of yasnippet, I think you'd rather not rely on internal details of yasnippet's interesting data structures, which may change in the future. I would do this based on the documentation of yas/insert-snippet and yas/prompt-functions:
(defun yas/insert-by-name (name)
(flet ((dummy-prompt
(prompt choices &optional display-fn)
(declare (ignore prompt))
(or (find name choices :key display-fn :test #'string=)
(throw 'notfound nil))))
(let ((yas/prompt-functions '(dummy-prompt)))
(catch 'notfound
(yas/insert-snippet t)))))
(yas/insert-by-name "defun")
I'm just getting into yasnippet and I wanted to automatically insert one of my snippets upon opening a new file for certain modes. That led me to here but I've generated a slightly different solution. Providing yet another alternative: ("new-shell" is the name of my personal snippet for providing a new shell script template)
(defun jsm/new-file-snippet (key)
"Call particular yasnippet template for newly created
files. Use by adding a lambda function to the particular mode
hook passing the correct yasnippet key"
(interactive)
(if (= (buffer-size) 0)
(progn
(insert key)
(call-interactively 'yas-expand))))
(add-hook 'sh-mode-hook '(lambda () (jsm/new-file-snippet "new-shell")))
IMO, my solution is a tad less susceptible to breaking should yasnippet change dramatically.
This is 2022 now, so we can simply do the following :
(yas-expand-snippet (yas-lookup-snippet "name-of-your-snippet"))
See the documentation

How to find which file provide(d) the feature in emacs elisp

Currently i am using the load-history variable to find the file from which a feature came from.
suppose to find the file the feature gnus came from.
I execute the following code in scratch buffer which prints filename and the symbols in separate lines consecutively.
(dolist (var load-history)
(princ (format "%s\n" (car var)))
(princ (format "\t%s\n" (cdr var))))
and then search for "(provide . gnus)" and then move the point to the start of line(Ctrl+A).
The file name in the previous line is the file from which the feature came from.
Is there any thing wrong with this method, or does a better method exist.
I don't really know what you're trying to do with this, but here are some notes.
Your method is fine. Any way to hack your own solution to a problem is good in my book.
#Tom is correct that you shouldn't really need to do this, because the problem is already solved for you by the help system. i.e. C-h f
But that's not so interesting. Let's say you really want an automatic, more elegant solution. You want a function -- locate-feature with this signature:
(defun locate-feature (feature)
"Return file-name as string where `feature' was provided"
...)
Method 1 load-history approach
I'll just describe the steps I took to solve this:
You've already got the most important part -- find the variable with the information you need.
I notice immediately that this variable has a lot of data. If I insert it into a buffer as a single line, Emacs will not be happy, because it's notoriously bad at handling long lines. I know that the prett-print package will be able to format this data nicely. So I open up my *scratch* buffer and run
M-: (insert (pp-to-string load-history))
I can now see the data structure I'm dealing with. It seems to be (in pseudo code):
((file-name
((defun|t|provide . symbol)|symbol)*)
...)
Now I just write the function
(eval-when-compile (require 'cl))
(defun locate-feature (feature)
"Return file name as string where `feature' was provided"
(interactive "Sfeature: ")
(dolist (file-info load-history)
(mapc (lambda (element)
(when (and (consp element)
(eq (car element) 'provide)
(eq (cdr element) feature))
(when (called-interactively-p 'any)
(message "%s defined in %s" feature (car file-info)))
(return (car file-info))))
(cdr file-info))))
The code here is pretty straight forward. Ask Emacs about the functions you don't understand.
Method 2 help approach
Method one works for features. But what if by I want to know where any
available function is defined? Not just features.
C-h f already tells me that, but I want the file-name in a string, not all of the verbose help text. I want this:
(defun locate-function (func)
"Return file-name as string where `func' was defined or will be autoloaded"
...)
Here we go.
C-h f is my starting point, but I really want to read the code that defines describe-function. I do this:
C-h k C-h f C-x o tab enter
Now I'm in help-fns.el at the definition of describe-function. I want to work only with this function definition. So narrowing is in order:
C-x n d
I have a hunch that the interesting command will have "find" or "locate" in its name, so I use occur to search for interesting lines:
M-s o find\|locate
No matches. Hmmm. Not a lot of lines in this defun. describe-function-1 seems to be doing the real work, so we try that.
I can visit the definition of describe-function-1 via C-h f. But I already have the file open. imenu is available now:
C-x n w M-x imenu desc*1 tab enter
Narrow and search again:
C-x n d M-s o up enter
I see find-lisp-object-file-name which looks promising.
After reading C-h f find-lisp-object-file-name I come up with:
(defun locate-function (func)
"Return file-name as string where `func' was defined or will be autoloaded"
(interactive "Ccommand: ")
(let ((res (find-lisp-object-file-name func (symbol-function func))))
(when (called-interactively-p 'any)
(message "%s defined in %s" func res))
res))
Now go have some fun exploring Emacs.
There is locate-library for that.
Try...
M-: (locate-library "my-feature")
eg: (locate-library "gnus")
Just use symbol-file. It scan load-history which has format:
Each entry has the form `(provide . FEATURE)',
`(require . FEATURE)', `(defun . FUNCTION)', `(autoload . SYMBOL)',
`(defface . SYMBOL)', or `(t . SYMBOL)'. Entries like `(t . SYMBOL)'
may precede a `(defun . FUNCTION)' entry, and means that SYMBOL was an
autoload before this file redefined it as a function. In addition,
entries may also be single symbols, which means that SYMBOL was
defined by `defvar' or `defconst'.
So call it as:
(symbol-file 'scheme 'provide) ; Who provide feature.
(symbol-file 'nxml-mode-hook 'defvar) ; Where variable defined.
(symbol-file 'message-send 'defun) ; Where function defined.
(symbol-file 'scheme) ; Look for symbol despite its type.
There is nothing wrong with it, but why is it simpler than getting help on a key or a function? If you use a gnus command for example and you want to know where it comes from then you can use C-h k and it tells you from which elisp file its definition comes.

Get a list of all tags in emacs

Is there a way to get all of the tags from the files defined in your tags table list? I've set my tags file like this:
(setq tags-table-list '("~/project/TAGS"))
I've tried (tags-completion-table), but it doesn't contain all the tags.
If you got only one TAGS file, M-x visit-tags-table ~/project/TAGS or (visit-tags-table "~/project/TAGS") should load the TAGS table into a buffer which means it becomes accessible to Emacs in the same way it would be used for, M-x tags-search.
If you add more TAGS files to the project or have more than one project, (setq tags-table-list '("~/project1/TAGS" "~/Project2/TAGS" ...)) and doing (visit-tags-table-buffer t) should visit the next table each time it is called, until the end of the list.
EDIT:
(defvar buffer-in-string)
(defvar string-list)
(defun write-buffer-to-string ()
(interactive)
(setq buffer-in-string (buffer-substring (point-min) (point-max)))
(kill-buffer) ;; If the buffer is big, it makes sense to kill it,
;; since its contents are copied into the string anyway
(setq string-list (split-string buffer-in-string " "))
)
That should bring the buffer into a string. There should be a more elegant way, but at the moment, this is the most I could write with my very limited elisp fluency.
Function tags-completion-table gives you a completion table to use. From the doc string:
Build 'tags-completion-table' on demand.
The tags included in the completion table are those in the current
tags table and its (recursively) included tags tables.
And tags-lazy-completion-table gives you a completion function to use. It uses tags-completion-table.

elisp macro to write a function?

I have written a few nearly identical functions, except for their names. For example:
; x is name, such as function/paragraph/line/etc.
(defun my-x-function
(interactive)
(mark-x) (do-more-stuff) (modify-x))
Is there a way to automatically generate such functions? I have a feeling this is what macros do, but I am not sure how to use them. Any help, maybe including a small example would be great.
Thanks!
Yep, that's exactly what macros do. Here's a straightforward macro that builds functions according to the pattern you specified:
(defmacro make-my-function (name)
(list 'defun (intern (format "my-%s-function" name)) ()
(list 'interactive)
(list (intern (format "mark-%s" name)))
(list 'do-more-stuff)
(list (intern (format "modify-%s" name)))))
You can copy this macro to a *scratch* buffer in Emacs and evaluate it, and then check that it works like this:
(make-my-function x) ; type control-J here
my-x-function ; <-- Emacs's output
(symbol-function 'my-x-function) ; type control-J here
(lambda nil (interactive) (mark-x) (do-more-stuff) (modify-x)) ; <-- Emacs's output
More commonly one would use the backquote facility to write macros more concisely, but all macros essentially work in the same manner as the above example.
Macros can do that, but there are lots of template modules for emacs to do similar work. I use a thing called yasnippet.el to do quick code-generation things. For example, in a C-source file, if I type for<TAB>, I get a for loop template; it allows me to fill in the template, setting the variable name, limits, and internal loop contents.
looks like this:
You can set up templates for anything you like. Function definitions, if statements, switch statements, whatever. Set up different templates for different modes. The template for a for loop in C is different than the template for a for loop in C#, and so on. Very handy.