mirror of
https://github.com/vale981/apheleia
synced 2025-03-04 17:11:40 -05:00
Add various helper functions for defining formatters (#166)
This commit is contained in:
parent
43ffed7890
commit
edec1e61c8
2 changed files with 112 additions and 43 deletions
|
@ -2,10 +2,103 @@
|
|||
|
||||
;;; Commentary:
|
||||
|
||||
;; Formatter definitions for `apheleia'.
|
||||
;; Formatter helper functions and definitions for `apheleia'.
|
||||
|
||||
;;; Code:
|
||||
|
||||
(require 'cl-lib)
|
||||
(require 'subr-x)
|
||||
|
||||
(defun apheleia-formatters-indent (tab-flag indent-flag indent-var)
|
||||
"Set flag for indentation.
|
||||
Helper function for `apheleia-formatters' which allows you to supply
|
||||
alternating flags based on the current buffers indent configuration. If the
|
||||
buffer is indented with tabs then returns TAB-FLAG. Otherwise if INDENT-VAR
|
||||
is set in the buffer return INDENT-FLAG and the value of INDENT-VAR. Use this
|
||||
to easily configure the indentation level of a formatter."
|
||||
(cond
|
||||
(indent-tabs-mode tab-flag)
|
||||
(indent-var
|
||||
(when-let ((indent (and (boundp indent-var)
|
||||
(symbol-value indent-var))))
|
||||
(list indent-flag (number-to-string indent))))))
|
||||
|
||||
(defun apheleia-formatters-js-indent (tab-flag indent-flag)
|
||||
"Variant of `apheleia-formatters-indent' for JavaScript like modes.
|
||||
See `apheleia-formatters-indent' for a description of TAB-FLAG and
|
||||
INDENT-FLAG."
|
||||
(apheleia-formatters-indent
|
||||
tab-flag indent-flag
|
||||
(cl-case major-mode
|
||||
(json-mode 'js-indent-level)
|
||||
(json-ts-mode 'json-ts-mode-indent-offset)
|
||||
(js-mode 'js-indent-level)
|
||||
(js-jsx-mode 'js-indent-level)
|
||||
(js2-mode 'js2-basic-offset)
|
||||
(js2-jsx-mode 'js2-basic-offset)
|
||||
(js3-mode 'js3-indent-level))))
|
||||
|
||||
(defcustom apheleia-formatters-respect-fill-column nil
|
||||
"Whether formatters should set `fill-column' related flags."
|
||||
:type 'boolean
|
||||
:group 'apheleia)
|
||||
|
||||
(defun apheleia-formatters-fill-column (fill-flag)
|
||||
"Set flag for wrap column.
|
||||
Helper function to set a flag based on `fill-column'. When `fill-column' is set
|
||||
and `apheleia-formatters-respect-fill-column' return a list of FILL-FLAG and
|
||||
`fill-column'."
|
||||
(when (and apheleia-formatters-respect-fill-column
|
||||
(bound-and-true-p fill-column))
|
||||
(list fill-flag (number-to-string fill-column))))
|
||||
|
||||
(defun apheleia-formatters-locate-file (file-flag file-name)
|
||||
"Set a flag based on a dominating-file.
|
||||
Look for a file up recursively from the current directory until FILE-NAME is
|
||||
found. If found return a list of FILE-FLAG and the absolute path to the located
|
||||
FILE-NAME."
|
||||
(when-let ((file (locate-dominating-file default-directory file-name)))
|
||||
(list file-flag (concat (expand-file-name file) file-name))))
|
||||
|
||||
(defun apheleia-formatters-extension-p (&rest exts)
|
||||
"Assert whether current buffer has an extension in EXTS."
|
||||
(when-let ((name buffer-file-name)
|
||||
(ext (file-name-extension name)))
|
||||
(cl-find-if (apply-partially #'string-equal ext)
|
||||
exts)))
|
||||
|
||||
(defcustom apheleia-formatters-mode-extension-assoc
|
||||
'((c-mode . ".c")
|
||||
(c-ts-mode . ".c")
|
||||
(c++-mode . ".cpp")
|
||||
(c++-ts-mode . ".cpp")
|
||||
(glsl-mode . ".glsl")
|
||||
(java-mode . ".java")
|
||||
(java-ts-mode . ".java"))
|
||||
"Association list between major-modes and common file extensions for them."
|
||||
:type 'alist
|
||||
:group 'apheleia)
|
||||
|
||||
(defun apheleia-formatters-mode-extension (&optional flag)
|
||||
"Get a file-extension based on the current `major-mode'.
|
||||
If FLAG is set this function returns a list of FLAG and then the extension.
|
||||
Otherwise return the extension only."
|
||||
(when-let ((ext
|
||||
(alist-get major-mode apheleia-formatters-mode-extension-assoc)))
|
||||
(if flag
|
||||
(list flag ext)
|
||||
ext)))
|
||||
|
||||
(defun apheleia-formatters-local-buffer-file-name ()
|
||||
"Get variable `buffer-file-name' without any remote components."
|
||||
(when-let ((name buffer-file-name))
|
||||
(let ((remote (file-remote-p name)))
|
||||
(if remote
|
||||
(substring name (length remote))
|
||||
name))))
|
||||
|
||||
|
||||
|
||||
(defcustom apheleia-formatters
|
||||
'((bean-format . ("bean-format"))
|
||||
(black . ("black" "-"))
|
||||
|
|
|
@ -32,19 +32,16 @@ If ALL is non-nil, unconditionally return all formatters."
|
|||
"Check out given Git REF and return `apheleia-formatters' from there.
|
||||
Return an Elisp data structure, same as the `apheleia-formatters'
|
||||
already in memory on the current branch."
|
||||
(let ((old-apheleia (make-temp-file "apheleia-" nil ".el"))
|
||||
(let ((old-apheleia (make-temp-file "apheleia-" 'dir))
|
||||
(stderr-file (make-temp-file "apheleia-ft-stderr-")))
|
||||
(with-temp-file old-apheleia
|
||||
(with-temp-buffer
|
||||
(let ((exit-status
|
||||
(call-process
|
||||
"git"
|
||||
nil (list (current-buffer) stderr-file) nil
|
||||
"show" (format "%s:apheleia-formatters.el" ref))))
|
||||
"--work-tree" old-apheleia "checkout" ref "--" "*.el")))
|
||||
(unless (zerop exit-status)
|
||||
(with-temp-buffer
|
||||
(insert-file-contents stderr-file)
|
||||
(princ (buffer-string)))
|
||||
(error "Failed to 'git show %s:apheleia.el', got exit status %S"
|
||||
(error "Failed to 'git checkout %s -- *.el', got exit status %S"
|
||||
ref exit-status))))
|
||||
(with-temp-buffer
|
||||
(call-process
|
||||
|
@ -52,7 +49,9 @@ already in memory on the current branch."
|
|||
(expand-file-name invocation-name invocation-directory)
|
||||
invocation-name)
|
||||
nil (current-buffer) nil
|
||||
"--batch" "-l" old-apheleia "--eval" "(prin1 apheleia-formatters)")
|
||||
"--batch" "-L" old-apheleia
|
||||
"--eval" "(require 'apheleia)"
|
||||
"--eval" "(prin1 apheleia-formatters)")
|
||||
(goto-char (point-min))
|
||||
(read (current-buffer)))))
|
||||
|
||||
|
@ -226,8 +225,12 @@ environment variable, defaulting to all formatters."
|
|||
(let ((load-suffixes '(".el")))
|
||||
(locate-library "apheleia"))))))
|
||||
exec-path)))
|
||||
;; Some formatters use the current file-name or buffer-name to interpret the
|
||||
;; type of file that is being formatted. Some may not be able to determine
|
||||
;; this from the contents of the file so we set this to force it.
|
||||
(rename-buffer in-file)
|
||||
(setq stdout-buffer (get-buffer-create
|
||||
(format "*apheleia-ft-stdout-%S" formatter)))
|
||||
(format "*apheleia-ft-stdout-%S%s" formatter extension)))
|
||||
(with-current-buffer stdout-buffer
|
||||
(erase-buffer))
|
||||
(if (functionp command)
|
||||
|
@ -243,41 +246,14 @@ environment variable, defaulting to all formatters."
|
|||
(copy-to-buffer stdout-buffer (point-min) (point-max))))
|
||||
(progn
|
||||
|
||||
(let ((result (apheleia--format-command command nil nil)))
|
||||
(setq command (nthcdr 3 result)
|
||||
in-temp-real-file (nth 0 result)
|
||||
out-temp-file (nth 1 result)))
|
||||
|
||||
(with-current-buffer stdout-buffer
|
||||
(erase-buffer))
|
||||
(mapc
|
||||
(lambda (arg)
|
||||
(when (memq arg '(file filepath input output inplace))
|
||||
(cl-pushnew arg syms)))
|
||||
command)
|
||||
(when (or (memq 'file syms) (memq 'filepath syms))
|
||||
(setq in-temp-real-file (apheleia-ft--write-temp-file
|
||||
in-text extension)))
|
||||
(when (or (memq 'input syms) (memq 'inplace syms))
|
||||
(setq in-temp-file (apheleia-ft--write-temp-file
|
||||
in-text extension))
|
||||
(when (memq 'inplace syms)
|
||||
(setq out-temp-file in-temp-file)))
|
||||
(when (memq 'output syms)
|
||||
(setq out-temp-file (apheleia-ft--write-temp-file
|
||||
"" extension)))
|
||||
(setq command (delq 'npx command))
|
||||
(setq command
|
||||
(mapcar
|
||||
(lambda (arg)
|
||||
(pcase arg
|
||||
((or `file `filepath)
|
||||
in-temp-real-file)
|
||||
((or `input `inplace)
|
||||
in-temp-file)
|
||||
(`output
|
||||
out-temp-file)
|
||||
((guard (stringp arg))
|
||||
arg)
|
||||
(_ (eval arg))))
|
||||
command))
|
||||
(setq stdout-buffer (get-buffer-create
|
||||
(format "*apheleia-ft-stdout-%S" formatter)))
|
||||
|
||||
(setq exit-status
|
||||
(apply
|
||||
#'call-process
|
||||
|
|
Loading…
Add table
Reference in a new issue