aboutsummaryrefslogtreecommitdiff
path: root/scripts/genvimvim.lua
blob: 868084a58339832e635039a733111ef62f41a866 (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
local mpack = require('mpack')

if arg[1] == '--help' then
  print('Usage: lua genvimvim.lua src/nvim runtime/syntax/vim/generated.vim')
  os.exit(0)
end

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

package.path = nvimsrcdir .. '/?.lua;' .. package.path

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 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 '
w(vimcmd_start)
local prev_cmd = nil
for _, cmd_desc in ipairs(ex_cmds.cmds) do
  if lld.line_length > 850 then
    w('\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
  prev_cmd = cmd
end

local vimopt_start = 'syn keyword vimOption contained '
w('\n\n' .. vimopt_start)

for _, opt_desc in ipairs(options.options) do
  if not opt_desc.varname or opt_desc.varname:sub(1, 7) ~= 'p_force' then
    if lld.line_length > 850 then
      w('\n' .. vimopt_start)
    end
    w(' ' .. opt_desc.full_name)
    if opt_desc.abbreviation then
      w(' ' .. opt_desc.abbreviation)
    end
    if opt_desc.type == 'bool' 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('\n\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 not auevents.nvim_specific[au] then
    if lld.line_length > 850 then
      w('\n' .. vimau_start)
    end
    w(' ' .. au)
  end
end

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

for au, _ in pairs(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.unpack(io.open(funcs_file, 'rb'):read("*all"))
for name, _ in pairs(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()