[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[nongnu] elpa/nix-mode 022fac17a6 308/500: Un-delete nix-indent-line.
From: |
ELPA Syncer |
Subject: |
[nongnu] elpa/nix-mode 022fac17a6 308/500: Un-delete nix-indent-line. |
Date: |
Sat, 29 Jan 2022 08:27:16 -0500 (EST) |
branch: elpa/nix-mode
commit 022fac17a6ab0042450e7fccaa539c6d720d3a16
Author: Jakub Piecuch <j.piecuch96@gmail.com>
Commit: Jakub Piecuch <j.piecuch96@gmail.com>
Un-delete nix-indent-line.
---
nix-mode.el | 173 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 171 insertions(+), 2 deletions(-)
diff --git a/nix-mode.el b/nix-mode.el
index 4de967ed6b..b520a29c32 100644
--- a/nix-mode.el
+++ b/nix-mode.el
@@ -34,7 +34,8 @@
Valid functions for this are:
- ‘indent-relative’
-- smie-indent-line (buggy)"
+- nix-indent-line (buggy)
+- smie-indent-line"
:group 'nix-mode
:type 'function)
@@ -601,6 +602,123 @@ STRING-TYPE type of string based off of Emacs syntax
table types"
;; begins. I'm not sure which one is better.
(+ tab-width (current-indentation))))))))
+;;; Indentation not using SMIE
+
+(defun nix-find-backward-matching-token ()
+ "Find the previous Nix token."
+ (cond
+ ((looking-at "in\\b")
+ (let ((counter 1))
+ (while (and (> counter 0)
+ (re-search-backward "\\b\\(let\\|in\\)\\b" nil t))
+ (unless (or (nix--get-string-type (nix--get-parse-state (point)))
+ (nix-is-comment-p))
+ (setq counter (cond ((looking-at "let") (- counter 1))
+ ((looking-at "in") (+ counter 1))))))
+ counter ))
+ ((looking-at "}")
+ (backward-up-list) t)
+ ((looking-at "]")
+ (backward-up-list) t)
+ ((looking-at ")")
+ (backward-up-list) t)))
+
+(defun nix-indent-to-backward-match ()
+ "Match the previous line’s indentation."
+ (let ((matching-indentation (save-excursion
+ (beginning-of-line)
+ (skip-chars-forward "[:space:]")
+ (if (nix-find-backward-matching-token)
+ (current-indentation)))))
+ (when matching-indentation (indent-line-to matching-indentation) t)))
+
+(defun nix-indent-first-line-in-block ()
+ "Indent the first line in a block."
+
+ (let ((matching-indentation (save-excursion
+ ;; Go back to previous line that contain
anything useful to check the
+ ;; contents of that line.
+ (beginning-of-line)
+ (skip-chars-backward "\n[:space:]")
+
+ ;; Grab the full string of the line before the
one we're indenting
+ (let ((line (buffer-substring-no-properties
(line-beginning-position) (line-end-position))))
+ ;; Then regex-match strings at the end of
the line to detect if we need to indent the line after.
+ ;; We could probably add more things to look
for here in the future.
+ (if (or (string-match "let$" line)
+ (string-match "import$" line)
+ (string-match "\\[$" line)
+ (string-match "=$" line)
+ (string-match "\($" line)
+ (string-match "\{$" line))
+
+ ;; If it matches any of the regexes
above, grab the indent level
+ ;; of the line and add 2 to ident the
line below this one.
+ (+ 2 (current-indentation)))))))
+ (when matching-indentation (indent-line-to matching-indentation) t)))
+
+(defun nix-mode-search-backward ()
+ "Search backward for items of interest regarding indentation."
+ (re-search-backward nix-re-ends nil t)
+ (re-search-backward nix-re-quotes nil t)
+ (re-search-backward nix-re-caps nil t))
+
+(defun nix-indent-expression-start ()
+ "Indent the start of a nix expression."
+ (let* ((ends 0)
+ (once nil)
+ (done nil)
+ (indent (current-indentation)))
+ (save-excursion
+ ;; we want to indent this line, so we don't care what it
+ ;; contains skip to the beginning so reverse searching doesn't
+ ;; find any matches within
+ (beginning-of-line)
+ ;; search backward until an unbalanced cap is found or no cap or
+ ;; end is found
+ (while (and (not done) (nix-mode-search-backward))
+ (cond
+ ((looking-at nix-re-quotes)
+ ;; skip over strings entirely
+ (re-search-backward nix-re-quotes nil t))
+ ((looking-at nix-re-comments)
+ ;; skip over comments entirely
+ (re-search-backward nix-re-comments nil t))
+ ((looking-at nix-re-ends)
+ ;; count the matched end
+ ;; this means we expect to find at least one more cap
+ (setq ends (+ ends 1)))
+ ((looking-at nix-re-caps)
+ ;; we found at least one cap
+ ;; this means our function will return true
+ ;; this signals to the caller we handled the indentation
+ (setq once t)
+ (if (> ends 0)
+ ;; this cap corresponds to a previously matched end
+ ;; reduce the number of unbalanced ends
+ (setq ends (- ends 1))
+ ;; no unbalanced ends correspond to this cap
+ ;; this means we have found the expression that contains our line
+ ;; we want to indent relative to this line
+ (setq indent (current-indentation))
+ ;; signal that the search loop should exit
+ (setq done t))))))
+ ;; done is t when we found an unbalanced expression cap
+ (when done
+ ;; indent relative to the indentation of the expression
+ ;; containing our line
+ (indent-line-to (+ tab-width indent)))
+ ;; return t to the caller if we found at least one cap
+ ;; this signals that we handled the indentation
+ once))
+
+(defun nix-indent-prev-level ()
+ "Get the indent level of the previous line."
+ (save-excursion
+ (beginning-of-line)
+ (skip-chars-backward "\n[:space:]")
+ (current-indentation)))
+
;;;###autoload
(defun nix-mode-format ()
"Format the entire nix-mode buffer."
@@ -611,9 +729,60 @@ STRING-TYPE type of string based off of Emacs syntax table
types"
(while (not (equal (point) (point-max)))
(if (equal (string-match-p "^[\s-]*$" (thing-at-point 'line)) 0)
(delete-horizontal-space)
- (smie-indent-line))
+ (nix-indent-line))
(forward-line)))))
+;;;###autoload
+(defun nix-indent-line ()
+ "Indent current line in a Nix expression."
+ (interactive)
+ (let ((end-of-indentation
+ (save-excursion
+ (cond
+ ;; Indent first line of file to 0
+ ((= (line-number-at-pos) 1)
+ (indent-line-to 0))
+
+ ;; comment
+ ((save-excursion
+ (beginning-of-line)
+ (nix-is-comment-p))
+ (indent-line-to (nix-indent-prev-level)))
+
+ ;; string
+ ((save-excursion
+ (beginning-of-line)
+ (nth 3 (syntax-ppss)))
+ (indent-line-to (+ (nix-indent-prev-level)
+ (* tab-width
+ (+ (if (save-excursion
+ (forward-line -1)
+ (end-of-line)
+ (skip-chars-backward "[:space:]")
+ (looking-back "''" 0)) 1 0)
+ (if (save-excursion
+ (beginning-of-line)
+ (skip-chars-forward
+ "[:space:]")
+ (looking-at "''")
+ ) -1 0)
+ )))))
+
+ ;; dedent '}', ']', ')' 'in'
+ ((nix-indent-to-backward-match))
+
+ ;; indent line after 'let', 'import', '[', '=', '(', '{'
+ ((nix-indent-first-line-in-block))
+
+ ;; indent between = and ; + 2, or to 2
+ ((nix-indent-expression-start))
+
+ ;; else
+ (t
+ (indent-line-to (nix-indent-prev-level))))
+ (point))))
+ (when (> end-of-indentation (point)) (goto-char end-of-indentation))))
+
(defun nix-is-comment-p ()
"Whether we are in a comment."
(nth 4 (syntax-ppss)))
- [nongnu] elpa/nix-mode 90ac0a74b2 273/500: Merge pull request #55 from teozkr/issue-54, (continued)
- [nongnu] elpa/nix-mode 90ac0a74b2 273/500: Merge pull request #55 from teozkr/issue-54, ELPA Syncer, 2022/01/29
- [nongnu] elpa/nix-mode 563f6bdb03 272/500: Fixed `nix-mode-comments` matching everything, ELPA Syncer, 2022/01/29
- [nongnu] elpa/nix-mode abdeae0f23 276/500: Make sure nix-instantiate-executable exists before running it, ELPA Syncer, 2022/01/29
- [nongnu] elpa/nix-mode 57ea981cb2 278/500: Use eval-when-compile for subr-x, ELPA Syncer, 2022/01/29
- [nongnu] elpa/nix-mode 1512d02830 279/500: Formatting, ELPA Syncer, 2022/01/29
- [nongnu] elpa/nix-mode 0c0ec7dbd6 281/500: ert/indent: Add macro to easily test indentation, ELPA Syncer, 2022/01/29
- [nongnu] elpa/nix-mode 7f968e8a7f 284/500: Merge pull request #61 from etu/master, ELPA Syncer, 2022/01/29
- [nongnu] elpa/nix-mode 4ac7b5afb6 287/500: Add indent region function, ELPA Syncer, 2022/01/29
- [nongnu] elpa/nix-mode ff0a773d31 297/500: fix-issue-72: Check the correct element from syntax-ppss, ELPA Syncer, 2022/01/29
- [nongnu] elpa/nix-mode 1798168074 307/500: Use nix-indent-function when setting indent-line-function., ELPA Syncer, 2022/01/29
- [nongnu] elpa/nix-mode 022fac17a6 308/500: Un-delete nix-indent-line.,
ELPA Syncer <=
- [nongnu] elpa/nix-mode 1cda7dabbc 309/500: Bug fix: replace memq with member, ELPA Syncer, 2022/01/29
- [nongnu] elpa/nix-mode 4016a1c89b 321/500: Release 1.4.0, ELPA Syncer, 2022/01/29
- [nongnu] elpa/nix-mode 91834848b4 320/500: Generate AUTHORS.md, ELPA Syncer, 2022/01/29
- [nongnu] elpa/nix-mode 0bab799a87 325/500: Add failing test that checks indentation of closing parens., ELPA Syncer, 2022/01/29
- [nongnu] elpa/nix-mode dd5f937a49 331/500: Change the description of a couple of tests., ELPA Syncer, 2022/01/29
- [nongnu] elpa/nix-mode 10ac680cd6 332/500: Merge pull request #80 from j-piecuch/smie-tweaks, ELPA Syncer, 2022/01/29
- [nongnu] elpa/nix-mode 907336cd0b 337/500: Silence byte compiler warnings in nix-shell, ELPA Syncer, 2022/01/29
- [nongnu] elpa/nix-mode 2f4bd0f09c 336/500: Release 1.4.1, ELPA Syncer, 2022/01/29
- [nongnu] elpa/nix-mode 00750803d9 356/500: Don't freeze full executable paths at load time, ELPA Syncer, 2022/01/29
- [nongnu] elpa/nix-mode 3248864b56 348/500: Add failing tests that check for correct lexing of angle paths., ELPA Syncer, 2022/01/29