aboutsummaryrefslogtreecommitdiff
path: root/scripts
diff options
context:
space:
mode:
Diffstat (limited to 'scripts')
-rw-r--r--scripts/gen_filetype.lua201
-rwxr-xr-xscripts/gen_vimdoc.py6
-rw-r--r--scripts/squash_typos.py263
-rwxr-xr-xscripts/vim-patch.sh57
4 files changed, 241 insertions, 286 deletions
diff --git a/scripts/gen_filetype.lua b/scripts/gen_filetype.lua
new file mode 100644
index 0000000000..42478a1082
--- /dev/null
+++ b/scripts/gen_filetype.lua
@@ -0,0 +1,201 @@
+local do_not_run = true
+if do_not_run then
+ print([[
+ This script was used to bootstrap the filetype patterns in runtime/lua/vim/filetype.lua. It
+ should no longer be used except for testing purposes. New filetypes, or changes to existing
+ filetypes, should be ported manually as part of the vim-patch process.
+ ]])
+ return
+end
+
+local filetype_vim = "runtime/filetype.vim"
+local filetype_lua = "runtime/lua/vim/filetype.lua"
+
+local keywords = {
+ ["for"] = true,
+ ["or"] = true,
+ ["and"] = true,
+ ["end"] = true,
+ ["do"] = true,
+ ["if"] = true,
+ ["while"] = true,
+ ["repeat"] = true,
+}
+
+local sections = {
+ extension = { str = {}, func = {} },
+ filename = { str = {}, func = {} },
+ pattern = { str = {}, func = {} },
+}
+
+local specialchars = "%*%?\\%$%[%]%{%}"
+
+local function add_pattern(pat, ft)
+ local ok = true
+
+ -- Patterns that start or end with { or } confuse splitting on commas and make parsing harder, so just skip those
+ if not string.find(pat, "^%{") and not string.find(pat, "%}$") then
+ for part in string.gmatch(pat, "[^,]+") do
+ if not string.find(part, "[" .. specialchars .. "]") then
+ if type(ft) == "string" then
+ sections.filename.str[part] = ft
+ else
+ sections.filename.func[part] = ft
+ end
+ elseif string.match(part, "^%*%.[^%./" .. specialchars .. "]+$") then
+ if type(ft) == "string" then
+ sections.extension.str[part:sub(3)] = ft
+ else
+ sections.extension.func[part:sub(3)] = ft
+ end
+ else
+ if string.match(part, "^%*/[^" .. specialchars .. "]+$") then
+ -- For patterns matching */some/pattern we want to easily match files
+ -- with path /some/pattern, so include those in filename detection
+ if type(ft) == "string" then
+ sections.filename.str[part:sub(2)] = ft
+ else
+ sections.filename.func[part:sub(2)] = ft
+ end
+ end
+
+ if string.find(part, "^[%w-_.*?%[%]/]+$") then
+ local p = part:gsub("%.", "%%."):gsub("%*", ".*"):gsub("%?", ".")
+ -- Insert into array to maintain order rather than setting
+ -- key-value directly
+ if type(ft) == "string" then
+ sections.pattern.str[p] = ft
+ else
+ sections.pattern.func[p] = ft
+ end
+ else
+ ok = false
+ end
+ end
+ end
+ end
+
+ return ok
+end
+
+local function parse_line(line)
+ local pat, ft
+ pat, ft = line:match("^%s*au%a* Buf[%a,]+%s+(%S+)%s+setf%s+(%S+)")
+ if pat then
+ return add_pattern(pat, ft)
+ else
+ local func
+ pat, func = line:match("^%s*au%a* Buf[%a,]+%s+(%S+)%s+call%s+(%S+)")
+ if pat then
+ return add_pattern(pat, function() return func end)
+ end
+ end
+end
+
+local unparsed = {}
+local full_line
+for line in io.lines(filetype_vim) do
+ local cont = string.match(line, "^%s*\\%s*(.*)$")
+ if cont then
+ full_line = full_line .. " " .. cont
+ else
+ if full_line then
+ if not parse_line(full_line) and string.find(full_line, "^%s*au%a* Buf") then
+ table.insert(unparsed, full_line)
+ end
+ end
+ full_line = line
+ end
+end
+
+if #unparsed > 0 then
+ print("Failed to parse the following patterns:")
+ for _, v in ipairs(unparsed) do
+ print(v)
+ end
+end
+
+local function add_item(indent, key, ft)
+ if type(ft) == "string" then
+ if string.find(key, "%A") or keywords[key] then
+ key = string.format("[\"%s\"]", key)
+ end
+ return string.format([[%s%s = "%s",]], indent, key, ft)
+ elseif type(ft) == "function" then
+ local func = ft()
+ if string.find(key, "%A") or keywords[key] then
+ key = string.format("[\"%s\"]", key)
+ end
+ -- Right now only a single argument is supported, which covers
+ -- everything in filetype.vim as of this writing
+ local arg = string.match(func, "%((.*)%)$")
+ func = string.gsub(func, "%(.*$", "")
+ if arg == "" then
+ -- Function with no arguments, call the function directly
+ return string.format([[%s%s = function() vim.fn["%s"]() end,]], indent, key, func)
+ elseif string.match(arg, [[^(["']).*%1$]]) then
+ -- String argument
+ if func == "s:StarSetf" then
+ return string.format([[%s%s = starsetf(%s),]], indent, key, arg)
+ else
+ return string.format([[%s%s = function() vim.fn["%s"](%s) end,]], indent, key, func, arg)
+ end
+ elseif string.find(arg, "%(") then
+ -- Function argument
+ return string.format([[%s%s = function() vim.fn["%s"](vim.fn.%s) end,]], indent, key, func, arg)
+ else
+ assert(false, arg)
+ end
+ end
+end
+
+do
+ local lines = {}
+ local start = false
+ for line in io.lines(filetype_lua) do
+ if line:match("^%s+-- END [A-Z]+$") then
+ start = false
+ end
+
+ if not start then
+ table.insert(lines, line)
+ end
+
+ local indent, section = line:match("^(%s+)-- BEGIN ([A-Z]+)$")
+ if section then
+ start = true
+ local t = sections[string.lower(section)]
+
+ local sorted = {}
+ for k, v in pairs(t.str) do
+ table.insert(sorted, {[k] = v})
+ end
+
+ table.sort(sorted, function(a, b)
+ return a[next(a)] < b[next(b)]
+ end)
+
+ for _, v in ipairs(sorted) do
+ local k = next(v)
+ table.insert(lines, add_item(indent, k, v[k]))
+ end
+
+ sorted = {}
+ for k, v in pairs(t.func) do
+ table.insert(sorted, {[k] = v})
+ end
+
+ table.sort(sorted, function(a, b)
+ return next(a) < next(b)
+ end)
+
+ for _, v in ipairs(sorted) do
+ local k = next(v)
+ table.insert(lines, add_item(indent, k, v[k]))
+ end
+ end
+ end
+ local f = io.open(filetype_lua, "w")
+ f:write(table.concat(lines, "\n") .. "\n")
+ f:close()
+end
diff --git a/scripts/gen_vimdoc.py b/scripts/gen_vimdoc.py
index 89fc14121e..3e9fb21039 100755
--- a/scripts/gen_vimdoc.py
+++ b/scripts/gen_vimdoc.py
@@ -128,12 +128,16 @@ CONFIG = {
'shared.lua',
'uri.lua',
'ui.lua',
+ 'filetype.lua',
+ 'keymap.lua',
],
'files': ' '.join([
os.path.join(base_dir, 'src/nvim/lua/vim.lua'),
os.path.join(base_dir, 'runtime/lua/vim/shared.lua'),
os.path.join(base_dir, 'runtime/lua/vim/uri.lua'),
os.path.join(base_dir, 'runtime/lua/vim/ui.lua'),
+ os.path.join(base_dir, 'runtime/lua/vim/filetype.lua'),
+ os.path.join(base_dir, 'runtime/lua/vim/keymap.lua'),
]),
'file_patterns': '*.lua',
'fn_name_prefix': '',
@@ -148,6 +152,8 @@ CONFIG = {
'shared': 'vim',
'uri': 'vim',
'ui': 'vim.ui',
+ 'filetype': 'vim.filetype',
+ 'keymap': 'vim.keymap',
},
'append_only': [
'shared.lua',
diff --git a/scripts/squash_typos.py b/scripts/squash_typos.py
deleted file mode 100644
index b403a9b7c8..0000000000
--- a/scripts/squash_typos.py
+++ /dev/null
@@ -1,263 +0,0 @@
-#!/usr/bin/env python
-"""
-
-This script squashes a PR tagged with the "typo" label into a single, dedicated
-"squash PR".
-
-"""
-
-import subprocess
-import sys
-import os
-
-
-def get_authors_and_emails_from_pr():
- """
-
- Return all contributing authors and their emails for the PR on current branch.
- This includes co-authors, meaning that if two authors are credited for a
- single commit, which is possible with GitHub, then both will get credited.
-
- """
-
- # Get a list of all authors involved in the pull request (including co-authors).
- authors = subprocess.check_output(
- [
- "gh",
- "pr",
- "view",
- os.environ["PR_NUMBER"],
- "--json",
- "commits",
- "--jq",
- ".[][].authors.[].name",
- ],
- text=True,
- ).splitlines()
-
- # Get a list of emails of the aforementioned authors.
- emails = subprocess.check_output(
- [
- "gh",
- "pr",
- "view",
- os.environ["PR_NUMBER"],
- "--json",
- "commits",
- "--jq",
- ".[][].authors.[].email",
- ],
- text=True,
- ).splitlines()
-
- authors_and_emails = [(author, mail) for author, mail in zip(authors, emails)]
-
- return authors_and_emails
-
-
-def rebase_onto_pr():
- """
-
- Rebase current branch onto the PR.
-
- """
-
- # Check out the pull request.
- subprocess.call(["gh", "pr", "checkout", os.environ["PR_NUMBER"]])
-
- rebase_onto_master()
-
- # Change back to the original branch.
- subprocess.call(["git", "switch", "-"])
-
- # Rebase onto the pull request, aka include the commits in the pull request
- # in the current branch. Abort with error message if rebase fails.
-
- try:
- subprocess.check_call(["git", "rebase", "-"])
- except subprocess.CalledProcessError:
- subprocess.call(["git", "rebase", "--abort"])
- squash_url = subprocess.check_output(
- ["gh", "pr", "view", "--json", "url", "--jq", ".url"], text=True
- ).strip()
-
- subprocess.call(
- [
- "gh",
- "pr",
- "comment",
- os.environ["PR_NUMBER"],
- "--body",
- f"Your edit conflicts with an already scheduled fix \
- ({squash_url}). Please check that batch PR whether your fix is \
- already included; if not, then please wait until the batch PR \
- is merged and then rebase your PR on top of master.",
- ]
- )
-
- sys.exit(
- f"\n\nERROR: Your edit conflicts with an already scheduled fix \
-{squash_url} \n\n"
- )
-
-
-def rebase_onto_master():
- """
-
- Rebase current branch onto the master i.e. make sure current branch is up
- to date. Abort on error.
-
- """
-
- default_branch = f"{os.environ['GITHUB_BASE_REF']}"
- subprocess.check_call(["git", "rebase", default_branch])
-
-
-def squash_all_commits(message_body_before):
- """
-
- Squash all commits on the PR into a single commit. Credit all authors by
- name and email.
-
- """
-
- default_branch = f"{os.environ['GITHUB_BASE_REF']}"
- subprocess.call(["git", "reset", "--soft", default_branch])
-
- authors_and_emails = get_authors_and_emails_from_pr()
- commit_message_coauthors = (
- "\n"
- + "\n".join([f"Co-authored-by: {i[0]} <{i[1]}>" for i in authors_and_emails])
- + "\n"
- + message_body_before
- )
- subprocess.call(
- ["git", "commit", "-m", "chore: typo fixes", "-m", commit_message_coauthors]
- )
-
-
-def force_push(branch):
- """
-
- Like the name implies, force push <branch>.
-
- """
-
- gh_actor = os.environ["GITHUB_ACTOR"]
- gh_token = os.environ["GITHUB_TOKEN"]
- gh_repo = os.environ["GITHUB_REPOSITORY"]
- subprocess.call(
- [
- "git",
- "push",
- "--force",
- f"https://{gh_actor}:{gh_token}@github.com/{gh_repo}",
- branch,
- ]
- )
-
-
-def checkout_branch(branch):
- """
-
- Create and checkout <branch>. Check if branch exists on remote, if so then
- sync local branch to remote.
-
- Return True if remote branch exists, else False.
-
- """
-
- # FIXME I'm not sure why the local branch isn't tracking the remote branch
- # automatically. This works but I'm pretty sure it can be done in a more
- # "elegant" fashion
-
- show_ref_output = subprocess.check_output(["git", "show-ref"], text=True).strip()
-
- if branch in show_ref_output:
- subprocess.call(["git", "checkout", "-b", branch, f"origin/{branch}"])
- return True
-
- subprocess.call(["git", "checkout", "-b", branch])
- return False
-
-
-def get_all_pr_urls(pr_branch_exists):
- """
-
- Return a list of URLs for the pull requests with the typo fixes. If a
- squash branch exists then extract the URLs from the body text.
-
- """
-
- all_pr_urls = ""
- if pr_branch_exists:
- all_pr_urls += subprocess.check_output(
- ["gh", "pr", "view", "--json", "body", "--jq", ".body"], text=True
- )
-
- all_pr_urls += subprocess.check_output(
- ["gh", "pr", "view", os.environ["PR_NUMBER"], "--json", "url", "--jq", ".url"],
- text=True,
- ).strip()
-
- return all_pr_urls
-
-
-def main():
- pr_branch = "marvim/squash-typos"
-
- pr_branch_exists = checkout_branch(pr_branch)
-
- rebase_onto_master()
- force_push(pr_branch)
-
- message_body_before = "\n".join(
- subprocess.check_output(
- ["git", "log", "--format=%B", "-n1", pr_branch], text=True
- ).splitlines()[2:]
- )
-
- rebase_onto_pr()
- force_push(pr_branch)
-
- subprocess.call(
- [
- "gh",
- "pr",
- "create",
- "--fill",
- "--head",
- pr_branch,
- "--title",
- "chore: typo fixes (automated)",
- ],
- text=True,
- )
-
- squash_all_commits(message_body_before)
- force_push(pr_branch)
-
- all_pr_urls = get_all_pr_urls(pr_branch_exists)
- subprocess.call(["gh", "pr", "edit", "--add-label", "typo", "--body", all_pr_urls])
-
- subprocess.call(["gh", "pr", "close", os.environ["PR_NUMBER"]])
-
- squash_url = subprocess.check_output(
- ["gh", "pr", "view", "--json", "url", "--jq", ".url"], text=True
- ).strip()
- subprocess.call(
- [
- "gh",
- "pr",
- "comment",
- os.environ["PR_NUMBER"],
- "--body",
- f"Thank you for your contribution! We collect all typo fixes \
- into a single pull request and merge it once it gets big enough: \
- {squash_url}",
- ]
- )
-
-
-if __name__ == "__main__":
- main()
diff --git a/scripts/vim-patch.sh b/scripts/vim-patch.sh
index ac47f6aafd..1c265f0f40 100755
--- a/scripts/vim-patch.sh
+++ b/scripts/vim-patch.sh
@@ -266,8 +266,6 @@ get_vimpatch() {
msg_ok "Saved patch to '${NVIM_SOURCE_DIR}/${patch_file}'."
}
-# shellcheck disable=SC2015
-# ^ "Note that A && B || C is not if-then-else."
stage_patch() {
get_vimpatch "$1"
local try_apply="${2:-}"
@@ -282,23 +280,32 @@ stage_patch() {
echo " branch; not creating a new branch."
else
printf '\nFetching "%s/master".\n' "${nvim_remote}"
- output="$(git fetch "${nvim_remote}" master 2>&1)" &&
- msg_ok "${output}" ||
- (msg_err "${output}"; false)
+ if output="$(git fetch "$nvim_remote" master 2>&1)"; then
+ msg_ok "$output"
+ else
+ msg_err "$output"
+ exit 1
+ fi
local nvim_branch="${BRANCH_PREFIX}${vim_version}"
echo
echo "Creating new branch '${nvim_branch}' based on '${nvim_remote}/master'."
cd "${NVIM_SOURCE_DIR}"
- output="$(git checkout -b "${nvim_branch}" "${nvim_remote}/master" 2>&1)" &&
- msg_ok "${output}" ||
- (msg_err "${output}"; false)
+ if output="$(git checkout -b "$nvim_branch" "$nvim_remote/master" 2>&1)"; then
+ msg_ok "$output"
+ else
+ msg_err "$output"
+ exit 1
+ fi
fi
printf "\nCreating empty commit with correct commit message.\n"
- output="$(commit_message | git commit --allow-empty --file 2>&1 -)" &&
- msg_ok "${output}" ||
- (msg_err "${output}"; false)
+ if output="$(commit_message | git commit --allow-empty --file 2>&1 -)"; then
+ msg_ok "$output"
+ else
+ msg_err "$output"
+ exit 1
+ fi
local ret=0
if test -n "$try_apply" ; then
@@ -340,8 +347,6 @@ git_hub_pr() {
git hub pull new -m "${pr_message}"
}
-# shellcheck disable=SC2015
-# ^ "Note that A && B || C is not if-then-else."
submit_pr() {
require_executable git
local push_first
@@ -392,17 +397,23 @@ submit_pr() {
fi
fi
echo "Pushing to '${push_remote}/${checked_out_branch}'."
- output="$(git push "${push_remote}" "${checked_out_branch}" 2>&1)" &&
- msg_ok "${output}" ||
- (msg_err "${output}"; false)
+ if output="$(git push "$push_remote" "$checked_out_branch" 2>&1)"; then
+ msg_ok "$output"
+ else
+ msg_err "$output"
+ exit 1
+ fi
echo
fi
echo "Creating pull request."
- output="$(${submit_fn} "${pr_title}" "${pr_body}" 2>&1)" &&
- msg_ok "${output}" ||
- (msg_err "${output}"; false)
+ if output="$($submit_fn "$pr_title" "$pr_body" 2>&1)"; then
+ msg_ok "$output"
+ else
+ msg_err "$output"
+ exit 1
+ fi
echo
echo "Cleaning up files."
@@ -565,13 +576,13 @@ show_vimpatches() {
runtime_commits[$commit]=1
done
- list_missing_vimpatches 1 "$@" | while read -r vim_commit; do
+ while read -r vim_commit; do
if [[ "${runtime_commits[$vim_commit]-}" ]]; then
printf ' • %s (+runtime)\n' "${vim_commit}"
else
printf ' • %s\n' "${vim_commit}"
fi
- done
+ done <<< "$(list_missing_vimpatches 1 "$@")"
cat << EOF
@@ -692,14 +703,14 @@ review_commit() {
message_length="$(wc -l <<< "${expected_commit_message}")"
local commit_message
commit_message="$(tail -n +4 "${NVIM_SOURCE_DIR}/n${patch_file}" | head -n "${message_length}")"
- if [[ "${commit_message#${git_patch_prefix}}" == "${expected_commit_message}" ]]; then
+ if [[ "${commit_message#"$git_patch_prefix"}" == "${expected_commit_message}" ]]; then
msg_ok "Found expected commit message."
else
msg_err "Wrong commit message."
echo " Expected:"
echo "${expected_commit_message}"
echo " Actual:"
- echo "${commit_message#${git_patch_prefix}}"
+ echo "${commit_message#"$git_patch_prefix"}"
fi
get_vimpatch "${vim_version}"