branch: elpa/haskell-tng-mode
commit 6f8258c2e626731d0e996f5698b9074f0bd1e549
Author: Tseen She <[email protected]>
Commit: Tseen She <[email protected]>
thinking about multiline
---
README.md | 4 ++--
haskell-tng-font-lock.el | 58 +++++++++++++++++++++++++++++++++++++++++-------
haskell-tng-mode.el | 9 ++++++--
3 files changed, 59 insertions(+), 12 deletions(-)
diff --git a/README.md b/README.md
index b9e636e..7a96e7c 100644
--- a/README.md
+++ b/README.md
@@ -6,7 +6,7 @@ This is an exploratory alternative to
[`haskell-mode`](https://github.com/haskel
`haskell-mode` is almost 30 years old and has accumulated more than 25,000
lines of code. It's too much to handle.
-Meanwhile, the GNU Emacs ecosystem has evolved to provide many features that
`haskell-mode` independently implemented, such as
[`projectile`](https://github.com/bbatsov/projectile),
[`comint-mode`](https://masteringemacs.org/article/comint-writing-command-interpreter),
[`highlight-symbol`](https://melpa.org/##/highlight-symbol),
[`pretty-symbols`](https://github.com/drothlis/pretty-symbols),
[`company-mode`](http://company-mode.github.io),
[`yasnippet`](http://joaotavora.github.io/yasnip [...]
+Meanwhile, the GNU Emacs ecosystem has evolved to provide many features that
`haskell-mode` independently implemented, such as
[`projectile`](https://github.com/bbatsov/projectile),
[`comint`](https://masteringemacs.org/article/comint-writing-command-interpreter),
[`highlight-symbol`](https://melpa.org/##/highlight-symbol),
[`pretty-symbols`](https://github.com/drothlis/pretty-symbols),
[`company`](http://company-mode.github.io),
[`yasnippet`](http://joaotavora.github.io/yasnippet/), [`p [...]
## Approach
@@ -22,7 +22,7 @@ If it is possible to implement a feature using another minor
mode, or command li
Bug reports and feature requests are a source of anxiety for maintainers, and
encourage an unhealthy customer / supplier relationship between users and
contributors.
-Instead, and following the [anarchical spirit of
Haskell](https://www.microsoft.com/en-us/research/wp-content/uploads/2016/07/history.pdf),
we encourage discussions and debate around code contributions. Merge requests
can be raised by anybody and discussed by anybody. If the maintainers are
convinced by the technical merit and quality of a proposal, they may accept it.
+Instead, and following the [anarchical spirit of
Haskell](https://www.microsoft.com/en-us/research/wp-content/uploads/2016/07/history.pdf),
we encourage discussions and debate around code contributions. Merge requests
can be raised by anybody and discussed by anybody, and do not need to be
complete. A failing automated test is the only way to report a bug. If the
maintainers are convinced by the technical merit and quality of a proposal,
they may accept it.
## Install
diff --git a/haskell-tng-font-lock.el b/haskell-tng-font-lock.el
index fef023e..bb8f897 100644
--- a/haskell-tng-font-lock.el
+++ b/haskell-tng-font-lock.el
@@ -47,6 +47,10 @@
"Haskell top level declarations."
:group 'haskell-tng:faces)
+;; TODO: a macro to call rx-to-string at runtime that doesn't need (: )
+;;
+;; TODO: regression tests https://github.com/Lindydancer/faceup
+;;
;; TODO: pragmas
;;
;; TODO: numeric / char primitives?
@@ -59,14 +63,24 @@
;;
;; TODO: consider ; in the "until the end of the line" searches.
+(defconst haskell-tng:conid '(: upper (* wordchar)))
+(defconst haskell-tng:consym '(: ":" (+ (syntax symbol))))
+(defconst haskell-tng:toplevel
+ `(: line-start (group (| (: (any lower ?_) (* wordchar))
+ (: "(" (+? (syntax symbol)) ")")))
+ symbol-end))
+
+;; TODO a macro that wraps these consts with short-form names
+
(setq
haskell-tng:keywords
;; These regexps use the `rx' library so we can reuse common subpatterns. It
;; also increases the readability of the code and, in many cases, allows us to
;; do more work in a single regexp instead of multiple passes.
- (let* ((conid '(: upper (* wordchar)))
- (qual `(: (+ (: ,conid (char ?.)))))
- (consym '(: ":" (+ (syntax symbol)))))
+ (let ((conid haskell-tng:conid)
+ (qual `(: (+ (: ,haskell-tng:conid (char ?.)))))
+ (consym haskell-tng:consym)
+ (toplevel haskell-tng:toplevel))
`(;; reservedid / reservedop
(,(rx-to-string
'(|
@@ -107,6 +121,8 @@
(,(rx-to-string `(: symbol-start "module" symbol-end (+ space)
symbol-start (group (opt ,qual) ,conid) symbol-end))
1 'haskell-tng:module)
+ ;; TODO types vs constructor highlighting.
+ ;; needs a multi-line anchor.
;; imports (multi-line support would improve this)
(,(rx-to-string '(: word-start "import" word-end)) ;; anchor matcher
@@ -127,11 +143,7 @@
nil nil (1 'haskell-tng:type)))
;; top-level
- (,(rx-to-string `(: line-start
- (group (|
- (: (any lower ?_) (* wordchar))
- (: "(" (+? (syntax symbol)) ")")))
- symbol-end))
+ (,(rx-to-string toplevel)
. 'haskell-tng:toplevel)
;; uses of F.Q.N.s
@@ -144,5 +156,35 @@
)))
+;; TODO: consider previous/next symbol instead of whole line detection in
+;; font-lock-extend-region-functions for super duper hyper perf.
+
+(defun haskell-tng:multiline-faces ()
+ "For use in `font-lock-extend-region-functions'.
+
+Detects multiline patterns, such as multiline `module', `import'
+and type signatures, setting `font-lock-beg' / `font-lock-end'
+appropriately, returning nil."
+ (defvar font-lock-beg)
+ (defvar font-log-end)
+ (save-excursion
+ (goto-char font-lock-beg)
+
+ ;; TODO: detect :: and extend forwards as necessary
+ ;; TODO: detect -> and check if it's a type, then extend both ways
+ ;; TODO: detect module / import and check if its multiline
+ )
+ nil)
+
+(defun haskell-tng:mark-block ()
+ ;; TODO: this is kinda obscure, replace with mark-defun when it is defined
+ "For use as `font-lock-mark-block-function'."
+ (let ((toplevel (rx-to-string haskell-tng:toplevel)))
+ (right-char)
+ (re-search-forward toplevel (point-max) 'max)
+ (move-beginning-of-line nil)
+ (set-mark (point))
+ (re-search-forward toplevel (point-min) 'min -1)))
+
(provide 'haskell-tng-font-lock)
;;; haskell-tng-font-lock.el ends here
diff --git a/haskell-tng-mode.el b/haskell-tng-mode.el
index 1887637..2ce02411 100644
--- a/haskell-tng-mode.el
+++ b/haskell-tng-mode.el
@@ -47,10 +47,15 @@
syntax-propertize-function #'haskell-tng:syntax-propertize
parse-sexp-lookup-properties t
- font-lock-defaults '(haskell-tng:keywords nil nil nil)
+ font-lock-defaults '(haskell-tng:keywords
+ nil nil nil nil
+ (font-lock-mark-block-function .
haskell-tng:mark-block))
+ font-lock-extend-region-functions '(font-lock-extend-region-wholelines
+ haskell-tng:multiline-faces)
;; whitespace is meaningful, no electric indentation
- electric-indent-inhibit t))
+ electric-indent-inhibit t)
+ )
(defcustom haskell-tng-mode-hook nil
"List of functions to run after `haskell-tng-mode' is enabled."