From 6e50ee8bbb50ef86707cefed8ebb20f027156843 Mon Sep 17 00:00:00 2001 From: Theodor Thornhill Date: Wed, 25 Jan 2023 21:04:00 +0100 Subject: [PATCH] Add c-ts-mode-set-style and :set for c-ts-mode-indent-style * lisp/progmodes/c-ts-mode.el (c-ts-mode--indent-style-setter): New setter for the indent style defcustom. (c-ts-mode-indent-style): Don't quote the values and refer to the setter. (c-ts-mode-set-style): New command to interactively set the indent style. (c-ts-mode--get-indent-style): New function renamed from 'c-ts-mode--set-indent-style'. --- lisp/progmodes/c-ts-mode.el | 67 ++++++++++++++++++++++++++----------- 1 file changed, 48 insertions(+), 19 deletions(-) diff --git a/lisp/progmodes/c-ts-mode.el b/lisp/progmodes/c-ts-mode.el index eb2be9b792b..c6eb1afecec 100644 --- a/lisp/progmodes/c-ts-mode.el +++ b/lisp/progmodes/c-ts-mode.el @@ -92,6 +92,34 @@ :safe 'integerp :group 'c) +(defun c-ts-mode--indent-style-setter (sym val) + "Custom setter for `c-ts-mode-set-style'." + (set-default sym val) + (named-let loop ((res nil) + (buffers (buffer-list))) + (if (null buffers) + (mapc (lambda (b) + (with-current-buffer b + (setq-local treesit-simple-indent-rules + (treesit--indent-rules-optimize + (c-ts-mode--get-indent-style + (if (eq major-mode 'c-ts-mode) 'c 'cpp)))))) + res) + (let ((buffer (car buffers))) + (with-current-buffer buffer + (if (or (eq major-mode 'c-ts-mode) (eq major-mode 'c++-ts-mode)) + (loop (append res (list buffer)) (cdr buffers)) + (loop res (cdr buffers)))))))) + +(defun c-ts-mode--get-indent-style (mode) + "Helper function to set indentation style. +MODE is either `c' or `cpp'." + (let ((style + (if (functionp c-ts-mode-indent-style) + (funcall c-ts-mode-indent-style) + (alist-get c-ts-mode-indent-style (c-ts-mode--indent-styles mode))))) + `((,mode ,@style)))) + (defcustom c-ts-mode-indent-style 'gnu "Style used for indentation. @@ -100,13 +128,27 @@ one of the supplied styles doesn't suffice a function could be set instead. This function is expected return a list that follows the form of `treesit-simple-indent-rules'." :version "29.1" - :type '(choice (symbol :tag "Gnu" 'gnu) - (symbol :tag "K&R" 'k&r) - (symbol :tag "Linux" 'linux) - (symbol :tag "BSD" 'bsd) + :type '(choice (symbol :tag "Gnu" gnu) + (symbol :tag "K&R" k&r) + (symbol :tag "Linux" linux) + (symbol :tag "BSD" bsd) (function :tag "A function for user customized style" ignore)) + :set #'c-ts-mode--indent-style-setter :group 'c) +(defun c-ts-mode-set-style () + (interactive) + (or (eq major-mode 'c-ts-mode) (eq major-mode 'c++-ts-mode) + (error "Buffer %s is not a c-ts-mode (c-ts-mode-set-style)" + (buffer-name))) + (c-ts-mode--indent-style-setter + 'c-ts-mode-indent-style + (intern + (completing-read + "Select style: " + (mapcar #'car (c-ts-mode--indent-styles (if (eq major-mode 'c-ts-mode) 'c 'cpp))) + nil t nil nil "gnu")))) + ;;; Syntax table (defvar c-ts-mode--syntax-table @@ -249,19 +291,6 @@ MODE is either `c' or `cpp'." ((parent-is "do_statement") parent-bol 0) ,@common)))) -(defun c-ts-mode--set-indent-style (mode) - "Helper function to set indentation style. -MODE is either `c' or `cpp'." - (let ((style - (if (functionp c-ts-mode-indent-style) - (funcall c-ts-mode-indent-style) - (pcase c-ts-mode-indent-style - ('gnu (alist-get 'gnu (c-ts-mode--indent-styles mode))) - ('k&r (alist-get 'k&r (c-ts-mode--indent-styles mode))) - ('bsd (alist-get 'bsd (c-ts-mode--indent-styles mode))) - ('linux (alist-get 'linux (c-ts-mode--indent-styles mode))))))) - `((,mode ,@style)))) - (defun c-ts-mode--top-level-label-matcher (node &rest _) "A matcher that matches a top-level label. NODE should be a labeled_statement." @@ -840,7 +869,7 @@ in your configuration." (setq-local comment-end " */") ;; Indent. (setq-local treesit-simple-indent-rules - (c-ts-mode--set-indent-style 'c)) + (c-ts-mode--get-indent-style 'c)) ;; Font-lock. (setq-local treesit-font-lock-settings (c-ts-mode--font-lock-settings 'c)) (treesit-major-mode-setup))) @@ -870,7 +899,7 @@ in your configuration." #'c-ts-mode--syntax-propertize) ;; Indent. (setq-local treesit-simple-indent-rules - (c-ts-mode--set-indent-style 'cpp)) + (c-ts-mode--get-indent-style 'cpp)) ;; Font-lock. (setq-local treesit-font-lock-settings (c-ts-mode--font-lock-settings 'cpp)) (treesit-major-mode-setup))) -- 2.39.2