Emacs Lisp Code Formatter, emacs-elisp-autofmt by Campbell Barton
what is emacs-elisp-autofmt
emacs-elisp-autofmt is a emacs lisp package that auto format emacs lisp code.
download at https://codeberg.org/ideasman42/emacs-elisp-autofmt
requirement
requires:
- Emacs 27.2 (or newer).
- Python 3.8 (or newer).
formatting engine
the formatting engine is a pyton script elisp-autofmt.py
but it has a emacs lisp command wrapper Alt+x elisp-autofmt-buffer
.
You can run the python code to reformat emacs lisp source code files. However, the result won't be compatible with emacs lisp convention. To have emacs lisp convention format, you need to call the emacs command, because emacs lisp has some technical complexity that emacs lisp can self-define how it should be formatted.
to run the python script:
python path/elisp-autofmt.py elisp_file_path
e.g.
python c:/Users/xah/git/emacs-elisp-autofmt/elisp-autofmt.py some.el
setup python executable path
run the following to setup your python path.
(setq elisp-autofmt-python-bin "python") ;; or (setq elisp-autofmt-python-bin "python3")
elisp-autofmt.py --h usage: elisp-autofmt.py [-h] [--fmt-defs-dir DIR] [--fmt-defs FILES] [--fmt-style {native,fixed}] [--quiet] [--fmt-trailing-parens] [--fmt-quoted FMT_USE_QUOTED] [--fmt-fill-column [FMT_FILL_COLUMN]] [--fmt-empty-lines [FMT_EMPTY_LINES]] [--fmt-line-range FMT_LINE_RANGE] [--parallel-jobs [PARALLEL_JOBS]] [--stdin] [--stdout] [--exit-code [EXIT_CODE]] ... Format emacs-lisp. positional arguments: files All trailing arguments are treated as file paths to format. optional arguments: -h, --help show this help message and exit --fmt-defs-dir DIR Directory used for storing definitions. --fmt-defs FILES Definition filenames within "--fmt-defs-dir" when only a filename is specified, otherwise absolute paths are used. split by PATH_SEPARATOR. (internal use, this is written by Emacs). --fmt-style {native,fixed} Formatting style in where "native" mimics EMACS default indentation and "fixed" formats using a simple 2-space for each nested block rule. --quiet Don output any status messages. --fmt-trailing-parens Give each trailing parenthesis it's own line. --fmt-quoted FMT_USE_QUOTED Format quoted S-expressions. --fmt-fill-column [FMT_FILL_COLUMN] Maxumum column width (zero disables). --fmt-empty-lines [FMT_EMPTY_LINES] Maximum column width. --fmt-line-range FMT_LINE_RANGE The line range (starting at 1 & inclusive) to format. Lines outside this range will output syntactically correct but the formatting is undefined. Note that this is intended for callers that are only only formatting a sub-region, in this case additional processing for anything outside this sub-region can be avoided.A value of 0-0 is ignored. --parallel-jobs [PARALLEL_JOBS] The number of parallel processes to use (zero to select automatically, -1 to disable multi-processing). --stdin Use the stdin for file contents instead of the file name passed in. --stdout Use the stdout to output the file contents instead of the file name passed in. --exit-code [EXIT_CODE] Exit code to use upon successfully re-formatting This program formats emacs lisp, from the standard input, or operating on files, in-place.
elisp-autofmt-mode
- Toggle the minor mode which formats upon saving.
elisp-autofmt-buffer
- Auto formats the current buffer (doesn't depend on the minor mode).
elisp-autofmt-region
- Auto formats the selected region.
elisp-autofmt-region-dwim
- Auto formats the selected region or the surrounding multi-line block when there is no active region.
emacs-elisp-autofmt
https://codeberg.org/ideasman42/emacs-elisp-autofmt
If you made that package robust, i'd highly recommend it. Back around 2007, i tried to pay someone some small money to implement it. It was a chinese coder, a hotshot, wrote tons of emacs packages but in general not good in my opinion. He coded it, but from what i see isn't usable.
I think what's needed is:
- Have a command to format current function.
- Have a command to format current region.
- Have a command to format current buffer.
- Have a command to format a file given file path.
- The command must be robust and 100% correct. It it screwed up the code 1 in a million, it's not usable. (watch out for comments, strings, escapes in string, and complex regex in string.)
- The command must be fast. So, writing it in elisp isn't that great. Eventually, it needs to be written in golang or such.
- It must be able to run in batch and update format of the 1.5k elisp files bundled in gnu emacs. It must not be slow. (compare speed of gofmt of golang and deno of JavaScript.)
- It must support the traditional gnu elisp format style. MUST. Other format style is optional. Else, the package won't be adopted by many.
- Most important: it must be able to format a compacted long line of lisp code into multi-lines.
Now, here's the MOST important thing, of ALL the above items: It must do the reformat completely. e.g. If i have
(defun f () "DOCSTRING" (interactive) (let () 3 ))
it must format to
(defun f () "DOCSTRING" (interactive) (let () 3 ))
Emacs Lisp Code Formatter, emacs-elisp-autofmt by Campbell Barton
just tried this https://codeberg.org/ideasman42/emacs-elisp-autofmt failed. sad.
first of all, for some unfathomable reason, the function are not commands, so you cannot call it by pressing Alt+x.
then, when you run it by
Alt+x eval-expression
then type
(elisp-autofmt-buffer)
, you get this error
it requires python, and by calling a command python3
.
lol jisus.
then, after you set
(setq elisp-autofmt-python-bin "python")
and do it on Emacs: Xah Fly Keys 📦 source code, a file of 4.7k lines. Froze emacs for one minute, still stuck. I aborted it.
worked on smaller files, but very slow.