From 74642c5a6fd68ae71545796f3f7a7ee3e641a2f7 Mon Sep 17 00:00:00 2001 From: Konstantin Kharlamov Date: Tue, 28 Mar 2023 18:50:18 +0300 Subject: ninja-mode.el: add support for indentation We default `ninja-indent-offset` to `2` because Meson and CMake use `1` and `2` values accordingly, but `1` seems like too little, so use `2`. The correctness was tested in particular on two `build.ninja` files, one generated by Meson (1790 lines), and another by CMake (7777 lines). After setting `ninja-indent-offset` to the expected by the file value and re-indenting whole file the buffer was left unchanged, i.e. the calculated offset matched the ones already used. --- misc/ninja-mode.el | 35 ++++++++++++++++++++++++++++++----- 1 file changed, 30 insertions(+), 5 deletions(-) diff --git a/misc/ninja-mode.el b/misc/ninja-mode.el index 76abf81..d4f06e6 100644 --- a/misc/ninja-mode.el +++ b/misc/ninja-mode.el @@ -19,15 +19,21 @@ ;;; Commentary: ;; Simple emacs mode for editing .ninja files. -;; Just some syntax highlighting for now. ;;; Code: +(defcustom ninja-indent-offset 2 + "*Amount of offset per level of indentation." + :type 'integer + :safe 'natnump + :group 'ninja) + +(defconst ninja-keywords-re + (concat "^" (regexp-opt '("rule" "build" "subninja" "include" "pool" "default") + 'words))) + (defvar ninja-keywords - `((,(concat "^" (regexp-opt '("rule" "build" "subninja" "include" - "pool" "default") - 'words)) - . font-lock-keyword-face) + `((,ninja-keywords-re . font-lock-keyword-face) ("^[[:space:]]*\\([[:alnum:]_]+\\)[[:space:]]*=" 1 font-lock-variable-name-face) ;; Variable expansion. ("$[[:alnum:]_]+" . font-lock-variable-name-face) @@ -69,11 +75,30 @@ (unless (= line-end (1+ (buffer-size))) (put-text-property line-end (1+ line-end) 'syntax-table '(12))))))))) +(defun ninja-compute-indentation () + "Calculate indentation for the current line." + (save-excursion + (beginning-of-line) + (if (or (looking-at ninja-keywords-re) + (= (line-number-at-pos) 1)) + 0 + (forward-line -1) + (if (looking-at ninja-keywords-re) + ninja-indent-offset + (current-indentation))))) + +(defun ninja-indent-line () + "Indent the current line. Uses previous indentation level if + available or `ninja-indent-offset'" + (interactive "*") + (indent-line-to (ninja-compute-indentation))) + ;;;###autoload (define-derived-mode ninja-mode prog-mode "ninja" (set (make-local-variable 'comment-start) "#") (set (make-local-variable 'parse-sexp-lookup-properties) t) (set (make-local-variable 'syntax-propertize-function) #'ninja-syntax-propertize) + (set (make-local-variable 'indent-line-function) 'ninja-indent-line) (setq font-lock-defaults '(ninja-keywords))) ;; Run ninja-mode for files ending in .ninja. -- cgit v1.2.1