Skip to content

Commit 0626cc9

Browse files
committed
Change fish provider, closes #626
1 parent 8af4f8e commit 0626cc9

File tree

6 files changed

+134
-35
lines changed

6 files changed

+134
-35
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ On top of all language packs from [vim repository](https://github.com/vim/vim/tr
7878
- [erlang](https://github.com/vim-erlang/vim-erlang-runtime) (Erlang syntax highlighting for erl, app.src, es, escript, hrl, xrl, yrl, app and yaws files)
7979
- [fennel](https://github.com/bakpakin/fennel.vim) (Syntax highlighting for fnl files)
8080
- [ferm](https://github.com/vim-scripts/ferm.vim) (Syntax highlighting for ferm files)
81-
- [fish](https://github.com/georgewitteman/vim-fish) (fish syntax highlighting for fish files)
81+
- [fish](https://github.com/blankname/vim-fish) (fish syntax highlighting for fish files)
8282
- [flatbuffers](https://github.com/dcharbon/vim-flatbuffers) (Syntax highlighting for fbs files)
8383
- [fsharp](https://github.com/ionide/Ionide-vim) (F# syntax highlighting for fs, fsi and fsx files)
8484
- [gdscript](https://github.com/calviken/vim-gdscript3) (GDScript syntax highlighting for gd files)

autoload/fish.vim

Lines changed: 99 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -2,44 +2,112 @@ if has_key(g:polyglot_is_disabled, 'fish')
22
finish
33
endif
44

5+
function! s:IsString(lnum, col)
6+
" Returns "true" if syntax item at the given position is part of fishString.
7+
let l:stack = map(synstack(a:lnum, a:col), 'synIDattr(v:val, "name")')
8+
return len(filter(l:stack, 'v:val ==# "fishString"'))
9+
endfunction
10+
11+
function! s:IsContinuedLine(lnum)
12+
" Returns "true" if the given line is a continued line.
13+
return getline(a:lnum - 1) =~ '\v\\$'
14+
endfunction
15+
16+
function! s:FindPrevLnum(lnum)
17+
" Starting on the given line, search backwards for a line that is not
18+
" empty, not part of a string and not a continued line.
19+
if a:lnum < 1 || a:lnum > line('$')
20+
" First line or wrong value, follow prevnonblank() behaviour and
21+
" return zero.
22+
return 0
23+
endif
24+
let l:lnum = prevnonblank(a:lnum)
25+
while l:lnum > 0 && ( s:IsContinuedLine(l:lnum) || s:IsString(l:lnum, 1) )
26+
let l:lnum = prevnonblank(l:lnum - 1)
27+
endwhile
28+
return l:lnum
29+
endfunction
30+
31+
function! s:IsSwitch(lnum)
32+
" Returns "true" if the given line is part of a switch block.
33+
let l:lnum = a:lnum
34+
let l:line = getline(l:lnum)
35+
let l:in_block = 0
36+
let l:stop_pat = '\v^\s*%(if|else|while|for|begin)>'
37+
let l:block_start_pat = '\v^\s*%(if|while|for|switch|begin)>'
38+
while l:lnum > 0
39+
let l:lnum = prevnonblank(l:lnum - 1)
40+
let l:line = getline(l:lnum)
41+
if l:line =~# '\v^\s*end>'
42+
let l:in_block += 1
43+
elseif l:in_block && l:line =~# l:block_start_pat
44+
let l:in_block -= 1
45+
elseif !l:in_block && l:line =~# l:stop_pat
46+
return 0
47+
elseif !l:in_block && l:line =~# '\v^\s*switch>'
48+
return 1
49+
endif
50+
endwhile
51+
return 0
52+
endfunction
53+
554
function! fish#Indent()
6-
let l:prevlnum = prevnonblank(v:lnum - 1)
7-
if l:prevlnum ==# 0
55+
let l:line = getline(v:lnum)
56+
if s:IsString(v:lnum, 1)
57+
return indent(v:lnum)
58+
endif
59+
" shiftwidth can be misleading in recent versions, use shiftwidth() if
60+
" it is available.
61+
if exists('*shiftwidth')
62+
let l:shiftwidth = shiftwidth()
63+
else
64+
let l:shiftwidth = &shiftwidth
65+
endif
66+
let l:prevlnum = s:FindPrevLnum(v:lnum - 1)
67+
if l:prevlnum == 0
868
return 0
969
endif
70+
let l:shift = 0
1071
let l:prevline = getline(l:prevlnum)
11-
let l:line = getline(v:lnum)
12-
let l:shiftwidth = shiftwidth()
1372
let l:previndent = indent(l:prevlnum)
14-
let l:indent = l:previndent
15-
if l:prevline =~# '\v^\s*%(begin|if|else|while|for|function|switch|case)>'
16-
let l:indent += l:shiftwidth
17-
endif
18-
if l:line =~# '\v^\s*end>'
19-
let l:indent -= l:shiftwidth
20-
" If we're inside a case, dedent twice because it ends the switch.
21-
if l:prevline =~# '\v^\s*case>'
22-
" Previous line starts the case.
23-
let l:indent -= l:shiftwidth
73+
if s:IsContinuedLine(v:lnum)
74+
" It is customary to increment indentation of continued lines by three
75+
" or a custom value defined by the user if available.
76+
let l:previndent = indent(v:lnum - 1)
77+
if s:IsContinuedLine(v:lnum - 1)
78+
return l:previndent
79+
elseif exists('g:fish_indent_cont')
80+
return l:previndent + g:fish_indent_cont
81+
elseif exists('g:indent_cont')
82+
return l:previndent + g:indent_cont
2483
else
25-
" Scan back to a dedented line to find whether we're in a case.
26-
let l:i = l:prevlnum
27-
while l:i >= 1 && indent(l:i) >= l:previndent
28-
let l:i = prevnonblank(l:i - 1)
29-
endwhile
30-
if indent(l:i) < l:previndent && getline(l:i) =~# '\v^\s*case>'
31-
let l:indent -= l:shiftwidth
32-
endif
84+
return l:previndent + 3
3385
endif
34-
elseif l:line =~# '\v^\s*else>'
35-
let l:indent -= l:shiftwidth
36-
elseif l:prevline !~# '\v^\s*switch>' && l:line =~# '\v^\s*case>'
37-
let l:indent -= l:shiftwidth
3886
endif
39-
if l:indent < 0
40-
return 0
87+
if l:prevline =~# '\v^\s*%(begin|if|else|while|for|function|case|switch)>'
88+
" First line inside a block, increase by one.
89+
let l:shift += 1
90+
endif
91+
if l:line =~# '\v^\s*%(end|case|else)>'
92+
" "end", "case" or "else", decrease by one.
93+
let l:shift -= 1
94+
endif
95+
if l:line =~# '\v^\s*<case>' && l:prevline =~# '\v<switch>'
96+
" "case" following "switch", increase by one.
97+
let l:shift += 1
98+
endif
99+
if l:line =~# '\v\s*end>' && s:IsSwitch(v:lnum)
100+
" "end" ends switch block, decrease by one more so it matches
101+
" the indentation of "switch".
102+
let l:shift -= 1
103+
endif
104+
if l:prevline =~# '\v^\s*%(if|while|for|else|switch|end)>.*<begin>'
105+
" "begin" after start of block, increase by one.
106+
let l:shift += 1
41107
endif
42-
return l:indent
108+
let l:indent = l:previndent + l:shift * l:shiftwidth
109+
" Only return zero or positive numbers.
110+
return l:indent < 0 ? 0 : l:indent
43111
endfunction
44112

45113
function! fish#Format()
@@ -49,6 +117,8 @@ function! fish#Format()
49117
let l:command = v:lnum.','.(v:lnum+v:count-1).'!fish_indent'
50118
echo l:command
51119
execute l:command
120+
" Fix indentation and replace tabs with spaces if necessary.
121+
normal! '[=']
52122
endif
53123
endfunction
54124

ftplugin/fish.vim

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,22 @@ if has_key(g:polyglot_is_disabled, 'fish')
22
finish
33
endif
44

5+
if exists('b:did_ftplugin')
6+
finish
7+
end
8+
let b:did_ftplugin = 1
9+
10+
let s:save_cpo = &cpo
11+
set cpo&vim
12+
513
setlocal comments=:#
614
setlocal commentstring=#%s
715
setlocal define=\\v^\\s*function>
816
setlocal foldexpr=fish#Fold()
917
setlocal formatoptions+=ron1
1018
setlocal formatoptions-=t
1119
setlocal include=\\v^\\s*\\.>
20+
setlocal iskeyword=@,48-57,-,_,.
1221
setlocal suffixesadd^=.fish
1322

1423
" Use the 'j' format option when available.
@@ -34,9 +43,27 @@ endif
3443
" argument to fish instead of man.
3544
execute 'setlocal keywordprg=fish\ '.fnameescape(expand('<sfile>:p:h:h').'/bin/man.fish')
3645

37-
let b:match_words =
38-
\ escape('<%(begin|function|if|switch|while|for)>:<end>', '<>%|)')
46+
let b:match_ignorecase = 0
47+
if has('patch-7.3.1037')
48+
let s:if = '%(else\s\+)\@15<!if'
49+
else
50+
let s:if = '%(else\s\+)\@<!if'
51+
endif
52+
53+
let b:match_words = escape(
54+
\'<%(begin|function|'.s:if.'|switch|while|for)>:<else\s\+if|case>:<else>:<end>'
55+
\, '<>%|)')
3956

4057
let b:endwise_addition = 'end'
4158
let b:endwise_words = 'begin,function,if,switch,while,for'
4259
let b:endwise_syngroups = 'fishKeyword,fishConditional,fishRepeat'
60+
61+
let b:undo_ftplugin = "
62+
\ setlocal comments< commentstring< define< foldexpr< formatoptions<
63+
\|setlocal include< iskeyword< suffixesadd<
64+
\|setlocal formatexpr< omnifunc< path< keywordprg<
65+
\|unlet! b:match_words b:endwise_addition b:endwise_words b:endwise_syngroups
66+
\"
67+
68+
let &cpo = s:save_cpo
69+
unlet s:save_cpo

indent/fish.vim

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,5 @@ if has_key(g:polyglot_is_disabled, 'fish')
33
endif
44

55
setlocal indentexpr=fish#Indent()
6+
setlocal indentkeys=!^F,o,O
67
setlocal indentkeys+==end,=else,=case

packages.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -575,7 +575,7 @@ filetypes:
575575
- ferm.conf
576576
---
577577
name: fish
578-
remote: georgewitteman/vim-fish
578+
remote: blankname/vim-fish
579579
filetypes:
580580
- name: fish
581581
linguist: fish

syntax/fish.vim

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ if exists('b:current_syntax')
77
endif
88

99
syntax case match
10+
syntax iskeyword @,48-57,-,_,.,/
1011

1112
syntax keyword fishKeyword begin function end
1213
syntax keyword fishConditional if else switch
@@ -16,8 +17,8 @@ syntax keyword fishLabel case
1617
syntax match fishComment /#.*/
1718
syntax match fishSpecial /\\$/
1819
syntax match fishIdentifier /\$[[:alnum:]_]\+/
19-
syntax region fishString start=/'/ skip=/\\'/ end=/'/
20-
syntax region fishString start=/"/ skip=/\\"/ end=/"/ contains=fishIdentifier
20+
syntax region fishString start=/'/ skip=/\v(\\{2})|(\\)'/ end=/'/
21+
syntax region fishString start=/"/ skip=/\v(\\{2})|(\\)"/ end=/"/ contains=fishIdentifier
2122
syntax match fishCharacter /\v\\[abefnrtv *?~%#(){}\[\]<>&;"']|\\[xX][0-9a-f]{1,2}|\\o[0-7]{1,2}|\\u[0-9a-f]{1,4}|\\U[0-9a-f]{1,8}|\\c[a-z]/
2223
syntax match fishStatement /\v;\s*\zs\k+>/
2324
syntax match fishCommandSub /\v\(\s*\zs\k+>/

0 commit comments

Comments
 (0)