diff -r 000000000000 -r 4d355b59e2a3 README.org --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/README.org Thu Dec 12 22:06:43 2024 +1000 @@ -0,0 +1,119 @@ + +* haskell-ts-mode + +A haskell mode that uses treesitter. + +* Screenshot + +[[./ss.png]] + +The above screenshot is indented coloured using haskell-ts-mode, with +prettify-symbols-mode enabled. + +* Usage + +=C-c C-r= to open REPL +=C-c C-c= to send code to repl +=C-M-q= Indent paragraph + +* Features +an overview of the features are: +- Syntax highliting +- Indentation +- Imenu support +- REPL (C-c r in the mode to run) +- Prettify symbols mode support + +* Comparasion with haskell-mode +The more interesting features are: +- Logical syntax highlighting: + - Only arguments that can be used in functions are highlighted, eg + in `f (_:(a:[])) only 'a' is highlighted, as it is the only + variable that is captured that can be used in body of function + - The return type of a function is highlighted + - All new variabels are(or should be) highlighted, this includes + generators, lambda args. + - highlighting the '=' operaotr in guarded matches correctly, this + would be stupidly hard in regexp based syntax +- Unlike haskell-mode, quasi quotes are understood and do not confuse + the mode, thanks to treesitter +- Predictable (but less powerful) indentation: haskell-mode's + indentation works in a cyclical way, it cycles through where you + might want indentation. haskell-ts-mode, meanwhile relies on you to + set the concrete syntax tree changing whitespace. +- More perfomant, this is especially seen in longer files +- Much much less code, haskell mode has accumlated 30,000 lines of + features to do with all things haskell related, this mode just keeps + the scope to basic major mode stuff, and leaves other stuff for + external packages. + +* Motivation + +haskell-mode contains nearly 30k lines of code, and is +about 30 years old. Therefore, a lot of stuff emacs has gained the +ability to do in those years, haskell-mode already has implemented +them. + +In 2018, a mode called haskell-tng-mode was made to solve some of +these problems. However because of haskell's syntax, it too became +very complex and required a web of dependencies. + +Both these modes ended up practically parsing haskells syntax to +implement indentation, so I thought why not use tree sitter? + +* Installation + +The package is avaiable on elpa, you can install it using: +M-x package-install RET haskell-ts-mode RET + +#+begin_src elisp +(add-to-list 'load-path "path/to/haskell-ts-mode") +(require 'haskell-ts-mode) +#+end_src + +* Customization + +If colour is too much or too less for you, adjust +treesit-font-lock-level accordingly. + +If you want to highlight signature declarations (disabled by default), +add the following to your init file: +#+begin_src emacs-lisp +(setq haskell-ts-highlight-signature t) +#+end_src + +** how to disable haskell-ts-mode indentation + +#+begin_src emacs-lisp +(setq haskell-ts-use-indent nil) +#+end_src + +** Pretify symbols mode +prettify symbols mode can be used to replace common symbols with +unicode alternatives. + +#+begin_src emacs-lisp +(add-hook 'haskell-ts-mode 'prettify-symbols-mode) +#+end_src + +** Adjusting font lock level +set haskell-ts-font-lock-level accordingly. + +** Language server + +haskell-ts-mode is compatiable with lsp-haskell. + +To enable eglot support, use the following code in your init.el: +#+begin_src emacs-lisp +(with-eval-after-load 'eglot (haskell-ts-setup-eglot)) +#+end_src + +* TODO and limitations +- Imenu support for functions with multiple definitions + +Limitations: _Proper indenting of multiline signatures_: the +treesitter grammer does not flatten the signautes, rather leaves them +to the standard infix interpretatoin. This makes indentation hard, as +it will mean the only way to check if the the signature node is an +ancestor of node at point is to perfom a recursive ascent, which is +horrible for perfomance.