Emacs: Run Current File 🚀

By Xah Lee. Date: . Last updated: .

Here's a emacs command that execute the current file. (the content can be JavaScript code, or python, ruby, bash, golang, etc.)

put this in your Emacs Init File:

(defvar xah-run-current-file-dispatch nil
"A dispatch table used by `xah-run-current-file' to call dedicated function to run code.
Value is a association list.
Each item is (EXT . FUNCTION).
EXT is filename extension (sans the dot), type string.
FUNCTION is a elisp function name to call, type symbol.
If file extension match, and FUNCTION is defined, call it, pass current buffer's filepath as arg.
Else, `xah-run-current-file-map' is looked up." )

(setq xah-run-current-file-dispatch
      '(("el" . load)
        ("elc" . load)
        ("java" . xah-java-compile-and-run)))

(defvar xah-run-current-file-map
  "A association list that maps file extension to a command for running the file, used by `xah-run-current-file'.
Each item is (EXT . PROGRAM).
EXT is filename extension (sans the dot), type string.
PROGRAM is program name or path, with command options to run a file, type string.
A filename is appended after the PROGRAM string as external command to call.")

(setq xah-run-current-file-map
      '(
        ;; following are tested as of 2024-12-20

        ("fs" . "dotnet fsi")
        ("fsx" . "dotnet fsi")
        ("go" . "go run")
        ("js" . "deno run")
        ("php" . "php")
        ("pl" . "perl")
        ("ps1" . "pwsh")
        ("py" . "python")
        ("py2" . "python2")
        ("py3" . "python3")
        ("rb" . "ruby")
        ("ts" . "deno run")
        ("m" . "wolframscript -print all -file")
        ("wl" . "wolframscript -print all -file")
        ("wls" . "wolframscript -print all -file")

        ;; following may be outdated

        ("clj" . "clj")
        ("hs" . "runhaskell")
        ("latex" . "pdflatex")
        ("ml" . "ocaml")
        ("rkt" . "racket")
        ("sh" . "bash")
        ("tex" . "pdflatex")
        ("tsx" . "tsc")
        ("vbs" . "cscript")
        ("pov" . "povray +R2 +A0.1 +J1.2 +Am2 +Q9 +H480 +W640")))

(defun xah-java-compile-and-run (Filename)
  "Compile and run java of current buffer.
Buffer is saved first if modified.

This command is designed for a simple single java class source file.
requires the commands 「javac」 and 「java」.

If compile fails, the error is displayed in a buffer.

Created: 2024-12-20
Version: 2024-12-20"
  (interactive (if buffer-file-name (progn (when (buffer-modified-p) (save-buffer)) (list buffer-file-name)) (user-error "Buffer is not file. Save it first.")))
  (let ((xoutbuf (get-buffer-create "*xah java output*" t))
        (xjavac-buf (get-buffer-create "*xah java compile output*" t)))
    (with-current-buffer xjavac-buf (erase-buffer))
    (call-process "javac" nil xjavac-buf nil Filename)
    (if (eq 1 (with-current-buffer xjavac-buf (point-max)))
        (progn
          (with-current-buffer xoutbuf (erase-buffer))
          (call-process "java" nil xoutbuf nil (file-name-nondirectory (file-name-sans-extension Filename)))
          (display-buffer xoutbuf))
      (display-buffer xjavac-buf))))

(defun xah-run-current-file (Filename)
  "Execute the current file.
Output is printed to buffer *xah-run output*.

File suffix is used to determine what external command to run, in the variable `xah-run-current-file-map'.

If file is modified, it is auto saved before run.

The variable `xah-run-current-file-dispatch' allows you to customize this command to call other function to run the current file.

URL `http://xahlee.info/emacs/emacs/elisp_run_current_file.html'
Created: 2020-09-24
Version: 2024-12-20"
  (interactive (if buffer-file-name (progn (when (buffer-modified-p) (save-buffer)) (list buffer-file-name)) (user-error "Buffer is not file. Save it first.")))
  (let ((xoutbuf (get-buffer-create "*xah-run output*" t))
        (xext (file-name-extension Filename))
        xdispatch)
    (setq xdispatch (assoc xext xah-run-current-file-dispatch))
    (if xdispatch
        (if (fboundp (cdr xdispatch))
            (progn
              (message "calling %s" (cdr xdispatch))
              (funcall (cdr xdispatch) Filename))
          (warn "`xah-run-current-file' found function %s in xah-run-current-file-dispatch but it is unbound. Normal run continues using `xah-run-current-file-map'." xdispatch))
      (let ((xappCmdStr (cdr (assoc xext xah-run-current-file-map))))
        (when (not xappCmdStr) (error "%s: Unknown file extension: %s. check `xah-run-current-file-map'" real-this-command xext))
        (cond
         (t
          (progn
            (with-current-buffer xoutbuf (erase-buffer))
            (apply 'start-process (append (list "xah run" xoutbuf) (split-string xappCmdStr " +" t) (list Filename) nil))
            (display-buffer xoutbuf))))))))

Test

console.log(Array(5).fill(0).map((x, i) => (x + i)));
print(list(range(5)))
Write-Output (1..5)
print (1..5)
p (1..5).to_a
printfn "%A" [1..5]
<?php
print_r(range(1, 5));
?>
Table[ x^2, {x, 1, 5}]
public class PrintMe {
    public static void main(String[] args) {
        System.out.println("73");
    }
}
package main

import "fmt"

func main() {
	for i := 0; i <= 5; i++ {
		fmt.Printf("%v ", i)
	}
}

Get Latest Version

Emacs, Run Current File