1if arg[1] == '--help' then 2 print('Usage: genoptions.lua src/nvim options_file') 3 os.exit(0) 4end 5 6local nvimsrcdir = arg[1] 7local options_file = arg[2] 8 9package.path = nvimsrcdir .. '/?.lua;' .. package.path 10 11local opt_fd = io.open(options_file, 'w') 12 13local w = function(s) 14 if s:match('^ %.') then 15 opt_fd:write(s .. ',\n') 16 else 17 opt_fd:write(s .. '\n') 18 end 19end 20 21local options = require('options') 22 23local cstr = options.cstr 24 25local type_flags={ 26 bool='P_BOOL', 27 number='P_NUM', 28 string='P_STRING', 29} 30 31local redraw_flags={ 32 statuslines='P_RSTAT', 33 current_window='P_RWIN', 34 current_window_only='P_RWINONLY', 35 current_buffer='P_RBUF', 36 all_windows='P_RALL', 37 everything='P_RCLR', 38 curswant='P_CURSWANT', 39 ui_option='P_UI_OPTION', 40} 41 42local list_flags={ 43 comma='P_COMMA', 44 onecomma='P_ONECOMMA', 45 flags='P_FLAGLIST', 46 flagscomma='P_COMMA|P_FLAGLIST', 47} 48 49local get_flags = function(o) 50 local ret = {type_flags[o.type]} 51 local add_flag = function(f) 52 ret[1] = ret[1] .. '|' .. f 53 end 54 if o.list then 55 add_flag(list_flags[o.list]) 56 end 57 if o.redraw then 58 for _, r_flag in ipairs(o.redraw) do 59 add_flag(redraw_flags[r_flag]) 60 end 61 end 62 if o.expand then 63 add_flag('P_EXPAND') 64 if o.expand == 'nodefault' then 65 add_flag('P_NO_DEF_EXP') 66 end 67 end 68 for _, flag_desc in ipairs({ 69 {'alloced'}, 70 {'nodefault'}, 71 {'no_mkrc'}, 72 {'secure'}, 73 {'gettext'}, 74 {'noglob'}, 75 {'normal_fname_chars', 'P_NFNAME'}, 76 {'normal_dname_chars', 'P_NDNAME'}, 77 {'pri_mkrc'}, 78 {'deny_in_modelines', 'P_NO_ML'}, 79 {'deny_duplicates', 'P_NODUP'}, 80 {'modelineexpr', 'P_MLE'}, 81 }) do 82 local key_name = flag_desc[1] 83 local def_name = flag_desc[2] or ('P_' .. key_name:upper()) 84 if o[key_name] then 85 add_flag(def_name) 86 end 87 end 88 return ret[1] 89end 90 91local get_cond 92get_cond = function(c, base_string) 93 local cond_string = base_string or '#if ' 94 if type(c) == 'table' then 95 cond_string = cond_string .. get_cond(c[1], '') 96 for i, subc in ipairs(c) do 97 if i > 1 then 98 cond_string = cond_string .. ' && ' .. get_cond(subc, '') 99 end 100 end 101 elseif c:sub(1, 1) == '!' then 102 cond_string = cond_string .. '!defined(' .. c:sub(2) .. ')' 103 else 104 cond_string = cond_string .. 'defined(' .. c .. ')' 105 end 106 return cond_string 107end 108 109local value_dumpers = { 110 ['function']=function(v) return v() end, 111 string=cstr, 112 boolean=function(v) return v and 'true' or 'false' end, 113 number=function(v) return ('%iL'):format(v) end, 114 ['nil']=function(_) return '0L' end, 115} 116 117local get_value = function(v) 118 return '(char_u *) ' .. value_dumpers[type(v)](v) 119end 120 121local get_defaults = function(d,n) 122 if d == nil then 123 error("option '"..n.."' should have a default value") 124 end 125 return get_value(d) 126end 127 128local defines = {} 129 130local dump_option = function(i, o) 131 w(' [' .. ('%u'):format(i - 1) .. ']={') 132 w(' .fullname=' .. cstr(o.full_name)) 133 if o.abbreviation then 134 w(' .shortname=' .. cstr(o.abbreviation)) 135 end 136 w(' .flags=' .. get_flags(o)) 137 if o.enable_if then 138 w(get_cond(o.enable_if)) 139 end 140 if o.varname then 141 w(' .var=(char_u *)&' .. o.varname) 142 elseif #o.scope == 1 and o.scope[1] == 'window' then 143 w(' .var=VAR_WIN') 144 end 145 if #o.scope == 1 and o.scope[1] == 'global' then 146 w(' .indir=PV_NONE') 147 else 148 assert (#o.scope == 1 or #o.scope == 2) 149 assert (#o.scope == 1 or o.scope[1] == 'global') 150 local min_scope = o.scope[#o.scope] 151 local varname = o.pv_name or o.varname or ( 152 'p_' .. (o.abbreviation or o.full_name)) 153 local pv_name = ( 154 'OPT_' .. min_scope:sub(1, 3):upper() .. '(' .. ( 155 min_scope:sub(1, 1):upper() .. 'V_' .. varname:sub(3):upper() 156 ) .. ')' 157 ) 158 if #o.scope == 2 then 159 pv_name = 'OPT_BOTH(' .. pv_name .. ')' 160 end 161 defines['PV_' .. varname:sub(3):upper()] = pv_name 162 w(' .indir=' .. pv_name) 163 end 164 if o.enable_if then 165 w('#else') 166 w(' .var=NULL') 167 w(' .indir=PV_NONE') 168 w('#endif') 169 end 170 if o.defaults then 171 if o.defaults.condition then 172 w(get_cond(o.defaults.condition)) 173 end 174 w(' .def_val=' .. get_defaults(o.defaults.if_true, o.full_name)) 175 if o.defaults.condition then 176 if o.defaults.if_false then 177 w('#else') 178 w(' .def_val=' .. get_defaults(o.defaults.if_false, o.full_name)) 179 end 180 w('#endif') 181 end 182 end 183 w(' },') 184end 185 186w('static vimoption_T options[] = {') 187for i, o in ipairs(options.options) do 188 dump_option(i, o) 189end 190w(' [' .. ('%u'):format(#options.options) .. ']={.fullname=NULL}') 191w('};') 192w('') 193 194for k, v in pairs(defines) do 195 w('#define ' .. k .. ' ' .. v) 196end 197opt_fd:close() 198