magit-define-popup-option not found - emacs

At some point I managed to add an option to the magit pull popup.
This line ended up in my .emacs (which I believe worked at some point):
(magit-define-popup-option 'magit-pull-popup
?s "recurse submodules" "--recurse-submodules=yes")
Now I get:
eval: Symbol’s function definition is void: magit-define-popup-option
The call looks correct to me according to:
https://github.com/magit/magit/wiki/Additional-proposed-infix-arguments-and-suffix-commands
(magit-define-popup-option 'magit-commit-popup
?D "Override the author date" "--date=" #'read-from-minibuffer)

You can't call a function before it has been defined.
(with-eval-after-load "magit-commit"
(magit-define-popup-option 'magit-commit-popup
?D "Override the author date" "--date=" #'read-from-minibuffer))
n.b. "magit-popup" is the library which defines the magit-define-popup-option function, but I am assuming you want to do this only after "magit-commit" has been loaded (at which point the popup you are specifically interested in has been defined).

Related

Org Mode and the `org-todo` function

I am trying to write a few keybindings.
M-x describe-function org-todo gives:
...
When called through ELisp, arg is also interpreted in the following way:
`none' -> empty state
""(empty string) -> switch to empty state
`done' -> switch to DONE
`nextset' -> switch to the next set of keywords
`previousset' -> switch to the previous set of keywords
"WAITING" -> switch to the specified keyword, but only if it
really is a member of `org-todo-keywords'.
However, I am trying to use the 'previousset symbol as:
(org-todo 'previousset)
which does not work. I know I am calling it validly because
(org-todo "TODO")
changes it to a TODO.
Where is previousset symbol defined? I can't find a definition anywhere.
ANSWER: I worked out that (org-todo 'left) does what I want. Note that the left symbol is not defined, so it sort of acts as a string instead of a variable, as CantrianBear describes.
One of the comments to following question pretty much answers your question.
previousset as well as nextset lead you to the next set of defined keywords. For that to work, org-todo-keywords needs to contain multiple keywords:
(setq org-todo-keywords '((sequence "TODO" "DONE")
(sequence "TODO2" "DONE2")))
If you just want to cycle through your defined keywords in one sequence, simply type C-c C-t (org-todo).

Function Definition - Don't know how to find

I use SlimeNav to read elisp code. It works good mostly, but for inbuilt functions, at times, it does not work.
(local-file (file-relative-name
temp-file
(file-name-directory buffer-file-name))))
In this snippet, when i press Alt + . on local-file function, it says,
Don't know how to find 'local-file'
local-file is not a function anywhere in the core. It's used as a let-bound variable 7 times though.
Maybe you confused it.
Also remember that when accessing the documentation on a function (eg with C-h f), you should see a link you can click to get to the source code. Works also with the C sources if they are available in a way Emacs can find.
As an example, the documentation for find-file looks like this:
find-file is an interactive compiled Lisp function in `files.el'.
It is bound to <open>, C-x C-f, <menu-bar> <file> <new-file>.
(find-file FILENAME &optional WILDCARDS)
Edit file FILENAME.
...
You should be able to see that `files.el' comes out in a different colour, this you can click and it will bring you to the definition of that function.

Emacs Lisp Built-In Indentation Issue with Keywords

Original
Say, I have a function like this:
(defun my-function ()
"This is my function."
:his-keyword xxx
:her-keyword yyy
(his-function)
(her-function))
After applying Emacs built-in indentation for Emacs Lisp, I get:
(defun my-function ()
"This is my function."
:his-keyword xxx
:her-keyword yyy
(his-function)
(her-function))
Of course I expected it to stay as it was, so looks like a bug to me. Does anyone know how to intercept this behavior? Or should I file a bug report? I'm on Emacs 24.3.
Update
I figured it out.
I've been extending the emacs-lisp-mode with my elisp-mode in order to add more syntax highlighting:
...
(define-derived-mode elisp-mode
fundamental-mode
"EL"
"A major mode for Emacs Lisp."
(emacs-lisp-mode)
...)
(provide 'elisp)
And then somewhere:
(require 'elisp)
(add-to-list
'auto-mode-alist
'("\\.el" . elisp-mode))
While elisp-mode was loading successfully, it turned out that emacs-lisp-mode did not load even though I've put (emacs-lisp-mode) into elisp-mode initialization (see above).
After changing to:
(define-derived-mode elisp-mode
emacs-lisp-mode
"EL"
"A major mode for Emacs Lisp."
...)
emacs-lisp-mode turns on properly and the indentation finally behaves as expected. That was pretty subtle.
Although, the 2nd variant seems more natural and right, can anyone give me a clue why the 1st variant didn't work?
original question
I cannot reproduce this with emacs -q and emacs-lisp-mode, so something is wrong with your setup.
You will have to figure out what in your .emacs triggers this behavior, and then report the bug (if it contradicts the documented behavior).
reply to your edit
I think the difference is, more or less, similar to a class inheriting from another class:
(defclass c1 (c2))
and having a field of that class:
(defclass c1 () ((a :type c2)))
See also
Defining Derived Modes
Create new mode in emacs
You might also want to ask a separate question.

How to call interactive Emacs Lisp function with a prefix argument, from another Emacs Lisp function?

I want to write an Emacs Lisp function that will turn on flyspell-mode regardless of the current state of the mode. Function flyspell-mode-on is deprecated. The documentation suggests that a positive prefix argument will turn flyspell-mode, but unfortunately running
(flyspell-mode 1)
results in an error message:
Wrong number of arguments: (lambda (flyspell-mode 1)), 0
If I could figure out how to call flyspell-mode with a prefix argument, I believe I could solve this problem.
The most relevant section I can find in the Emacs Lisp manual is the section entitled "Interactive Call", which describes such commands as call-interactively. This is emphatically not what I want.
(The ultimate problem I am trying to solve is to create a mode hook that turns on the mode regardless of its current state.)
N.B. The title of the question emacs lisp call function with prefix argument programmatically makes it appear to be related, but that question was asking about how to create an interactive command, and the issue was ultimately resolved by using call-interactively.
EDIT: This question is moot; I have found an alternate solution to my original problem:
(add-hook 'text-mode-hook
(function (lambda ()
(require 'flyspell)
(if flyspell-mode nil (flyspell-mode)))))
But I would still like to know how to call an Emacs Lisp function with a prefix argument, from another Emacs Lisp function, with nothing interactive.
UPDATE: Perhaps I should have asked why I was getting that error message...
It looks like your version of Flyspell mode does not follow the minor mode conventions, which require that you can turn on a minor mode with (name-of-mode t) or any positive prefix argument, turn it off with (name-of-mode 0) any negative prefix argument, and toggle it with (name-of-mode nil).
If you have the latest version of Flyspell, a bug report might be in order. I have the version shipped with GNU Emacs 23.2 on my machine, and it respects the convention. My version also defines two functions turn-on-flyspell and turn-off-flyspell, both trivial wrappers around flyspell-mode; functions with such names are common, but not official conventions. The functions flyspell-mode-on and flyspell-mode-off are apparently intended for internal use.
As a general matter, commands read the current prefix argument from the current-prefix-arg variable. Don't confuse that with prefix-arg, which is the value for the next command (only a few commands like universal-argument touch this variable). Thus, if you need to pass a prefix argument when calling a function, bind or set current-prefix-arg.
(let ((current-prefix-arg t))
(flyspell-mode))
If you are not calling a function interactively, then the (interactive) declaration is not used to obtain the arguments.
In the vast majority of cases, you do not need to worry about whether an argument can be a "prefix argument" for non-interactive calls; just check the function documentation, and pass the value you need for whatever it is you want to do.
If for some reason you do need to replicate sending a prefix argument in a non-interactive context, you will need to check that function's (interactive) declaration and determine exactly how it is using that argument, and ensure that you replicate that behaviour for the argument you do pass.
For full details, see:
C-hf interactive RET
M-: (info "(elisp) Prefix Command Arguments") RET
In more complex cases where the function changes its behaviour based on the current-prefix-arg variable, you may be able to set that variable directly.
(let ((current-prefix-arg '(4)))
(foo current-prefix-arg))
I can think of this.. Should be more better
(call-interactively (lambda ()
(interactive)
(flyspell-mode '(4))))
UPDATE:
I can run this directly.. what am i missing from the question.?
(flyspell-mode '(4))
EDITED: Removed quote for lambda expression (I added this note because SX forces an edit to be at least six characters long, so this can be deleted).
FWIW, the `flyspell-mode' function has accepted an argument (as in "(flyspell-mode 1)") at least since Emacs-21, so I don't know how you got that error.
But while I'm here, I might as well point out that (add-hook 'text-mode-hook 'flyspell-mode) has changed meaning in Emacs-24: instead of meaning "toggle flyspell-mode in text modes" it will now mean "enable flyspell-mode in text modes". It's a backward-incompatible change, but I believe it will fix more latent bugs than it will introduce.
See my comment for the fix to the source of your problem. As for the answer to your question, the way the prefix arg is turned into some kind of Lisp argument depends on the interactive spec, so the only way to do it reliably (i.e. without prior knowledge such as the fact that it's a minor mode function) is to call the function interactively:
(let ((current-prefix-arg '(4)))
(call-interactively 'flyspell-mode))
I'm not Emacs and Elisp master (yet ;)) but I think in this case you may use Ctrl-u 1 Alt-x flyspell-mode.

Emacs Lisp: Can't set any value to variable named 's'

This is rather queer. I can't set any value to a variable if it is named 's' in an interactive session:
(setq s 'foo)
=> foo
s
=> nil
Why?
Update 1:
Here is the output from describe-variable on s:
s is void as a variable.
Documentation:
Not documented as a variable.
Why is it that s is kept void in emacs lisp as a global variable?
Update 2:
Turned out, it doesn't happen on a vanilla emacs (meaning one of the modules I load in .emacs or some code in .emacs is causing this).
So the question now is:
What would the original source look like when describe-variable yields "<var> is void as a variable"?
I tried it with setq, defconst, defvar, and defcustom, but none of those produced the message I'm showing.
Update 3:
The message shown above is produced when the variable is literally not bound (though it can be fbound).
(describe-variable 'non-existent)
=> "non-existent is void as a variable.
Documentation:
Not documented as a variable."
So latest question is: Is there any way to prevent a certain variable name
from being bound?
An answer to your revised question:
(defvar s)
The only thing is that this won't let you use describe-variable on it interactively.
(You could then do something like (setplist 's '(variable-documentation "Meh")) to set a description for it without going through defvar.
Just bisect your init file (~/.emacs) recursively until you find the sexp that causes the problem. If it is a sexp that loads another library then either don't use that library or fix it by first finding out what its problem is, the same way: bisect the code in that library recursively, etc.
This is a binary search, and it is very quick. You can quickly comment out half, then 3/4, 7/8, etc. of your file, using M-x comment-region (I bind it to C-x ;). with a prefix arg, comment-region uncomments.
With Emacs 23.1, running the following code makes C-h v s RET show “s is void as a variable.”, but I can't reproduce the inconsistency between setq and retrieving the value of the variable (which I agree is weird).
(setq s t)
(make-local-variable 's)
(makunbound 's)
I suspect an Emacs 24-specific feature or bug.