From 3340735d482f7ee735a7a3ff02270c76e650e89d Mon Sep 17 00:00:00 2001 From: Andreas Gerler Date: Mon, 2 Feb 2026 09:57:59 +0100 Subject: [PATCH] add reformatter * elpa/reformatter-20241204.1051 --- .../reformatter-autoloads.el | 139 +++++++ .../reformatter-pkg.el | 10 + elpa/reformatter-20241204.1051/reformatter.el | 351 ++++++++++++++++++ 3 files changed, 500 insertions(+) create mode 100644 elpa/reformatter-20241204.1051/reformatter-autoloads.el create mode 100644 elpa/reformatter-20241204.1051/reformatter-pkg.el create mode 100644 elpa/reformatter-20241204.1051/reformatter.el diff --git a/elpa/reformatter-20241204.1051/reformatter-autoloads.el b/elpa/reformatter-20241204.1051/reformatter-autoloads.el new file mode 100644 index 00000000..18894438 --- /dev/null +++ b/elpa/reformatter-20241204.1051/reformatter-autoloads.el @@ -0,0 +1,139 @@ +;;; reformatter-autoloads.el --- automatically extracted autoloads (do not edit) -*- lexical-binding: t -*- +;; Generated by the `loaddefs-generate' function. + +;; This file is part of GNU Emacs. + +;;; Code: + +(add-to-list 'load-path (or (and load-file-name (directory-file-name (file-name-directory load-file-name))) (car load-path))) + + + +;;; Generated autoloads from reformatter.el + +(autoload 'reformatter-define "reformatter" "\ +Define a reformatter command with NAME. + +When called, the reformatter will use PROGRAM and any ARGS to +reformat the current buffer. The contents of the buffer will be +passed as standard input to the reformatter, which should output +them to standard output. A nonzero exit code will be reported as +failure, and the output of the command to standard error will be +displayed to the user. + +The macro accepts the following keyword arguments: + +PROGRAM (required) + + Provides a form which should evaluate to a string at runtime, + e.g. a literal string, or the name of a variable which holds + the program path. + +ARGS + + Command-line arguments for the program. If provided, this is a + form which evaluates to a list of strings at runtime. Default + is the empty list. This form is evaluated at runtime so that + you can use buffer-local variables to influence the args passed + to the reformatter program: the variable `input-file' will be + lexically bound to the path of a file containing the text to be + reformatted: see the keyword options INPUT-FILE, STDIN and + STDOUT for more information. + +STDIN + + When non-nil (the default), the program is passed the input + data on stdin. Set this to nil when your reformatter can only + operate on files in place. In such a case, your ARGS should + include a reference to the `input-file' variable, which will be + bound to an input path when evaluated. + +STDOUT + + When non-nil (the default), the program is expected to write + the reformatted text to stdout. Set this to nil if your + reformatter can only operate on files in place, in which case + the contents of the temporary input file will be used as the + replacement text. + +INPUT-FILE + + Sometimes your reformatter program might expect files to be in + a certain directory or have a certain file extension. This option + lets you handle that. + + If provided, it is a form which will be evaluated before each + run of the formatter, and is expected to return a temporary + file path suitable for holding the region to be reformatted. + It must not produce the same path as the current buffer's file + if that is set: you shouldn't be operating directly on the + buffer's backing file. The temporary input file will be + deleted automatically. You might find the functions + `reformatter-temp-file-in-current-directory' and + `reformatter-temp-file' helpful. + +MODE + + Unless nil, also generate a minor mode that will call the + reformatter command from `before-save-hook' when enabled. + Default is t. + +GROUP + + If provided, this is the custom group used for any generated + modes or custom variables. Don't forget to declare this group + using a `defgroup' form. + +LIGHTER + + If provided, this is a mode lighter string which will be used + for the \"-on-save\" minor mode. It should have a leading + space. The supplied value will be used as the default for a + generated custom variable which specifies the mode lighter. + Default is nil, ie. no lighter. + +KEYMAP + + If provided, this is the symbol name of the \"-on-save\" mode's + keymap, which you must declare yourself. Default is no keymap. + +EXIT-CODE-SUCCESS-P + + If provided, this is a function object callable with `funcall' + which accepts an integer process exit code, and returns non-nil + if that exit code is considered successful. This could be a + lambda, quoted symbol or sharp-quoted symbol. If not supplied, + the code is considered successful if it is `zerop'. + +WORKING-DIRECTORY + + Directory where your reformatter program is started. If provided, this + should be a form that evaluates to a string at runtime. Default is the + value of `default-directory' in the buffer. + +INTERACTIVE-MODES + + If provided, this is a list of mode names (as unquoted + symbols). The created commands for formatting regions and + buffers are then tagged for interactive use in these modes, + making them compatible with some built-in predicate functions + for `read-extended-command-predicate', like + `command-completion-default-include-p'. + +(fn NAME &key PROGRAM ARGS (MODE t) (STDIN t) (STDOUT t) INPUT-FILE LIGHTER KEYMAP GROUP (EXIT-CODE-SUCCESS-P \\='zerop) WORKING-DIRECTORY INTERACTIVE-MODES)" nil t) +(function-put 'reformatter-define 'lisp-indent-function 'defun) +(register-definition-prefixes "reformatter" '("reformatter-")) + +;;; End of scraped data + +(provide 'reformatter-autoloads) + +;; Local Variables: +;; version-control: never +;; no-byte-compile: t +;; no-update-autoloads: t +;; no-native-compile: t +;; coding: utf-8-emacs-unix +;; End: + +;;; reformatter-autoloads.el ends here diff --git a/elpa/reformatter-20241204.1051/reformatter-pkg.el b/elpa/reformatter-20241204.1051/reformatter-pkg.el new file mode 100644 index 00000000..879076d2 --- /dev/null +++ b/elpa/reformatter-20241204.1051/reformatter-pkg.el @@ -0,0 +1,10 @@ +;; -*- no-byte-compile: t; lexical-binding: nil -*- +(define-package "reformatter" "20241204.1051" + "Define commands which run reformatters on the current buffer." + '((emacs "24.3")) + :url "https://github.com/purcell/emacs-reformatter" + :commit "f2cb59466b1c3f85a8c960f7d4b7b7ead015bedc" + :revdesc "f2cb59466b1c" + :keywords '("convenience" "tools") + :authors '(("Steve Purcell" . "steve@sanityinc.com")) + :maintainers '(("Steve Purcell" . "steve@sanityinc.com"))) diff --git a/elpa/reformatter-20241204.1051/reformatter.el b/elpa/reformatter-20241204.1051/reformatter.el new file mode 100644 index 00000000..f95bf2b2 --- /dev/null +++ b/elpa/reformatter-20241204.1051/reformatter.el @@ -0,0 +1,351 @@ +;;; reformatter.el --- Define commands which run reformatters on the current buffer -*- lexical-binding: t; -*- + +;; Copyright (C) 2019 Steve Purcell + +;; Author: Steve Purcell +;; Keywords: convenience, tools +;; Homepage: https://github.com/purcell/emacs-reformatter +;; Package-Requires: ((emacs "24.3")) +;; Package-Version: 20241204.1051 +;; Package-Revision: f2cb59466b1c + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see . + +;;; Commentary: + +;; This library lets elisp authors easily define an idiomatic command +;; to reformat the current buffer using a command-line program, +;; together with an optional minor mode which can apply this command +;; automatically on save. + +;; By default, reformatter.el expects programs to read from stdin and +;; write to stdout, and you should prefer this mode of operation where +;; possible. If this isn't possible with your particular formatting +;; program, refer to the options for `reformatter-define', and see the +;; examples in the package's tests. + +;; As an example, let's define a reformat command that applies the +;; "dhall format" command. We'll assume here that we've already defined a +;; variable `dhall-command' which holds the string name or path of the +;; dhall executable: + +;; (reformatter-define dhall-format +;; :program dhall-command +;; :args '("format")) + +;; The `reformatter-define' macro expands to code which generates +;; `dhall-format-buffer' and `dhall-format-region' interactive +;; commands, and a local minor mode called +;; `dhall-format-on-save-mode'. The :args" and :program expressions +;; will be evaluated at runtime, so they can refer to variables that +;; may (later) have a buffer-local value. A custom variable will be +;; generated for the mode lighter, with the supplied value becoming +;; the default. + +;; The generated minor mode allows idiomatic per-directory or per-file +;; customisation, via the "modes" support baked into Emacs' file-local +;; and directory-local variables mechanisms. For example, users of +;; the above example might add the following to a project-specific +;; .dir-locals.el file: + +;; ((dhall-mode +;; (mode . dhall-format-on-save))) + +;; See the documentation for `reformatter-define', which provides a +;; number of options for customising the generated code. + +;; Library authors might like to provide autoloads for the generated +;; code, e.g.: + +;; ;;;###autoload (autoload 'dhall-format-buffer "current-file" nil t) +;; ;;;###autoload (autoload 'dhall-format-region "current-file" nil t) +;; ;;;###autoload (autoload 'dhall-format-on-save-mode "current-file" nil t) + +;;; Code: +(eval-when-compile + (require 'cl-lib)) +(require 'ansi-color) + +(defun reformatter--make-temp-file (sym) + "Create a temporary file whose filename is based on SYM, but with +slashes replaced by underscores. `make-temp-file' fails +otherwise as it cannot create intermediate directories." + (make-temp-file + (replace-regexp-in-string "/" "_" (symbol-name sym)))) + +(defun reformatter--do-region (name beg end program args stdin stdout input-file exit-code-success-p display-errors &optional working-directory) + "Do the work of reformatter called NAME. +Reformats the current buffer's region from BEG to END using PROGRAM and +ARGS. When DISPLAY-ERRORS is non-nil, shows a buffer if the formatting +fails. For args STDIN, STDOUT, INPUT-FILE, EXIT-CODE-SUCCESS-P and +WORKING-DIRECTORY see the documentation of the `reformatter-define' macro." + (cl-assert input-file) + (cl-assert (functionp exit-code-success-p)) + (when (and input-file + (buffer-file-name) + (string= (file-truename input-file) + (file-truename (buffer-file-name)))) + (error "The reformatter must not operate on the current file in-place")) + (let* ((stderr-file (reformatter--make-temp-file name)) + (stdout-file (reformatter--make-temp-file name)) + ;; Setting this coding system might not universally be + ;; the best default, but was apparently necessary for + ;; some hand-rolled reformatter functions that this + ;; library was written to replace. + (coding-system-for-read 'utf-8) + (coding-system-for-write 'utf-8) + (default-directory (or working-directory default-directory))) + (unwind-protect + (progn + (write-region beg end input-file nil :quiet) + (let* ((error-buffer (get-buffer-create (format "*%s errors*" name))) + (retcode + (condition-case e + (apply 'call-process program + (when stdin input-file) + (list (list :file stdout-file) stderr-file) + nil + args) + (error e)))) + (with-current-buffer error-buffer + (let ((inhibit-read-only t)) + (insert-file-contents stderr-file nil nil nil t) + (unless (integerp retcode) + (insert (error-message-string retcode))) + (ansi-color-apply-on-region (point-min) (point-max))) + (special-mode)) + (if (and (integerp retcode) (funcall exit-code-success-p retcode)) + (progn + (save-restriction + ;; This replacement method minimises + ;; disruption to marker positions and the + ;; undo list + (narrow-to-region beg end) + (reformatter-replace-buffer-contents-from-file (if stdout + stdout-file + input-file))) + ;; If there are no errors then we hide the error buffer + (delete-windows-on error-buffer)) + (if display-errors + (display-buffer error-buffer) + (message (concat (symbol-name name) " failed: see %s") (buffer-name error-buffer)))))) + (delete-file stderr-file) + (delete-file stdout-file)))) + +;;;###autoload +(cl-defmacro reformatter-define (name &key program args (mode t) (stdin t) (stdout t) input-file lighter keymap group (exit-code-success-p 'zerop) working-directory interactive-modes) + "Define a reformatter command with NAME. + +When called, the reformatter will use PROGRAM and any ARGS to +reformat the current buffer. The contents of the buffer will be +passed as standard input to the reformatter, which should output +them to standard output. A nonzero exit code will be reported as +failure, and the output of the command to standard error will be +displayed to the user. + +The macro accepts the following keyword arguments: + +PROGRAM (required) + + Provides a form which should evaluate to a string at runtime, + e.g. a literal string, or the name of a variable which holds + the program path. + +ARGS + + Command-line arguments for the program. If provided, this is a + form which evaluates to a list of strings at runtime. Default + is the empty list. This form is evaluated at runtime so that + you can use buffer-local variables to influence the args passed + to the reformatter program: the variable `input-file' will be + lexically bound to the path of a file containing the text to be + reformatted: see the keyword options INPUT-FILE, STDIN and + STDOUT for more information. + +STDIN + + When non-nil (the default), the program is passed the input + data on stdin. Set this to nil when your reformatter can only + operate on files in place. In such a case, your ARGS should + include a reference to the `input-file' variable, which will be + bound to an input path when evaluated. + +STDOUT + + When non-nil (the default), the program is expected to write + the reformatted text to stdout. Set this to nil if your + reformatter can only operate on files in place, in which case + the contents of the temporary input file will be used as the + replacement text. + +INPUT-FILE + + Sometimes your reformatter program might expect files to be in + a certain directory or have a certain file extension. This option + lets you handle that. + + If provided, it is a form which will be evaluated before each + run of the formatter, and is expected to return a temporary + file path suitable for holding the region to be reformatted. + It must not produce the same path as the current buffer's file + if that is set: you shouldn't be operating directly on the + buffer's backing file. The temporary input file will be + deleted automatically. You might find the functions + `reformatter-temp-file-in-current-directory' and + `reformatter-temp-file' helpful. + +MODE + + Unless nil, also generate a minor mode that will call the + reformatter command from `before-save-hook' when enabled. + Default is t. + +GROUP + + If provided, this is the custom group used for any generated + modes or custom variables. Don't forget to declare this group + using a `defgroup' form. + +LIGHTER + + If provided, this is a mode lighter string which will be used + for the \"-on-save\" minor mode. It should have a leading + space. The supplied value will be used as the default for a + generated custom variable which specifies the mode lighter. + Default is nil, ie. no lighter. + +KEYMAP + + If provided, this is the symbol name of the \"-on-save\" mode's + keymap, which you must declare yourself. Default is no keymap. + +EXIT-CODE-SUCCESS-P + + If provided, this is a function object callable with `funcall' + which accepts an integer process exit code, and returns non-nil + if that exit code is considered successful. This could be a + lambda, quoted symbol or sharp-quoted symbol. If not supplied, + the code is considered successful if it is `zerop'. + +WORKING-DIRECTORY + + Directory where your reformatter program is started. If provided, this + should be a form that evaluates to a string at runtime. Default is the + value of `default-directory' in the buffer. + +INTERACTIVE-MODES + + If provided, this is a list of mode names (as unquoted + symbols). The created commands for formatting regions and + buffers are then tagged for interactive use in these modes, + making them compatible with some built-in predicate functions + for `read-extended-command-predicate', like + `command-completion-default-include-p'." + (declare (indent defun)) + (cl-assert (symbolp name)) + (cl-assert (functionp exit-code-success-p)) + (cl-assert program) + ;; Note: we skip using `gensym' here because the macro arguments are only + ;; referred to once below, but this may have to change later. + (let* ((buffer-fn-name (intern (format "%s-buffer" name))) + (region-fn-name (intern (format "%s-region" name))) + (minor-mode-form + (when mode + (let ((on-save-mode-name (intern (format "%s-on-save-mode" name))) + (lighter-name (intern (format "%s-on-save-mode-lighter" name)))) + `(progn + (defcustom ,lighter-name ,lighter + ,(format "Mode lighter for `%s'." on-save-mode-name) + :group ,group + :type 'string) + (define-minor-mode ,on-save-mode-name + ,(format "When enabled, call `%s' when this buffer is saved. + +To enable this unconditionally in a major mode, add this mode +to the major mode's hook. To enable it in specific files or directories, +use the local variables \"mode\" mechanism, e.g. in \".dir-locals.el\" you +might use: + + ((some-major-mode + (mode . %s-on-save))) + " buffer-fn-name name) + :global nil + :lighter ,lighter-name + :keymap ,keymap + :group ,group + (if ,on-save-mode-name + (add-hook 'before-save-hook ',buffer-fn-name nil t) + (remove-hook 'before-save-hook ',buffer-fn-name t)))))))) + `(progn + (defun ,region-fn-name (beg end &optional display-errors) + "Reformats the region from BEG to END. +When called interactively, or with prefix argument +DISPLAY-ERRORS, shows a buffer if the formatting fails." + (interactive "rp" ,@interactive-modes) + (let ((input-file ,(if input-file + input-file + `(reformatter--make-temp-file ',name)))) + ;; Evaluate args with input-file bound + (unwind-protect + (progn + (reformatter--do-region + ',name beg end + ,program ,args ,stdin ,stdout input-file + #',exit-code-success-p display-errors ,working-directory)) + (when (file-exists-p input-file) + (delete-file input-file))))) + + (defun ,buffer-fn-name (&optional display-errors) + "Reformats the current buffer. +When called interactively, or with prefix argument +DISPLAY-ERRORS, shows a buffer if the formatting fails." + (interactive "p" ,@interactive-modes) + (message "Formatting buffer") + (,region-fn-name (point-min) (point-max) display-errors)) + + ,minor-mode-form))) + + +(defun reformatter-replace-buffer-contents-from-file (file) + "Replace the accessible portion of the current buffer with the contents of FILE." + ;; While the function `replace-buffer-contents' exists in recent + ;; Emacs versions, it exhibits pathologically slow behaviour in many + ;; cases, and the simple replacement approach we use instead is well + ;; proven and typically preserves point and markers to a reasonable + ;; degree. + (insert-file-contents file nil nil nil t)) + +(defun reformatter-temp-file (&optional default-extension) + "Make a temp file re-using the current extension. +If the current file is not backed by a file, then use +DEFAULT-EXTENSION, which should not contain a leading dot. + +The working directory for the command will always be the +`default-directory' of the calling buffer." + (let ((extension (if buffer-file-name + (file-name-extension buffer-file-name) + default-extension))) + (make-temp-file "reformatter" nil + (when extension + (concat "." extension))))) + +(defun reformatter-temp-file-in-current-directory (&optional default-extension) + "Make a temp file in the current directory re-using the current extension. +If the current file is not backed by a file, then use +DEFAULT-EXTENSION, which should not contain a leading dot." + (let ((temporary-file-directory default-directory)) + (reformatter-temp-file default-extension))) + +(provide 'reformatter) +;;; reformatter.el ends here -- 2.47.3