├── .gitignore ├── LICENSE ├── README.md ├── after └── syntax │ └── reason.vim ├── doc └── reason.txt ├── ftdetect └── reason.vim ├── indent └── reason.vim ├── syntax ├── merlin.vim └── reason.vim └── syntax_checkers ├── ocaml └── merlin.vim ├── omlet └── merlin.vim └── reason └── reasonc.vim /.gitignore: -------------------------------------------------------------------------------- 1 | *.native 2 | /reasonfmt_merlin_impl.sh 3 | /refmt_merlin_impl.sh 4 | *.byte 5 | *.cmt 6 | *.docdir 7 | _build 8 | *.install 9 | pkg/META 10 | src_gen/confusables.txt 11 | src_test/_tags 12 | .paths 13 | .settings 14 | .project 15 | .DS_Store 16 | formatTest/customMLFiles/*.ml 17 | formatTest/customMLFormatOutput.re 18 | formatTest/failed_tests 19 | formatTest/**/actual_output/ 20 | miscTests/reactjs_jsx_ppx_tests/actual*.re 21 | npm-debug.log 22 | reason-parser/src/reason_parser.messages.bak 23 | reason-parser/src/reason_parser_message.ml 24 | *~ 25 | node_modules 26 | /bspacks/*.ml 27 | /bspacks/**/*.cm* 28 | /bspacks/**/*.o 29 | /bspacks/**/*.exe 30 | *.pyc 31 | doc/tags 32 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2015 The Rust Project Developers 2 | 3 | Permission is hereby granted, free of charge, to any 4 | person obtaining a copy of this software and associated 5 | documentation files (the "Software"), to deal in the 6 | Software without restriction, including without 7 | limitation the rights to use, copy, modify, merge, 8 | publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software 10 | is furnished to do so, subject to the following 11 | conditions: 12 | 13 | The above copyright notice and this permission notice 14 | shall be included in all copies or substantial portions 15 | of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF 18 | ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 19 | TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 20 | PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT 21 | SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 22 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 23 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR 24 | IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 25 | DEALINGS IN THE SOFTWARE. 26 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Vim/Neovim support for [Reason](http://reasonml.github.io) 2 | 3 | To have the complete Vim/Neovim Reason experience, there are two plugins to install: this one, and the [language-server](https://github.com/jaredly/reason-language-server). 4 | 5 | This one provides syntax highlight, snippets for Reason and allows related features to recognize the Reason syntax. 6 | 7 | Language-server provides all the others (autocompletion, type hint, jump-to-definition, etc.). 8 | 9 | ## Prerequisite 10 | 11 | You'll need either Vim with Python 3 support, or Neovim. 12 | 13 | ## This Plugin's Installation 14 | 15 | If you are using a plugin manager, add a line such as the following to your `.vimrc` (or `~/.config/nvim/init.vim` for neovim): 16 | 17 | ``` 18 | " If using Vim-Plug (recommended. Install from https://github.com/junegunn/vim-plug) 19 | Plug 'reasonml-editor/vim-reason-plus' 20 | 21 | " Or, using NeoBundle 22 | NeoBundle 'reasonml-editor/vim-reason-plus' 23 | 24 | " Or, using Vundle 25 | Plugin 'reasonml-editor/vim-reason-plus' 26 | ``` 27 | 28 | ## Language Server Installation 29 | 30 | See https://github.com/jaredly/reason-language-server#vim for language-server installation and configuration. 31 | 32 | You also need to install Vim/NeoVim's [Language Client](https://github.com/autozimu/LanguageClient-neovim). Please follow its [Quick Start](https://github.com/autozimu/LanguageClient-neovim#quick-start) for configurations. 33 | 34 | Here's a complete configuration in your `~/.vimrc` (or `~/.config/nvim/init.vim` for neovim), assuming you use the [vim-plug](https://github.com/junegunn/vim-plug) package manager. 35 | 36 | ```viml 37 | call plug#begin('~/.vim/plugged') 38 | 39 | Plug 'reasonml-editor/vim-reason-plus' 40 | 41 | Plug 'autozimu/LanguageClient-neovim', { 42 | \ 'branch': 'next', 43 | \ 'do': 'bash install.sh', 44 | \ } 45 | 46 | " for neovim 47 | if has('nvim') 48 | Plug 'Shougo/deoplete.nvim', { 'do': ':UpdateRemotePlugins' } 49 | " for vim 8 with python 50 | else 51 | Plug 'Shougo/deoplete.nvim' 52 | Plug 'roxma/nvim-yarp' 53 | Plug 'roxma/vim-hug-neovim-rpc' 54 | " the path to python3 is obtained through executing `:echo exepath('python3')` in vim 55 | let g:python3_host_prog = "/absolute/path/to/python3" 56 | endif 57 | 58 | " nice to have 59 | Plug '/usr/local/opt/fzf' | Plug 'junegunn/fzf.vim' 60 | 61 | call plug#end() 62 | 63 | let g:LanguageClient_serverCommands = { 64 | \ 'reason': ['/absolute/path/to/reason-language-server.exe'], 65 | \ } 66 | 67 | " enable autocomplete 68 | let g:deoplete#enable_at_startup = 1 69 | ``` 70 | 71 | To install those, do `:PlugClean`, `:PlugInstall`, `:PlugUpdate` then `:UpdateRemotePlugins` (for neovim). This may seem contrived, but folks often forget to properly setup their plugins, so we're not taking chances with the instructions here. 72 | 73 | Reason-language-server currently only supports BuckleScript and OCaml 4.02.3 as compiler backends. 74 | For native development using OCaml 4.03 or later, you should prefer [ocaml-language-server](https://github.com/freebroccolo/ocaml-language-server#installation-1). 75 | 76 | ## Bonus Language Server Configuration 77 | 78 | Please follow [LanguageClient-neovim's documentation on how to configure features](https://github.com/autozimu/LanguageClient-neovim/blob/dd45e31449511152f2127fe862d955237caa130f/doc/LanguageClient.txt#L199). Here's an example configuration: 79 | 80 | ``` 81 | nnoremap gd :call LanguageClient#textDocument_definition() 82 | nnoremap gf :call LanguageClient#textDocument_formatting() 83 | nnoremap :call LanguageClient#textDocument_hover() 84 | ``` 85 | 86 | Now, for example, triggering `gf` in normal mode would format the code. 87 | -------------------------------------------------------------------------------- /after/syntax/reason.vim: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/reasonml-editor/vim-reason-plus/c11a2940f8f3e3915e472c366fe460b0fe008bac/after/syntax/reason.vim -------------------------------------------------------------------------------- /doc/reason.txt: -------------------------------------------------------------------------------- 1 | *reason.txt* Filetype plugin for Reason 2 | 3 | ============================================================================== 4 | CONTENTS *reason* *ft-reason* 5 | 6 | 7 | ============================================================================== 8 | INTRODUCTION *reason-intro* 9 | 10 | 11 | ============================================================================== 12 | SETTINGS *reason-settings* 13 | 14 | 15 | ============================================================================== 16 | MAPPINGS *reason-mappings* 17 | 18 | 19 | ============================================================================== 20 | vim:tw=78:sw=4:noet:ts=8:ft=help:norl: 21 | -------------------------------------------------------------------------------- /ftdetect/reason.vim: -------------------------------------------------------------------------------- 1 | " Copyright (c) 2015-present, Facebook, Inc. All rights reserved. 2 | 3 | au BufRead,BufNewFile *.re set filetype=reason 4 | au BufRead,BufNewFile *.rei set filetype=reason 5 | au BufNewFile,BufRead .merlin set ft=merlin 6 | -------------------------------------------------------------------------------- /indent/reason.vim: -------------------------------------------------------------------------------- 1 | " Vim indent file 2 | " Language: Reason (adapted from Rust) 3 | " Author: Chris Morgan (Modifications by Jordan W) 4 | " Portions Copyright (c) 2015-present, Facebook, Inc. All rights reserved 5 | 6 | " Only load this indent file when no other was loaded. 7 | if exists("b:did_indent") 8 | finish 9 | endif 10 | let b:did_indent = 1 11 | 12 | " m1 is needed to make parens line up correct: 13 | " 14 | " let result = callSomething ( 15 | " 1, 16 | " 2 17 | " ); 18 | " 19 | " fN (See the docs) - additional indentation *w.r.t the "prevailing indent" only applies to blocks 20 | " *not* in nested braces! We want it to match the blocks *inside* nested braces - and be zero, but 21 | " the problem is that the "prevailing indent" not inside of braces is different than inside braces. 22 | setlocal cinoptions=L0,(0,Ws,J1,j1,m1,{0,f0s 23 | " cinkeys is ignored if indentexpr is activated so this setting is useless. See indentkeys below. 24 | setlocal cinkeys=0{,0},0),!^F,o,O,0[,0] 25 | " Don't think cinwords will actually do anything at all... never mind 26 | setlocal cinwords=for,if,else,while,loop,impl,mod,unsafe,trait,struct,enum,fun,let,extern 27 | 28 | " Some preliminary settings 29 | setlocal nolisp " Make sure lisp indenting doesn't supersede us 30 | setlocal autoindent " indentexpr isn't much help otherwise 31 | " Also do indentkeys, otherwise # gets shoved to column 0 :-/ 32 | setlocal indentkeys=0{,0},0),!^F,o,O,0[,0] 33 | 34 | 35 | setlocal indentexpr=GetReasonIndent(v:lnum) 36 | 37 | " Only define the function once. 38 | if exists("*GetReasonIndent") 39 | finish 40 | endif 41 | 42 | " Come here when loading the script the first time. 43 | 44 | function! s:get_line_trimmed(lnum) 45 | " Get the line and remove a trailing comment. 46 | " Use syntax highlighting attributes when possible. 47 | " NOTE: this is not accurate; /* */ or a line continuation could trick it 48 | let line = getline(a:lnum) 49 | let line_len = strlen(line) 50 | if has('syntax_items') 51 | " If the last character in the line is a comment, do a binary search for 52 | " the start of the comment. synID() is slow, a linear search would take 53 | " too long on a long line. 54 | if synIDattr(synID(a:lnum, line_len, 1), "name") =~ 'Comment\|Todo' 55 | let min = 1 56 | let max = line_len 57 | while min < max 58 | let col = (min + max) / 2 59 | if synIDattr(synID(a:lnum, col, 1), "name") =~ 'Comment\|Todo' 60 | let max = col 61 | else 62 | let min = col + 1 63 | endif 64 | endwhile 65 | let line = strpart(line, 0, min - 1) 66 | endif 67 | return substitute(line, "\s*$", "", "") 68 | else 69 | " Sorry, this is not complete, nor fully correct (e.g. string "//"). 70 | " Such is life. 71 | return substitute(line, "\s*//.*$", "", "") 72 | endif 73 | endfunction 74 | 75 | function! s:is_string_comment(lnum, col) 76 | if has('syntax_items') 77 | for id in synstack(a:lnum, a:col) 78 | let synname = synIDattr(id, "name") 79 | if synname == "reasonString" || synname =~ "^reasonComment" 80 | return 1 81 | endif 82 | endfor 83 | else 84 | " without syntax, let's not even try 85 | return 0 86 | endif 87 | endfunction 88 | 89 | function GetReasonIndent(lnum) 90 | 91 | " Starting assumption: cindent (called at the end) will do it right 92 | " normally. We just want to fix up a few cases. 93 | 94 | let line = getline(a:lnum) 95 | 96 | if has('syntax_items') 97 | let synname = synIDattr(synID(a:lnum, 1, 1), "name") 98 | if synname == "reasonString" 99 | " If the start of the line is in a string, don't change the indent 100 | return -1 101 | elseif synname =~ '\(Comment\|Todo\)' 102 | \ && line !~ '^\s*/\*' " not /* opening line 103 | if synname =~ "CommentML" " multi-line 104 | if line !~ '^\s*\*' && getline(a:lnum - 1) =~ '^\s*/\*' 105 | " This is (hopefully) the line after a /*, and it has no 106 | " leader, so the correct indentation is that of the 107 | " previous line. 108 | return GetReasonIndent(a:lnum - 1) 109 | endif 110 | endif 111 | " If it's in a comment, let cindent take care of it now. This is 112 | " for cases like "/*" where the next line should start " * ", not 113 | " "* " as the code below would otherwise cause for module scope 114 | " Fun fact: " /*\n*\n*/" takes two calls to get right! 115 | return cindent(a:lnum) 116 | endif 117 | endif 118 | 119 | " cindent gets second and subsequent match patterns/struct members wrong, 120 | " as it treats the comma as indicating an unfinished statement:: 121 | " 122 | " switch a { 123 | " | b => c 124 | " | d => e 125 | " | f => g 126 | " }; 127 | 128 | " Search backwards for the previous non-empty line. 129 | let prevlinenum = prevnonblank(a:lnum - 1) 130 | let prevline = s:get_line_trimmed(prevlinenum) 131 | while prevlinenum > 1 && prevline !~ '[^[:blank:]]' 132 | let prevlinenum = prevnonblank(prevlinenum - 1) 133 | let prevline = s:get_line_trimmed(prevlinenum) 134 | endwhile 135 | 136 | " Handle where clauses nicely: subsequent values should line up nicely. 137 | if prevline[len(prevline) - 1] == "," 138 | \ && prevline =~# '^\s*where\s' 139 | return indent(prevlinenum) + 6 140 | endif 141 | 142 | if prevline =~ "\s*|.*[{(\[]$" 143 | " \ && s:get_line_trimmed(a:lnum) !~ '^\s*[\[\]{}]' 144 | " \ && prevline !~ '^\s*fun\s' 145 | " \ && prevline !~ '([^()]\+,$' 146 | " Oh ho! The previous line ended in a comma! I bet cindent will try to 147 | " take this too far... For now, let's normally use the previous line's 148 | " indent. 149 | 150 | " One case where this doesn't work out is where *this* line contains 151 | " square or curly brackets; then we normally *do* want to be indenting 152 | " further. 153 | " 154 | " Another case where we don't want to is one like a function 155 | " definition with arguments spread over multiple lines: 156 | " 157 | " fun foo(baz: Baz, 158 | " baz: Baz) // <-- cindent gets this right by itself 159 | " 160 | " Another case is similar to the previous, except calling a function 161 | " instead of defining it, or any conditional expression that leaves 162 | " an open paren: 163 | " 164 | " foo(baz, 165 | " baz); 166 | " 167 | " if baz && (foo || 168 | " bar) { 169 | " 170 | " There are probably other cases where we don't want to do this as 171 | " well. Add them as needed. 172 | return indent(prevlinenum) + &shiftwidth 173 | endif 174 | if prevline =~ "\s*|" 175 | return indent(prevlinenum) 176 | endif 177 | 178 | if !has("patch-7.4.355") 179 | " cindent before 7.4.355 doesn't do the module scope well at all; e.g.:: 180 | " 181 | " static FOO : &'static [bool] = [ 182 | " true, 183 | " false, 184 | " false, 185 | " true, 186 | " ]; 187 | " 188 | " uh oh, next statement is indented further! 189 | 190 | " Note that this does *not* apply the line continuation pattern properly; 191 | " that's too hard to do correctly for my liking at present, so I'll just 192 | " start with these two main cases (square brackets and not returning to 193 | " column zero) 194 | 195 | call cursor(a:lnum, 1) 196 | if searchpair('{\|(', '', '}\|)', 'nbW', 197 | \ 's:is_string_comment(line("."), col("."))') == 0 198 | if searchpair('\[', '', '\]', 'nbW', 199 | \ 's:is_string_comment(line("."), col("."))') == 0 200 | " Global scope, should be zero 201 | return 0 202 | else 203 | " At the module scope, inside square brackets only 204 | "if getline(a:lnum)[0] == ']' || search('\[', '', '\]', 'nW') == a:lnum 205 | if line =~ "^\\s*]" 206 | " It's the closing line, dedent it 207 | return 0 208 | else 209 | return &shiftwidth 210 | endif 211 | endif 212 | endif 213 | endif 214 | 215 | " Fall back on cindent, which does it mostly right 216 | return cindent(a:lnum) 217 | endfunction 218 | -------------------------------------------------------------------------------- /syntax/merlin.vim: -------------------------------------------------------------------------------- 1 | " Vim syntax file for editing merlin project files 2 | if exists("b:current_syntax") 3 | finish 4 | endif 5 | 6 | syn keyword merlinKeyword S B SUFFIX PKG REC EXT PRJ FLG CMI CMT 7 | syn match merlinComment "\v#.*$" 8 | 9 | hi link merlinKeyword Keyword 10 | hi link merlinComment Comment 11 | 12 | let b:current_syntax = "merlin" 13 | 14 | -------------------------------------------------------------------------------- /syntax/reason.vim: -------------------------------------------------------------------------------- 1 | " Vim syntax file 2 | " Language: Reason (Forked from Rust) 3 | " Maintainer: (Jordan - for Reason changes) Patrick Walton 4 | " Maintainer: Ben Blum 5 | " Maintainer: Chris Morgan 6 | " Last Change: January 29, 2015 7 | " Portions Copyright (c) 2015-present, Facebook, Inc. All rights reserved. 8 | 9 | if version < 600 10 | syntax clear 11 | elseif exists("b:current_syntax") 12 | finish 13 | endif 14 | 15 | " Syntax definitions {{{1 16 | " Basic keywords {{{2 17 | syn keyword reasonConditional switch match if else for in when fun 18 | syn keyword reasonOperator as 19 | 20 | syn match reasonAssert "\[^\.]"me=e-1 42 | " Polymorphic variants 43 | syn match reasonEnumVariant "`\w\(\w\|'\)*\>" 44 | 45 | syn match reasonModPath "\<\u\w*\." 46 | 47 | 48 | syn region reasonBoxPlacement matchgroup=reasonBoxPlacementParens start="(" end=")" contains=TOP contained 49 | " Ideally we'd have syntax rules set up to match arbitrary expressions. Since 50 | " we don't, we'll just define temporary contained rules to handle balancing 51 | " delimiters. 52 | syn region reasonBoxPlacementBalance start="(" end=")" containedin=reasonBoxPlacement transparent 53 | syn region reasonBoxPlacementBalance start="\[" end="\]" containedin=reasonBoxPlacement transparent 54 | " {} are handled by reasonFoldBraces 55 | 56 | 57 | syn region reasonMacroRepeat matchgroup=reasonMacroRepeatDelimiters start="$(" end=")" contains=TOP nextgroup=reasonMacroRepeatCount 58 | syn match reasonMacroRepeatCount ".\?[*+]" contained 59 | syn match reasonMacroVariable "$\w\+" 60 | 61 | " Reserved (but not yet used) keywords {{{2 62 | syn keyword reasonReservedKeyword alignof become do offsetof priv pure sizeof typeof unsized yield abstract virtual final override macro 63 | 64 | " Built-in types {{{2 65 | syn keyword reasonType int float option list array unit ref bool string 66 | 67 | " Things from the libstd v1 prelude (src/libstd/prelude/v1.rs) {{{2 68 | " This section is just straight transformation of the contents of the prelude, 69 | " to make it easy to update. 70 | 71 | " Reexported core operators {{{3 72 | syn keyword reasonTrait Copy Send Sized Sync 73 | syn keyword reasonTrait Drop Fn FnMut FnOnce 74 | 75 | " Reexported functions {{{3 76 | " There’s no point in highlighting these; when one writes drop( or drop::< it 77 | " gets the same highlighting anyway, and if someone writes `let drop = …;` we 78 | " don’t really want *that* drop to be highlighted. 79 | "syn keyword reasonFunction drop 80 | 81 | " Reexported types and traits {{{3 82 | syn keyword reasonTrait Box 83 | syn keyword reasonTrait ToOwned 84 | syn keyword reasonTrait Clone 85 | syn keyword reasonTrait PartialEq PartialOrd Eq Ord 86 | syn keyword reasonTrait AsRef AsMut Into From 87 | syn keyword reasonTrait Default 88 | syn keyword reasonTrait Iterator Extend IntoIterator 89 | syn keyword reasonTrait DoubleEndedIterator ExactSizeIterator 90 | syn keyword reasonEnum Option 91 | syn keyword reasonEnumVariant Some None 92 | syn keyword reasonEnum Result 93 | syn keyword reasonEnumVariant Ok Err 94 | syn keyword reasonTrait SliceConcatExt 95 | syn keyword reasonTrait String ToString 96 | syn keyword reasonTrait Vec 97 | 98 | " Other syntax {{{2 99 | syn keyword reasonSelf self 100 | syn keyword reasonBoolean true false 101 | 102 | " This is merely a convention; note also the use of [A-Z], restricting it to 103 | " latin identifiers rather than the full Unicode uppercase. I have not used 104 | " [:upper:] as it depends upon 'noignorecase' 105 | "syn match reasonCapsIdent display "[A-Z]\w\(\w\)*" 106 | 107 | syn match reasonOperator display "\%(+\|-\|/\|*\|=\|\^\|&\||\|!\|>\|<\|%\)=\?" 108 | " This one isn't *quite* right, as we could have binary-& with a reference 109 | 110 | " This isn't actually correct; a closure with no arguments can be `|| { }`. 111 | " Last, because the & in && isn't a sigil 112 | syn match reasonOperator display "&&\|||" 113 | " This is reasonArrowCharacter rather than reasonArrow for the sake of matchparen, 114 | " so it skips the ->; see http://stackoverflow.com/a/30309949 for details. 115 | syn match reasonArrowCharacter display "=>" 116 | 117 | syn match reasonEscapeError display contained /\\./ 118 | syn match reasonEscape display contained /\\\([nrt0\\'"]\|x\x\{2}\)/ 119 | syn match reasonEscapeUnicode display contained /\\\(u\x\{4}\|U\x\{8}\)/ 120 | syn match reasonEscapeUnicode display contained /\\u{\x\{1,6}}/ 121 | syn match reasonStringContinuation display contained /\\\n\s*/ 122 | syn region reasonString start='{j|' end='|j}' contains=reasonMacroVariable,@Spell 123 | syn region reasonString start=+b"+ skip=+\\\\\|\\"+ end=+"+ contains=reasonEscape,reasonEscapeError,reasonStringContinuation 124 | syn region reasonString start=+"+ skip=+\\\\\|\\"+ end=+"+ contains=reasonEscape,reasonEscapeUnicode,reasonEscapeError,reasonStringContinuation,@Spell 125 | syn region reasonString start='b\?r\z(#*\)"' end='"\z1' contains=@Spell 126 | 127 | syn region reasonAttribute start="#!\?\[" end="\]" contains=reasonString,reasonDerive 128 | syn region reasonDerive start="derive(" end=")" contained contains=reasonDeriveTrait 129 | " This list comes from src/libsyntax/ext/deriving/mod.rs 130 | " Some are deprecated (Encodable, Decodable) or to be removed after a new snapshot (Show). 131 | syn keyword reasonDeriveTrait contained Clone Hash RustcEncodable RustcDecodable Encodable Decodable PartialEq Eq PartialOrd Ord Rand Show Debug Default FromPrimitive Send Sync Copy 132 | 133 | " Number literals 134 | syn match reasonDecNumber display "\<[0-9][0-9_]*\%([iu]\%(size\|8\|16\|32\|64\)\)\=" 135 | syn match reasonHexNumber display "\<0x[a-fA-F0-9_]\+\%([iu]\%(size\|8\|16\|32\|64\)\)\=" 136 | syn match reasonOctNumber display "\<0o[0-7_]\+\%([iu]\%(size\|8\|16\|32\|64\)\)\=" 137 | syn match reasonBinNumber display "\<0b[01_]\+\%([iu]\%(size\|8\|16\|32\|64\)\)\=" 138 | 139 | " Special case for numbers of the form "1." which are float literals, unless followed by 140 | " an identifier, which makes them integer literals with a method call or field access, 141 | " or by another ".", which makes them integer literals followed by the ".." token. 142 | " (This must go first so the others take precedence.) 143 | syn match reasonFloat display "\<[0-9][0-9_]*\.\%([^[:cntrl:][:space:][:punct:][:digit:]]\|_\|\.\)\@!" 144 | " To mark a number as a normal float, it must have at least one of the three things integral values don't have: 145 | " a decimal point and more numbers; an exponent; and a type suffix. 146 | syn match reasonFloat display "\<[0-9][0-9_]*\%(\.[0-9][0-9_]*\)\%([eE][+-]\=[0-9_]\+\)\=\(f32\|f64\)\=" 147 | syn match reasonFloat display "\<[0-9][0-9_]*\%(\.[0-9][0-9_]*\)\=\%([eE][+-]\=[0-9_]\+\)\(f32\|f64\)\=" 148 | syn match reasonFloat display "\<[0-9][0-9_]*\%(\.[0-9][0-9_]*\)\=\%([eE][+-]\=[0-9_]\+\)\=\(f32\|f64\)" 149 | 150 | " For the benefit of delimitMate 151 | 152 | syn match reasonCharacterInvalid display contained /b\?'\zs[\n\r\t']\ze'/ 153 | " The groups negated here add up to 0-255 but nothing else (they do not seem to go beyond ASCII). 154 | syn match reasonCharacterInvalidUnicode display contained /b'\zs[^[:cntrl:][:graph:][:alnum:][:space:]]\ze'/ 155 | syn match reasonCharacter /b'\([^\\]\|\\\(.\|x\x\{2}\)\)'/ contains=reasonEscape,reasonEscapeError,reasonCharacterInvalid,reasonCharacterInvalidUnicode 156 | syn match reasonCharacter /'\([^\\]\|\\\(.\|x\x\{2}\|u\x\{4}\|U\x\{8}\|u{\x\{1,6}}\)\)'/ contains=reasonEscape,reasonEscapeUnicode,reasonEscapeError,reasonCharacterInvalid 157 | 158 | syn match reasonShebang /\%^#![^[].*/ 159 | syn region reasonCommentLine start="//" end="$" contains=reasonTodo,@Spell 160 | syn region reasonCommentLineDoc start="//\%(//\@!\|!\)" end="$" contains=reasonTodo,@Spell 161 | syn region reasonCommentBlock matchgroup=reasonCommentBlock start="/\*\%(!\|\*[*/]\@!\)\@!" end="\*/" contains=reasonTodo,reasonCommentBlockNest,@Spell 162 | syn region reasonCommentBlockDoc matchgroup=reasonCommentBlockDoc start="/\*\%(!\|\*[*/]\@!\)" end="\*/" contains=reasonTodo,reasonCommentBlockDocNest,@Spell 163 | syn region reasonCommentBlockNest matchgroup=reasonCommentBlock start="/\*" end="\*/" contains=reasonTodo,reasonCommentBlockNest,@Spell contained transparent 164 | syn region reasonCommentBlockDocNest matchgroup=reasonCommentBlockDoc start="/\*" end="\*/" contains=reasonTodo,reasonCommentBlockDocNest,@Spell contained transparent 165 | " FIXME: this is a really ugly and not fully correct implementation. Most 166 | " importantly, a case like ``/* */*`` should have the final ``*`` not being in 167 | " a comment, but in practice at present it leaves comments open two levels 168 | " deep. But as long as you stay away from that particular case, I *believe* 169 | " the highlighting is correct. Due to the way Vim's syntax engine works 170 | " (greedy for start matches, unlike Rust's tokeniser which is searching for 171 | " the earliest-starting match, start or end), I believe this cannot be solved. 172 | " Oh you who would fix it, don't bother with things like duplicating the Block 173 | " rules and putting ``\*\@ 4 | "Portions Copyright (c) 2015-present, Facebook, Inc. All rights reserved. 5 | " 6 | " See for details on how to add an external Syntastic checker: 7 | " https://github.com/scrooloose/syntastic/wiki/Syntax-Checker-Guide#external 8 | " Based on the OCaml syntastic plugin. 9 | " Portions Copyright (c) 2015-present, Facebook, Inc. All rights reserved 10 | 11 | function! SyntaxCheckers_reason_merlin_IsAvailable() 12 | if !exists("*merlin#SelectBinary") 13 | return 0 14 | endif 15 | let l:path = "" 16 | try 17 | if !exists("b:merlin_binary") 18 | let l:path = merlin#SelectBinary() 19 | else 20 | let l:path = b:merlin_binary 21 | endif 22 | catch 23 | return 0 24 | endtry 25 | if exists("b:merlin_path") 26 | let l:path = b:merlin_path 27 | endif 28 | return executable(l:path) 29 | endfunction 30 | 31 | function! SyntaxCheckers_reason_merlin_GetLocList() 32 | return merlin#ErrorLocList() 33 | endfunction 34 | 35 | call g:SyntasticRegistry.CreateAndRegisterChecker({ 36 | \ 'filetype': 'reason', 37 | \ 'name': 'merlin'}) 38 | 39 | --------------------------------------------------------------------------------