7

This question in inspired by https://stackoverflow.com/q/605785/. By M-x describe-function <TAB> I can get a list of all interactive or nonintractive functions available in the current state of emacs. If an specific mode is activated (e.g. latex-mode) we get a longer list, as the functions available in latex-mode are also listed.

My question is how to obtain a list of all functions exclusively available in an specific mode (e.g. latex-mode)? In other words excluding all other functions not provided by that mode. Like in the above link providing a short description of the functions would also be handy.

  • 1
    smex attempts this and provides a list of commands for the current major mode when using smex-major-mode-commands. – wasamasa Jul 24 '15 at 18:13
  • @wasamasa thanks for introducing smex. For the commands (interactive functions) this seems to do the job. It remains the non-interactive functions. – Name Jul 24 '15 at 19:05
  • 1
    Oops, forgot my actual point. Study its sources to have something to compare with the code from the other answers. – wasamasa Jul 24 '15 at 21:11
2

What does it mean for a mode to provide a function? You say "a list of all functions exclusively available in an specific mode" and "excluding all other functions not provided by that mode".

It sounds like you are confusing a mode with the library that defines it. A library provides/defines functions. A mode generally does not do so.

If you want to get a list of all of the functions defined in a given library, then see @wvxvw's answer, for a start. You can also try matching the library prefix against function names - that is often pertinent, but it is by no means definitive.

If, however, you want to get a list of all of the functions that might be pertinent to a given mode, e.g., functions that can be used only, or are most useful, when that mode is turned on, then I'm afraid you will need to examine the library where the mode is defined. And you might even need to examine some other libraries.

A given library typically defines more than just some things that are pertinent to a given mode. And a given mode can very well make use of things that are defined in different libraries, and in some cases things that make sense only for that given mode or a set of modes that includes it.

In sum, as currently posed, your question is not very clear. You might help yourself to better answers by clarifying it.

  • You are right, the question should be more precise. For example for latex I mean all functions defined in the .el files contained in the folder site-lisp>auctex. For org-mode I mean all functions defined in the .el files contained in the folder site-lisp>org. For many modes the situation is more straightforward as for them there is only one .el file. I hope these explanations make the motive of my question clear now. – Name Jul 24 '15 at 19:35
2

Perhaps, this code will have some educational effect:

(defun remove-all-extensions (file-name)
  (let ((go-on t) next)
    (while go-on
      (setq next (file-name-sans-extension file-name))
      (setq go-on (not (string= next file-name))
            file-name next))
    next))

(defun function-symbols-of (library)
  (let ((origin (remove-all-extensions
                 (find-library-name
                  (if (stringp library) library
                    (symbol-name library)))))
        (result))
    (mapatoms (lambda (sym)
                (when (and (symbol-function sym)
                           (symbol-file sym)
                           (string= (remove-all-extensions (symbol-file sym))
                                    origin))
                  (push sym result))))
    result))

The problem

Due to non-deterministic nature of code parsing and loading several issues need to be addressed:

  1. When is the function defined in a file? Functions can be defined conditionally, and predicting whether a condition will favor function definition or not is equivalent to solving the halting problem. To illustrate this, suppose this code:

    (if (> (random 100) 50)
       (defun foo ())
       (defun bar ()))
    
  2. It is not generally possible to tell, whether a lisp form defined a function before (successfully) evaluating the form. This is, again, equivalent to halting problem, so, not solvable in general.
  3. There are some common special cases such as aliasing and advising, which (a) create duplicates, (b) may misguide you as to the source file which declared the function.
  4. Large fraction of functions are declared in C code (not necessarily accessible), which isn't really divided into libraries in the same sense that Emacs Lisp code is.

All this said, you probably want to look into find-func.el for inspiration, to get the general idea of the layout and the problems related to locating the source code for Emacs Lisp functions.

  • Let me report this: when running this code I get the error Symbol's function definition is void: find-library-name. The is also a small typo symobols-->symbols. – Name Jul 24 '15 at 19:14
  • @Name hm... but this function is very old (I find it mentioned in source code in 2002). Could you try (require 'find-func) before running this code. Thanks for the typo found. I'll correct that. – wvxvw Jul 24 '15 at 20:04
  • Thanks, It would be great if the name of library can be given by regular expressions. – Name Jul 24 '15 at 20:53
1

I've just added this functionality to lispy. The new command, lispy-goto-elisp-commands, is bound to oge.

The generic g (lispy-goto) gives a list of all tags, highlighting commands with a different face, while lispy-goto-elisp-commands only gives the command tags.

Code listing

(defun lispy-goto-elisp-commands (&optional arg)
  "Jump to Elisp commands within current file.
When ARG is non-nil, force a reparse."
  (interactive "P")
  (deactivate-mark)
  (let ((lispy-force-reparse arg))
    (lispy--fetch-tags (list (buffer-file-name)))
    (let ((struct (gethash (buffer-file-name) lispy-db)))
      (lispy--select-candidate
       (mapcar #'lispy--format-tag-line
               (delq nil
                     (cl-mapcar
                      (lambda (tag pretty-tag)
                        (when (semantic-tag-get-attribute tag :user-visible-flag)
                          pretty-tag))
                      (lispy-dbfile-plain-tags struct)
                      (lispy-dbfile-tags struct))))
       #'lispy--action-jump))))

This is just to show that CEDET's semantic is used to obtain the list of tags; (semantic-tag-get-attribute tag :user-visible-flag) is used to determine if the tag is a command or not.

How to use

  1. Navigate to the file that contains the code. This can be done with f1 f. I like to use counsel-describe-function instead, since pressing C-. there omits having to go through *Help* buffer.

  2. Make point special (move it before open paren, or activate region) and press oge. It's also possible to just use M-x lispy-goto-elisp-commands.

  • I am a little confused, if I like to obtain all functions provided by latex mode what I have to do using your code? – Name Jul 24 '15 at 12:39
  • Open tex-mode.el. Press "oge" get a list of 23 command tags that this file contains. Selecting one of the tags will navigate there. – abo-abo Jul 24 '15 at 12:45
  • Running M-x lispy-goto-elisp-commands on the buffer tex-mode.el gives the error lispy--fetch-tags: Wrong type argument: stringp, ("c:/Program Files/GNU Emacs/share/emacs/24.5/lisp/textmodes/tex-mode.el") – Name Jul 24 '15 at 13:03
  • I have no experience running CEDET on Windows. The command should work fine on GNU/Linux for 24.5.2 and 25 though. – abo-abo Jul 24 '15 at 13:09
  • Your answer speaks of "commands", but the OP question is about functions, not just commands. If you really mean functions then you might want to correct the text. If you mean only commands then this post does not really answer the question yet, in which case you might want to correct it (e.g. change the code or whatever). – Drew Jul 24 '15 at 17:18
1

The smex package has code to list all commands of a package. You could adapt this code to get all functions.

  • Oh yes, sorry i missed that. – rumember Jul 25 '15 at 9:22

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.