Read terminal argument and pass the function in lisp? - lisp

(defun gppinterpreter (filename)
(setq fileContent (read-a-file filename))
(write filecontent)
)
(gppinterpreter filename)
I compile this file in ubuntu
clisp example.lisp
I want to get the filename parameter directly from the terminal such as >> clisp example.lisp filename
but this command not working. How can I get filename parameter in gppinterpreter from terminal

In Clisp, the program arguments are given in the variable EXT:*ARGS*..
https://clisp.sourceforge.io/impnotes/clisp.html
Before it is loaded, the variable EXT:ARGS is bound to a LIST of STRINGs, representing the arguments given to the Lisp script (i.e., $1 in /bin/sh becomes (FIRST EXT:ARGS) etc).
So I think you want to use (second EXT:*ARGS*)

Related

how to make own shell command with arguments in emacs?

I want to make my own shell command where i have a variable filename in the command. The filename is passed in an interactive function. I don't know how to save the filename passed as an argument to a variable and further use it to append the whole command.
To ask for a file name (or any other type of value), use interactive. (interactive "fFile: ") means to ask for an existing file (that's what f stands for), prompting with File:.
Then, to concatenate a number of strings, use the concat function.
So the function would look something like this:
(defun my-cat-file (filename)
(interactive "fFile: ")
(shell-command (concat "cat " filename)))

Load file with a relative path

I am trying to load a file in Lisp from a file in the same directory using a relative path.
My file structure looks like this:
repo/
subdir/
main.lisp
test.lisp
In main.lisp I have a number of function definitions, and in test.lisp I want to test the functions.
I have tried using (load "main.lisp") and (load "main") in test.lisp, as well as a number of variations on the pathname (i.e., including ./ before the filename) but both times I get the following error (where <filename> is the filename passed to the load function):
File-error in function LISP::INTERNAL-LOAD: "<filename>" does not exist.
Is it possible to load main.lisp using a relative path?
It may be worth noting that I am running CMUCL and executing the code using SublimeREPL inside of Sublime Text 3.
When a file is being loaded, the variable *LOAD-PATHNAME* is bound to the pathname of the file being loaded, and *LOAD-TRUENAME* to its truename.
So, to load a file in the same directory with the file currently being loaded, you can say
(load (merge-pathnames "main.lisp" *load-truename*))
jlahd's answer is excellent.
If you need to make different pathname calculations, you can do it with the built-in functions:
(let* ((p1 (pathname "test.lisp")) ; not fully specified
(name1 (pathname-name p1)) ; the name "test"
(type1 (pathname-type p1)) ; the type "lisp"
(p2 #p"/Users/joswig/Documents/bar.text") ; a complete pathname
(dir2 (pathname-directory p2))) ; (:ABSOLUTE "Users" "joswig" "Documents")
; now let's construct a new pathname
(make-pathname :name name1
:type type1
:directory (append dir2 (list "Lisp")) ; we append a dir
:defaults p2)) ; all the defaults
; relevant when the filesystem supports
; host, device or version
The result: #P"/Users/joswig/Documents/Lisp/test.lisp".
Usually to reuse something like above, one turn it into a utility function...

Emacs Lisp - declare functions with a variable/varying name

I'm working on an Emacs Lisp package and one particular feature I would like to add is ability to define functions on the fly - they would follow the same naming convention, but it would help me not having to declare every single one of them manually.
To give an example, I have a basic function called exec, which takes an argument that is the name of executable to launch:
(def exec (cmd)
(async-shell-command cmd "buffer"))
At the same time, in this particular case, I know the list of the executables that I will want to use - or more precisely, I know how to get a list of them, as it can change over time. So what I would like to do, given the following list of executables:
("a" "b" "c")
is to iterate over them and for each one to create a function with a name exec-[executable] - exec-a, exec-b, exec-c.
Unfortunately, defun does not evaluate the NAME argument so I cannot create the function name dynamically.
PS. The exec command is good enough in itself - it uses completing-read with the list of executables supplied, but I thought the above would be nice addition.
How 'bout
(dolist (name name-list)
(defalias (intern (concat "exec-" name))
`(lambda () ,(format "Run %s via `exec'." name) (interactive) (exec ,name))))

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