Invoking an elisp function and make it prompt for input - elisp

In a function that I am writing myself, I would like to invoke the command compile but have it run interactively, just as if I had done Meta-x compile. Just invoking (compile) doesn't work as it expects arguments. So how do force emacs to run compile "interactively"?

The answer is:
(call-interactively 'compile)
This does exactly what I asked for in the question.

Related

Start emacs from shell with predefined lisp code

It is possible to start emacs from the shell and tell it to execute a lisp function, e.g.
emacs -f some-lisp-function my_file.py
However, I would like to pass also lisp functions with arguments, like
emacs -f "(goto-line 10)" my_file.py
# --> not working
and in the best of all worlds, pass also more complex lisp code consisting of multiple function calls, like
emacs -f "(goto-line 10) (some-other-func some-arg)" my_file.py
# --> not working
Does somebody know how?
Edit: To clarify this point, I need a way to evaluate the lisp code in the file's own buffer, after opening it.
(Btw. I know that the goto-line problem could be solved differently without using -f but thats just one example for my general problem)
Try emacs my_file.py --eval '(progn (goto-line 10) (some-other-func some-arg))'. Also note that invoking Emacs as emacs +10 my_file.py will open the file at the tenth line.
You have access to the command line that Emacs was invoked with. You can add code to handle your own command line switches. Depending on what you want, this may be cleaner than --eval. See http://www.gnu.org/software/emacs/manual/html_node/elisp/Command_002dLine-Arguments.html and Emacs custom command line argument.

Can't execute a string as a shell command in elisp

(shell-command "\"C:\\Documents and Settings\\ggustafson\\Desktop\\stuff\\ctags58\\ctags.exe\" -eR -f \"C:\\Documents and Settings\\ggustafson\\Desktop\\BlueTooth_7020\\TAGS\" \"C:\\Documents and Settings\\ggustafson\\Desktop\\BlueTooth_7020\"")
(message "\"C:\\Documents and Settings\\ggustafson\\Desktop\\stuff\\ctags58\\ctags.exe\" -eR -f \"C:\\Documents and Settings\\ggustafson\\Desktop\\BlueTooth_7020\\TAGS\" \"C:\\Documents and Settings\\ggustafson\\Desktop\\BlueTooth_7020\"")
Executing the top form gives me the error 'C:\Documents' is not recognized as an internal or external command, operable program or batch file.. Executing the output the second form puts into the *Messages* buffer works as intended (creates a tags file).
Why am I not getting the same results with both techniques? Does shell-command do something that changes the string before sending it to the shell? How can I use elisp to execute a string exactly as if I had pasted it into a command prompt?
shell-quote-argument does not work either as it produces a string that cannot be executed with either method:
(message (shell-quote-argument "\"C:\\Documents and Settings\\ggustafson\\Desktop\\stuff\\ctags58\\ctags.exe\" -eR -f \"C:\\Documents and Settings\\ggustafson\\Desktop\\BlueTooth_7020\\TAGS\" \"C:\\Documents and Settings\\ggustafson\\Desktop\\BlueTooth_7020\""))
"^\"\\^\"C:\\Documents and Settings\\ggustafson\\Desktop\\stuff\\ctags58\\ctags.exe\\^\" -eR -f \\^\"C:\\Documents and Settings\\ggustafson\\Desktop\\BlueTooth_7020\\TAGS\\^\" \\^\"C:\\Documents and Settings\\ggustafson\\Desktop\\BlueTooth_7020\\^\"^\""
shell-quote-argument is for quoting a single argument to a shell command (hence the name), not a shell command in its entirety.
Given that the error you were seeing suggested a lack of quoting somewhere, it seemed like a good idea to use the built-in command to deal with quoting rather than writing it manually and assuming you had the correct syntax.
Another alternative is using M-! to execute the command (or a similar one) interactively, figure out what gets accepted, and then afterwards use C-xM-: to obtain the elisp form.
I would suggest you to doublecheck both if executions are using same path, and therefore same ctags.exe. I think that might be the problem. You may want to use the full path to ctags.exe to make sure of that.
My ctags (Linux) gives me the same error if I use the -Re option on a normal shell; that is what makes me think that way.
I'd strongly recommend you use call-program instead of shell-command here, since you don't use any of the features of the shell, and it just gets in the way, forcing you to do quoting gymnastics to explain to the shell what you mean.

Cannot `source` shc-compiled scripts

Is there any way to source (include) compiled script?
I use shc to compile all of my scripts and when I run them from the command line they work OK to start. But when script have to include other two scripts (variables.sh.x and functions.sh.x) it crashes and returns an error, that binary files can not be included.
Is there any way to accomplish this?
including piece of code:
source $(dirname $0)/variables.sh.x
source $(dirname $0)/functions.sh.x
shc does not actually compile scripts. It merely obfuscates them by encrypting and embedding them inside a C program, so it cannot improve performance. The actual shell still interprets and executes the code and is required for the script to run.
If you absolutely must use this tool to obfuscate your code, you will have to combine everything into a single file.

Emacs and Long Shell Commands

Is there a way to run a shell command, have the output show up in a new buffer and have that output show up incrementally? Eshell and other emacs terminal emulators do a find job of this but I see no way to script them.
What I'd like to do is write little elisp functions to do stuff like run unit tests, etc. and watch the output trickle into a buffer.
The elisp function shell-command is close to what I want but it shows all the output at once when the process finishes.
As doublep mentioned, there is M-x compile, and there's also just the simple M-x shell and in that shell you run whatever you want.
You can also use comint-run to execute a command without needing to start a sub-shell first. I believe M-x shell uses comint mode with some modifications, so this won't be a whole lot different from that. But if you want to call a program directly and have its input and output be tied to a buffer, comint-run is the function to call. It is a little tricky to use, so read the documentation: C-h f comint-run.

How do I execute a .scm script (outside of the REPL) with MIT-Scheme?

I want to type something like 'scheme file.scm' and have it interpret the file, and then take me back to my shell, rather than loading it in the REPL.
edit: I tried scheme < test.scm and it still uses the REPL, the only difference is that scheme exits when the stream ends.
scheme < file.scm should work (as long as you don't specify --interactive and stdin is not a terminal, scheme works non-interactively).
To run a scheme program using MIT Scheme:
scheme --quiet < program.scm
The --quiet option ensures that the output from your program is the only thing that is displayed (i.e. you won't see the REPL, as per your requirements).
Caveat: This will not work if your program prompts the user for input using the input procedures (e.g. read, read-char, read-line, etc.). This is because of the shell input redirection (<) (See: relevant question). Unfortunately, there is currently no proper way of executing an MIT Scheme script from the command line when input procedures are used. The best option is probably mit-scheme --quiet --load 'myscript', but you'd have to manually exit MIT Scheme when the script finishes. Relevant mailing list thread: [MIT-Scheme-devel] How to run a script and exit?
EDIT: Due to the possibility that you may mistype < as >, resulting in the overwrite of your source code, I would suggest encapsulating the above command within a shell script or a shell function. For example:
runscheme () {
scheme --quiet < "$1"
}
Then you can run runscheme program.scm without fear that your source code will be overwritten. (Special thanks to Paul Rooney for bringing this potential mistake to my attention).
References
scheme --help:
--batch-mode, --quiet, --silent
Suppresses the startup report of versions and copyrights, and the
valediction.
This command line option seems to have been mistakenly ommitted from the list of command line options in the documentation, but I think this is a legimate command line option because scheme --help shows it, and because --batch-mode is used in other parts of the reference manual (e.g. here).
I think what you want is SCM. You can execute a .scm script like this:
$ scm -f foo.scm arg1 arg2 arg3
See http://people.csail.mit.edu/jaffer/scm_3.html#SEC28 for more details.
The SCM homepage: http://people.csail.mit.edu/jaffer/SCM
checked chez --help, and then I found this(let's say that I'm using chez scheme):
chez --script ./temp.scm
Also, --verbose is very useful:
chez --verbose --script ./temp.scm

Resources