README.org
changeset 2 9272314a1c65
parent 0 4d355b59e2a3
equal deleted inserted replaced
1:27f2627e9f2f 2:9272314a1c65
       
     1 #+title: haskell-ts-mode
       
     2 #+author: Pranshu Sharma
     1 
     3 
     2 * haskell-ts-mode
     4 * haskell-ts-mode
     3 
     5 
     4 A haskell mode that uses treesitter.
     6 A haskell mode that uses treesitter.
     5 
     7 
     6 * Screenshot
     8 * Screenshot
     7 
     9 
     8 [[./ss.png]]
    10 [[./ss.png]]
     9 
    11 
    10 The above screenshot is indented coloured using haskell-ts-mode, with
    12 The above screenshot is indented and coloured using haskell-ts-mode,
    11 prettify-symbols-mode enabled.
    13 with =prettify-symbols-mode= enabled.
    12 
    14 
    13 * Usage
    15 * Usage
    14 
    16 
    15 =C-c C-r= to open REPL
    17 =C-c C-r= to open REPL
    16 =C-c C-c= to send code to repl
    18 =C-c C-c= to send code to repl
    17 =C-M-q=   Indent paragraph
    19 =C-M-q=   Indent the function
    18 
    20 
    19 * Features
    21 * Features
       
    22 
       
    23 say it with me: indentation does not change the syntax-tree.  This
       
    24 means that the indenation is a lot more predictable, but sometimes you
       
    25 must manually press M-i to indent.
       
    26 
    20 an overview of the features are:
    27 an overview of the features are:
    21 - Syntax highliting
    28 - Syntax highliting
    22 - Indentation
    29 - Indentation
    23 - Imenu support
    30 - Imenu support
    24 - REPL (C-c r in the mode to run)
    31 - REPL (C-c r in the mode to run)
    26 
    33 
    27 * Comparasion with haskell-mode
    34 * Comparasion with haskell-mode
    28 The more interesting features are:
    35 The more interesting features are:
    29 - Logical syntax highlighting:
    36 - Logical syntax highlighting:
    30   - Only arguments that can be used in functions are highlighted, eg
    37   - Only arguments that can be used in functions are highlighted, eg
    31     in `f (_:(a:[])) only 'a' is highlighted, as it is the only
    38     in =f (_:(a:[]))= only =a= is highlighted, as it is the only
    32     variable that is captured that can be used in body of function
    39     variable that is captured that can be used in body of function
    33   - The return type of a function is highlighted
    40   - The return type of a function is highlighted
    34   - All new variabels are(or should be) highlighted, this includes
    41   - All new variabels are(or should be) highlighted, this includes
    35     generators, lambda args.
    42     generators, lambda args.
    36   - highlighting the '=' operaotr in guarded matches correctly, this
    43   - highlighting the '=' operaotr in guarded matches correctly, this
    37     would be stupidly hard in regexp based syntax
    44     would be stupidly hard in regexp based syntax
    38 - Unlike haskell-mode, quasi quotes are understood and do not confuse
       
    39   the mode, thanks to treesitter
       
    40 - Predictable (but less powerful) indentation: haskell-mode's
       
    41   indentation works in a cyclical way, it cycles through where you
       
    42   might want indentation.  haskell-ts-mode, meanwhile relies on you to
       
    43   set the concrete syntax tree changing whitespace.
       
    44 - More perfomant, this is especially seen in longer files
    45 - More perfomant, this is especially seen in longer files
    45 - Much much less code, haskell mode has accumlated 30,000 lines of
    46 - Much much less code, haskell mode has accumlated 30,000 lines of
    46   features to do with all things haskell related, this mode just keeps
    47   features to do with all things haskell related, this mode just keeps
    47   the scope to basic major mode stuff, and leaves other stuff for
    48   the scope to basic major mode stuff, and leaves other stuff for
    48   external packages.
    49   external packages.
    49 
    50 
    50 * Motivation
    51 * Motivation
    51   
    52   
    52 haskell-mode contains nearly 30k lines of code, and is
    53 =haskell-mode= contains nearly 30k lines of code, and is
    53 about 30 years old.  Therefore, a lot of stuff emacs has gained the
    54 about 30 years old.  Therefore, a lot of stuff emacs has gained the
    54 ability to do in those years, haskell-mode already has implemented
    55 ability to do in those years, haskell-mode already has implemented
    55 them.
    56 them.
    56 
    57 
    57 In 2018, a mode called haskell-tng-mode was made to solve some of
    58 In 2018, a mode called =haskell-tng-mode= was made to solve some of
    58 these problems. However because of haskell's syntax, it too became
    59 these problems. However because of haskell's syntax, it too became
    59 very complex and required a web of dependencies.
    60 very complex and required a web of dependencies.
    60 
    61 
    61 Both these modes ended up practically parsing haskells syntax to
    62 Both these modes ended up practically parsing haskells syntax to
    62 implement indentation, so I thought why not use tree sitter?
    63 implement indentation, so I thought why not use tree sitter?
    72 #+end_src
    73 #+end_src
    73 
    74 
    74 * Customization
    75 * Customization
    75 
    76 
    76 If colour is too much or too less for you, adjust
    77 If colour is too much or too less for you, adjust
    77 treesit-font-lock-level accordingly.
    78 =treesit-font-lock-level= accordingly.
    78 
    79 
    79 If you want to highlight signature declarations (disabled by default),
    80 If you want to highlight signature declarations (disabled by default),
    80 add the following to your init file:
    81 add the following to your init file:
    81 #+begin_src emacs-lisp
    82 #+begin_src emacs-lisp
    82 (setq haskell-ts-highlight-signature t)
    83 (setq haskell-ts-highlight-signature t)
    87 #+begin_src emacs-lisp
    88 #+begin_src emacs-lisp
    88 (setq haskell-ts-use-indent nil)
    89 (setq haskell-ts-use-indent nil)
    89 #+end_src
    90 #+end_src
    90 
    91 
    91 ** Pretify symbols mode
    92 ** Pretify symbols mode
    92 prettify symbols mode can be used to replace common symbols with
    93 =prettify-symbols-mode= can be used to replace common symbols with
    93 unicode alternatives.
    94 unicode alternatives.
    94 
    95 
    95 #+begin_src emacs-lisp
    96 #+begin_src emacs-lisp
    96 (add-hook 'haskell-ts-mode 'prettify-symbols-mode)
    97 (add-hook 'haskell-ts-mode 'prettify-symbols-mode)
    97 #+end_src
    98 #+end_src
    98 
    99 
    99 ** Adjusting font lock level
   100 ** Adjusting font lock level
   100 set haskell-ts-font-lock-level accordingly.
   101 set =haskell-ts-font-lock-level= accordingly.  Default value is 4, so if
       
   102 you suffer from contagious dehydration, you can lower it.
   101 
   103 
   102 ** Language server
   104 ** Language server
   103 
   105 
   104 haskell-ts-mode is compatiable with lsp-haskell.
   106 =haskell-ts-mode= now works with =lsp-mode=, however =lsp-haskell= still requires on =haskell-mode=.
   105 
   107 
   106 To enable eglot support, use the following code in your init.el:
   108 To add =eglot= support, add the following code to you init.el:
       
   109 
   107 #+begin_src emacs-lisp
   110 #+begin_src emacs-lisp
   108 (with-eval-after-load 'eglot (haskell-ts-setup-eglot))
   111   (with-eval-after-load 'eglot
       
   112     (defvar eglot-server-programs)
       
   113     (add-to-list 'eglot-server-programs
       
   114   	       '(haskell-ts-mode . ("haskell-language-server-wrapper" "--lsp"))))
   109 #+end_src
   115 #+end_src
   110 
   116 
   111 * TODO and limitations
   117 * TODO
   112 - Imenu support for functions with multiple definitions
   118 - Imenu support for functions with multiple definitions
   113 
   119 - _Proper indenting of multiline signatures_: the treesitter grammer
   114 Limitations: _Proper indenting of multiline signatures_: the
   120   does not flatten the signautes, rather leaves them to the standard
   115 treesitter grammer does not flatten the signautes, rather leaves them
   121   infix interpretatoin. This makes indentation hard, as it will mean
   116 to the standard infix interpretatoin. This makes indentation hard, as
   122   the only way to check if the the signature node is an ancestor of
   117 it will mean the only way to check if the the signature node is an
   123   node at point is to perfom a recursive ascent.
   118 ancestor of node at point is to perfom a recursive ascent, which is
       
   119 horrible for perfomance.