branch: elpa/haskell-tng-mode commit de488407754696fee891a6edac6cab173abb0fc4 Author: Tseen She <ts33n....@gmail.com> Commit: Tseen She <ts33n....@gmail.com>
multiline import anchors --- README.md | 6 ++-- haskell-tng-font-lock.el | 74 +++++++++++++++++++++++++++--------------------- haskell-tng-syntax.el | 2 ++ 3 files changed, 47 insertions(+), 35 deletions(-) diff --git a/README.md b/README.md index 36cfd4f..48cb224 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`](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 [...] +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 @@ -41,7 +41,7 @@ This is the status of core features: - Navigation: - [x] performance-minded `syntax-table` - - [ ] `font-lock` to visually distinguish types and values + - [x] `font-lock` to visually distinguish types and values - [ ] `sexp` navigation (SMIE) - [ ] `projectile` / [`fast-tags`](https://github.com/elaforge/fast-tags) integration for `TAGS` - [ ] hoogle CLI jump-to-source @@ -50,7 +50,7 @@ This is the status of core features: - [ ] indentation (SMIE) - [ ] `abbrev` table - [ ] `yasnippet` templates - - [ ] `smartparens` compatibility (or something from stdlib) + - [ ] `smartparens` / `paredit` rules - [ ] `LANGUAGE` management - [ ] `import` management (via hoogle and [`hsimport`](https://hackage.haskell.org/package/hsimport)) - Compiling: diff --git a/haskell-tng-font-lock.el b/haskell-tng-font-lock.el index 2024919..c110e17 100644 --- a/haskell-tng-font-lock.el +++ b/haskell-tng-font-lock.el @@ -68,7 +68,7 @@ (: symbol-start "--" (+ (not (syntax comment-end))) - (+ (syntax comment-end)))) + (syntax comment-end))) "Newline or line comment.") ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -81,7 +81,8 @@ (let ((conid haskell-tng:rx:conid) (qual haskell-tng:rx:qual) (consym haskell-tng:rx:consym) - (toplevel haskell-tng:rx:toplevel)) + (toplevel haskell-tng:rx:toplevel) + (bigspace `(| space ,haskell-tng:rx:newline))) `(;; reservedid / reservedop (,(rx-to-string '(| @@ -113,28 +114,26 @@ (group (opt ,qual) (| ,conid ,consym)))) (1 'haskell-tng:type)) - ;; modules - ;; (,(rx-to-string `(: symbol-start "module" symbol-end (+ space) - ;; symbol-start (group (opt ,qual) ,conid) symbol-end)) - ;; 1 'haskell-tng:module) + ;; TODO modules ;; imports - ;; (,(rx-to-string '(: word-start "import" word-end)) ;; anchor matcher - ;; (,(rx-to-string `(: point (+ space) (group word-start "qualified" word-end))) - ;; nil nil (1 'haskell-tng:keyword)) - ;; (,(rx-to-string `(: point - ;; (opt (+ space) word-start "qualified" word-end) - ;; (+ space) word-start (group (opt ,qual) ,conid) word-end)) - ;; nil nil (1 'haskell-tng:module)) - ;; (,(rx-to-string `(: point (+? (not (any ?\())) - ;; word-start (group (| "hiding" "as")) word-end - ;; (opt (+ space) word-start (group ,conid) word-end))) - ;; nil nil (1 'haskell-tng:keyword) (2 'haskell-tng:module nil t)) - ;; (,(rx-to-string `(: symbol-start (group (| ,conid ,consym)) symbol-end - ;; (* space) "(..)")) - ;; nil nil (1 'haskell-tng:constructor)) - ;; (,(rx-to-string `(: symbol-start (group (| ,conid ,consym)) symbol-end)) - ;; nil nil (1 'haskell-tng:type))) + (haskell-tng:font:import:keyword + (,(rx-to-string + `(: line-start "import" (+ space) + (group (opt word-start "qualified" word-end)) (* space) + ;; TODO PackageImports + ;; TODO Safe / Trustworthy / Unsafe + (group symbol-start (* ,conid ".") ,conid symbol-end) (* ,bigspace) + (group (opt word-start "as" word-end (* space))) + (group (opt word-start "hiding" word-end (* space))))) + (haskell-tng:font:multiline:pre) nil + (1 'haskell-tng:keyword) + (2 'haskell-tng:module) + (3 'haskell-tng:keyword) + (4 'haskell-tng:keyword)) + ;; TODO constructors vs types in import brackets + ;; TODO ExplicitNamespaces + ) ;; TODO: pragmas ;; TODO: numeric / char primitives? @@ -154,6 +153,11 @@ ))) +(defun haskell-tng:font:multiline:pre () + "Multiline MATCH-ANCHORED forms must move point and return LIMIT." + (goto-char (match-beginning 0)) + (match-end 0)) + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Here are `function' matchers for use in `font-lock-keywords' and ;; `font-lock-extend-region-functions' procedures for extending the region. @@ -236,15 +240,15 @@ succeeds and may further restrict the FIND search limit." haskell-tng:indent-close-previous) (haskell-tng:font:multiline topdecl - (rx line-start (| "data" "newtype" "class" "instance") symbol-end) - (rx line-start (| "data" "newtype" "class" "instance") symbol-end + (rx line-start (| "data" "newtype" "class" "instance") word-end) + (rx line-start (| "data" "newtype" "class" "instance") word-end (group (+? anything)) (| (: line-start symbol-start) (: symbol-start (| "where" "=") symbol-end)))) (haskell-tng:font:multiline type - (rx line-start "type" symbol-end) - (rx line-start "type" symbol-end (+ space) (group (+ anything))) + (rx line-start "type" word-end) + (rx line-start "type" word-end (group (+ anything))) haskell-tng:indent-close) ;; DeriveAnyClass @@ -253,15 +257,21 @@ succeeds and may further restrict the FIND search limit." ;; TODO DerivingVia ;; TODO StandaloneDeriving (haskell-tng:font:multiline deriving - (rx symbol-start "deriving" symbol-end) - (rx symbol-start "deriving" symbol-end - (+ space) (group (opt (| "anyclass" "stock" "newtype"))) + (rx word-start "deriving" word-end) + (rx word-start "deriving" word-end + (+ space) (group (opt (| "anyclass" "stock" "newtype") word-end)) (* space) ?\( (group (* anything)) ?\)) haskell-tng:indent-close) -;; TODO modules -;; TODO imports -;; TODO ExplicitNamespaces +(haskell-tng:font:multiline import + (rx line-start "import" word-end) + (rx line-start "import" word-end (group (+ anything))) + haskell-tng:indent-close) + +(haskell-tng:font:multiline module + (rx line-start "module" word-end) + (rx line-start "module" word-end (group (+ anything))) + haskell-tng:indent-close) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Helpers diff --git a/haskell-tng-syntax.el b/haskell-tng-syntax.el index 48b073f..92cd0fe 100644 --- a/haskell-tng-syntax.el +++ b/haskell-tng-syntax.el @@ -90,5 +90,7 @@ (put-text-property (- (point) 1) (point) 'syntax-table '(9 . ?\\))))) +;; TODO newlines should be whitespace if there is no comment to close + (provide 'haskell-tng-syntax) ;;; haskell-tng-syntax.el ends here