From 1b7f2cf9969e7dfe610780b38b6f3dd834d1c01d Mon Sep 17 00:00:00 2001 From: Mohsin Kaleem Date: Sun, 31 Oct 2021 17:57:44 +0000 Subject: Evaluate any non-special args in apheleia-formatters (#55) (#56) * Evaluate any non-special args in apheleia-formatters (#55) Allows you to place snippets of elisp within a formatter command that will be evaluated and substituted in place when apheleia decides to run that command. * Update apheleia.el Co-authored-by: Radon Rosborough --- CHANGELOG.md | 4 ++++ README.md | 25 +++++++++++++++++++++++++ apheleia.el | 20 ++++++++++++++++++++ 3 files changed, 49 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 157b3ce..07a971d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,8 @@ The format is based on [Keep a Changelog]. * Support multiple formatters ([#31]). You can now configure a list of formatters for a major-mode in `apheleia-mode-alist` and they will be run in sequence. +* Support evaluating items in `apheleia-formatters` to make formatter + commands more dynamic ([#50], [#55]). ### Formatters * [ClangFormat](https://clang.llvm.org/docs/ClangFormat.html) for @@ -43,7 +45,9 @@ The format is based on [Keep a Changelog]. [#39]: https://github.com/raxod502/apheleia/issues/39 [#48]: https://github.com/raxod502/apheleia/pull/48 [#49]: https://github.com/raxod502/apheleia/pull/49 +[#50]: https://github.com/raxod502/apheleia/pull/50 [#54]: https://github.com/raxod502/apheleia/pull/54 +[#55]: https://github.com/raxod502/apheleia/issues/55 ## 1.1.2 (released 2021-02-26) ### Enhancements diff --git a/README.md b/README.md index 5e84422..9292322 100644 --- a/README.md +++ b/README.md @@ -83,6 +83,31 @@ variables: (setf (alist-get 'black apheleia-formatters) '("black" "--option" "..." "-")) ``` + * There are a list of symbols that are interpreted by apheleia + specially when formatting a command (example: `npx`). Any + non-string entries in a formatter that doesn't equal one of + these symbols is evaluated and replaced in place. This can be + used to pass certain flags to the formatter process depending on + the state of the current buffer. For example: + + ```elisp + (push '(shfmt . ("beautysh" + "-filename" filepath + (when-let ((indent (bound-and-true-p sh-basic-offset))) + (list "--indent-size" (number-to-string indent))) + (when indent-tabs-mode "--tab") + "-")) + apheleia-formatters) + ``` + + This adds an entry to `apheleia-formatters` for the `beautysh` + formatter. The evaluated entries makes it so that the `--tab` + flag is only passed to `beautysh` when the value of + `indent-tabs-mode` is true. Similarly the indent-size flag is + passed the exact value of the `sh-basic-offset` variable + only when it is bound. Observe that one of these evaluations + returns a list of flags whereas the other returns a single + string. These are substituted into the command as you'd expect. * `apheleia-mode-alist`: Alist mapping major modes and filename regexps to names of formatters to use in those modes and files. See the docstring for more information. diff --git a/apheleia.el b/apheleia.el index 5cc18db..625c44e 100644 --- a/apheleia.el +++ b/apheleia.el @@ -467,6 +467,26 @@ sequence unless it's first in the sequence")) (cl-return))) arg)) command))) + ;; Evaluate each element of arg that isn't a string and replace + ;; it with the evaluated value. The result of an evaluation should + ;; be a string or a list of strings. If the former its replaced as + ;; is. If the latter the contents of the list is substituted in + ;; place. + (setq command + (cl-loop + for arg in command + with val = nil + do (setq val (if (stringp arg) + arg + (eval arg))) + if val + if (and (consp val) + (cl-every #'stringp val)) + append val + else if (stringp val) + collect val + else do (error "Result of command evaluation must be a string \ +or list of strings: %S" arg))) `(,input-fname ,output-fname ,stdin ,@command)))) (defun apheleia--run-formatters (commands buffer callback &optional stdin) -- cgit v1.0