This page shows a example of writing a emacs lisp function that execute or compile the current file. If you don't know elisp, first take a look at Emacs Lisp Basics.
I want to be able to press a button, and have the current file executed or compiled. The file may be a Perl, Python, Ruby, PHP, Bash, or any shell script.
If you work with scripting languages often, it'd be nice to have a command to run the current buffer directly, even without going into
shell in emacs.
This way is even better than using a interactive command line (aka REPL), because you can write and edit normally with full emacs power. And you can run it by just pressing a key, such as F8.
Here's the solution:
The code does a very few things. It gets the current file's name, current file's suffix, and use the suffix to determine which shell command to run. Then, it generate the shell command string, then run it in a shell.
First, it defines a “suffixMap” which is a list of pairs. In each pair, the first element is the file suffix, and the second element is the language's command line path or name. Such a list of pairs is called “association list” in lisp. (a similar concept is hash table, but we don't need it here since our list only has a handful of elements. See: Emacs Lisp Tutorial: Hash Table.)
To extract the value of a given key in a association list, use the
assoc function like this:
(cdr (assoc myKey myAList)). This is used in our code to obtain a command-line program name of a given file extention, in this line:
(setq progName (cdr (assoc suffix suffixMap))).
(info "(elisp) Association Lists")
The rest of the program is rather simple:
buffer-file-namereturns the full path of the file name of the current buffer.
file-name-extensionreturns the file extension of a given file path/name.
(concat progName " " fName)is the string we want to execute in shell.
(shell-command cmdStr)executes our cmdStr in a shell.
(info "(elisp) Buffer File Name")
(info "(elisp) File Name Components")
Now, we can define a keyboard shortcut for this:
(global-set-key (kbd "<f8>") 'xah-run-current-file)
So now, doesn't matter we are writing in Perl, Python, elisp, …, we can just press a button and have the file executed or compiled.
If you don't have file extension, you might use the current major mode to determine what language it is.
The major mode's name is stored in the variable major-mode.
You also need to redefine your associative list to store major mode names corresponding to program paths.
(thanks to Matic Bojan for suggesting major mode for determining language.)