branch: scratch/editorconfig commit 583bcb13dfa9e59d128e0b0aa29fb34b1e25e48a Author: Stefan Monnier <monn...@iro.umontreal.ca> Commit: Stefan Monnier <monn...@iro.umontreal.ca>
(editorconfig-indentation-alist): Make it more declarative Make the functions in `editorconfig-indentation-alist` return the list of (VAR . VAL) to set rather than letting them set the vars directly. This makes it possible to obey `editorconfig--should-set` for those vars, and more importantly makes it usable within for Emacs's hack-dir-local system where we manipulate such lists of settings before we apply them. --- editorconfig.el | 75 +++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 49 insertions(+), 26 deletions(-) diff --git a/editorconfig.el b/editorconfig.el index 6cbc76a5d7..12874d670c 100644 --- a/editorconfig.el +++ b/editorconfig.el @@ -38,6 +38,11 @@ ;; EditorConfig files are easily readable and they work nicely with ;; version control systems. +;; News: + +;; In `editorconfig-indentation-alist', if a mode is associated to a function +;; that function should not set the vars but should instead *return* them. + ;;; Code: (require 'cl-lib) @@ -244,7 +249,7 @@ This hook will be run even when there are no matching sections in (julia-mode julia-indent-offset) (kotlin-mode kotlin-tab-width) (kotlin-ts-mode kotlin-ts-mode-indent-offset) - (latex-mode . editorconfig-set-indentation-latex-mode) + (latex-mode . editorconfig--indentation-latex-mode) (lisp-mode lisp-indent-offset) (livescript-mode livescript-tab-width) (lua-mode lua-indent-level) @@ -272,8 +277,8 @@ This hook will be run even when there are no matching sections in (ps-mode ps-mode-tab) (pug-mode pug-tab-width) (puppet-mode puppet-indent-level) - (python-mode . editorconfig-set-indentation-python-mode) - (python-ts-mode . editorconfig-set-indentation-python-mode) + (python-mode . editorconfig--indentation-python-mode) + (python-ts-mode . editorconfig--indentation-python-mode) (rjsx-mode js-indent-level sgml-basic-offset) (ruby-mode ruby-indent-level) (ruby-ts-mode ruby-indent-level) @@ -319,7 +324,8 @@ This hook will be run even when there are no matching sections in Each element looks like (MODE . FUNCTION) or (MODE . INDENT-SPEC-LIST). If FUNCTION is provided, it will be called when setting the -indentation. The indent size will be passed. +indentation. The indent size will be passed and it should return +a list of settings of the form (VAR . VAL). If INDENT-SPEC-LIST is provided, each element of it must have one of the following forms: @@ -426,26 +432,21 @@ Make a message by passing ARGS to `format-message'." (and (stringp string) (string-match-p "\\`[0-9]+\\'" string))) -(defun editorconfig-set-indentation-python-mode (size) - "Set `python-mode' indent size to SIZE." - (when (boundp 'python-indent-offset) - (setq-local python-indent-offset size)) - ;; For https://gitlab.com/python-mode-devs/python-mode - (when (boundp 'py-indent-offset) - (setq-local py-indent-offset size))) - -(defun editorconfig-set-indentation-latex-mode (size) - "Set `latex-mode' indent size to SIZE." - (setq-local tex-indent-basic size) - (setq-local tex-indent-item size) - (setq-local tex-indent-arg (* 2 size)) - ;; For AUCTeX - (when (boundp 'TeX-brace-indent-level) - (setq-local TeX-brace-indent-level size)) - (when (boundp 'LaTeX-indent-level) - (setq-local LaTeX-indent-level size)) - (when (boundp 'LaTeX-item-indent) - (setq-local LaTeX-item-indent (- size)))) +(defun editorconfig--indentation-python-mode (size) + "Var to set `python-mode' indent size to SIZE." + `((python-indent-offset . ,size) + ;; For https://gitlab.com/python-mode-devs/python-mode + (py-indent-offset . ,size))) + +(defun editorconfig--indentation-latex-mode (size) + "Vars to set `latex-mode' indent size to SIZE." + `((tex-indent-basic . ,size) + (tex-indent-item . ,size) + (tex-indent-arg . ,(* 2 size)) + ;; For AUCTeX + (TeX-brace-indent-level . ,size) + (LaTeX-indent-level . ,size) + (LaTeX-item-indent . ,(- size)))) (cl-defun editorconfig--should-set (symbol &optional size) "Determine if editorconfig should set SYMBOL. @@ -516,7 +517,10 @@ See `editorconfig-lisp-use-default-indent' for details." (setq parent (get parent 'derived-mode-parent)))) (when entry (let ((fn-or-list (cdr entry))) - (cond ((functionp fn-or-list) (funcall fn-or-list size)) + (cond ((functionp fn-or-list) + (pcase-dolist (`(,var . ,val) (funcall fn-or-list size)) + (when (editorconfig--should-set var size) + (set (make-local-variable var) val)))) ((listp fn-or-list) (dolist (elem fn-or-list) (cond ((and (symbolp elem) @@ -865,7 +869,26 @@ F is that function, and FILENAME and ARGS are arguments passed to F." (defvar editorconfig-indent-vars-function ;; FIXME: Obey `editorconfig-indentation-alist' as best as we can? ;; Set `smie-indent-basic' if all else fails? - #'ignore) + ;; FIXME: Change `editorconfig-indentation-alist' so that the functions + ;; therein return an list of (VAR . VAL) instead of setting the vars directly. + #'editorconfig--get-indent-vars) + +(defun editorconfig--get-indent-vars (size) + (let ((parents (derived-mode-all-parents major-mode)) + (entry ())) + (while (and parents (not entry)) + (setq entry (assq (pop parents) editorconfig-indentation-alist))) + (if (functionp (cdr entry)) + (funcall (cdr entry)) + (mapcar (lambda (elem) + (if (consp elem) + (let ((spec (cdr elem))) + (cons (car elem) + (cond ((functionp spec) (funcall spec size)) + ((integerp spec) (* spec size)) + (t spec)))) + (cons elem size))) + (cdr entry))))) (defun editorconfig--get-dir-local-variables () (when (and (stringp buffer-file-name)