isearch `interactive` spec uses special characters for user input - emacs

(defun isearch-forward (&optional regexp-p no-recursive-edit)
(interactive "P\np")
(isearch-mode t (not (null regexp-p)) nil (not no-recursive-edit)))
what does special characters p(small lettered p) do as args to interactive function? does the first character P (in caps) mean that regexp-p value comes from a global var definition.
Again, coming to arguments, user inputted word is passed as regexp-p, how does no-recursive-edit gets its value?

The first letter, P, stands for the raw prefix argument, which is the value of variable current-prefix-arg. This is bound to the first formal parameter, regexp-p in this case.
This is separated from the second letter, p, by \n (a newline character). That's the convention for separating inputs in interactive specs.
The second letter, p, stands for the numeric prefix argument, which is the value of (prefix-numeric-value current-prefix-arg). This is bound to the second formal parameter, no-recursive-edit in this case.
Read about this in the Elisp manual, node Interactive Codes.

Related

How to programmatically input answer for user prompt?

Some emacs functions takes a user input string as argument. For example, M-x search-forward, takes a user input string and search for it in buffer.
There are some search string that I uses frequently. Hence I would like to make my own function and hard-code this search string as a parameter for search-forward. For this function search-forward, this is easy because this function's function parameter list has a parameter for search string, as in its defun declaration: (search-forward STRING &optional BOUND NOERROR COUNT). I can just pass the string into STRING paramater.
But for some other function that does similar string search, it does not specify the search string as a parameter. For example, in Magnar's multiple-cursor library, mc/mark-all-in-region-regexp, is a function that search for regexp string provided by user. I would like to make my own short-cut function that takes a fixed string, say, "abc". However, mc/mark-all-in-region-regexp 's parameter list does not have a parameter for search string. Here is the function parameter list: (mc/mark-all-in-region-regexp BEG END). It only has parameter for the region begin and end position. However, if you execute it as a M-x command, i.e. M-x mc/mark-all-in-region-regexp ENTER, then it prompt you to enter the search string.
My question is, how do I write my function, to pass my search string into mc/mark-all-in-region-regexp?
My initial trial is like this. But not achieving what I expected.
(defun my-mc-mark-non-empty-lines ()
(interactive)
(mc/mark-all-in-region)
(insert-string "abc")
)
When crafting a programmatic solution that deals with a function originally designed to request input from the user, it is generally advisable to devise a means to pass a value in the form of an argument or have the value derived from a variable.
For example, the author of the function at issue previously created an additional argument in a commit on April 3, 2015 -- the following is the diff -- i.e., - means removed, + means added.
-(defun mc/mark-all-in-region (beg end)
+(defun mc/mark-all-in-region (beg end &optional search)
"Find and mark all the parts in the region matching the given search"
(interactive "r")
- (let ((search (read-from-minibuffer "Mark all in region: "))
+ (let ((search (or search (read-from-minibuffer "Mark all in region: ")))
(case-fold-search nil))
(if (string= search "")
(message "Mark aborted")
The following link contains an example to programmatically input a yes/no response requested by the user (which is kind of semi-related to your question), but there are already 7 upvotes to the comment by Drew wherein he stated don't do that: https://emacs.stackexchange.com/questions/19077/how-to-programmatically-answer-yes-to-those-commands-that-prompt-for-a-decisio

NIL representation in PC Scheme TI implementation

I am learning LISP using PC Scheme TI implementation and from the book 'Structure and Interpretation of Computer Programs'. PC scheme doesn't seem to have a 'nil' variable
[VM ERROR encountered!] Variable not defined in current environment
NIL
Instead '()' seems to work.
[55] (define one-through-four (list 1 2 3 4 ()))
ONE-THROUGH-FOUR
Do both have the same meaning? What is the correct way to use a sequence of no elements in the PC scheme dialect?
Thanks.
When you say that this dialect "does not have a NIL variable", you are right in two ways. Not only does not nil exist, but it seems to be treated as an ordinary symbol that you can use as a variable. It says "Variable not defined".
In Lisp dialects where nil has a special meaning, nil usually cannot be used as a variable.
nil is equivalent to () only in "classical" Lisps (my term). By this I mean Lisps that are related by ancestry or imitation to the original John MacCarthy Lisp. Emacs Lisp and Common Lisp are that way. The classical Lisps use nil as the list terminator: i.e. (cons 1 nil) producing the list (1)
Scheme is not a classical Lisp in this sense. There is no nil. It uses () as the printed notation for an empty list and when you want that value in an expression, it is quoted, just like a non-empty list literal: '(). In Scheme, (cons 1 nil) is written (cons 1 '()). Boolean false is represented by an object which is notated #f. An empty list is true not false, so (if '() 1 2) yields 1, not 2 like in a classical Lisp. Neither '() nor #f are symbols.
Scheme is also case-sensitive. Even if you do have a variable NIL in Scheme, it has nothing to do with nil. You can use both as variable names.
The SICP text causes confusion on this topic by, in its early chapters, making references to a variable called nil which holds the value of '(). There is no such variable in Scheme; you have to make it yourself if you want those examples to work. This is an unfortunate aspect of the textbook.
If you define a variable nil whose value is the object '(), so that that Chapter 2 code from SICP works, it is still not equivalent to an empty list the way it is in a classical Lisp, because in a classical Lisp, nil and () are equivalent notations for a symbol. The symbol nil itself is the empty list, and vice versa. It is not the name of a variable which merely holds a list. And so the quote expression 'nil also evaluates to the empty list! Whereas in scheme 'nil evaluates to the ordinary symbol nil even if you've defined it as a variable holding the empty list.
Regarding the second question, "() seems to work, do both have the same meaning?". The "same meaning" aspect is covered above: no, not the same meaning in Scheme. As far as it working, consider the following quote from the R5RS Scheme Report:
Note: In many dialects of Lisp, the empty combination, (), is a legitimate expression. In Scheme, combinations must have at least one subexpression, so () is not a syntactically valid expression. [4.1.3 Procedure Calls]
Therefore this loose treatment of () as valid expression that produces the empty list appears to be a PC Scheme extension of behavior, not standard Scheme. It is accepting an expression which is not a syntactically valid Scheme expression.

set text properties

I want to copy a text from one buffer to another with text properties. So I have
(with-current-buffer from-buffer
(setq text-to-copy (buffer-substring beg end)))
How can I insert the text-to-copy to another buffer with all text properties? I'm interested especially in 'face' properties.
The function buffer-substring returns a list, for example ("substring" 42 51 (face font-lock-keyword-face) 52 59 (face font-lock-function-name-face))
If I pass this list to (insert text-to-copy) it seems that it ignores text properties
If font-lock-mode is turned on in the target buffer of insertion, the face property will be reset once the fontification kicks in. I think you'll need to either turn off font-lock-mode, or munge the text properties to replace 'face' with 'font-lock-face' before insertion.
The 'insert' function should handle strings that include text-properties, as-is. Since buffer-substring by default will return a string with text-properties if present, '(insert text-to-copy)' should be all you need to do.
If on the other hand you wanted to extract the string without the text-properties, you'd want to be using buffer-substring-no-properties instead
That should work. This is from Emacs 23.1.1:
buffer-substring is a built-in function in `C source code'.
(buffer-substring start end)
Return the contents of part of the current buffer as a string.
The two arguments start and end are character positions;
they can be in either order.
The string returned is multibyte if the buffer is multibyte.
This function copies the text properties of that part of the buffer
into the result string; if you don't want the text properties,
use `buffer-substring-no-properties' instead.
You can use the command describe-text-properties interactively to see what it is you actually got:
describe-text-properties is an interactive compiled Lisp function in
`descr-text.el'.
It is bound to <C-down-mouse-2> <dp>, <menu-bar> <edit> <props> <dp>.
(describe-text-properties pos &optional output-buffer)
Describe widgets, buttons, overlays and text properties at pos.
Interactively, describe them for the character after point.
If optional second argument output-buffer is non-nil,
insert the output into that buffer, and don't initialize or clear it
otherwise.

Unable to understand a line of Emacs Lisp

The line is
function info() {
emacs -eval "(progn (setq Man-notify-method 'bully) (info \"$1\"))"
}
I know from manuals that
Progn
progn is a special form in `C source
code'.
Setq
setq is a special form in `C source
code'. (setq SYM VAL SYM VAL ...)
Set each SYM to the value of its VAL.
The symbols SYM are variables; they
are literal (not evaluated). The
values VAL are expressions; they are
evaluated. Thus, (setq x (1+ y)) sets
x' to the value of(1+ y)'. The
second VAL is not computed until after
the first SYM is set, and so on; each
VAL can use the new value of variables
set earlier in the setq'. The return
value of thesetq' form is the value
of the last VAL.
$1 seems to a reference to the first parameter after the command man which the user gives.
'bully seems to be a random variable.
Man-notify-method seems to be an action function which is run when man command is executed.
-eval seems to be an evalutian statemant which tells Emacs to run the statement which follows it.
However, I am not completely sure about the function.
I need to understand the function, since I want to bind a bash code of mine to the action function of man. Man-notify-method seems to be that action function, at least in Emacs.
How do you understand the line of Emacs Lisp?
The code you posted is a combination of shell script and elisp.
function info()
{
emacs -eval "(progn (setq Man-notify-method 'bully) (info \"$1\"))"
}
This defines a shell script function named info. It takes 1 parameter, named $1. When you call this function (say, from another shell script), the value of the argument gets substituted in for $1, and it runs the commands specified in sequence. So, if you were to call it like this:
info("something")
The shell would execute this command:
emacs -eval "(progn (setq Man-notify-method 'bully) (info \"something\"))"
This invokes the emacs executable with two arguments, -eval and the command string, which contains embedded escaped quotes. This is asking emacs to invoke the following elisp code:
(progn (setq Man-notify-method 'bully) (info "something"))
progn is a special form. Special forms evaluate their arguments differently than normal function calls. You can find the documentation for progn in chapter 10.1 of the GNU Emacs Lisp Reference Manual. progn is a simple construct for executing a sequence of statements in order. The reason you may need to do this is for cases when you want to execute multiple statements, but the context that you're in only expects a single statement.
For example, an if statement takes 3 (or more) arguments: the condition to evaluate, the expression to evaluate if true, and the expression to evaluate if false. If more than 3 arguments are provided, the subsequent arguments are part of the else branch. If you want to use more than one statement in the true branch, you have to use progn:
(if condition
(progn first-statement-if-true
second-statement-if-true)
first-statement-if-false
second-statement-if-false
)
In this case, if condition is true, then first-statement-if-true and second-statement-if-true will be evaluated. Otherwise, first-statement-if-false and second-statement-if-false will be evaluated.
Thus, your code will simply evaluate the two statements (setq Man-notify-method 'bully) and (info "something") in order.
setq is another special form. See chapter 11.8 for its documentation. It simply sets a variable, named by the first parameter, to the value of the second parameter. The first parameter is not evaluated -- it is taken literally.
A value preceded by a single quote (such as 'bully) is not evaluated. See chapter 9.3 for details on quoting. Hence, (setq Man-notify-method) sets a variable named Man-notify-method to the literal token bully (which is a data type called a symbol, which is distinct from the string "bully").
I can't find the documentation on the info function online, you can get help on any given function in emacs by typing C-h f function-name. So, by typing C-h f info, I got this:
info is an interactive autoloaded Lisp function in `info'.
[Arg list not available until function definition is loaded.]
Enter Info, the documentation browser.
Optional argument FILE specifies the file to examine;
the default is the top-level directory of Info.
Called from a program, FILE may specify an Info node of the form
`(FILENAME)NODENAME'.
In interactive use, a prefix argument directs this command
to read a file name from the minibuffer.
The search path for Info files is in the variable `Info-directory-list'.
The top-level Info directory is made by combining all the files named `dir'
in all the directories in that path.
The online reference manual is very useful, and emacs' interactive help is also indispensible. If you don't understand what a particular function does, just C-h f it.
PROGN simply evaluates the expressions in order, returning the return value of the last one.
SETQ is the basic assignment operator.
INFO enters the emacs info browser.
So, what this does is first assign the symbol 'bully to the variable Man-notify-method, then enter the info browser. 'bully is likely the name of a function, and Man-notify-method a place where the info browser looks up a function to call for some notification (Warning: I am just guessing here).
I guess that you will have to define your own function that calls your shell command like this:
(defun my-cmd ()
(call-process ; Look up the syntax in the emacs lisp manual
))
Then assign its symbol to Man-notify-method:
(setq Man-notify-method 'my-cmd)

What does (interactive) mean in an Emacs Lisp function?

Emacs Lisp function often start like this:
(lambda () (interactive) ...
What does "(interactive)" do?
Just to clarify (it is in the quoted docs that Charlie cites) (interactive) is not just for key-bound functions, but for any function. Without (interactive), it can only be called programmatically, not from M-x (or via key-binding).
EDIT: Note that just adding "(interactive)" to a function won't necessarily make it work that way, either -- there could be many reasons functions are not interactive. Scoping, dependencies, parameters, etc.
I means that you're including some code for the things you need to make a function callable when bound to a key -- things like getting the argument from CTRL-u.
Have a look at CTRL-h f interactive for details:
interactive is a special form in `C source code'.
(interactive args)
Specify a way of parsing arguments for interactive use of a function.
For example, write
(defun foo (arg) "Doc string" (interactive "p") ...use arg...)
to make ARG be the prefix argument when `foo' is called as a command.
The "call" to `interactive' is actually a declaration rather than a function;
it tells `call-interactively' how to read arguments
to pass to the function.
When actually called, `interactive' just returns nil.
The argument of `interactive' is usually a string containing a code letter
followed by a prompt. (Some code letters do not use I/O to get
the argument and do not need prompts.) To prompt for multiple arguments,
give a code letter, its prompt, a newline, and another code letter, etc.
Prompts are passed to format, and may use % escapes to print the
arguments that have already been read.
Furthermore it’s worth mentioning that interactive's main purpose is, in an interactive context (e.g. when user calls function with key binding), let user specify function arguments that otherwise could be only given programmatically.
For instance, consider function sum returns sum of two numbers.
(defun sum (a b)
(+ a b))
You may call it by (sum 1 2) but you can do it only in a Lisp program (or in a REPL). If you use the interactive special form in your function, you can ask the user for the arguments.
(defun sum (a b)
(interactive
(list
(read-number "First num: ")
(read-number "Second num: ")))
(+ a b))
Now M-x sum will let you type two numbers in the minibuffer, and you can still do (sum 1 2) as well.
interactive should return a list that would be used as the argument list if function called interactively.
(interactive) is for functions meant to interact with the user, be it through M-x or through keybindings.
M-x describe-function RET interactive RET for detailed info on how to use it, including parameter to catch strings, integers, buffer names, etc.
One of the "gotchas" that this clarifies is that the argument to interactive is actually a kind of mini-formatting language (like for printf) that specifies the following (for the surrounding function's input):
schema (number of arguments and their type)
source (e.g., marked-region in buffer and/or user input, etc.)
For example,
'r'
Point and the mark, as two numeric arguments, smallest first.
means that the interactive-annotated function needs exactly two arguments.
e.g. this will work
(defun show-mark (start stop)
(interactive "r")
(print start)
(print stop))
This will break:
(defun show-mark (start)
(interactive "r")
(print start))
Wrong number of arguments: ((t) (start) (interactive "r") (print start)), 2