aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/generators/gen_vimvim.lua
blob: d8053822bf63da684efc41bcae022132886ff40d (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
local mpack = vim.mpack

local syntax_file = arg[1]
local funcs_file = arg[2]

local lld = {}
local syn_fd = io.open(syntax_file, 'w')
lld.line_length = 0
local function w(s)
  syn_fd:write(s)
  if s:find('\n') then
    lld.line_length = #(s:gsub('.*\n', ''))
  else
    lld.line_length = lld.line_length + #s
  end
end

local options = require('options')
local auevents = require('auevents')
local ex_cmds = require('ex_cmds')

local function cmd_kw(prev_cmd, cmd)
  if not prev_cmd then
    return cmd:sub(1, 1) .. '[' .. cmd:sub(2) .. ']'
  else
    local shift = 1
    while cmd:sub(shift, shift) == prev_cmd:sub(shift, shift) do
      shift = shift + 1
    end
    if cmd:sub(1, shift) == 'def' then
      shift = shift + 1
    end
    if shift >= #cmd then
      return cmd
    else
      return cmd:sub(1, shift) .. '[' .. cmd:sub(shift + 1) .. ']'
    end
  end
end

-- Exclude these from the vimCommand keyword list, they are handled specially
-- in syntax/vim.vim (vimAugroupKey, vimAutoCmd, vimGlobal, vimSubst). #9327
local function is_special_cased_cmd(cmd)
  return (
    cmd == 'augroup'
    or cmd == 'autocmd'
    or cmd == 'doautocmd'
    or cmd == 'doautoall'
    or cmd == 'global'
    or cmd == 'substitute'
  )
end

local vimcmd_start = 'syn keyword vimCommand contained '
local vimcmd_end = ' nextgroup=vimBang'
w(vimcmd_start)

local prev_cmd = nil
for _, cmd_desc in ipairs(ex_cmds.cmds) do
  if lld.line_length > 850 then
    w(vimcmd_end .. '\n' .. vimcmd_start)
  end
  local cmd = cmd_desc.command
  if cmd:match('%w') and cmd ~= 'z' and not is_special_cased_cmd(cmd) then
    w(' ' .. cmd_kw(prev_cmd, cmd))
  end
  if cmd == 'delete' then
    -- Add special abbreviations of :delete
    w(' ' .. cmd_kw('d', 'dl'))
    w(' ' .. cmd_kw('del', 'dell'))
    w(' ' .. cmd_kw('dele', 'delel'))
    w(' ' .. cmd_kw('delet', 'deletl'))
    w(' ' .. cmd_kw('delete', 'deletel'))
    w(' ' .. cmd_kw('d', 'dp'))
    w(' ' .. cmd_kw('de', 'dep'))
    w(' ' .. cmd_kw('del', 'delp'))
    w(' ' .. cmd_kw('dele', 'delep'))
    w(' ' .. cmd_kw('delet', 'deletp'))
    w(' ' .. cmd_kw('delete', 'deletep'))
  end
  prev_cmd = cmd
end

w(vimcmd_end .. '\n')

local vimopt_start = 'syn keyword vimOption contained '
local vimopt_end = ' skipwhite nextgroup=vimSetEqual,vimSetMod'
w('\n' .. vimopt_start)

for _, opt_desc in ipairs(options.options) do
  if not opt_desc.immutable then
    if lld.line_length > 850 then
      w(vimopt_end .. '\n' .. vimopt_start)
    end
    w(' ' .. opt_desc.full_name)
    if opt_desc.abbreviation then
      w(' ' .. opt_desc.abbreviation)
    end
    if opt_desc.type == 'boolean' then
      w(' inv' .. opt_desc.full_name)
      w(' no' .. opt_desc.full_name)
      if opt_desc.abbreviation then
        w(' inv' .. opt_desc.abbreviation)
        w(' no' .. opt_desc.abbreviation)
      end
    end
  end
end

w(vimopt_end .. '\n')

w('\nsyn case ignore')
local vimau_start = 'syn keyword vimAutoEvent contained '
w('\n\n' .. vimau_start)

for _, au in ipairs(auevents.events) do
  if not auevents.nvim_specific[au] then
    if lld.line_length > 850 then
      w('\n' .. vimau_start)
    end
    w(' ' .. au)
  end
end
for _, au in pairs(auevents.aliases) do
  if lld.line_length > 850 then
    w('\n' .. vimau_start)
  end
  -- au[1] is aliased to au[2]
  w(' ' .. au[1])
end

local nvimau_start = 'syn keyword nvimAutoEvent contained '
w('\n\n' .. nvimau_start)

for au, _ in vim.spairs(auevents.nvim_specific) do
  if lld.line_length > 850 then
    w('\n' .. nvimau_start)
  end
  w(' ' .. au)
end

w('\n\nsyn case match')
local vimfun_start = 'syn keyword vimFuncName contained '
w('\n\n' .. vimfun_start)
local funcs = mpack.decode(io.open(funcs_file, 'rb'):read('*all'))
for _, name in ipairs(funcs) do
  if name then
    if lld.line_length > 850 then
      w('\n' .. vimfun_start)
    end
    w(' ' .. name)
  end
end

w('\n')
syn_fd:close()