aboutsummaryrefslogtreecommitdiff
path: root/scripts
diff options
context:
space:
mode:
Diffstat (limited to 'scripts')
-rw-r--r--scripts/gen_events.lua65
-rw-r--r--scripts/genoptions.lua183
-rw-r--r--scripts/genvimvim.lua138
-rw-r--r--scripts/msgpack-gen.lua6
-rwxr-xr-xscripts/vim-patch.sh172
5 files changed, 518 insertions, 46 deletions
diff --git a/scripts/gen_events.lua b/scripts/gen_events.lua
new file mode 100644
index 0000000000..75e0b3da3a
--- /dev/null
+++ b/scripts/gen_events.lua
@@ -0,0 +1,65 @@
+if arg[1] == '--help' then
+ print('Usage: gen_events.lua src/nvim enum_file event_names_file')
+ os.exit(0)
+end
+
+local nvimsrcdir = arg[1]
+local fileio_enum_file = arg[2]
+local names_file = arg[3]
+
+package.path = nvimsrcdir .. '/?.lua;' .. package.path
+
+local auevents = require('auevents')
+local events = auevents.events
+local aliases = auevents.aliases
+
+enum_tgt = io.open(fileio_enum_file, 'w')
+names_tgt = io.open(names_file, 'w')
+
+enum_tgt:write('typedef enum auto_event {')
+names_tgt:write([[
+static const struct event_name {
+ size_t len;
+ char *name;
+ event_T event;
+} event_names[] = {]])
+
+for i, event in ipairs(events) do
+ if i > 1 then
+ comma = ',\n'
+ else
+ comma = '\n'
+ end
+ enum_tgt:write(('%s EVENT_%s = %u'):format(comma, event:upper(), i - 1))
+ names_tgt:write(('%s {%u, "%s", EVENT_%s}'):format(comma, #event, event, event:upper()))
+end
+
+for alias, event in pairs(aliases) do
+ names_tgt:write((',\n {%u, "%s", EVENT_%s}'):format(#alias, alias, event:upper()))
+end
+
+names_tgt:write(',\n {0, NULL, (event_T)0}')
+
+enum_tgt:write('\n} event_T;\n')
+names_tgt:write('\n};\n')
+
+enum_tgt:write(('\n#define NUM_EVENTS %u\n'):format(#events))
+names_tgt:write('\nstatic AutoPat *first_autopat[NUM_EVENTS] = {\n ')
+line_len = 1
+for i = 1,((#events) - 1) do
+ line_len = line_len + #(' NULL,')
+ if line_len > 80 then
+ names_tgt:write('\n ')
+ line_len = 1 + #(' NULL,')
+ end
+ names_tgt:write(' NULL,')
+end
+if line_len + #(' NULL') > 80 then
+ names_tgt:write('\n NULL')
+else
+ names_tgt:write(' NULL')
+end
+names_tgt:write('\n};\n')
+
+enum_tgt:close()
+names_tgt:close()
diff --git a/scripts/genoptions.lua b/scripts/genoptions.lua
new file mode 100644
index 0000000000..2859ca1795
--- /dev/null
+++ b/scripts/genoptions.lua
@@ -0,0 +1,183 @@
+if arg[1] == '--help' then
+ print('Usage: genoptions.lua src/nvim options_file')
+ os.exit(0)
+end
+
+local nvimsrcdir = arg[1]
+local options_file = arg[2]
+
+package.path = nvimsrcdir .. '/?.lua;' .. package.path
+
+local opt_fd = io.open(options_file, 'w')
+
+local w = function(s)
+ if s:match('^ %.') then
+ opt_fd:write(s .. ',\n')
+ else
+ opt_fd:write(s .. '\n')
+ end
+end
+
+local options = require('options')
+
+cstr = options.cstr
+
+local type_flags={
+ bool='P_BOOL',
+ number='P_NUM',
+ string='P_STRING',
+}
+
+local redraw_flags={
+ statuslines='P_RSTAT',
+ current_window='P_RWIN',
+ current_buffer='P_RBUF',
+ all_windows='P_RALL',
+ everything='P_RCLR',
+ curswant='P_CURSWANT',
+}
+
+local list_flags={
+ comma='P_COMMA',
+ flags='P_FLAGLIST',
+ flagscomma='P_COMMA|P_FLAGLIST',
+}
+
+local get_flags = function(o)
+ local ret = {type_flags[o.type]}
+ local add_flag = function(f)
+ ret[1] = ret[1] .. '|' .. f
+ end
+ if o.list then
+ add_flag(list_flags[o.list])
+ end
+ if o.redraw then
+ for _, r_flag in ipairs(o.redraw) do
+ add_flag(redraw_flags[r_flag])
+ end
+ end
+ for _, flag_desc in ipairs({
+ {'alloced'},
+ {'expand'},
+ {'nodefault'},
+ {'no_mkrc'},
+ {'vi_def'},
+ {'vim'},
+ {'secure'},
+ {'gettext'},
+ {'noglob'},
+ {'normal_fname_chars', 'P_NFNAME'},
+ {'pri_mkrc'},
+ {'deny_in_modelines', 'P_NO_ML'},
+ {'deny_duplicates', 'P_NODUP'},
+ }) do
+ local key_name = flag_desc[1]
+ local def_name = flag_desc[2] or ('P_' .. key_name:upper())
+ if o[key_name] then
+ add_flag(def_name)
+ end
+ end
+ return ret[1]
+end
+
+local get_cond
+get_cond = function(c, base_string)
+ local cond_string = base_string or '#if '
+ if type(c) == 'table' then
+ cond_string = cond_string .. get_cond(c[1], '')
+ for i, subc in ipairs(c) do
+ if i > 1 then
+ cond_string = cond_string .. ' && ' .. get_cond(subc, '')
+ end
+ end
+ elseif c:sub(1, 1) == '!' then
+ cond_string = cond_string .. '!defined(' .. c:sub(2) .. ')'
+ else
+ cond_string = cond_string .. 'defined(' .. c .. ')'
+ end
+ return cond_string
+end
+
+value_dumpers = {
+ ['function']=function(v) return v() end,
+ string=cstr,
+ boolean=function(v) return v and 'true' or 'false' end,
+ number=function(v) return ('%iL'):format(v) end,
+ ['nil']=function(v) return '0L' end,
+}
+
+local get_value = function(v)
+ return '(char_u *) ' .. value_dumpers[type(v)](v)
+end
+
+local get_defaults = function(d)
+ return '{' .. get_value(d.vi) .. ', ' .. get_value(d.vim) .. '}'
+end
+
+local defines = {}
+
+local dump_option = function(i, o)
+ w(' [' .. ('%u'):format(i - 1) .. ']={')
+ w(' .fullname=' .. cstr(o.full_name))
+ if o.abbreviation then
+ w(' .shortname=' .. cstr(o.abbreviation))
+ end
+ w(' .flags=' .. get_flags(o))
+ if o.enable_if then
+ w(get_cond(o.enable_if))
+ end
+ if o.varname then
+ w(' .var=(char_u *)&' .. o.varname)
+ elseif #o.scope == 1 and o.scope[1] == 'window' then
+ w(' .var=VAR_WIN')
+ end
+ if o.enable_if then
+ w('#endif')
+ end
+ if #o.scope == 1 and o.scope[1] == 'global' then
+ w(' .indir=PV_NONE')
+ else
+ assert (#o.scope == 1 or #o.scope == 2)
+ assert (#o.scope == 1 or o.scope[1] == 'global')
+ local min_scope = o.scope[#o.scope]
+ local varname = o.pv_name or o.varname or (
+ 'p_' .. (o.abbreviation or o.full_name))
+ local pv_name = (
+ 'OPT_' .. min_scope:sub(1, 3):upper() .. '(' .. (
+ min_scope:sub(1, 1):upper() .. 'V_' .. varname:sub(3):upper()
+ ) .. ')'
+ )
+ if #o.scope == 2 then
+ pv_name = 'OPT_BOTH(' .. pv_name .. ')'
+ end
+ defines['PV_' .. varname:sub(3):upper()] = pv_name
+ w(' .indir=' .. pv_name)
+ end
+ if o.defaults then
+ if o.defaults.condition then
+ w(get_cond(o.defaults.condition))
+ end
+ w(' .def_val=' .. get_defaults(o.defaults.if_true))
+ if o.defaults.condition then
+ if o.defaults.if_false then
+ w('#else')
+ w(' .def_val=' .. get_defaults(o.defaults.if_false))
+ end
+ w('#endif')
+ end
+ end
+ w(' },')
+end
+
+w('static vimoption_T options[] = {')
+for i, o in ipairs(options.options) do
+ dump_option(i, o)
+end
+w(' [' .. ('%u'):format(#options.options) .. ']={.fullname=NULL}')
+w('};')
+w('')
+
+for k, v in pairs(defines) do
+ w('#define ' .. k .. ' ' .. v)
+end
+opt_fd:close()
diff --git a/scripts/genvimvim.lua b/scripts/genvimvim.lua
new file mode 100644
index 0000000000..9135c8e3ab
--- /dev/null
+++ b/scripts/genvimvim.lua
@@ -0,0 +1,138 @@
+if arg[1] == '--help' then
+ print('Usage: genoptions.lua src/nvim runtime/syntax/vim/generated.vim')
+ os.exit(0)
+end
+
+local nvimsrcdir = arg[1]
+local syntax_file = arg[2]
+
+package.path = nvimsrcdir .. '/?.lua;' .. package.path
+
+local lld = {}
+local syn_fd = io.open(syntax_file, 'w')
+lld.line_length = 0
+local w = function(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 cmd_kw = function(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
+
+vimcmd_start = 'syn keyword vimCommand contained '
+w(vimcmd_start)
+local prev_cmd = nil
+for _, cmd_desc in ipairs(ex_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' 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.neovim_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.neovim_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.neovim_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)
+eval_fd = io.open(nvimsrcdir .. '/eval.c', 'r')
+local started = 0
+for line in eval_fd:lines() do
+ if line == '} functions[] =' then
+ started = 1
+ elseif started == 1 then
+ assert (line == '{')
+ started = 2
+ elseif started == 2 then
+ if line == '};' then
+ break
+ end
+ local func_name = line:match('^ {"(%w+)",')
+ if func_name then
+ if lld.line_length > 850 then
+ w('\n' .. vimfun_start)
+ end
+ w(' ' .. func_name)
+ end
+ end
+end
+eval_fd:close()
+
+w('\n')
+syn_fd:close()
diff --git a/scripts/msgpack-gen.lua b/scripts/msgpack-gen.lua
index bb37ae94da..581641ae06 100644
--- a/scripts/msgpack-gen.lua
+++ b/scripts/msgpack-gen.lua
@@ -34,8 +34,8 @@ c_params = Ct(c_void + c_param_list)
c_proto = Ct(
Cg(c_type, 'return_type') * Cg(c_id, 'name') *
fill * P('(') * fill * Cg(c_params, 'parameters') * fill * P(')') *
- Cg(Cc(false), 'deferred') *
- (fill * Cg((P('FUNC_ATTR_DEFERRED') * Cc(true)), 'deferred') ^ -1) *
+ Cg(Cc(false), 'async') *
+ (fill * Cg((P('FUNC_ATTR_ASYNC') * Cc(true)), 'async') ^ -1) *
fill * P(';')
)
grammar = Ct((c_proto + c_comment + c_preproc + ws) ^ 1)
@@ -279,7 +279,7 @@ for i = 1, #functions do
'(String) {.data = "'..fn.name..'", '..
'.size = sizeof("'..fn.name..'") - 1}, '..
'(MsgpackRpcRequestHandler) {.fn = handle_'.. fn.name..
- ', .defer = '..tostring(fn.deferred)..'});\n')
+ ', .async = '..tostring(fn.async)..'});\n')
if #fn.name > max_fname_len then
max_fname_len = #fn.name
diff --git a/scripts/vim-patch.sh b/scripts/vim-patch.sh
index f17b23101d..9ae9377d8f 100755
--- a/scripts/vim-patch.sh
+++ b/scripts/vim-patch.sh
@@ -1,6 +1,7 @@
#!/usr/bin/env bash
set -e
+set -u
set -o pipefail
readonly NEOVIM_SOURCE_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
@@ -12,21 +13,31 @@ usage() {
echo "Helper script for porting Vim patches. For more information, see"
echo "https://github.com/neovim/neovim/wiki/Merging-patches-from-upstream-vim"
echo
- echo "Usage: ${BASENAME} [option]"
- echo " ${BASENAME} vim-revision"
+ echo "Usage: ${BASENAME} [-h | -l | -p vim-revision | -r pr-number]"
echo
echo "Options:"
- echo " -h, --help Show this message."
- echo " -l, --list Show list of Vim patches missing from Neovim."
- echo
- echo "vim-revision can be a version number of the format '7.4.xxx'"
- echo "or a Mercurial commit hash."
+ echo " -h Show this message and exit."
+ echo " -l Show list of Vim patches missing from Neovim."
+ echo " -p {vim-revision} Download and apply the Vim patch vim-revision."
+ echo " vim-revision can be a version number of the "
+ echo " format '7.4.xxx' or a Mercurial commit hash."
+ echo " -r {pr-number} Review a vim-patch pull request to Neovim."
echo
echo "Set VIM_SOURCE_DIR to change where Vim's sources are stored."
echo "The default is '${VIM_SOURCE_DIR_DEFAULT}'."
}
+# Checks if a program is in the user's PATH, and is executable.
+check_executable() {
+ if [[ ! -x $(command -v "${1}") ]]; then
+ >&2 echo "${BASENAME}: '${1}' not found in PATH or not executable."
+ exit 1
+ fi
+}
+
get_vim_sources() {
+ check_executable hg
+
echo "Retrieving Vim sources."
if [[ ! -d ${VIM_SOURCE_DIR} ]]; then
echo "Cloning Vim sources into '${VIM_SOURCE_DIR}'."
@@ -41,20 +52,39 @@ get_vim_sources() {
fi
}
-get_vim_patch() {
+commit_message() {
+ echo "vim-patch:${vim_version}
+
+${vim_message}
+
+${vim_commit_url}"
+}
+
+assign_commit_details() {
if [[ ${1} =~ [0-9]\.[0-9]\.[0-9]{3,4} ]]; then
# Interpret parameter as version number.
vim_version="${1}"
vim_commit="v${1//./-}"
- strip_commit_line=true
+ local strip_commit_line=true
vim_commit_url="https://github.com/vim/vim/commit/${vim_commit}"
else
# Interpret parameter as commit hash.
vim_version="${1:0:7}"
vim_commit="${1}"
- strip_commit_line=false
+ local strip_commit_line=false
vim_commit_url="https://code.google.com/p/vim/source/detail?r=${vim_commit}"
fi
+ vim_message="$(hg log --template "{desc}" --rev "${vim_commit}")"
+ if [[ ${strip_commit_line} == "true" ]]; then
+ # Remove first line of commit message.
+ vim_message="$(echo "${vim_message}" | sed -e '1d')"
+ fi
+}
+
+get_vim_patch() {
+ get_vim_sources
+
+ assign_commit_details "${1}"
hg log --rev "${vim_commit}" >/dev/null 2>&1 || {
>&2 echo "✘ Couldn't find Vim revision '${vim_commit}'."
@@ -65,19 +95,9 @@ get_vim_patch() {
# Collect patch details and store into variables.
vim_full="$(hg log --patch --git --verbose --rev "${vim_commit}")"
- vim_message="$(hg log --template "{desc}" --rev "${vim_commit}")"
- if [[ ${strip_commit_line} == "true" ]]; then
- # Remove first line of commit message.
- vim_message="$(echo "${vim_message}" | sed -e '1d')"
- fi
vim_diff="$(hg diff --show-function --git --change "${vim_commit}" \
| sed -e 's/\( [ab]\/src\)/\1\/nvim/g')" # Change directory to src/nvim.
- neovim_message="
-vim-patch:${vim_version}
-
-${vim_message}
-
-${vim_commit_url}"
+ neovim_message="$(commit_message)"
neovim_pr="
\`\`\`
${vim_message}
@@ -108,7 +128,7 @@ ${vim_diff}
echo
echo "Creating files."
echo "${vim_diff}" > "${NEOVIM_SOURCE_DIR}/${neovim_branch}.diff"
- echo "✔ Saved patch to '${NEOVIM_SOURCE_DIR}/${neovim_branch}.diff'."
+ echo "✔ Saved diff to '${NEOVIM_SOURCE_DIR}/${neovim_branch}.diff'."
echo "${vim_full}" > "${NEOVIM_SOURCE_DIR}/${neovim_branch}.patch"
echo "✔ Saved full commit details to '${NEOVIM_SOURCE_DIR}/${neovim_branch}.patch'."
echo "${neovim_pr}" > "${NEOVIM_SOURCE_DIR}/${neovim_branch}.pr"
@@ -132,6 +152,8 @@ ${vim_diff}
}
list_vim_patches() {
+ get_vim_sources
+
echo
echo "Vim patches missing from Neovim:"
@@ -184,24 +206,88 @@ list_vim_patches() {
echo " '${BASENAME} 1e8ebf870720e7b671f98f22d653009826304c4f'"
}
-if [[ ${1} == "--help" || ${1} == "-h" ]]; then
- usage
- exit 0
-elif [[ ${#} != 1 ]]; then
- usage
- exit 1
-fi
-
-# Checks if mercurial is in the user's PATH, and is executable.
-if [[ ! -x $(command -v hg) ]]; then
- >&2 echo "${BASENAME}: 'hg' (mercurial) not found in PATH or not executable"
- exit 1
-fi
-
-get_vim_sources
-
-if [[ ${1} == "--list" || ${1} == "-l" ]]; then
- list_vim_patches
-else
- get_vim_patch "${1}"
-fi
+review_pr() {
+ check_executable curl
+ check_executable nvim
+
+ get_vim_sources
+
+ local pr="${1}"
+ echo
+ echo "Downloading data for pull request #${pr}."
+
+ local git_patch_prefix='Subject: \[PATCH\] '
+ local neovim_patch="$(curl -Ssf "https://patch-diff.githubusercontent.com/raw/neovim/neovim/pull/${pr}.patch")"
+ echo "${neovim_patch}" > a
+ local vim_version="$(head -n 4 <<< "${neovim_patch}" | sed -n "s/${git_patch_prefix}vim-patch:\([a-z0-9.]*\)$/\1/p")"
+
+ if [[ -n "${vim_version}" ]]; then
+ echo "✔ Detected Vim patch '${vim_version}'."
+ else
+ echo "✘ Could not detect the Vim patch number."
+ echo " This script assumes that the PR contains a single commit"
+ echo " with 'vim-patch:XXX' as its title."
+ exit 1
+ fi
+
+ assign_commit_details "${vim_version}"
+
+ local expected_commit_message="$(commit_message)"
+ local message_length="$(wc -l <<< "${expected_commit_message}")"
+ local commit_message="$(tail -n +4 <<< "${neovim_patch}" | head -n "${message_length}")"
+ if [[ "${commit_message#${git_patch_prefix}}" == "${expected_commit_message}" ]]; then
+ echo "✔ Found expected commit message."
+ else
+ echo "✘ Wrong commit message."
+ echo " Expected:"
+ echo "${expected_commit_message}"
+ echo " Actual:"
+ echo "${commit_message#${git_patch_prefix}}"
+ exit 1
+ fi
+
+ local base_name="vim-${vim_version}"
+ echo
+ echo "Creating files."
+ curl -Ssfo "${NEOVIM_SOURCE_DIR}/n${base_name}.diff" "https://patch-diff.githubusercontent.com/raw/neovim/neovim/pull/${pr}.diff"
+ echo "✔ Saved pull request diff to '${NEOVIM_SOURCE_DIR}/n${base_name}.diff'."
+ echo "${neovim_patch}" > "${NEOVIM_SOURCE_DIR}/n${base_name}.patch"
+ echo "✔ Saved full pull request commit details to '${NEOVIM_SOURCE_DIR}/n${base_name}.patch'."
+ hg diff --show-function --git --change "${vim_commit}" > "${NEOVIM_SOURCE_DIR}/${base_name}.diff"
+ echo "✔ Saved Vim diff to '${NEOVIM_SOURCE_DIR}/${base_name}.diff'."
+ hg log --patch --git --verbose --rev "${vim_commit}" > "${NEOVIM_SOURCE_DIR}/${base_name}.patch"
+ echo "✔ Saved full Vim commit details to '${NEOVIM_SOURCE_DIR}/${base_name}.patch'."
+ echo "You can use 'git clean' to remove these files when you're done."
+
+ echo
+ echo "Launching nvim."
+ exec nvim -O "${NEOVIM_SOURCE_DIR}/${base_name}.diff" "${NEOVIM_SOURCE_DIR}/n${base_name}.diff"
+}
+
+while getopts "hlp:r:" opt; do
+ case ${opt} in
+ h)
+ usage
+ exit 0
+ ;;
+ l)
+ list_vim_patches
+ exit 0
+ ;;
+ p)
+ get_vim_patch "${OPTARG}"
+ exit 0
+ ;;
+ r)
+ review_pr "${OPTARG}"
+ exit 0
+ ;;
+ *)
+ exit 1
+ ;;
+ esac
+done
+
+usage
+
+# vim: et sw=2