├── README.md
├── after
└── syntax
│ ├── haskell.vim
│ └── lhaskell.vim
├── demo.hs
├── demo.lhs
├── demo.png
├── gendemo.sh
└── tests
├── test-with-pack.sh
└── test-with-pathogen.sh
/README.md:
--------------------------------------------------------------------------------
1 | ## Vim Haskell Conceal+
2 |
3 | This bundle provides extended Haskell Conceal feature for Vim. The feature
4 | is used to display unicode operators in Haskell code without changing the
5 | underlying file.
6 |
7 | This package offers more (and, more importantly, configurable) features
8 | than the
9 | [baseline vim-haskellConcealbundle](https://github.com/Twinside/vim-haskellConceal).
10 | The baseline bundle has numerous forks, which is possible to combine, so
11 | everyone is welcome to share, improve or contribute new notations to this
12 | Conceal Plus package.
13 |
14 | GitHub: https://github.com/enomsg/vim-haskellConcealPlus
15 |
16 | ### Why Concealing
17 |
18 | - Using things like '->' instead real arrows '→' was never a deliberate
19 | choice, but a choice made due to limitations of teletypewriters and
20 | input inconvenience.
21 |
22 | - With concealing you don't have to deal with cumbersome unicode-input
23 | methods, yet you can enjoy proper notation.
24 |
25 | - It is not only about aesthetics. Excess of multi-character functions may
26 | create visual noise, which negatively affects readability. Using special
27 | symbols and true arrows, together with colors and bold/italic face seems
28 | to improve the situation. The image shows Vim with and without
29 | concealing, both running in a plain terminal emulator:
30 |
31 | 
32 |
33 | - Using concealing instead of *-unicode* versions of packages also has
34 | some advantages. Mainly, concealing does not require any changes to the
35 | source code, it is backwards-compatible with idiomatic code. Secondly,
36 | with concealing no special input methods are needed. Plus, currently
37 | some features are hardly possible without editor's concealing (e.g.
38 | power superscripts).
39 |
40 | ### Installation
41 |
42 | Using Vim built-in `pack` support:
43 |
44 | ```
45 | $ mkdir -p ~/.vim/pack/vim-haskellConcealPlus/start
46 | $ cd ~/.vim/pack/vim-haskellConcealPlus/start
47 | $ git clone https://github.com/enomsg/vim-haskellConcealPlus
48 | $ echo "syn on" >> ~/.vimrc # If not already in .vimrc
49 | $ echo "setlocal conceallevel=2" >> ~/.vimrc # If not already in .vimrc
50 | $ echo "set concealcursor=nciv" >> ~/.vimrc # Optional
51 | ```
52 |
53 | ### Available Options
54 |
55 | 'q' option to disable concealing of scientific constants (e.g. π)
56 | '℘' option to disable concealing of powerset function
57 | '𝐒' option to disable String type to 𝐒 concealing
58 | '𝐓' option to disable Text type to 𝐓 concealing
59 | '𝐄' option to disable Either/Right/Left to 𝐄/𝑅/𝐿 concealing
60 | '𝐌' option to disable Maybe/Just/Nothing to 𝐌/𝐽/𝑁 concealing
61 | 'A' option to not try to preserve indentation
62 | 's' option to disable space consumption after ∑,∏,√ and ¬ functions
63 | '*' option to enable concealing of asterisk with '⋅' sign
64 | 'x' option to disable default concealing of asterisk with '×' sign
65 | 'E' option to enable ellipsis concealing with ‥ (two dot leader)
66 | 'e' option to disable ellipsis concealing with … (ellipsis sign)
67 | '⇒' option to disable `implies` concealing with ⇒
68 | '⇔' option to disable `iff` concealing with ⇔
69 | 'r' option to disable return (η) and join (µ) concealing
70 | 'b' option to disable bind (left and right) concealing
71 | 'f' option to enable formal (★) right bind concealing
72 | 'c' option to enable encircled b/d (ⓑ/ⓓ) for right and left binds
73 | 'h' option to enable partial concealing of binds (e.g. »=)
74 | 'C' option to enable encircled 'm' letter ⓜ concealing for fmap
75 | 'l' option to disable fmap/lift concealing with ↥
76 | '↱' option to disable mapM/forM concealing with ↱/↰
77 | 'w' option to disable 'where' concealing with "due to"/∵ symbol
78 | '-' option to disable subtract/(-) concealing with ⊟
79 | 'I' option to enable alternative ':+' concealing with with ⨢
80 | 'i' option to disable default concealing of ':+' with ⅈ
81 | 'R' option to disable realPart/imagPart concealing with ℜ/ℑ
82 | 'T' option to enable True/False constants concealing with bold 𝐓/𝐅
83 | 't' option to disable True/False constants concealing with italic 𝑇/𝐹
84 | 'B' option to disable Bool type to 𝔹 concealing
85 | 'Q' option to disable Rational type to ℚ concealing
86 | 'Z' option to disable Integer type to ℤ concealing
87 | 'N' option to disable Natural, Nat types to ℕ concealing
88 | 'D' option to disable Double type to 𝔻 concealing
89 | 'C' option to disable Complex type to ℂ concealing
90 | '1' option to disable numeric superscripts concealing, e.g. x²
91 | 'a' option to disable alphabet superscripts concealing, e.g. xⁿ
92 |
93 | The flags can be specified via hscoptions variable. For example, *let
94 | hscoptions="fc"* in your *~/.vimrc*.
95 |
96 | ### Known Issues and Hints:
97 |
98 | - Concealing may seriously mess up indentation. By default the bundle
99 | tries to preserve spaces for commonly troublesome symbols (e.g. ->, <-
100 | and => arrows). But to be sure about indentation, you still have to see
101 | the non-concealed code. *set conceallevel=0* might be handy in these
102 | cases.
103 |
104 | - *set concealcursor=nciv* seem to not play well with Vim matchparen
105 | feature (which is enabled by default). You can either disable concealing
106 | under the cursor, or disable matchparen by adding *let
107 | loaded_matchparen=1* at the very top of your *~/.vimrc*.
108 |
109 | - With *set concealcursor=nciv* navigation through concealed parts of code
110 | might be somewhat irritating because the cursor behaves a bit
111 | differently. It becomes less of an issue if you are used to Vim's *w/b*
112 | commands (word forward/backward). You can also try *set
113 | concealcursor=ncv* instead.
114 |
115 | - Finding proper fonts might be a pain. Most of modern, so called
116 | programming fonts (*Inconsolata*, *Anonymous Pro*, etc.) often lack
117 | decent unicode support. As a recommendation, try *DejaVu Sans Mono*.
118 |
119 | **Update**: thanks to [monospacifier](https://github.com/cpitclaudel/monospacifier)
120 | package, fonts are no longer a problem. Pick your favourite font, then in
121 | addition download one of the "monospacified" fallback fonts, save into
122 | `~/.fonts`, and adjust fontconfig, e.g.
123 | `~/.config/fontconfig/fonts.conf`:
124 |
125 | ```
126 |
127 |
128 | ~/.fonts
129 |
130 | monospace
131 |
132 | TeX Gyre Schola Math monospacified for DejaVu Sans Mono
133 |
134 |
135 |
136 | ```
137 |
138 | - Most of the terminal emulators have one or more issues with regard to the
139 | unicode characters handling. Emulators that don't have problems with unicode
140 | might be pretty slow. As a recommendation, try xst, or *evilvte* (it has weird
141 | configuration, but draws things correctly) or *lxterminal* (seems to be quite
142 | capable, but limited configurability) or any other terminal emulator that
143 | happened to work for you.
144 |
145 | [xst](https://github.com/gnotclub/xst) is known to work well with DejaVu Sans
146 | Mono, plus [monospacified](https://github.com/cpitclaudel/monospacifier) fonts
147 | as a fallback.
148 |
--------------------------------------------------------------------------------
/after/syntax/haskell.vim:
--------------------------------------------------------------------------------
1 | " vim: sw=4
2 | "=============================================================================
3 | " What Is This: Add some conceal operator for your haskell files
4 | " File: haskell.vim (conceal enhancement)
5 | " Last Change: 2011-09-07
6 | " Version: 1.3.2
7 | " Require:
8 | " set nocompatible
9 | " somewhere on your .vimrc
10 | "
11 | " Vim 7.3 or Vim compiled with conceal patch.
12 | " Use --with-features=big or huge in order to compile it in.
13 | "
14 | " Usage:
15 | " Drop this file in your
16 | " ~/.vim/after/syntax folder (Linux/MacOSX/BSD...)
17 | " ~/vimfiles/after/syntax folder (Windows)
18 | "
19 | " For this script to work, you have to set the encoding
20 | " to utf-8 :set enc=utf-8
21 | "
22 | " Additional:
23 | " * if you want to avoid the loading, add the following
24 | " line in your .vimrc :
25 | " let g:no_haskell_conceal = 1
26 | " Changelog:
27 | " - 1.3.1: putting undefined in extra conceal, not appearing on windows
28 | " - 1.3: adding new arrow characters used by GHC in Unicode extension.
29 | " - 1.2: Fixing conceal level to be local (thx Erlend Hamberg)
30 | " - 1.1: Better handling of non utf-8 systems, and avoid some
31 | " concealing operations on windows on some fonts
32 | "
33 |
34 | " Cf - check a flag. Return true if the flag is specified.
35 | function! Cf(flag)
36 | return exists('g:hscoptions') && stridx(g:hscoptions, a:flag) >= 0
37 | endfunction
38 |
39 | if exists('g:no_haskell_conceal') || !has('conceal') || &enc != 'utf-8'
40 | finish
41 | endif
42 |
43 | " vim: set fenc=utf-8:
44 | syntax match hsNiceOperator "\\\ze[[:alpha:][:space:]_([]" conceal cchar=λ
45 |
46 | " 'q' option to disable concealing of scientific constants (e.g. π).
47 | if !Cf('q')
48 | syntax match hsNiceOperator "\" conceal cchar=π
49 | syntax match hsNiceOperator "\" conceal cchar=τ
50 | syntax match hsNiceOperator "\" conceal cchar=ℎ
51 | syntax match hsNiceOperator "\" conceal cchar=ℏ
52 | endif
53 |
54 | syntax match hsNiceOperator "==" conceal cchar=≡
55 | syntax match hsNiceOperator "\/=" conceal cchar=≢
56 |
57 | let s:extraConceal = 1
58 | " Some windows font don't support some of the characters,
59 | " so if they are the main font, we don't load them :)
60 | if has("win32")
61 | let s:incompleteFont = [ 'Consolas'
62 | \ , 'Lucida Console'
63 | \ , 'Courier New'
64 | \ ]
65 | let s:mainfont = substitute( &guifont, '^\([^:,]\+\).*', '\1', '')
66 | for s:fontName in s:incompleteFont
67 | if s:mainfont ==? s:fontName
68 | let s:extraConceal = 0
69 | break
70 | endif
71 | endfor
72 | endif
73 |
74 | if s:extraConceal
75 | syntax match hsNiceOperator "\" conceal cchar=⊥
76 |
77 | " Match greater than and lower than w/o messing with Kleisli composition
78 | syntax match hsNiceOperator "<=\ze[^<]" conceal cchar=≤
79 | syntax match hsNiceOperator ">=\ze[^>]" conceal cchar=≥
80 |
81 | " Redfining to get proper '::' concealing
82 | syntax match hs_DeclareFunction /^[a-z_(]\S*\(\s\|\n\)*::/me=e-2 nextgroup=hsNiceOperator contains=hs_FunctionName,hs_OpFunctionName
83 |
84 | syntax match hsNiceoperator "!!" conceal cchar=‼
85 | syntax match hsNiceoperator "++\ze[^+]" conceal cchar=⧺
86 | syntax match hsNiceOperator "\" conceal cchar=∀
87 | syntax match hsNiceOperator "-<" conceal cchar=↢
88 | syntax match hsNiceOperator ">-" conceal cchar=↣
89 | syntax match hsNiceOperator "-<<" conceal cchar=⤛
90 | syntax match hsNiceOperator ">>-" conceal cchar=⤜
91 | " the star does not seem so good...
92 | " syntax match hsNiceOperator "*" conceal cchar=★
93 | syntax match hsNiceOperator "`div`" conceal cchar=÷
94 |
95 | " Only replace the dot, avoid taking spaces around.
96 | syntax match hsNiceOperator /\s\.\s/ms=s+1,me=e-1 conceal cchar=∘
97 |
98 | syntax match hsQQEnd "|\]" contained conceal cchar=〛
99 | " sy match hsQQEnd "|\]" contained conceal=〚
100 |
101 | syntax match hsNiceOperator "`elem`" conceal cchar=∈
102 | syntax match hsNiceOperator "`notElem`" conceal cchar=∉
103 | syntax match hsNiceOperator "`isSubsetOf`" conceal cchar=⊆
104 | syntax match hsNiceOperator "`union`" conceal cchar=∪
105 | syntax match hsNiceOperator "`intersect`" conceal cchar=∩
106 | syntax match hsNiceOperator "\\\\\ze[[:alpha:][:space:]_([]" conceal cchar=∖
107 |
108 | syntax match hsNiceOperator "||\ze[[:alpha:][:space:]_([]" conceal cchar=∨
109 | syntax match hsNiceOperator "&&\ze[[:alpha:][:space:]_([]" conceal cchar=∧
110 |
111 | syntax match hsNiceOperator "<\*>" conceal cchar=⊛
112 | syntax match hsNiceOperator "`mappend`" conceal cchar=⊕
113 | syntax match hsNiceOperator "\" conceal cchar=⊕
114 | syntax match hsNiceOperator "<>" conceal cchar=⊕
115 | syntax match hsNiceOperator "\" conceal cchar=∅
116 | syntax match hsNiceOperator "\" conceal cchar=∅
117 | syntax match hsNiceOperator "\" conceal cchar=∅
118 | endif
119 |
120 | hi link hsNiceOperator Operator
121 | hi! link Conceal Operator
122 | setlocal conceallevel=2
123 |
124 | " '℘' option to disable concealing of powerset function
125 | if !Cf('℘')
126 | syntax match hsNiceOperator "\" conceal cchar=℘
127 | endif
128 |
129 | " '𝐒' option to disable String type to 𝐒 concealing
130 | if !Cf('𝐒')
131 | syntax match hsNiceOperator "\" conceal cchar=𝐒
132 | endif
133 |
134 | " '𝐓' option to disable Text type to 𝐓 concealing
135 | if !Cf('𝐓')
136 | syntax match hsNiceOperator "\" conceal cchar=𝐓
137 | endif
138 |
139 | " '𝐄' option to disable Either/Right/Left to 𝐄/𝑅/𝐿 concealing
140 | if !Cf('𝐄')
141 | syntax match hsNiceOperator "\" conceal cchar=𝐄
142 | syntax match hsNiceOperator "\" conceal cchar=𝑅
143 | syntax match hsNiceOperator "\" conceal cchar=𝐿
144 | endif
145 |
146 | " '𝐌' option to disable Maybe/Just/Nothing to 𝐌/𝐽/𝑁 concealing
147 | if !Cf('𝐌')
148 | syntax match hsNiceOperator "\" conceal cchar=𝐌
149 | syntax match hsNiceOperator "\" conceal cchar=𝐽
150 | syntax match hsNiceOperator "\" conceal cchar=𝑁
151 | endif
152 |
153 | " 'A' option to not try to preserve indentation.
154 | if Cf('A')
155 | syntax match hsNiceOperator "<-" conceal cchar=←
156 | syntax match hsNiceOperator "->" conceal cchar=→
157 | syntax match hsNiceOperator "=>" conceal cchar=⇒
158 | syntax match hsNiceOperator "\:\:" conceal cchar=∷
159 | else
160 | syntax match hsLRArrowHead contained ">" conceal cchar=
161 | syntax match hsLRArrowTail contained "-" conceal cchar=→
162 | syntax match hsLRArrowFull "->" contains=hsLRArrowHead,hsLRArrowTail
163 |
164 | syntax match hsRLArrowHead contained "<" conceal cchar=←
165 | syntax match hsRLArrowTail contained "-" conceal cchar=
166 | syntax match hsRLArrowFull "<-" contains=hsRLArrowHead,hsRLArrowTail
167 |
168 | syntax match hsLRDArrowHead contained ">" conceal cchar=
169 | syntax match hsLRDArrowTail contained "=" conceal cchar=⇒
170 | syntax match hsLRDArrowFull "=>" contains=hsLRDArrowHead,hsLRDArrowTail
171 | endif
172 |
173 | " 's' option to disable space consumption after ∑,∏,√ and ¬ functions.
174 | if Cf('s')
175 | syntax match hsNiceOperator "\" conceal cchar=∑
176 | syntax match hsNiceOperator "\" conceal cchar=∏
177 | syntax match hsNiceOperator "\" conceal cchar=√
178 | syntax match hsNiceOperator "\" conceal cchar=¬
179 | else
180 | syntax match hsNiceOperator "\\(\ze\s*[.$]\|\s*\)" conceal cchar=∑
181 | syntax match hsNiceOperator "\\(\ze\s*[.$]\|\s*\)" conceal cchar=∏
182 | syntax match hsNiceOperator "\\(\ze\s*[.$]\|\s*\)" conceal cchar=√
183 | syntax match hsNiceOperator "\\(\ze\s*[.$]\|\s*\)" conceal cchar=¬
184 | endif
185 |
186 | " '*' option to enable concealing of asterisk with '⋅' sign.
187 | if Cf('*')
188 | syntax match hsNiceOperator "*" conceal cchar=⋅
189 | " 'x' option to disable default concealing of asterisk with '×' sign.
190 | elseif !Cf('x')
191 | syntax match hsNiceOperator "*" conceal cchar=×
192 | endif
193 |
194 | " 'E' option to enable ellipsis concealing with ‥ (two dot leader).
195 | if Cf('E')
196 | " The two dot leader is not guaranteed to be at the bottom. So, it
197 | " will break on some fonts.
198 | syntax match hsNiceOperator "\.\." conceal cchar=‥
199 | " 'e' option to disable ellipsis concealing with … (ellipsis sign).
200 | elseif !Cf('e')
201 | syntax match hsNiceOperator "\.\." conceal cchar=…
202 | end
203 |
204 | " '⇒' option to disable `implies` concealing with ⇒
205 | if !Cf('⇒')
206 | " Easily distinguishable from => keyword since the keyword can only be
207 | " used in type signatures.
208 | syntax match hsNiceOperator "`implies`" conceal cchar=⇒
209 | endif
210 |
211 | " '⇔' option to disable `iff` concealing with ⇔
212 | if !Cf('⇔')
213 | syntax match hsNiceOperator "`iff`" conceal cchar=⇔
214 | endif
215 |
216 | " 'r' option to disable return (η) and join (µ) concealing.
217 | if !Cf('r')
218 | syntax match hsNiceOperator "\" conceal cchar=η
219 | syntax match hsNiceOperator "\" conceal cchar=µ
220 | endif
221 |
222 | " 'b' option to disable bind (left and right) concealing
223 | if Cf('b')
224 | " Vim has some issues concealing with composite symbols like '«̳', and
225 | " unfortunately there is no other common short notation for both
226 | " binds. So 'b' option to disable bind concealing altogether.
227 | " 'f' option to enable formal (★) right bind concealing
228 | elseif Cf('f')
229 | syntax match hsNiceOperator ">>=" conceal cchar=★
230 | " 'c' option to enable encircled b/d (ⓑ/ⓓ) for right and left binds.
231 | elseif Cf('c')
232 | syntax match hsNiceOperator ">>=" conceal cchar=ⓑ
233 | syntax match hsNiceOperator "=<<" conceal cchar=ⓓ
234 | " 'h' option to enable partial concealing of binds (e.g. »=).
235 | elseif Cf('h')
236 | syntax match hsNiceOperator ">>" conceal cchar=»
237 | syntax match hsNiceOperator "<<" conceal cchar=«
238 | syntax match hsNiceOperator "=\zs<<" conceal cchar=«
239 | " Left and right arrows with hooks are the default option for binds.
240 | else
241 | syntax match hsNiceOperator ">>=\ze\_[[:alpha:][:space:]_()[\]]" conceal cchar=↪
242 | syntax match hsNiceOperator "=<<\ze\_[[:alpha:][:space:]_()[\]]" conceal cchar=↩
243 | endif
244 |
245 | if !Cf('h')
246 | syntax match hsNiceOperator ">>\ze\_[[:alpha:][:space:]_()[\]]" conceal cchar=»
247 | syntax match hsNiceOperator "<<\ze\_[[:alpha:][:space:]_()[\]]" conceal cchar=«
248 | endif
249 |
250 | " 'C' option to enable encircled 'm' letter ⓜ concealing for fmap.
251 | if Cf('C')
252 | syntax match hsNiceOperator "<$>" conceal cchar=ⓜ
253 | syntax match hsNiceOperator "`fmap`" conceal cchar=ⓜ
254 | " 'l' option to disable fmap/lift concealing with ↥.
255 | elseif !Cf('l')
256 | syntax match hsNiceOperator "`liftM`" conceal cchar=↥
257 | syntax match hsNiceOperator "`liftA`" conceal cchar=↥
258 | syntax match hsNiceOperator "`fmap`" conceal cchar=↥
259 | syntax match hsNiceOperator "<$>" conceal cchar=↥
260 |
261 | syntax match LIFTQ contained "`" conceal
262 | syntax match LIFTQl contained "l" conceal cchar=↥
263 | syntax match LIFTl contained "l" conceal cchar=↥
264 | syntax match LIFTi contained "i" conceal
265 | syntax match LIFTf contained "f" conceal
266 | syntax match LIFTt contained "t" conceal
267 | syntax match LIFTA contained "A" conceal
268 | syntax match LIFTM contained "M" conceal
269 | syntax match LIFT2 contained "2" conceal cchar=²
270 | syntax match LIFT3 contained "3" conceal cchar=³
271 | syntax match LIFT4 contained "4" conceal cchar=⁴
272 | syntax match LIFT5 contained "5" conceal cchar=⁵
273 |
274 | syntax match hsNiceOperator "`liftM2`" contains=LIFTQ,LIFTQl,LIFTi,LIFTf,LIFTt,LIFTM,LIFT2
275 | syntax match hsNiceOperator "`liftM3`" contains=LIFTQ,LIFTQl,LIFTi,LIFTf,LIFTt,LIFTM,LIFT3
276 | syntax match hsNiceOperator "`liftM4`" contains=LIFTQ,LIFTQl,LIFTi,LIFTf,LIFTt,LIFTM,LIFT4
277 | syntax match hsNiceOperator "`liftM5`" contains=LIFTQ,LIFTQl,LIFTi,LIFTf,LIFTt,LIFTM,LIFT5
278 | syntax match hsNiceOperator "`liftA2`" contains=LIFTQ,LIFTQl,LIFTi,LIFTf,LIFTt,LIFTA,LIFT2
279 | syntax match hsNiceOperator "`liftA3`" contains=LIFTQ,LIFTQl,LIFTi,LIFTf,LIFTt,LIFTA,LIFT3
280 |
281 | syntax match FMAPf contained "f" conceal cchar=↥
282 | syntax match FMAPm contained "m" conceal
283 | syntax match FMAPa contained "a" conceal
284 | syntax match FMAPp contained "p" conceal
285 | syntax match FMAPSPC contained " " conceal
286 | syntax match hsNiceOperator "\\s*" contains=FMAPf,FMAPm,FMAPa,FMAPp,FMAPSPC
287 |
288 | syntax match LIFTSPC contained " " conceal
289 | syntax match hsNiceOperator "\\s*" contains=LIFTl,LIFTi,LIFTf,LIFTt,LIFTA,LIFTSPC
290 | syntax match hsNiceOperator "\\s*" contains=LIFTl,LIFTi,LIFTf,LIFTt,LIFTA,LIFT2,LIFTSPC
291 | syntax match hsNiceOperator "\\s*" contains=LIFTl,LIFTi,LIFTf,LIFTt,LIFTA,LIFT3,LIFTSPC
292 |
293 | syntax match hsNiceOperator "\\s*" contains=LIFTl,LIFTi,LIFTf,LIFTt,LIFTM,LIFTSPC
294 | syntax match hsNiceOperator "\\s*" contains=LIFTl,LIFTi,LIFTf,LIFTt,LIFTM,LIFT2,LIFTSPC
295 | syntax match hsNiceOperator "\\s*" contains=LIFTl,LIFTi,LIFTf,LIFTt,LIFTM,LIFT3,LIFTSPC
296 | syntax match hsNiceOperator "\\s*" contains=LIFTl,LIFTi,LIFTf,LIFTt,LIFTM,LIFT4,LIFTSPC
297 | syntax match hsNiceOperator "\\s*" contains=LIFTl,LIFTi,LIFTf,LIFTt,LIFTM,LIFT5,LIFTSPC
298 |
299 | " TODO: Move liftIO to its own flag?
300 | syntax match LIFTIOL contained "l" conceal
301 | syntax match LIFTI contained "I" conceal cchar=i
302 | syntax match LIFTO contained "O" conceal cchar=o
303 | syntax match hsNiceOperator "\" contains=LIFTIOl,LIFTi,LIFTf,LIFTt,LIFTI,LIFTO
304 | endif
305 |
306 | " '↱' option to disable mapM/forM concealing with ↱/↰
307 | if !Cf('↱')
308 | syntax match MAPMQ contained "`" conceal
309 | syntax match MAPMm contained "m" conceal cchar=↱
310 | syntax match MAPMmQ contained "m" conceal cchar=↰
311 | syntax match MAPMa contained "a" conceal
312 | syntax match MAPMp contained "p" conceal
313 | syntax match MAPMM contained "M" conceal
314 | syntax match MAPMM contained "M" conceal
315 | syntax match MAPMU contained "_" conceal cchar=_
316 | syntax match SPC contained " " conceal
317 | syntax match hsNiceOperator "`mapM_`" contains=MAPMQ,MAPMmQ,MAPMa,MAPMp,MAPMM,MAPMU
318 | syntax match hsNiceOperator "`mapM`" contains=MAPMQ,MAPMmQ,MAPMa,MAPMp,MAPMM
319 | syntax match hsNiceOperator "\\s*" contains=MAPMm,MAPMa,MAPMp,MAPMM,SPC
320 | syntax match hsNiceOperator "\\s*" contains=MAPMm,MAPMa,MAPMp,MAPMM,MAPMU,SPC
321 |
322 | syntax match FORMQ contained "`" conceal
323 | syntax match FORMfQ contained "f" conceal cchar=↱
324 | syntax match FORMf contained "f" conceal cchar=↰
325 | syntax match FORMo contained "o" conceal
326 | syntax match FORMr contained "r" conceal
327 | syntax match FORMM contained "M" conceal
328 | syntax match FORMU contained "_" conceal cchar=_
329 |
330 | syntax match hsNiceOperator "`forM`" contains=FORMQ,FORMfQ,FORMo,FORMr,FORMM
331 | syntax match hsNiceOperator "`forM_`" contains=FORMQ,FORMfQ,FORMo,FORMr,FORMM,FORMU
332 |
333 | syntax match hsNiceOperator "\