emacs-elpa-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[nongnu] elpa/nix-mode 10ac680cd6 332/500: Merge pull request #80 from j


From: ELPA Syncer
Subject: [nongnu] elpa/nix-mode 10ac680cd6 332/500: Merge pull request #80 from j-piecuch/smie-tweaks
Date: Sat, 29 Jan 2022 08:27:18 -0500 (EST)

branch: elpa/nix-mode
commit 10ac680cd6c8de871ba73561daf6ca732386c840
Merge: a33ccd4fd7 dd5f937a49
Author: Matthew Bauer <mjbauer95@gmail.com>
Commit: GitHub <noreply@github.com>

    Merge pull request #80 from j-piecuch/smie-tweaks
    
    SMIE tweaks & bug fixes
---
 nix-mode.el                           | 80 ++++++++++++++++++++++-------------
 tests/nix-mode-tests.el               | 37 ++++++++++------
 tests/testcases/smie-close-parens.nix | 50 ++++++++++++++++++++++
 tests/testcases/smie-lambdas.nix      | 41 ++++++++++++++++++
 4 files changed, 164 insertions(+), 44 deletions(-)

diff --git a/nix-mode.el b/nix-mode.el
index 2353695b91..edc154c18b 100644
--- a/nix-mode.el
+++ b/nix-mode.el
@@ -442,15 +442,8 @@ STRING-TYPE type of string based off of Emacs syntax table 
types"
          `(column . ,(current-column))
        (nix-smie--indent-anchor)))
     (`(:after . ":")
-     ;; Skip over the argument.
-     (smie-backward-sexp " -bseqskip- ")
-     (cond
-      ((smie-rule-bolp)
-       `(column . ,(current-column)))
-      ((= (current-indentation) 0)
-       '(column . 0))
-      (t
-       (nix-smie--indent-anchor))))
+     (or (nix-smie--indent-args-line)
+         (nix-smie--indent-anchor)))
     (`(:after . ",")
      (smie-rule-parent tab-width))
     (`(:before . "in")
@@ -477,25 +470,43 @@ STRING-TYPE type of string based off of Emacs syntax 
table types"
 
 (defun nix-smie--anchor ()
   "Return the anchor's offset from the beginning of the current line."
-  (goto-char (+ (line-beginning-position) (current-indentation)))
-  (let ((eol (line-end-position))
-        (anchor (current-column))
-        tok)
-    (catch 'break
-      (while (and (setq tok (car (smie-indent-forward-token)))
-                  (<= (point) eol))
-        (when (equal "=" tok)
-          (backward-char)
-          (smie-backward-sexp " -bseqskip- ")
-          (setq anchor (current-column))
-          (throw 'break nil))))
-    anchor))
+  (save-excursion
+    (beginning-of-line)
+    (let ((eol (line-end-position))
+          anchor
+          tok)
+      (forward-comment (point-max))
+      (unless (or (eobp) (< eol (point)))
+        (setq anchor (current-column))
+        (catch 'break
+          (while (and (not (eobp))
+                      (progn
+                        (setq tok (car (smie-indent-forward-token)))
+                        (<= (point) eol)))
+            (when (equal "=" tok)
+              (backward-char)
+              (smie-backward-sexp " -bseqskip- ")
+              (setq anchor (current-column))
+              (throw 'break nil))))
+        anchor))))
 
 (defun nix-smie--indent-anchor (&optional indent)
   "Intended for use only in the rules function."
   (let ((indent (or indent tab-width)))
     `(column . ,(+ indent (nix-smie--anchor)))))
 
+(defun nix-smie--indent-args-line ()
+  "Indent the body of a lambda whose argument(s) are on a line of their own."
+  (save-excursion
+    ;; Assume that point is right before ':', skip it
+    (forward-char)
+    (let ((tok ":"))
+      (catch 'break
+        (while (equal tok ":")
+          (setq tok (nth 2 (smie-backward-sexp t)))
+          (when (smie-rule-bolp)
+            (throw 'break `(column . ,(current-column)))))))))
+
 (defconst nix-smie--path-chars "a-zA-Z0-9-+_.:/~")
 
 (defun nix-smie--skip-path (how)
@@ -554,11 +565,8 @@ STRING-TYPE type of string based off of Emacs syntax table 
types"
 
 (defun nix-smie--nonsep-semicolon-p ()
   "Whether the semicolon at point terminates a `with' or `assert'."
-  (let (tok)
-    (save-excursion
-      ;; Skip over identifiers, balanced parens etc. as far back as we can.
-      (while (null (setq tok (nth 2 (smie-backward-sexp " -bexpskip- "))))))
-    (member tok '("with" "assert"))))
+  (save-excursion
+    (member (nth 2 (smie-backward-sexp " -bexpskip- ")) '("with" "assert"))))
 
 (defun nix-smie--arg-?-p ()
   "Whether the question mark at point is part of an argument declaration."
@@ -568,6 +576,14 @@ STRING-TYPE type of string based off of Emacs syntax table 
types"
             (smie-backward-sexp)))
    '("{" ",")))
 
+(defun nix-smie--eol-p ()
+  "Whether there are no tokens after point on the current line."
+  (let ((eol (line-end-position)))
+    (save-excursion
+      (forward-comment (point-max))
+      (or (eobp)
+          (< eol (point))))))
+
 (defun nix-smie--indent-close ()
   "Align close paren with opening paren."
   (save-excursion
@@ -576,9 +592,13 @@ STRING-TYPE type of string based off of Emacs syntax table 
types"
       (condition-case nil
           (progn
             (backward-sexp 1)
-            ;; Align to the first token on the line containing
-            ;; the opening paren.
-            (current-indentation))
+            ;; If the opening paren is not the last token on its line,
+            ;; and it's either '[' or '{', align to the opening paren's
+            ;; position. Otherwise, align its line's anchor.
+            (if (and (memq (char-after) '(?\[ ?{))
+                     (not (save-excursion (forward-char) (nix-smie--eol-p))))
+                (current-column)
+             (nix-smie--anchor)))
         (scan-error nil)))))
 
 (defun nix-smie--indent-exps ()
diff --git a/tests/nix-mode-tests.el b/tests/nix-mode-tests.el
index 7aa3995415..2a58e0d67c 100644
--- a/tests/nix-mode-tests.el
+++ b/tests/nix-mode-tests.el
@@ -39,8 +39,9 @@
 (cl-defmacro with-nix-mode-test ((file &key indent) &rest body)
   "Set up environment for testing `nix-mode'.
 Execute BODY in a temporary buffer containing the contents of
-FILE, in `nix-mode'. All tests will use the `nix-indent-line'
-function to do the indentation tests."
+FILE, in `nix-mode'. INDENT should be the desired value of
+`nix-indent-function'. If it's non-nil, an indentation test
+will be run before executing BODY."
 
   `(with-temp-buffer
      ;; Read test data file
@@ -48,21 +49,21 @@ function to do the indentation tests."
 
      ;; Store the file as a local variable and set the right indentation 
function to use
      (let ((raw-file (buffer-substring-no-properties (point-min) (point-max)))
-           (nix-indent-function 'nix-indent-line)
+           (nix-indent-function
+            ,(or indent `',(default-value 'nix-indent-function)))
            (inhibit-message t))
        ;; Load up nix-mode
        (nix-mode)
 
        ;; If we're doing an indentation test
        (when ,indent
-         (let ((indent-line-function 'smie-indent-line))
-           ;; Indent the buffer
-           (indent-region (point-min) (point-max))
+         ;; Indent the buffer
+         (indent-region (point-min) (point-max))
 
-           ;; Compare buffer to the stored buffer contents
-           (should (equal
-                    (buffer-substring-no-properties (point-min) (point-max))
-                    raw-file))))
+         ;; Compare buffer to the stored buffer contents
+         (should (equal
+                  (buffer-substring-no-properties (point-min) (point-max))
+                  raw-file)))
 
        ;; Go to beginning
        (goto-char (point-min))
@@ -165,19 +166,19 @@ Related issue: 
https://github.com/NixOS/nix-mode/issues/72";
   (with-nix-mode-test ("issue-72.nix" :indent 'nix-indent-line)))
 
 (ert-deftest nix-mode-test-indent-hello-smie ()
-  "Proper indentation of strings in a multi-line string."
+  "Proper indentation of a simple derivation."
   (with-nix-mode-test ("hello.nix" :indent 'smie-indent-line)))
 
 (ert-deftest nix-mode-test-indent-hello ()
-  "Proper indentation of strings in a multi-line string."
+  "Proper indentation of a simple derivation."
   (with-nix-mode-test ("hello.nix" :indent 'nix-indent-line)))
 
 (ert-deftest nix-mode-test-indent-all-packages-smie ()
-  "Proper indentation of strings in a multi-line string."
+  "Proper indentation of a set of package definitions."
   (with-nix-mode-test ("all-packages.nix" :indent 'smie-indent-line)))
 
 (ert-deftest nix-mode-test-indent-issue-74-smie ()
-  "Proper indentation of strings in a multi-line string."
+  "Proper indentation of a set of package definitions."
   (with-nix-mode-test ("issue-74.nix" :indent 'smie-indent-line)))
 
 (ert-deftest nix-mode-test-indent-issue-77-smie ()
@@ -188,5 +189,13 @@ Related issue: https://github.com/NixOS/nix-mode/issues/72";
   "Proper indentation of strings in a multi-line string."
   (with-nix-mode-test ("issue-78.nix" :indent 'smie-indent-line)))
 
+(ert-deftest nix-mode-test-indent-lambdas-smie ()
+  "Proper indentation of function bodies."
+  (with-nix-mode-test ("smie-lambdas.nix" :indent 'smie-indent-line)))
+
+(ert-deftest nix-mode-test-close-parens-smie ()
+  "Proper indentation of closing parentheses."
+  (with-nix-mode-test ("smie-close-parens.nix" :indent 'smie-indent-line)))
+
 (provide 'nix-mode-tests)
 ;;; nix-mode-tests.el ends here
diff --git a/tests/testcases/smie-close-parens.nix 
b/tests/testcases/smie-close-parens.nix
new file mode 100644
index 0000000000..29dc4ef924
--- /dev/null
+++ b/tests/testcases/smie-close-parens.nix
@@ -0,0 +1,50 @@
+{
+  test1 =
+    { foo = {
+        bar = 42;
+      };
+    };
+
+  test2 =
+    {
+      foo = {
+        bar = 42;
+      };
+    };
+
+  test3 = {
+    foo = { bar = 42;
+            baz = 42;
+          };
+  };
+
+  test4 = [
+    {
+      foo = 42;
+    }
+  ];
+
+  test5 = [
+    { foo = 42;
+      bar = 42;
+    }
+  ];
+
+  test6 =
+    [ { foo = 42;
+        bar = 42;
+      }
+    ];
+
+  test7 =
+    [
+      {
+        foo = 42;
+        bar = 42;
+      }
+    ];
+
+  test8 = (foo:
+    42
+  );
+}
diff --git a/tests/testcases/smie-lambdas.nix b/tests/testcases/smie-lambdas.nix
new file mode 100644
index 0000000000..387bddd157
--- /dev/null
+++ b/tests/testcases/smie-lambdas.nix
@@ -0,0 +1,41 @@
+{ foo, bar }:
+{ foo, bar } @ baz:
+foo: bar:
+
+{ test0 = x:
+    42;
+
+  test1 =
+    { f = x:
+        42 };
+
+  test2 = x:
+    42;
+
+  test3 = map (x:
+    42) [ 1 2 3 ];
+
+  test4 =
+    { f = x: y: z:
+        42 };
+
+  test5 = x: y: z:
+    42;
+
+  test6 = map (x: y: z:
+    42) [ 1 2 3 ];
+
+  test7 = map
+    (x:
+      42);
+
+  test7 = map
+    (x: y: z:
+      42);
+
+  test8 =
+    x:
+    y:
+    z:
+    42;
+}



reply via email to

[Prev in Thread] Current Thread [Next in Thread]