Skip to content

Commit 7fbd4ee

Browse files
committed
Merge pull request #1158 from cruegge/master
Implement backward case in haskell-forward-sexp
2 parents 02dfe27 + 2ee2bc3 commit 7fbd4ee

File tree

2 files changed

+40
-7
lines changed

2 files changed

+40
-7
lines changed

haskell-mode.el

+19-7
Original file line numberDiff line numberDiff line change
@@ -849,16 +849,28 @@ it that many times. Negative arg -N means move backward across N
849849
balanced expressions. This command assumes point is not in a
850850
string or comment.
851851
852-
Note that negative arguments do not work so well."
852+
If unable to move over a sexp, signal `scan-error' with three
853+
arguments: a message, the start of the obstacle (a parenthesis or
854+
list marker of some kind), and end of the obstacle."
853855
(interactive "^p")
854856
(or arg (setq arg 1))
855857
(if (< arg 0)
856-
;; Fall back to native Emacs method for negative arguments.
857-
;; Haskell has maximum munch rule that does not work well
858-
;; backwards.
859-
(progn
860-
(goto-char (or (scan-sexps (point) arg) (buffer-end arg)))
861-
(backward-prefix-chars))
858+
(while (< arg 0)
859+
(skip-syntax-backward "->")
860+
;; Navigate backwards using plain `backward-sexp', assume that it
861+
;; skipped over at least one Haskell expression, and jump forward until
862+
;; last possible point before the starting position. If applicable,
863+
;; `scan-error' is signalled by `backward-sexp'.
864+
(let ((end (point))
865+
(forward-sexp-function nil))
866+
(backward-sexp)
867+
(let ((cur (point)))
868+
(while (< (point) end)
869+
(setf cur (point))
870+
(haskell-forward-sexp)
871+
(skip-syntax-forward "->"))
872+
(goto-char cur)))
873+
(setf arg (1+ arg)))
862874
(save-match-data
863875
(while (> arg 0)
864876
(when (haskell-lexeme-looking-at-token)

tests/haskell-mode-tests.el

+21
Original file line numberDiff line numberDiff line change
@@ -464,4 +464,25 @@ of sexp."
464464
(haskell-forward-sexp 1)
465465
(eq (point) 6))))
466466

467+
(ert-deftest backward-sexp ()
468+
"Check if `forward-sexp-function' behaves properly on
469+
beginning of sexp."
470+
(should (with-temp-buffer
471+
(haskell-mode)
472+
(insert "(foo) bar")
473+
(goto-char 2)
474+
(condition-case err
475+
(progn (backward-sexp)
476+
nil)
477+
(scan-error (equal (cddr err) (list 1 1)))))))
478+
479+
(ert-deftest haskell-backward-sexp ()
480+
"Check if `haskell-forward-sexp' with negatives arg properly
481+
moves over sexps."
482+
(should (with-temp-buffer
483+
(insert "a (b c) = d . e")
484+
(goto-char 15)
485+
(haskell-forward-sexp -4)
486+
(eq (point) 3))))
487+
467488
(provide 'haskell-mode-tests)

0 commit comments

Comments
 (0)