aboutsummaryrefslogtreecommitdiff
path: root/scripts/vim-patch.sh
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/vim-patch.sh')
-rwxr-xr-xscripts/vim-patch.sh448
1 files changed, 294 insertions, 154 deletions
diff --git a/scripts/vim-patch.sh b/scripts/vim-patch.sh
index a40090d4c3..11305421e5 100755
--- a/scripts/vim-patch.sh
+++ b/scripts/vim-patch.sh
@@ -2,10 +2,11 @@
set -e
set -u
-set -o pipefail
+# Use privileged mode, which e.g. skips using CDPATH.
+set -p
-readonly NEOVIM_SOURCE_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
-readonly VIM_SOURCE_DIR_DEFAULT="${NEOVIM_SOURCE_DIR}/.vim-src"
+readonly NVIM_SOURCE_DIR="${NVIM_SOURCE_DIR:-$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)}"
+readonly VIM_SOURCE_DIR_DEFAULT="${NVIM_SOURCE_DIR}/.vim-src"
readonly VIM_SOURCE_DIR="${VIM_SOURCE_DIR:-${VIM_SOURCE_DIR_DEFAULT}}"
readonly BASENAME="$(basename "${0}")"
readonly BRANCH_PREFIX="vim-"
@@ -13,22 +14,34 @@ readonly BRANCH_PREFIX="vim-"
CREATED_FILES=()
usage() {
- echo "Helper script for porting Vim patches. For more information, see"
+ echo "Port Vim patches to Neovim"
echo "https://github.com/neovim/neovim/wiki/Merging-patches-from-upstream-vim"
echo
echo "Usage: ${BASENAME} [-h | -l | -p vim-revision | -r pr-number]"
echo
echo "Options:"
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 Git commit hash."
- echo " -s Submit a vim-patch pull request to Neovim."
- echo " -r {pr-number} Review a vim-patch pull request to Neovim."
+ echo " -l List missing Vim patches."
+ echo " -L List missing Vim patches (for scripts)."
+ echo " -M List all merged patch-numbers (at current v:version)."
+ echo " -p {vim-revision} Download and generate a Vim patch. vim-revision"
+ echo " can be a Vim version (8.0.xxx) or a Git hash."
+ echo " -P {vim-revision} Download, generate and apply a Vim patch."
+ echo " -g {vim-revision} Download a Vim patch."
+ echo " -s Create a vim-patch pull request."
+ echo " -r {pr-number} Review a vim-patch pull request."
+ echo ' -V Clone the Vim source code to $VIM_SOURCE_DIR.'
echo
- echo "Set VIM_SOURCE_DIR to change where Vim's sources are stored."
- echo "The default is '${VIM_SOURCE_DIR_DEFAULT}'."
+ echo ' $VIM_SOURCE_DIR controls where Vim sources are found'
+ echo " (default: '${VIM_SOURCE_DIR_DEFAULT}')"
+}
+
+msg_ok() {
+ printf '\e[32m✔\e[0m %s\n' "$@"
+}
+
+msg_err() {
+ printf '\e[31m✘\e[0m %s\n' "$@"
}
# Checks if a program is in the user's PATH, and is executable.
@@ -57,10 +70,10 @@ clean_files() {
read -p "Delete these files (Y/n)? " -n 1 -r reply
echo
- if [[ "${reply}" =~ ^[Yy]$ ]]; then
- rm -- "${CREATED_FILES[@]}"
- else
+ if [[ "${reply}" == n ]]; then
echo "You can use 'git clean' to remove these files when you're done."
+ else
+ rm -- "${CREATED_FILES[@]}"
fi
}
@@ -68,26 +81,30 @@ get_vim_sources() {
require_executable git
if [[ ! -d ${VIM_SOURCE_DIR} ]]; then
- echo "Cloning Vim sources into '${VIM_SOURCE_DIR}'."
+ echo "Cloning Vim into: ${VIM_SOURCE_DIR}"
git clone https://github.com/vim/vim.git "${VIM_SOURCE_DIR}"
cd "${VIM_SOURCE_DIR}"
else
- if [[ ! -d "${VIM_SOURCE_DIR}/.git" ]]; then
- echo "✘ ${VIM_SOURCE_DIR} does not appear to be a git repository."
+ cd "${VIM_SOURCE_DIR}"
+ if ! [ -d ".git" ] \
+ && ! [ "$(git rev-parse --show-toplevel)" = "${VIM_SOURCE_DIR}" ]; then
+ msg_err "${VIM_SOURCE_DIR} does not appear to be a git repository."
echo " Please remove it and try again."
exit 1
fi
- cd "${VIM_SOURCE_DIR}"
- echo "Updating Vim sources in '${VIM_SOURCE_DIR}'."
- git pull &&
- echo "✔ Updated Vim sources." ||
- echo "✘ Could not update Vim sources; ignoring error."
+ echo "Updating Vim sources: ${VIM_SOURCE_DIR}"
+ git pull --ff &&
+ msg_ok "Updated Vim sources." ||
+ msg_err "Could not update Vim sources; ignoring error."
fi
}
commit_message() {
- printf 'vim-patch:%s\n\n%s\n\n%s' "${vim_version}" \
- "${vim_message}" "${vim_commit_url}"
+ if [[ -n "$vim_tag" ]]; then
+ printf '%s\n%s' "${vim_message}" "${vim_commit_url}"
+ else
+ printf 'vim-patch:%s\n\n%s\n%s' "$vim_version" "$vim_message" "$vim_commit_url"
+ fi
}
find_git_remote() {
@@ -102,100 +119,162 @@ assign_commit_details() {
vim_tag="v${1}"
vim_commit=$(cd "${VIM_SOURCE_DIR}" \
&& git log -1 --format="%H" "${vim_tag}")
- local strip_commit_line=true
+ local munge_commit_line=true
else
# Interpret parameter as commit hash.
- vim_version="${1:0:7}"
+ vim_version="${1:0:12}"
+ vim_tag=
vim_commit=$(cd "${VIM_SOURCE_DIR}" \
&& git log -1 --format="%H" "${vim_version}")
- local strip_commit_line=false
+ local munge_commit_line=false
fi
vim_commit_url="https://github.com/vim/vim/commit/${vim_commit}"
vim_message="$(cd "${VIM_SOURCE_DIR}" \
&& git log -1 --pretty='format:%B' "${vim_commit}" \
- | sed -e 's/\(#[0-9]*\)/vim\/vim\1/g')"
- if [[ ${strip_commit_line} == "true" ]]; then
+ | sed -e 's/\(#[0-9]\{1,\}\)/vim\/vim\1/g')"
+ if [[ ${munge_commit_line} == "true" ]]; then
# Remove first line of commit message.
- vim_message="$(echo "${vim_message}" | sed -e '1d')"
+ vim_message="$(echo "${vim_message}" | sed -e '1s/^patch /vim-patch:/')"
fi
patch_file="vim-${vim_version}.patch"
}
-get_vim_patch() {
+# Patch surgery
+preprocess_patch() {
+ local file="$1"
+ local nvim="nvim -u NORC -i NONE --headless"
+
+ # Remove *.proto, Make*, gui_*, some if_*
+ local na_src='proto\|Make*\|gui_*\|if_lua\|if_mzsch\|if_olepp\|if_ole\|if_perl\|if_py\|if_ruby\|if_tcl\|if_xcmdsrv'
+ 2>/dev/null $nvim --cmd 'set dir=/tmp' +'g@^diff --git a/src/\S*\<\%(testdir/\)\@<!\%('${na_src}'\)@norm! d/\v(^diff)|%$ ' +w +q "$file"
+
+ # Remove unwanted Vim doc files.
+ local na_doc='channel\.txt\|netbeans\.txt\|os_\w\+\.txt\|term\.txt\|todo\.txt\|version\d\.txt\|sponsor\.txt\|intro\.txt\|tags'
+ 2>/dev/null $nvim --cmd 'set dir=/tmp' +'g@^diff --git a/runtime/doc/\<\%('${na_doc}'\)\>@norm! d/\v(^diff)|%$ ' +w +q "$file"
+
+ # Remove "Last change ..." changes in doc files.
+ 2>/dev/null $nvim --cmd 'set dir=/tmp' +'%s/^@@.*\n.*For Vim version.*Last change.*\n.*For Vim version.*Last change.*//' +w +q "$file"
+
+ # Remove screen dumps, testdir/Make_*.mak files
+ local na_src_testdir='Make_amiga.mak\|Make_dos.mak\|Make_ming.mak\|Make_vms.mms\|dumps/.*.dump'
+ 2>/dev/null $nvim --cmd 'set dir=/tmp' +'g@^diff --git a/src/testdir/\<\%('${na_src_testdir}'\)\>@norm! d/\v(^diff)|%$ ' +w +q "$file"
+
+ # Remove version.c #7555
+ local na_po='version.c'
+ 2>/dev/null $nvim --cmd 'set dir=/tmp' +'g@^diff --git a/src/\<\%('${na_po}'\)\>@norm! d/\v(^diff)|%$ ' +w +q "$file"
+
+ # Remove some *.po files. #5622
+ local na_po='sjiscorr.c\|ja.sjis.po\|ko.po\|pl.cp1250.po\|pl.po\|ru.cp1251.po\|uk.cp1251.po\|zh_CN.cp936.po\|zh_CN.po\|zh_TW.po'
+ 2>/dev/null $nvim --cmd 'set dir=/tmp' +'g@^diff --git a/src/po/\<\%('${na_po}'\)\>@norm! d/\v(^diff)|%$ ' +w +q "$file"
+
+ # Remove vimrc_example.vim
+ local na_vimrcexample='vimrc_example\.vim'
+ 2>/dev/null $nvim --cmd 'set dir=/tmp' +'g@^diff --git a/runtime/\<\%('${na_vimrcexample}'\)\>@norm! d/\v(^diff)|%$ ' +w +q "$file"
+
+ # Rename src/ paths to src/nvim/
+ LC_ALL=C sed -e 's/\( [ab]\/src\)/\1\/nvim/g' \
+ "$file" > "$file".tmp && mv "$file".tmp "$file"
+
+ # Rename path to matchit plugin.
+ LC_ALL=C sed -e 's@\( [ab]/runtime\)/pack/dist/opt/matchit/\(plugin/matchit.vim\)@\1/\2@g' \
+ "$file" > "$file".tmp && mv "$file".tmp "$file"
+ LC_ALL=C sed -e 's@\( [ab]/runtime\)/pack/dist/opt/matchit/doc/\(matchit.txt\)@\1/doc/pi_\2@g' \
+ "$file" > "$file".tmp && mv "$file".tmp "$file"
+
+ # Rename test_urls.vim to check_urls.vim
+ LC_ALL=C sed -e 's@\( [ab]\)/runtime/doc/test\(_urls.vim\)@\1/scripts/check\2@g' \
+ "$file" > "$file".tmp && mv "$file".tmp "$file"
+
+ # Rename path to check_colors.vim
+ LC_ALL=C sed -e 's@\( [ab]/runtime\)/colors/\(tools/check_colors.vim\)@\1/\2@g' \
+ "$file" > "$file".tmp && mv "$file".tmp "$file"
+}
+
+get_vimpatch() {
get_vim_sources
assign_commit_details "${1}"
git log -1 "${vim_commit}" -- >/dev/null 2>&1 || {
- >&2 echo "✘ Couldn't find Vim revision '${vim_commit}'."
+ >&2 msg_err "Couldn't find Vim revision '${vim_commit}'."
exit 3
}
- echo
- echo "✔ Found Vim revision '${vim_commit}'."
+ msg_ok "Found Vim revision '${vim_commit}'."
+
+ local patch_content
+ patch_content="$(git --no-pager show --color=never -1 --pretty=medium "${vim_commit}")"
+
+ cd "${NVIM_SOURCE_DIR}"
+
+ printf "Creating patch...\n"
+ echo "$patch_content" > "${NVIM_SOURCE_DIR}/${patch_file}"
- # Patch surgery: preprocess the patch.
- # - transform src/ paths to src/nvim/
- local vim_full
- vim_full="$(git show -1 --pretty=medium "${vim_commit}" \
- | LC_ALL=C sed -e 's/\( [ab]\/src\)/\1\/nvim/g')"
- local neovim_branch="${BRANCH_PREFIX}${vim_version}"
+ printf "Pre-processing patch...\n"
+ preprocess_patch "${NVIM_SOURCE_DIR}/${patch_file}"
+
+ msg_ok "Saved patch to '${NVIM_SOURCE_DIR}/${patch_file}'."
+}
+
+stage_patch() {
+ get_vimpatch "$1"
+ local try_apply="${2:-}"
- cd "${NEOVIM_SOURCE_DIR}"
local git_remote
git_remote="$(find_git_remote)"
local checked_out_branch
checked_out_branch="$(git rev-parse --abbrev-ref HEAD)"
if [[ "${checked_out_branch}" == ${BRANCH_PREFIX}* ]]; then
- echo "✔ Current branch '${checked_out_branch}' seems to be a vim-patch"
+ msg_ok "Current branch '${checked_out_branch}' seems to be a vim-patch"
echo " branch; not creating a new branch."
else
- echo
- echo "Fetching '${git_remote}/master'."
+ printf '\nFetching "%s/master".\n' "${git_remote}"
output="$(git fetch "${git_remote}" master 2>&1)" &&
- echo "✔ ${output}" ||
- (echo "✘ ${output}"; false)
+ msg_ok "${output}" ||
+ (msg_err "${output}"; false)
+ local nvim_branch="${BRANCH_PREFIX}${vim_version}"
echo
- echo "Creating new branch '${neovim_branch}' based on '${git_remote}/master'."
- cd "${NEOVIM_SOURCE_DIR}"
- output="$(git checkout -b "${neovim_branch}" "${git_remote}/master" 2>&1)" &&
- echo "✔ ${output}" ||
- (echo "✘ ${output}"; false)
+ echo "Creating new branch '${nvim_branch}' based on '${git_remote}/master'."
+ cd "${NVIM_SOURCE_DIR}"
+ output="$(git checkout -b "${nvim_branch}" "${git_remote}/master" 2>&1)" &&
+ msg_ok "${output}" ||
+ (msg_err "${output}"; false)
fi
- echo
- echo "Creating empty commit with correct commit message."
+ printf "\nCreating empty commit with correct commit message.\n"
output="$(commit_message | git commit --allow-empty --file 2>&1 -)" &&
- echo "✔ ${output}" ||
- (echo "✘ ${output}"; false)
+ msg_ok "${output}" ||
+ (msg_err "${output}"; false)
- echo
- echo "Creating files."
- echo "${vim_full}" > "${NEOVIM_SOURCE_DIR}/${patch_file}"
- echo "✔ Saved full commit details to '${NEOVIM_SOURCE_DIR}/${patch_file}'."
+ if test -n "$try_apply" ; then
+ if ! check_executable patch; then
+ printf "\n"
+ msg_err "'patch' command not found\n"
+ else
+ printf "\nApplying patch...\n"
+ patch -p1 < "${patch_file}" || true
+ find . -name '*.orig' -type f -delete
+ fi
+ printf "\nInstructions:\n Proceed to port the patch.\n"
+ else
+ printf '\nInstructions:\n Proceed to port the patch.\n Try the "patch" command (or use "%s -P ..." next time):\n patch -p1 < %s\n' "${BASENAME}" "${patch_file}"
+ fi
- echo
- echo "Instructions:"
- echo
- echo " Proceed to port the patch."
- echo " You might want to try 'patch -p1 < ${patch_file}' first."
- echo
- echo " If the patch contains a new test, consider porting it to Lua."
- echo " You might want to try 'scripts/legacy2luatest.pl'."
- echo
- echo " Stage your changes ('git add ...') and use 'git commit --amend' to commit."
- echo
- echo " To port additional patches related to ${vim_version} and add them to the current"
- echo " branch, call '${BASENAME} -p' again. Please use this only if it wouldn't make"
- echo " sense to send in each patch individually, as it will increase the size of the"
- echo " pull request and make it harder to review."
- echo
- echo " When you are finished, use '${BASENAME} -s' to submit a pull request."
- echo
- echo " See https://github.com/neovim/neovim/wiki/Merging-patches-from-upstream-vim"
- echo " for more information."
+ printf '
+ Stage your changes ("git add ..."), then use "git commit --amend" to commit.
+
+ To port more patches (if any) related to %s,
+ run "%s" again.
+ * Do this only for _related_ patches (otherwise it increases the
+ size of the pull request, making it harder to review)
+
+ When you are done, try "%s -s" to create the pull request.
+
+ See the wiki for more information:
+ * https://github.com/neovim/neovim/wiki/Merging-patches-from-upstream-vim
+' "${vim_version}" "${BASENAME}" "${BASENAME}"
}
hub_pr() {
@@ -221,20 +300,21 @@ submit_pr() {
exit 1
fi
- cd "${NEOVIM_SOURCE_DIR}"
+ cd "${NVIM_SOURCE_DIR}"
local checked_out_branch
checked_out_branch="$(git rev-parse --abbrev-ref HEAD)"
if [[ "${checked_out_branch}" != ${BRANCH_PREFIX}* ]]; then
- echo "✘ Current branch '${checked_out_branch}' doesn't seem to be a vim-patch branch."
+ msg_err "Current branch '${checked_out_branch}' doesn't seem to be a vim-patch branch."
exit 1
fi
local git_remote
git_remote="$(find_git_remote)"
local pr_body
- pr_body="$(git log --reverse --format='#### %s%n%n%b%n' "${git_remote}"/master..HEAD)"
+ pr_body="$(git log --grep=vim-patch --reverse --format='#### %s%n%n%b%n' "${git_remote}"/master..HEAD)"
local patches
- patches=("$(git log --reverse --format='%s' "${git_remote}"/master..HEAD)")
+ # Extract just the "vim-patch:X.Y.ZZZZ" or "vim-patch:sha" portion of each log
+ patches=("$(git log --grep=vim-patch --reverse --format='%s' "${git_remote}"/master..HEAD | sed 's/: .*//')")
patches=(${patches[@]//vim-patch:}) # Remove 'vim-patch:' prefix for each item in array.
local pr_title="${patches[*]}" # Create space-separated string from array.
pr_title="${pr_title// /,}" # Replace spaces with commas.
@@ -245,133 +325,173 @@ submit_pr() {
if [[ $push_first -ne 0 ]]; then
echo "Pushing to 'origin/${checked_out_branch}'."
output="$(git push origin "${checked_out_branch}" 2>&1)" &&
- echo "✔ ${output}" ||
- (echo "✘ ${output}"; git reset --soft HEAD^1; false)
+ msg_ok "${output}" ||
+ (msg_err "${output}"; false)
echo
fi
echo "Creating pull request."
output="$(${submit_fn} "${pr_message}" 2>&1)" &&
- echo "✔ ${output}" ||
- (echo "✘ ${output}"; false)
+ msg_ok "${output}" ||
+ (msg_err "${output}"; false)
echo
echo "Cleaning up files."
local patch_file
for patch_file in "${patches[@]}"; do
patch_file="vim-${patch_file}.patch"
- if [[ ! -f "${NEOVIM_SOURCE_DIR}/${patch_file}" ]]; then
+ if [[ ! -f "${NVIM_SOURCE_DIR}/${patch_file}" ]]; then
continue
fi
- rm -- "${NEOVIM_SOURCE_DIR}/${patch_file}"
- echo "✔ Removed '${NEOVIM_SOURCE_DIR}/${patch_file}'."
+ rm -- "${NVIM_SOURCE_DIR}/${patch_file}"
+ msg_ok "Removed '${NVIM_SOURCE_DIR}/${patch_file}'."
done
}
-list_vim_patches() {
- get_vim_sources
+# Gets all Vim commits since the "start" commit.
+list_vim_commits() { (
+ cd "${VIM_SOURCE_DIR}" && git log --reverse --format='%H' v8.0.0000..HEAD
+) }
+
+# Prints all (sorted) "vim-patch:xxx" tokens found in the Nvim git log.
+list_vimpatch_tokens() {
+ local tokens
+ # Find all "vim-patch:xxx" tokens in the Nvim git log.
+ tokens="$(cd "${NVIM_SOURCE_DIR}" && git log -E --grep='vim-patch:[^ ]+' | grep 'vim-patch')"
+ echo "$tokens" | grep -E 'vim-patch:[^ ,{]{7,}' \
+ | sed 's/.*\(vim-patch:[.0-9a-z]\+\).*/\1/' \
+ | sort \
+ | uniq
+}
- printf "\nVim patches missing from Neovim:\n"
+# Prints all patch-numbers (for the current v:version) for which there is
+# a "vim-patch:xxx" token in the Nvim git log.
+list_vimpatch_numbers() {
+ # Transform "vim-patch:X.Y.ZZZZ" to "ZZZZ".
+ list_vimpatch_tokens | while read vimpatch_token; do
+ echo "$vimpatch_token" | grep '8\.0\.' | sed 's/.*vim-patch:8\.0\.\([0-9a-z]\+\).*/\1/'
+ done
+}
- # Get commits since 7.4.602.
- local vim_commits
- vim_commits="$(cd "${VIM_SOURCE_DIR}" && git log --reverse --format='%H' v7.4.602..HEAD)"
+# Prints a newline-delimited list of Vim commits, for use by scripts.
+list_missing_vimpatches() {
+ local tokens vim_commit vim_commits is_missing vim_tag patch_number
- local vim_commit
+ # Find all "vim-patch:xxx" tokens in the Nvim git log.
+ tokens="$(list_vimpatch_tokens)"
+
+ # Get missing Vim commits
+ vim_commits="$(list_vim_commits)"
for vim_commit in ${vim_commits}; do
- local is_missing
- local vim_tag
- # This fails for untagged commits (e.g., runtime file updates) so mask the return status
- vim_tag="$(cd "${VIM_SOURCE_DIR}" && git describe --tags --exact-match "${vim_commit}" 2>/dev/null)" || true
- if [[ -n "${vim_tag}" ]]; then
- local patch_number="${vim_tag:5}" # Remove prefix like "v7.4."
- # Tagged Vim patch, check version.c:
- is_missing="$(sed -n '/static int included_patches/,/}/p' "${NEOVIM_SOURCE_DIR}/src/nvim/version.c" |
- grep -x -e "[[:space:]]*//[[:space:]]${patch_number} NA.*" -e "[[:space:]]*${patch_number}," >/dev/null && echo "false" || echo "true")"
+ # Check for vim-patch:<commit_hash> (usually runtime updates).
+ is_missing="$(echo "$tokens" | >/dev/null 2>&1 grep "vim\-patch:${vim_commit:0:7}" && echo false || echo true)"
+
+ if ! [ "$is_missing" = "false" ] \
+ && vim_tag="$(cd "${VIM_SOURCE_DIR}" && git describe --tags --exact-match "${vim_commit}" 2>/dev/null)"
+ then
+ # Vim version number (not commit hash).
+ # Check for vim-patch:<tag> (not commit hash).
+ patch_number="${vim_tag:1}" # "v7.4.0001" => "7.4.0001"
+ is_missing="$(echo "$tokens" | >/dev/null 2>&1 grep "vim\-patch:${patch_number}" && echo false || echo true)"
vim_commit="${vim_tag#v}"
- if (cd "${VIM_SOURCE_DIR}" && git show --name-only "v${vim_commit}" 2>/dev/null) | grep -q ^runtime; then
- vim_commit="${vim_commit} (+runtime)"
- fi
- else
- # Untagged Vim patch (e.g. runtime updates), check the Neovim git log:
- is_missing="$(cd "${NEOVIM_SOURCE_DIR}" &&
- git log -1 --no-merges --grep="vim\-patch:${vim_commit:0:7}" --pretty=format:false)"
fi
- if [[ ${is_missing} != "false" ]]; then
- echo " • ${vim_commit}"
+ if ! [ "$is_missing" = "false" ]; then
+ echo "${vim_commit}"
fi
done
+}
- echo
- echo "Instructions:"
- echo
- echo " To port one of the above patches to Neovim, execute"
- echo " this script with the patch revision as argument and"
- echo " follow the instructions."
- echo
- echo " Examples: '${BASENAME} -p 7.4.487'"
- echo " '${BASENAME} -p 1e8ebf870720e7b671f98f22d653009826304c4f'"
- echo
- echo " NOTE: Please port the _oldest_ patch if you possibly can."
- echo " Out-of-order patches increase the possibility of bugs."
+# Prints a human-formatted list of Vim commits, with instructional messages.
+show_vimpatches() {
+ get_vim_sources
+ printf "\nVim patches missing from Neovim:\n"
+
+ list_missing_vimpatches | while read vim_commit; do
+ if (cd "${VIM_SOURCE_DIR}" && git --no-pager show --color=never --name-only "v${vim_commit}" 2>/dev/null) | grep -q ^runtime; then
+ printf ' • %s (+runtime)\n' "${vim_commit}"
+ else
+ printf ' • %s\n' "${vim_commit}"
+ fi
+ done
+
+ printf "Instructions:
+
+ To port one of the above patches to Neovim, execute
+ this script with the patch revision as argument and
+ follow the instructions.
+
+ Examples: '%s -p 7.4.487'
+ '%s -p 1e8ebf870720e7b671f98f22d653009826304c4f'
+
+ NOTE: Please port the _oldest_ patch if you possibly can.
+ Out-of-order patches increase the possibility of bugs.
+" "${BASENAME}" "${BASENAME}"
}
review_commit() {
- local neovim_commit_url="${1}"
- local neovim_patch_url="${neovim_commit_url}.patch"
+ local nvim_commit_url="${1}"
+ local nvim_patch_url="${nvim_commit_url}.patch"
local git_patch_prefix='Subject: \[PATCH\] '
- local neovim_patch
- neovim_patch="$(curl -Ssf "${neovim_patch_url}")"
+ local nvim_patch
+ nvim_patch="$(curl -Ssf "${nvim_patch_url}")"
local vim_version
- vim_version="$(head -n 4 <<< "${neovim_patch}" | sed -n "s/${git_patch_prefix}vim-patch:\([a-z0-9.]*\)$/\1/p")"
+ vim_version="$(head -n 4 <<< "${nvim_patch}" | sed -n 's/'"${git_patch_prefix}"'vim-patch:\([a-z0-9.]*\)\(:.*\)\{0,1\}$/\1/p')"
echo
if [[ -n "${vim_version}" ]]; then
- echo "✔ Detected Vim patch '${vim_version}'."
+ msg_ok "Detected Vim patch '${vim_version}'."
else
- echo "✘ Could not detect the Vim patch number."
+ msg_err "Could not detect the Vim patch number."
echo " This script assumes that the PR contains only commits"
echo " with 'vim-patch:XXX' in their title."
+ echo
+ printf -- '%s\n\n' "$(head -n 4 <<< "${nvim_patch}")"
+ local reply
+ read -p "Continue reviewing (y/N)? " -n 1 -r reply
+ if [[ "${reply}" == y ]]; then
+ echo
+ return
+ fi
exit 1
fi
assign_commit_details "${vim_version}"
- local vim_patch_url="${vim_commit_url}.patch"
+ echo
+ echo "Creating files."
+ echo "${nvim_patch}" > "${NVIM_SOURCE_DIR}/n${patch_file}"
+ msg_ok "Saved pull request diff to '${NVIM_SOURCE_DIR}/n${patch_file}'."
+ CREATED_FILES+=("${NVIM_SOURCE_DIR}/n${patch_file}")
+
+ local nvim="nvim -u NORC -n -i NONE --headless"
+ 2>/dev/null $nvim --cmd 'set dir=/tmp' +'1,/^$/g/^ /-1join' +w +q "${NVIM_SOURCE_DIR}/n${patch_file}"
local expected_commit_message
expected_commit_message="$(commit_message)"
local message_length
message_length="$(wc -l <<< "${expected_commit_message}")"
local commit_message
- commit_message="$(tail -n +4 <<< "${neovim_patch}" | head -n "${message_length}")"
+ 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
- echo "✔ Found expected commit message."
+ msg_ok "Found expected commit message."
else
- echo "✘ Wrong commit message."
+ msg_err "Wrong commit message."
echo " Expected:"
echo "${expected_commit_message}"
echo " Actual:"
echo "${commit_message#${git_patch_prefix}}"
fi
- echo
- echo "Creating files."
- echo "${neovim_patch}" > "${NEOVIM_SOURCE_DIR}/n${patch_file}"
- echo "✔ Saved pull request diff to '${NEOVIM_SOURCE_DIR}/n${patch_file}'."
- CREATED_FILES+=("${NEOVIM_SOURCE_DIR}/n${patch_file}")
-
- curl -Ssfo "${NEOVIM_SOURCE_DIR}/${patch_file}" "${vim_patch_url}"
- echo "✔ Saved Vim diff to '${NEOVIM_SOURCE_DIR}/${patch_file}'."
- CREATED_FILES+=("${NEOVIM_SOURCE_DIR}/${patch_file}")
+ get_vimpatch "${vim_version}"
+ CREATED_FILES+=("${NVIM_SOURCE_DIR}/${patch_file}")
echo
echo "Launching nvim."
- nvim -c "cd ${NEOVIM_SOURCE_DIR}" \
- -O "${NEOVIM_SOURCE_DIR}/${patch_file}" "${NEOVIM_SOURCE_DIR}/n${patch_file}"
+ nvim -c "cd ${NVIM_SOURCE_DIR}" \
+ -O "${NVIM_SOURCE_DIR}/${patch_file}" "${NVIM_SOURCE_DIR}/n${patch_file}"
}
review_pr() {
@@ -397,7 +517,7 @@ review_pr() {
if [[ "${pr_commit_url}" != "${pr_commit_urls[-1]}" ]]; then
read -p "Continue with next commit (Y/n)? " -n 1 -r reply
echo
- if [[ ! "${reply}" =~ ^[Yy]$ ]]; then
+ if [[ "${reply}" == n ]]; then
break
fi
fi
@@ -406,18 +526,34 @@ review_pr() {
clean_files
}
-while getopts "hlp:r:s" opt; do
+while getopts "hlLMVp:P:g:r:s" opt; do
case ${opt} in
h)
usage
exit 0
;;
l)
- list_vim_patches
+ show_vimpatches
+ exit 0
+ ;;
+ L)
+ list_missing_vimpatches
+ exit 0
+ ;;
+ M)
+ list_vimpatch_numbers
exit 0
;;
p)
- get_vim_patch "${OPTARG}"
+ stage_patch "${OPTARG}"
+ exit 0
+ ;;
+ P)
+ stage_patch "${OPTARG}" TRY_APPLY
+ exit 0
+ ;;
+ g)
+ get_vimpatch "${OPTARG}"
exit 0
;;
r)
@@ -428,6 +564,10 @@ while getopts "hlp:r:s" opt; do
submit_pr
exit 0
;;
+ V)
+ get_vim_sources
+ exit 0
+ ;;
*)
exit 1
;;