How to know when to use parenthesis - emacs

I am reading through An Introduction to Programming in Emacs Lisp, and I see the following:
This code works:
(message "The name of this buffer is: %s." (buffer-name))
while this one fails:
(message "The name of this buffer is: %s." buffer-name)
However, this code works:
(message "The value of fill-column is %d." fill-column)
while this one fails:
(message "The value of fill-column is %d." (fill-column))
My question is why? What is the difference between buffer-name and fill-column? How do I know when to use parentheses?

Simply put - buffer-name is a function (that returns a string) and fill-column is a variable (that evaluates to an integer).
Functions calls in all Lisp dialects should be surrounded by parentheses.
To see details about a function in Emacs press C-h f function-name RET.
To see details about a variable in Emacs press C-h v variable-name RET.

Related

Why is (commandp '(customize-option 'foo)) nil?

I want to bind customize-option for a certain variable to a key, since I need to change it rather often. I have two options:
(global-set-key (kbd "<f12>") '(lambda() (interactive) (customize-option 'my-variable) ) )
(global-set-key (kbd "<f12>") '(customize-option 'my-variable )
The first one works, the second does not, because commandp complains that customize-option is not a command. Why? As far as I know, customize-option is an interactive function, so commandp should be t:
customize-option is an interactive compiled Lisp function.
It is bound to .
(customize-option SYMBOL)
Customize SYMBOL, which must be a user option variable.
It is the form (customize-option 'my-variable) which is not a command. You cannot bind to an arbitrary quoted form, any more than you can bind to a literal string or an unbound symbol. Some of those would be useful to bind to, but it's not hard to work around the limitations. Write a macro if you find it hard to live with. (As the saying goes, now you have two problems.)
The second argument to global-set-key must be a command definition, typically a symbol naming an interactive function. An interactive function is a function that begins with the (interactive) form. For example:
(defun delete-to-end ()
"Delete text from point to the end of buffer."
(interactive)
(delete-region (point) (point-max)))
This defines an interactive function and assigns it to the symbol delete-to-end. After that, delete-to-end is a valid command that you can pass to global-set-key:
(global-set-key [f12] 'delete-to-end)
Without the (interactive) line, delete-to-end would still name a function callable from Lisp programs, but it would not be a "command". Since it is marked interactive, (commandp 'delete-to-end) returns true, and M-x delete-to-end works.
Interactive functions don't need to be bound to a symbol, they can be anonymous. Like any other anonymous functions, they are created using a lambda form, except that for commands it must also include (interactive). Anonymous commands can be passed as the second argument to global-set-key without assigning them to a symbol, so the following definition is equivalent to the one above:
(global-set-key [f12]
(lambda ()
"Delete text from point to the end of buffer."
(interactive)
(delete-region (point) (point-max))))
...except it's somewhat less readable, and looks uglier when inspected with C-h c
or C-h k.
In your case, the first call to global-set-key is given a valid command (a quoted lambda form is itself a valid function), but the second one isn't, it is given a two-element list that can neither be called nor satisfies the requirement of being marked "interactive".

Passing Emacs variables to minibuffer shell commands

I can run a shell command quickly by hitting M-!. One thing I'd like to do is perform shell quick operations on the current file. An example would be checking the file out through perforce:
M-! p4 edit buffer-file-name RET
(Yes there are perforce integrations, but I'm more interested in the minishell/variable problem rather than a specific workflow)
Of course, the buffer-file-name variable is not evaluated before the command is sent to the shell.
Is there an easy on-the-fly way to do this? Or will I have to roll a custom elisp function?
It seems current Emacs has something built-in to achieve the desired result, after M-! (shell-command) press <down>, you will get the file name you are currently visiting on the prompt. Now you can edit it to add the command you want to run on it.
In dired-mode it will give you the file your cursor is currently on.
Indeed using C-u M-: is almost right. I'm not so sure about using shell-quote-argument in eval-to-shell-argument since it only works on strings making it impossible to use eval-to-shell-argument to insert a number or a symbol. You could try something like:
(defun sm-minibuffer-insert-val (exp)
(interactive
(list (let ((enable-recursive-minibuffers t))
(read-from-minibuffer "Insert: "
nil read-expression-map t
'read-expression-history))))
(let ((val (with-selected-window (minibuffer-selected-window)
(eval exp)))
(standard-output (current-buffer)))
(prin1 val)))
and then bind this function in your minibuffer with (define-key minibuffer-local-map [?\M-:] 'sm-minibuffer-insert-val).
Of course, if the only thing you ever want to insert is the buffer-file-name, then your execute-shell-command-on-buffer is simpler.
I did roll my own elisp function, and it looks like this:
(defun execute-shell-command-on-buffer (shell-command-text)
(interactive "MShell command:")
(shell-command (format shell-command-text (shell-quote-argument buffer-file-name)))
)
https://gist.github.com/2367513
I bound it to M-", so now my example can be completed with:
M-"p4 edit %sRET
I won't accept this as the answer, because I did ask for solutions that don't require a function.
You can use C-u M-: (eval-expression with a universal prefix argument) to evaluate any Lisp expression and insert its value at point in the current buffer (including minibuffers, as long as you have enable-recursive-minibuffers set to a non-nil value).
In your example: C-u M-: buffer-file-name RET.
Note that the result of the expression is printed in Lisp form: that is, quoted in such a way that a subsequent call to read would construct an equal Lisp value. For strings, this means enclosing in double quotes, which will probably be interpreted as you expect by the inferior shell. However, you may run into problems with strings that contain special characters, which need different escaping by Elisp and the shell.
The more correct way uses shell-quote-argument, as in phils' solution. Here's a quick defun that reads a Lisp expression and inserts its value at point as a properly quoted shell word:
(defun eval-to-shell-argument (form)
(interactive "XEval: ")
(insert (shell-quote-argument form)))
The read-and-evaluate step happens automatically by using an "X" as the argument to interactive.
Edited to add: As #tenpn notes, the above solution doesn't work for inserting buffer-local variables like buffer-file-name in a minibuffer like the one M-! pops up (more precisely, it inserts the buffer-local value of the minibuffer, which is unlikely to be useful). Here is a revised version which seems to work. If the minibuffer is active, it makes the buffer of the previously-selected window temporarily active while reading and evaluating an expression.
Final edit: From #Stefan's answer I see that I should have used (minibuffer-selected-window) to find the previously-selected window. I've also added a (format "%s" ..) to allow inserting non-string values, while still quoting special characters in strings. Here's the final version:
(defun eval-to-shell-argument ()
(interactive)
(let* ((buffer
(if (minibufferp)
(window-buffer (minibuffer-selected-window))
(current-buffer)))
(result
(with-current-buffer buffer
(eval-minibuffer "Eval: "))))
(insert (shell-quote-argument (format "%s" result)))))
You can't do that with M-!, but you can evaluate arbitrary elisp from the minibuffer, so writing a function isn't strictly necessary:
M-: (shell-command (format "p4 edit %s" (shell-quote-argument buffer-file-name))) RET
In this case however, I think eshell is what you want to use:
M-x eshell-command RET p4 edit (eval buffer-file-name) RET
Edit: Except unfortunately that doesn't work, as the *eshell cmd* buffer is selected when that is evaluated. One solution would be:
M-x eshell-command RET p4 edit (eval buffer-file-name (other-buffer nil t)) RET
(Not quite as elegant, sorry.)
Everyone seems to be rolling their own version, so here's mine -- it will substitue the current filename or marked dired-files or current dired file wherever a % is in the shell command. It follows the same conventions as M-! so I bind it to that.
(defun my-shell-command (command &optional output-buffer error-buffer)
"Run a shell command with the current file (or marked dired files).
In the shell command, the file(s) will be substituted wherever a '%' is."
(interactive (list (read-from-minibuffer "Shell command: "
nil nil nil 'shell-command-history)
current-prefix-arg
shell-command-default-error-buffer))
(cond ((buffer-file-name)
(setq command (replace-regexp-in-string "%" (buffer-file-name) command nil t)))
((and (equal major-mode 'dired-mode) (save-excursion (dired-move-to-filename)))
(setq command (replace-regexp-in-string "%" (mapconcat 'identity (dired-get-marked-files) " ") command nil t))))
(shell-command command output-buffer error-buffer))

Interactive command for inserting the string returned by a function

When evaluating elisp symbolic expressions with (eval-last-sexp), bound to C-x C-e, I can just type C-u before that command to insert the result of the expression into the current buffer.
Is there some equivalent to that when calling functions interactively? For example, if I want to insert the string returned by (emacs-version) into the current-buffer, how would I do that? M-x emacs-version only shows the string in the minibuffer and typing C-u before M-x emacs-version won't work either.
If there is no such equivalent, what would be the easiest way to insert a string returned by a function without first having to type the function down before evaluating it?
UPDATE:
C-u M-x emacs-version does actually work. My mistake. But it does not work for emacs-uptime. How come it doesn't work for that one?
(defun my-insert-command-value (command)
"Insert the return value of the command."
(interactive "*C(insert) M-x ")
(print (call-interactively command) (current-buffer)))
emacs-uptime was implemented to output the result only to minibuffer
(defun emacs-uptime (&optional format)
(interactive)
(let ((str
(format-seconds (or format "%Y, %D, %H, %M, %z%S")
(float-time
(time-subtract (current-time) before-init-time)))))
(if (called-interactively-p 'interactive)
(message "%s" str)
str)))
emacs-version has the following code which prints output if called with C-u
(if here
(insert version-string)
(if (called-interactively-p 'interactive)
(message "%s" version-string)
version-string))
If you want to print the result of a particular command (e.g. emacs-uptime) you can wrap it to insert result into the current buffer (similar to emacs-version).
However, I don't know a generic solution - how to output the result of any Emacs command.
C-u M-x pp-eval-expression RET (emacs-uptime) RET
"Evaluate Emacs-Lisp sexp EXPRESSION, and pretty-print its value.
With a prefix arg, insert the value into the current buffer at point.
With a negative prefix arg, if the value is a string, then insert it
into the buffer without double-quotes (`"')."
See pp+.el.

How to check if a variable is set to what in elisp/emacs?

Let's say I have the following line in .emacs file.
(setq-default default-directory "~/Desktop/mag")
How can I check the value for `default-directory' in elisp?
Added
I asked this question as I need to check the value of default-directory based on this question.
The elisp code should change the default directory when I click C-x C-f, but I still get ~/, not ~/Desktop/mag. So, I need to check what value the default-directory has.
If you're at the console you can type C-h v, which will prompt you for a variable name. Type in default-directory (or any other name) and you'll get a buffer with some info about that variable, including its value.
The elisp function you're running is describe-variable:
(describe-variable VARIABLE)
I figured this out by C-h k C-h v. C-h k shows you what function the next key or key sequence would call.
If you just want to check the value, you can run the following from the *scratch* buffer:
(print default-directory) <ctrl-j>
The *scratch* buffer allows you to evaluate lisp on the fly. You must hit ctrl-j after to evaluate.
As previously stated, C-h v is the easiest way to find out a variables value. To make it even better, place your cursor on the variable you want to know about, and then run C-h v, and it will default to the word under the cursor. Really handy.
Try:
(print default-directory)
write the above code in one line inside of emacs, got to the end of the line and hit C-x C-e
If you just want to see the variable value in the echo
area (less of a mess), try:
(defun describe-variable-short (var)
(interactive "vVariable: ")
(message (format "%s: %s" (symbol-name var) (symbol-value var))) )
(global-set-key "\C-hV" 'describe-variable-short)

How do I make an Emacs keybinding to set a variable?

I've got a variable in Emacs called my-var that I'd like to set whenever I press C-v. How do I do that? I tried this:
(defun set-my-var (value)
"set my var"
(interactive)
(defvar my-var value
"a variable of mine")
)
(global-set-key "\C-v" 'set-my-var)
But that fails:
call-interactively: Wrong number of arguments: (lambda (value) "set my var"
(interactive) (defvar my-var value "a variable of mine")), 0
Actually, defvar doesn't do what you think it does either: it only changes the value IF there was no value before. Here's a chunk that does what you're looking for, using the CTRL-u argument:
(defun set-my-var (value)
"Revised version by Charlie Martin"
(interactive "p")
(setq my-var value))
and here's an example, code from the *scratch* buffer
(defun set-my-var (value)
"Revised version by Charlie Martin"
(interactive "p")
(setq my-var value)) ; do ^J to evaluate the defun form, showing return in the buffer.
set-my-var
(global-set-key "\C-v" 'set-my-var)
set-my-var
;Another ^J
;;; Now, what's the value after ^U^V?
my-var
4
;;; Now ^U 8 ^V
my-var
8
;;; now ^U^U^V
my-var
16
It's in the argument. Look over at the text I just posted about (interactive). When you bind set-my-var to a key, it's looking for an argument, but since you used (interactive) there's no argument to be had. What you wanted is something like (interactive "p") to get the CTRL-u argument, or (interactive "M") to get a string.
Read the EMACS Lisp manual on "Using Interactive."
A couple of other hints:
CTRL-v is a standard binding and
pretty heavily used (scroll-up).
You'd be better off finding
something that's not otherwise used.
Canonically, those would be added to
the CTRL-c keymap.
Don't get in the habit of treating
parens as if they were C braces.
It's better (more customary) LISP
style for the rest of us who might
read your code to just close all the
parens at the end.