summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKonstantin Kharlamov <Hi-Angel@yandex.ru>2023-03-28 18:50:18 +0300
committerKonstantin Kharlamov <Hi-Angel@yandex.ru>2023-03-28 18:52:26 +0300
commit74642c5a6fd68ae71545796f3f7a7ee3e641a2f7 (patch)
treeab41c98809ede3741dbe6a306a28f401b2c6be03
parentda6645e7d75065e170126785335a1de03afd7dff (diff)
downloadninja-74642c5a6fd68ae71545796f3f7a7ee3e641a2f7.tar.gz
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.
-rw-r--r--misc/ninja-mode.el35
1 files 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.