[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[nongnu] elpa/haskell-tng-mode cb801b4 015/385: moar multiline type sear
From: |
ELPA Syncer |
Subject: |
[nongnu] elpa/haskell-tng-mode cb801b4 015/385: moar multiline type search |
Date: |
Tue, 5 Oct 2021 23:58:52 -0400 (EDT) |
branch: elpa/haskell-tng-mode
commit cb801b48fb6241d0993600962dade122605eff90
Author: Tseen She <ts33n.sh3@gmail.com>
Commit: Tseen She <ts33n.sh3@gmail.com>
moar multiline type search
---
haskell-tng-font-lock.el | 135 ++++++++++++++++++++++++++---------------------
1 file changed, 75 insertions(+), 60 deletions(-)
diff --git a/haskell-tng-font-lock.el b/haskell-tng-font-lock.el
index 9f1fe88..8b48c34 100644
--- a/haskell-tng-font-lock.el
+++ b/haskell-tng-font-lock.el
@@ -72,9 +72,28 @@
`(: line-start (group (| (: (any lower ?_) (* wordchar))
(: "(" (+? (syntax symbol)) ")")))
symbol-end))
+;; note that \n has syntax `comment-end'
+(defconst haskell-tng:newline
+ '(| (syntax comment-end)
+ (: symbol-start
+ "--"
+ (+ (not (syntax comment-end)))
+ (+ (syntax comment-end))))
+ "Newline or line comment.")
+;; note that type matching must be bounded for inline occurences
+(defconst haskell-tng:type
+ ;; TODO literal types and generic lists ... eek!
+ (let ((typepart `(| (+ (any ?\( ?\)))
+ (+ (any lower ?_))
+ (: (opt ,haskell-tng:qual)
+ (| "::" ,haskell-tng:conid ,haskell-tng:consym)))))
+ `(: (opt ,haskell-tng:newline) (+ (| space ,typepart))
+ (* (opt ,haskell-tng:newline (+ space)) "->" (+ (| space ,typepart)))))
+ "An explicit type")
;; TODO a macro that wraps these consts with short-form names
+;; TODO use the levels support so users can turn off type fontification
(setq
haskell-tng:keywords
;; These regexps use the `rx' library so we can reuse common subpatterns. It
@@ -159,8 +178,14 @@
)))
-;; TODO: consider previous/next symbol instead of the default whole line
-;; detection in font-lock-extend-region-functions for super duper hyper perf.
+(defvar haskell-tng:explicit-type-regex
+ (rx-to-string `(: point "::" (* space) ,haskell-tng:type))
+ "Cache of a regex internal to `haskell-tng:explicit-type'")
+(defun haskell-tng:explicit-type ()
+ "Matches an explicit type at point, bounded by a closing paren."
+ (re-search-forward
+ haskell-tng:explicit-type-regex
+ (or (haskell-tng:paren-close) (point-max)) t))
(eval-when-compile
;; available inside font-lock-extend-region-functions procedures.
@@ -168,16 +193,17 @@
(defvar font-lock-beg)
(defvar font-lock-end))
-;; TODO optimise extend-parens-* to module / import / types
+;; TODO optimise extend-parens-* to just module / import / types
(defun haskell-tng:extend-parens-open ()
"For use in `font-lock-extend-region-functions'.
Expand the region to include the opening parenthesis.
The caller loops until everything is opened."
(goto-char font-lock-beg)
;; TODO: exit early if in comment
+ ;; TODO: use a bounded search-backward to exclude non-package characters
(when-let (open (nth 1 (syntax-ppss)))
- (when (and (goto-char open)
- (looking-at "("))
+ (goto-char open)
+ (when (looking-at "(")
;;(haskell-tng:debug-extend (point))
(setq font-lock-beg (point)))))
@@ -187,69 +213,54 @@ Expand the region to include a closing parenthesis.
The caller loops until everything is closed."
(goto-char font-lock-end)
;; TODO: exit early if in comment
- (when-let (open (nth 1 (syntax-ppss)))
- (when (and (goto-char open)
- (looking-at "(")
- (goto-char font-lock-end)
- (re-search-forward ")" (point-max) t))
- ;;(haskell-tng:debug-extend (point))
- (setq font-lock-end (point)))))
+ ;; TODO: use a bounded search-forward to exclude non-package characters
+ (when-let (close (haskell-tng:paren-close))
+ ;;(haskell-tng:debug-extend (point))
+ (setq font-lock-end (+ 1 close))))
+
+(defun haskell-tng:paren-close ()
+ "Return the position of the next `)', if it closes the current paren depth."
+ (interactive) ;; TODO for manual testing
+ (save-excursion
+ (when-let (close (ignore-errors (scan-lists (point) 1 1)))
+ (goto-char (- close 1))
+ (when (looking-at ")")
+ (point)))))
(defun haskell-tng:extend-type-open ()
"For use in `font-lock-extend-region-functions'.
Ensures that multiline type signatures are opened."
(goto-char font-lock-beg)
;; TODO: exit early if in comment
- (when (and (re-search-forward
- (rx symbol-start "->" symbol-end)
- font-lock-end t)
- (re-search-backward
- (rx symbol-start "::" symbol-end)
- (point-min) t))
- (goto-char (match-beginning 0))
- (let ((beg (point)))
- (haskell-tng:type-end)
- (when (< font-lock-beg (point))
- (haskell-tng:debug-extend beg)
- (setq font-lock-beg beg)
- (when (< font-lock-end (point))
- (haskell-tng:debug-extend (point))
- (setq font-lock-end (point))))))
- nil
- )
-
-;; note that \n has syntax `comment-end'
-(defconst haskell-tng:newline
- '(| (syntax comment-end)
- (: symbol-start
- "--"
- (+ (not (syntax comment-end)))
- (+ (syntax comment-end))))
- "Newline or line comment.")
-
-;; TODO literal types and generic lists ... eek!
-(defconst haskell-tng:type
- (let ((typepart `(| (+ (| ?\( ?\)))
- (+ (| lower ?_))
- (: (opt ,haskell-tng:qual)
- (| "::" ,haskell-tng:conid ,haskell-tng:consym)))))
- `(: (opt ,haskell-tng:newline) (+ (| space ,typepart))
- (* (opt ,haskell-tng:newline (+ space)) "->" (+ (| space ,typepart)))))
- "An explicit type")
-
-(defun haskell-tng:type-end ()
- "Move to the end of this type signature."
- (interactive)
- (let* ((case-fold-search nil))
- (re-search-forward
- (rx-to-string `(: point "::" (* space) ,haskell-tng:type))
- (point-max) t)))
-
-;; also consider multiline data / newtype / type definitions to the equals sign
+ (when (re-search-backward
+ ;; TODO: replace \ with a larger list of non-type chars
+ (rx symbol-start "::" symbol-end (*? (not (any ?\\))) point)
+ (point-min) t)
+ (let ((beg (match-beginning 0)))
+ (when (< beg font-lock-beg)
+ (goto-char beg)
+ ;; validate that it's actually a type
+ (haskell-tng:explicit-type) ;; is this needed if we trust the
non-lambda backscan?
+ (when (< font-lock-beg (point))
+ (haskell-tng:debug-extend beg)
+ (setq font-lock-beg beg)))))
+ nil)
(defun haskell-tng:extend-type-close ()
"For use in `font-lock-extend-region-functions'.
Ensures that multiline type signatures are closed."
+ (goto-char font-lock-end)
+ ;; TODO: exit early if in comment
+ (when (re-search-backward
+ ;; TODO: replace \ with a larger list of non-type chars
+ (rx symbol-start "::" symbol-end (*? (not (any ?\\))) point)
+ font-lock-beg t)
+ (let ((beg (match-beginning 0)))
+ (goto-char beg)
+ (haskell-tng:explicit-type)
+ (when (< font-lock-end (point))
+ (haskell-tng:debug-extend (point))
+ (setq font-lock-beg (point)))))
nil)
(defun haskell-tng:extend-module-open ()
@@ -272,12 +283,16 @@ Ensures that multiline `import' definitions are opened."
Ensures that multiline `import' definitions are closed."
nil)
+;; TODO multiline data / newtype / type definitions
+
(defun haskell-tng:debug-extend (to)
(message "extending `%s' to include `%s'!"
(buffer-substring-no-properties font-lock-beg font-lock-end)
- (if (< to font-lock-beg)
+ (if (<= to font-lock-beg)
(buffer-substring-no-properties to font-lock-beg)
- (buffer-substring-no-properties font-lock-end to))))
+ (if (<= font-lock-end to)
+ (buffer-substring-no-properties font-lock-end to)
+ "BADNESS! Reduced the region"))))
(defun haskell-tng:mark-block ()
;; TODO: this is kinda obscure, replace with mark-defun when it is defined
- [nongnu] elpa/haskell-tng-mode 36ece6d 117/385: low hanging fruit, (continued)
- [nongnu] elpa/haskell-tng-mode 36ece6d 117/385: low hanging fruit, ELPA Syncer, 2021/10/06
- [nongnu] elpa/haskell-tng-mode 489e4c9 124/385: document explicit export fontification bug, ELPA Syncer, 2021/10/06
- [nongnu] elpa/haskell-tng-mode 91a1d08 136/385: creating small scenarios for indentation specs, ELPA Syncer, 2021/10/06
- [nongnu] elpa/haskell-tng-mode ec39a64 133/385: improvements to indentation alts and compilation info, ELPA Syncer, 2021/10/06
- [nongnu] elpa/haskell-tng-mode f67557b 142/385: fix a layout corner case, ELPA Syncer, 2021/10/06
- [nongnu] elpa/haskell-tng-mode 20f4091 152/385: support dollars in indentation, ELPA Syncer, 2021/10/06
- [nongnu] elpa/haskell-tng-mode 0d5e020 151/385: support LambdaCase, ELPA Syncer, 2021/10/06
- [nongnu] elpa/haskell-tng-mode 08a3946 163/385: records indentation, ELPA Syncer, 2021/10/06
- [nongnu] elpa/haskell-tng-mode 3449847 162/385: no need to special-case dollar, ELPA Syncer, 2021/10/06
- [nongnu] elpa/haskell-tng-mode 8b5a4d4 177/385: improve indentation tests, ELPA Syncer, 2021/10/06
- [nongnu] elpa/haskell-tng-mode cb801b4 015/385: moar multiline type search,
ELPA Syncer <=
- [nongnu] elpa/haskell-tng-mode de48840 030/385: multiline import anchors, ELPA Syncer, 2021/10/06
- [nongnu] elpa/haskell-tng-mode 5c50be0 044/385: remove redundant TODOs, ELPA Syncer, 2021/10/06
- [nongnu] elpa/haskell-tng-mode 174c63b 046/385: laying the foundations for SMIE, ELPA Syncer, 2021/10/06
- [nongnu] elpa/haskell-tng-mode 97ce717 058/385: improve the testing, ELPA Syncer, 2021/10/06
- [nongnu] elpa/haskell-tng-mode 2a2afee 064/385: cache invalidation and tests for layout invalidation, ELPA Syncer, 2021/10/06
- [nongnu] elpa/haskell-tng-mode 3ca869f 067/385: code reorganisation, ELPA Syncer, 2021/10/06
- [nongnu] elpa/haskell-tng-mode 0ffb885 071/385: a thought, ELPA Syncer, 2021/10/06
- [nongnu] elpa/haskell-tng-mode 79aeb82 076/385: most of the grammar, ELPA Syncer, 2021/10/06
- [nongnu] elpa/haskell-tng-mode 7eaef51 078/385: optimisation in the sexp test, ELPA Syncer, 2021/10/06
- [nongnu] elpa/haskell-tng-mode cb0f3d2 082/385: starting indentation rules, ELPA Syncer, 2021/10/06