README.org
author Pranshu Sharma <pranshu@bauherren.ovh>
Thu, 12 Dec 2024 23:29:55 +1000
changeset 2 9272314a1c65
parent 0 4d355b59e2a3
permissions -rw-r--r--
Fixed up readme and some typos, and added .elpaignore .elpaignore: Added the file README.org: Formatting changes haskell-ts-mode.el: Remvoed eglot support by default

#+title: haskell-ts-mode
#+author: Pranshu Sharma

* haskell-ts-mode

A haskell mode that uses treesitter.

* Screenshot

[[./ss.png]]

The above screenshot is indented and 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 the function

* Features

say it with me: indentation does not change the syntax-tree.  This
means that the indenation is a lot more predictable, but sometimes you
must manually press M-i to indent.

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
- 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.  Default value is 4, so if
you suffer from contagious dehydration, you can lower it.

** Language server

=haskell-ts-mode= now works with =lsp-mode=, however =lsp-haskell= still requires on =haskell-mode=.

To add =eglot= support, add the following code to you init.el:

#+begin_src emacs-lisp
  (with-eval-after-load 'eglot
    (defvar eglot-server-programs)
    (add-to-list 'eglot-server-programs
  	       '(haskell-ts-mode . ("haskell-language-server-wrapper" "--lsp"))))
#+end_src

* TODO
- Imenu support for functions with multiple definitions
- _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.