branch: elpa/nix-mode
commit aaef8580c5bbbfb8eb1c448aaf33bbe67b108f39
Merge: c577957d66 795cc0c4c5
Author: Matthew Bauer <[email protected]>
Commit: GitHub <[email protected]>
Merge pull request #86 from j-piecuch/smie-tweaks
SMIE: parse paths enclosed in angle brackets (e.g. <nixpkgs>) correctly
---
nix-mode.el | 41 ++++++++++++++++++++++++++++++++++-------
tests/nix-mode-tests.el | 38 ++++++++++++++++++++++++++++++++++++++
2 files changed, 72 insertions(+), 7 deletions(-)
diff --git a/nix-mode.el b/nix-mode.el
index e1dba6c1c9..96d3401370 100644
--- a/nix-mode.el
+++ b/nix-mode.el
@@ -527,22 +527,48 @@ STRING-TYPE type of string based off of Emacs syntax
table types"
(defconst nix-smie--path-chars "a-zA-Z0-9-+_.:/~")
-(defun nix-smie--skip-path (how)
+(defun nix-smie--skip-angle-path-forward ()
+ "Skip forward a path enclosed in angle brackets, e.g <nixpkgs>"
+ (let ((start (point)))
+ (when (eq (char-after) ?<)
+ (forward-char)
+ (if (and (nix-smie--skip-path 'forward t)
+ (eq (char-after) ?>))
+ (progn
+ (forward-char)
+ (buffer-substring-no-properties start (point)))
+ (ignore (goto-char start))))))
+
+(defun nix-smie--skip-angle-path-backward ()
+ "Skip backward a path enclosed in angle brackets, e.g <nixpkgs>"
+ (let ((start (point)))
+ (when (eq (char-before) ?>)
+ (backward-char)
+ (if (and (nix-smie--skip-path 'backward t)
+ (eq (char-before) ?<))
+ (progn
+ (backward-char)
+ (buffer-substring-no-properties start (point)))
+ (ignore (goto-char start))))))
+
+(defun nix-smie--skip-path (how &optional no-sep-check)
"Skip path related characters."
(let ((start (point)))
- (pcase how
+ (pcase-exhaustive how
('forward (skip-chars-forward nix-smie--path-chars))
- ('backward (skip-chars-backward nix-smie--path-chars))
- (_ (error "expected 'forward or 'backward")))
+ ('backward (skip-chars-backward nix-smie--path-chars)))
(let ((sub (buffer-substring-no-properties start (point))))
- (if (string-match-p "/" sub)
+ (if (or (and no-sep-check
+ (< 0 (length sub)))
+ (string-match-p "/" sub))
sub
(ignore (goto-char start))))))
(defun nix-smie--forward-token-1 ()
"Move forward one token."
(forward-comment (point-max))
- (or (nix-smie--skip-path 'forward)
+ (or (nix-smie--skip-angle-path-forward)
+ (nix-smie--skip-path 'forward)
(buffer-substring-no-properties
(point)
(progn
@@ -563,7 +589,8 @@ STRING-TYPE type of string based off of Emacs syntax table
types"
(defun nix-smie--backward-token-1 ()
"Move backward one token."
(forward-comment (- (point)))
- (or (nix-smie--skip-path 'backward)
+ (or (nix-smie--skip-angle-path-backward)
+ (nix-smie--skip-path 'backward)
(buffer-substring-no-properties
(point)
(progn
diff --git a/tests/nix-mode-tests.el b/tests/nix-mode-tests.el
index f3e4a77b98..9bbeff713c 100644
--- a/tests/nix-mode-tests.el
+++ b/tests/nix-mode-tests.el
@@ -27,6 +27,44 @@
(nix-mode)
(eq (nix--get-string-type (nix--get-parse-state (point))) nil))))
+(ert-deftest nix-smie-angle-path-backward-detection ()
+ (should (with-temp-buffer
+ (nix-mode)
+ (insert "<nixpkgs/nixos>")
+ (nix-smie--skip-angle-path-backward)
+ (bobp))))
+
+(ert-deftest nix-smie-angle-path-backward-invalid ()
+ (should (with-temp-buffer
+ (nix-mode)
+ (insert "<nixpkgs/nixos>foo/bar>")
+ (null (nix-smie--skip-angle-path-backward)))))
+
+(ert-deftest nix-smie-angle-path-backward-early ()
+ (should (with-temp-buffer
+ (nix-mode)
+ (insert "<nixpkgs/nixos<foo/bar>")
+ (equal "<foo/bar>" (nix-smie--skip-angle-path-backward)))))
+
+(ert-deftest nix-smie-angle-path-forward-detection ()
+ (should (with-temp-buffer
+ (nix-mode)
+ (save-excursion (insert "<nixpkgs/nixos>"))
+ (nix-smie--forward-token)
+ (eobp))))
+
+(ert-deftest nix-smie-angle-path-forward-invalid ()
+ (should (with-temp-buffer
+ (nix-mode)
+ (save-excursion (insert "<nixpkgs/nixos<foo/bar>"))
+ (null (nix-smie--skip-angle-path-forward)))))
+
+(ert-deftest nix-smie-angle-path-forward-early ()
+ (should (with-temp-buffer
+ (nix-mode)
+ (save-excursion (insert "<foo/bar>nixpkgs/nixos>"))
+ (equal "<foo/bar>" (nix-smie--skip-angle-path-forward)))))
+
;;; Indentation tests
(defvar nix-mode-test-dir (expand-file-name "testcases"