branch: elpa/nix-mode commit aaef8580c5bbbfb8eb1c448aaf33bbe67b108f39 Merge: c577957d66 795cc0c4c5 Author: Matthew Bauer <mjbaue...@gmail.com> Commit: GitHub <nore...@github.com>
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"