Skip to content

Commit

Permalink
Implement going to the beginning of a defun
Browse files Browse the repository at this point in the history
This implements support for `(beginning-of-defun)`. As a side note,
the match is done inside a single line string because I tried
implementing a regexp to make Emacs to restrain to a single line, and
it turned out to be very hard. I didn't succeed at that for like
½-hour I spent, and constraining the search artifically turned out not
just much easier, but also significantly simplified the regexp.
  • Loading branch information
Hi-Angel committed Nov 6, 2024
1 parent d187b3d commit b6d68e3
Showing 1 changed file with 30 additions and 0 deletions.
30 changes: 30 additions & 0 deletions purescript-mode.el
Original file line number Diff line number Diff line change
Expand Up @@ -340,6 +340,7 @@ see documentation for that variable for more details."
(set (make-local-variable 'dabbrev-case-distinction) nil)
(set (make-local-variable 'dabbrev-case-replace) nil)
(set (make-local-variable 'dabbrev-abbrev-char-regexp) "\\sw\\|[.]")
(setq-local beginning-of-defun-function 'purescript-beginning-of-defun)
(setq prettify-symbols-alist purescript-font-lock-prettify-symbols-alist)
(when (bound-and-true-p purescript-font-lock-symbols)
(warn "`purescript-font-lock-symbols' is obsolete: please enable `prettify-symbols-mode' locally or globally instead."))
Expand Down Expand Up @@ -470,6 +471,35 @@ Brings up the documentation for purescript-mode-hook."
(format " [ %s .. ]" (purescript-string-take (purescript-trim (cadr lines)) 10))
""))))))

(defun purescript-current-line-string ()
"Returns current line as a string."
(buffer-substring-no-properties (line-beginning-position) (line-end-position)))

(defun purescript-beginning-of-defun-single ()
(while (and (looking-at-p (rx (* space) eol))
(not (bobp)))
(forward-line -1)) ; can't get indentation on an empty line
(let ((indent-level (current-indentation)))
(while
(not
(or (ignore (forward-line -1)) ; do-while implementation
(bobp)
(and (< (current-indentation) indent-level)
(string-match-p
(rx (*? anything)
(or bol space word-boundary) "="
(or eol space word-boundary))
;; Emacs doesn't allow to limit search just to the curent line
;; barring the regex eol, but eol overly complicates matching.
(purescript-current-line-string))))))))

(defun purescript-beginning-of-defun (&optional repeat)
"Move point to the beginning of the current PureScript function."
(purescript-beginning-of-defun-single)
(dotimes (_ (if repeat
(- repeat 1) ; the function was already called once
0))
(purescript-beginning-of-defun-single)))

(provide 'purescript-mode)

Expand Down

0 comments on commit b6d68e3

Please sign in to comment.