xref: /vim-8.2.3635/runtime/syntax/dircolors.vim (revision 22f1d0e3)
1" Vim syntax file
2" Language:        dircolors(1) input file
3" Maintainer:      Jan Larres <[email protected]>
4" Previous Maintainer: Nikolai Weibull <[email protected]>
5" Latest Revision: 2018-02-19
6
7if exists("b:current_syntax")
8    finish
9endif
10
11let s:cpo_save = &cpo
12set cpo&vim
13
14syntax keyword dircolorsTodo    FIXME TODO XXX NOTE contained
15
16syntax region  dircolorsComment start='#' end='$' contains=dircolorsTodo,@Spell
17
18syntax keyword dircolorsKeyword TERM LEFT LEFTCODE RIGHT RIGHTCODE END ENDCODE
19
20syntax keyword dircolorsKeyword NORMAL NORM FILE RESET DIR LNK LINK SYMLINK
21                              \ MULTIHARDLINK FIFO SOCK DOOR BLK CHR ORPHAN
22                              \ MISSING PIPE BLOCK CHR EXEC SETUID SETGID
23                              \ CAPABILITY STICKY_OTHER_WRITABLE
24                              \ OTHER_WRITABLE STICKY
25
26" Slackware only, ignored by GNU dircolors.
27syntax keyword dircolorsKeyword COLOR OPTIONS EIGHTBIT
28
29syntax match dircolorsExtension '^\s*\zs[.*]\S\+'
30
31syntax match dircolorsEscape '\\[abefnrtv?_\\^#]'
32syntax match dircolorsEscape '\\[0-9]\{3}'
33syntax match dircolorsEscape '\\x[0-9a-f]\{3}'
34
35if !has('gui_running') && &t_Co == ''
36    syntax match dircolorsNumber '\<\d\+\>'
37    highlight default link dircolorsNumber Number
38endif
39
40highlight default link dircolorsTodo      Todo
41highlight default link dircolorsComment   Comment
42highlight default link dircolorsKeyword   Keyword
43highlight default link dircolorsExtension Identifier
44highlight default link dircolorsEscape    Special
45
46function! s:set_guicolors() abort
47    let s:termguicolors = {}
48
49    let s:termguicolors[0]  = "Black"
50    let s:termguicolors[1]  = "DarkRed"
51    let s:termguicolors[2]  = "DarkGreen"
52    let s:termguicolors[3]  = "DarkYellow"
53    let s:termguicolors[4]  = "DarkBlue"
54    let s:termguicolors[5]  = "DarkMagenta"
55    let s:termguicolors[6]  = "DarkCyan"
56    let s:termguicolors[7]  = "Gray"
57    let s:termguicolors[8]  = "DarkGray"
58    let s:termguicolors[9]  = "Red"
59    let s:termguicolors[10] = "Green"
60    let s:termguicolors[11] = "Yellow"
61    let s:termguicolors[12] = "Blue"
62    let s:termguicolors[13] = "Magenta"
63    let s:termguicolors[14] = "Cyan"
64    let s:termguicolors[15] = "White"
65
66    let xterm_palette = ["00", "5f", "87", "af", "d7", "ff"]
67
68    let cur_col = 16
69
70    for r in xterm_palette
71        for g in xterm_palette
72            for b in xterm_palette
73                let s:termguicolors[cur_col] = '#' . r . g . b
74                let cur_col += 1
75            endfor
76        endfor
77    endfor
78
79    for i in range(24)
80        let g = i * 0xa + 8
81        let s:termguicolors[i + 232] = '#' . g . g . g
82    endfor
83endfunction
84
85function! s:get_hi_str(color, place) abort
86    if a:color >= 0 && a:color <= 255
87        if has('gui_running')
88            return ' gui' . a:place . '=' . s:termguicolors[a:color]
89        elseif a:color <= 7 || &t_Co == 256 || &t_Co == 88
90            return ' cterm' . a:place . '=' . a:color
91        endif
92    endif
93    return ''
94endfunction
95
96function! s:get_256color(colors) abort
97    if len(a:colors) >= 2 " May be fewer while editing
98        let [_five, color] = remove(a:colors, 0, 1)
99        if _five != '5' || color == ''
100            return -1
101        else
102            return str2nr(color)
103        endif
104    else
105        return -1
106    endif
107endfunction
108
109function! s:preview_color(linenr) abort
110    let line = getline(a:linenr)
111    let defline = matchlist(line, '^\v([A-Z_]+|[*.]\S+)\s+([0-9;]+)')
112    if empty(defline)
113        return
114    endif
115
116    let colordef = defline[2]
117
118    let colors = split(colordef, ';')
119
120    let hi_str = ''
121    let hi_attrs = []
122    while len(colors) > 0
123        let item = str2nr(remove(colors, 0))
124        if item == 1
125            call add(hi_attrs, 'bold')
126        elseif item == 3
127            call add(hi_attrs, 'italic')
128        elseif item == 4
129            call add(hi_attrs, 'underline')
130        elseif item == 7
131            call add(hi_attrs, 'inverse')
132        elseif item >= 30 && item <= 37
133            " ANSI SGR foreground color
134            let hi_str .= s:get_hi_str(item - 30, 'fg')
135        elseif item >= 40 && item <= 47
136            " ANSI SGR background color
137            let hi_str .= s:get_hi_str(item - 40, 'bg')
138        elseif item >= 90 && item <= 97
139            " ANSI SGR+8 foreground color (xterm 16-color support)
140            let hi_str .= s:get_hi_str(item - 82, 'fg')
141        elseif item >= 100 && item <= 107
142            " ANSI SGR+8 background color (xterm 16-color support)
143            let hi_str .= s:get_hi_str(item - 92, 'bg')
144        elseif item == 38
145            " Foreground for terminals with 88/256 color support
146            let color = s:get_256color(colors)
147            if color == -1
148                break
149            endif
150            let hi_str .= s:get_hi_str(color, 'fg')
151        elseif item == 48
152            " Background for terminals with 88/256 color support
153            let color = s:get_256color(colors)
154            if color == -1
155                break
156            endif
157            let hi_str .= s:get_hi_str(color, 'bg')
158        endif
159    endwhile
160
161    if hi_str == '' && empty(hi_attrs)
162        return
163    endif
164
165    " Check whether we have already defined this color
166    redir => s:currentmatch
167    silent! execute 'syntax list'
168    redir END
169
170    if s:currentmatch !~# '\/\\_s\\zs' . colordef . '\\ze\\_s\/'
171        " Append the buffer number to avoid problems with other dircolors
172        " buffers interfering
173        let bufnr = bufnr('%')
174        execute 'syntax match dircolorsColor' . b:dc_next_index . '_' . bufnr .
175              \ ' "\_s\zs' . colordef . '\ze\_s"'
176        let hi_attrs_str = ''
177        if !empty(hi_attrs)
178            if has('gui_running')
179                let hi_attrs_str = ' gui=' . join(hi_attrs, ',')
180            else
181                let hi_attrs_str = ' cterm=' . join(hi_attrs, ',')
182            endif
183        endif
184        execute 'highlight default dircolorsColor' . b:dc_next_index . '_' .
185              \ bufnr . hi_str . hi_attrs_str
186        let b:dc_next_index += 1
187    endif
188endfunction
189
190" Avoid accumulating too many definitions while editing
191function! s:reset_colors() abort
192    if b:dc_next_index > 0
193        let bufnr = bufnr('%')
194        for i in range(b:dc_next_index)
195            execute 'syntax clear dircolorsColor' . i . '_' . bufnr
196            execute 'highlight clear dircolorsColor' . i . '_' . bufnr
197        endfor
198        let b:dc_next_index = 0
199    endif
200
201    for linenr in range(1, line('$'))
202        call s:preview_color(linenr)
203    endfor
204endfunction
205
206let b:dc_next_index = 0
207
208if has('gui_running')
209    call s:set_guicolors()
210endif
211
212if has('gui_running') || &t_Co != ''
213    call s:reset_colors()
214
215    autocmd CursorMoved,CursorMovedI <buffer> call s:preview_color('.')
216    autocmd CursorHold,CursorHoldI   <buffer> call s:reset_colors()
217endif
218
219let b:current_syntax = "dircolors"
220
221let &cpo = s:cpo_save
222unlet s:cpo_save
223