This commit is contained in:
Shawn Anderson 2021-06-13 17:08:47 -07:00
parent 9978c4905c
commit 03dd656039
17 changed files with 1029 additions and 385 deletions

View File

@ -1,19 +1,19 @@
complete -c nvm --exclusive --long version -d "Print version" complete --command nvm --exclusive --long version --description "Print version"
complete -c nvm --exclusive --long help -d "Print this help message" complete --command nvm --exclusive --long help --description "Print help"
complete -c nvm --exclusive --condition "__fish_use_subcommand" -a install -d "Download and activate the specified Node version" complete --command nvm --exclusive --condition __fish_use_subcommand --arguments install --description "Download and activate the specified Node version"
complete -c nvm --exclusive --condition "__fish_use_subcommand" -a use -d "Activate a version in the current shell" complete --command nvm --exclusive --condition __fish_use_subcommand --arguments use --description "Activate a version in the current shell"
complete -c nvm --exclusive --condition "__fish_use_subcommand" -a list -d "List installed versions" complete --command nvm --exclusive --condition __fish_use_subcommand --arguments list --description "List installed versions"
complete -c nvm --exclusive --condition "__fish_use_subcommand" -a list-remote -d "List versions available to install matching optional regex" complete --command nvm --exclusive --condition __fish_use_subcommand --arguments list-remote --description "List versions available to install matching optional regex"
complete -c nvm --exclusive --condition "__fish_use_subcommand" -a current -d "Print the currently-active version" complete --command nvm --exclusive --condition __fish_use_subcommand --arguments current --description "Print the currently-active version"
complete -c nvm --exclusive --condition "__fish_seen_subcommand_from install" -a "( complete --command nvm --exclusive --condition "__fish_seen_subcommand_from install" --arguments "(
test -e $nvm_data && string split ' ' <$nvm_data/.index test -e $nvm_data && string split ' ' <$nvm_data/.index
)" )"
complete -c nvm --exclusive --condition "__fish_seen_subcommand_from use" -a "(_nvm_list | string split ' ')" complete --command nvm --exclusive --condition "__fish_seen_subcommand_from use" --arguments "(_nvm_list | string split ' ')"
complete -c nvm --exclusive --condition "__fish_use_subcommand" -a uninstall -d "Uninstall a version" complete --command nvm --exclusive --condition __fish_use_subcommand --arguments uninstall --description "Uninstall a version"
complete -c nvm --exclusive --condition "__fish_seen_subcommand_from uninstall" -a "( complete --command nvm --exclusive --condition "__fish_seen_subcommand_from uninstall" --arguments "(
_nvm_list | string split ' ' | string replace system '' _nvm_list | string split ' ' | string replace system ''
)" )"
complete -c nvm --exclusive --condition "__fish_seen_subcommand_from use uninstall" -a "( complete --command nvm --exclusive --condition "__fish_seen_subcommand_from use uninstall" --arguments "(
set --query nvm_default_version && echo default set --query nvm_default_version && echo default
)" )"

View File

@ -0,0 +1,142 @@
function __fish_poetry_b179e9296ef2e34b_complete_no_subcommand
for i in (commandline -opc)
if contains -- $i about add build cache check config debug env export help init install lock new publish remove run search self shell show update version
return 1
end
end
return 0
end
# global options
complete -c poetry -n '__fish_poetry_b179e9296ef2e34b_complete_no_subcommand' -l ansi -d 'Force ANSI output'
complete -c poetry -n '__fish_poetry_b179e9296ef2e34b_complete_no_subcommand' -l help -d 'Display this help message'
complete -c poetry -n '__fish_poetry_b179e9296ef2e34b_complete_no_subcommand' -l no-ansi -d 'Disable ANSI output'
complete -c poetry -n '__fish_poetry_b179e9296ef2e34b_complete_no_subcommand' -l no-interaction -d 'Do not ask any interactive question'
complete -c poetry -n '__fish_poetry_b179e9296ef2e34b_complete_no_subcommand' -l quiet -d 'Do not output any message'
complete -c poetry -n '__fish_poetry_b179e9296ef2e34b_complete_no_subcommand' -l verbose -d 'Increase the verbosity of messages: "-v" for normal output, "-vv" for more verbose output and "-vvv" for debug'
complete -c poetry -n '__fish_poetry_b179e9296ef2e34b_complete_no_subcommand' -l version -d 'Display this application version'
# commands
complete -c poetry -f -n '__fish_poetry_b179e9296ef2e34b_complete_no_subcommand' -a about -d 'Shows information about Poetry.'
complete -c poetry -f -n '__fish_poetry_b179e9296ef2e34b_complete_no_subcommand' -a add -d 'Adds a new dependency to pyproject.toml.'
complete -c poetry -f -n '__fish_poetry_b179e9296ef2e34b_complete_no_subcommand' -a build -d 'Builds a package, as a tarball and a wheel by default.'
complete -c poetry -f -n '__fish_poetry_b179e9296ef2e34b_complete_no_subcommand' -a cache -d 'Interact with Poetry\'s cache'
complete -c poetry -f -n '__fish_poetry_b179e9296ef2e34b_complete_no_subcommand' -a check -d 'Checks the validity of the pyproject.toml file.'
complete -c poetry -f -n '__fish_poetry_b179e9296ef2e34b_complete_no_subcommand' -a config -d 'Manages configuration settings.'
complete -c poetry -f -n '__fish_poetry_b179e9296ef2e34b_complete_no_subcommand' -a debug -d 'Debug various elements of Poetry.'
complete -c poetry -f -n '__fish_poetry_b179e9296ef2e34b_complete_no_subcommand' -a env -d 'Interact with Poetry\'s project environments.'
complete -c poetry -f -n '__fish_poetry_b179e9296ef2e34b_complete_no_subcommand' -a export -d 'Exports the lock file to alternative formats.'
complete -c poetry -f -n '__fish_poetry_b179e9296ef2e34b_complete_no_subcommand' -a help -d 'Display the manual of a command'
complete -c poetry -f -n '__fish_poetry_b179e9296ef2e34b_complete_no_subcommand' -a init -d 'Creates a basic pyproject.toml file in the current directory.'
complete -c poetry -f -n '__fish_poetry_b179e9296ef2e34b_complete_no_subcommand' -a install -d 'Installs the project dependencies.'
complete -c poetry -f -n '__fish_poetry_b179e9296ef2e34b_complete_no_subcommand' -a lock -d 'Locks the project dependencies.'
complete -c poetry -f -n '__fish_poetry_b179e9296ef2e34b_complete_no_subcommand' -a new -d 'Creates a new Python project at <path>.'
complete -c poetry -f -n '__fish_poetry_b179e9296ef2e34b_complete_no_subcommand' -a publish -d 'Publishes a package to a remote repository.'
complete -c poetry -f -n '__fish_poetry_b179e9296ef2e34b_complete_no_subcommand' -a remove -d 'Removes a package from the project dependencies.'
complete -c poetry -f -n '__fish_poetry_b179e9296ef2e34b_complete_no_subcommand' -a run -d 'Runs a command in the appropriate environment.'
complete -c poetry -f -n '__fish_poetry_b179e9296ef2e34b_complete_no_subcommand' -a search -d 'Searches for packages on remote repositories.'
complete -c poetry -f -n '__fish_poetry_b179e9296ef2e34b_complete_no_subcommand' -a self -d 'Interact with Poetry directly.'
complete -c poetry -f -n '__fish_poetry_b179e9296ef2e34b_complete_no_subcommand' -a shell -d 'Spawns a shell within the virtual environment.'
complete -c poetry -f -n '__fish_poetry_b179e9296ef2e34b_complete_no_subcommand' -a show -d 'Shows information about packages.'
complete -c poetry -f -n '__fish_poetry_b179e9296ef2e34b_complete_no_subcommand' -a update -d 'Update the dependencies as according to the pyproject.toml file.'
complete -c poetry -f -n '__fish_poetry_b179e9296ef2e34b_complete_no_subcommand' -a version -d 'Shows the version of the project or bumps it when a valid bump rule is provided.'
# command options
# about
# add
complete -c poetry -A -n '__fish_seen_subcommand_from add' -l allow-prereleases -d 'Accept prereleases.'
complete -c poetry -A -n '__fish_seen_subcommand_from add' -l dev -d 'Add as a development dependency.'
complete -c poetry -A -n '__fish_seen_subcommand_from add' -l dry-run -d 'Output the operations but do not execute anything (implicitly enables --verbose).'
complete -c poetry -A -n '__fish_seen_subcommand_from add' -l extras -d 'Extras to activate for the dependency.'
complete -c poetry -A -n '__fish_seen_subcommand_from add' -l lock -d 'Do not perform operations (only update the lockfile).'
complete -c poetry -A -n '__fish_seen_subcommand_from add' -l optional -d 'Add as an optional dependency.'
complete -c poetry -A -n '__fish_seen_subcommand_from add' -l platform -d 'Platforms for which the dependency must be installed.'
complete -c poetry -A -n '__fish_seen_subcommand_from add' -l python -d 'Python version for which the dependency must be installed.'
complete -c poetry -A -n '__fish_seen_subcommand_from add' -l source -d 'Name of the source to use to install the package.'
# build
complete -c poetry -A -n '__fish_seen_subcommand_from build' -l format -d 'Limit the format to either sdist or wheel.'
# cache
# check
# config
complete -c poetry -A -n '__fish_seen_subcommand_from config' -l list -d 'List configuration settings.'
complete -c poetry -A -n '__fish_seen_subcommand_from config' -l local -d 'Set/Get from the project\'s local configuration.'
complete -c poetry -A -n '__fish_seen_subcommand_from config' -l unset -d 'Unset configuration setting.'
# debug
# env
# export
complete -c poetry -A -n '__fish_seen_subcommand_from export' -l dev -d 'Include development dependencies.'
complete -c poetry -A -n '__fish_seen_subcommand_from export' -l extras -d 'Extra sets of dependencies to include.'
complete -c poetry -A -n '__fish_seen_subcommand_from export' -l format -d 'Format to export to. Currently, only requirements.txt is supported.'
complete -c poetry -A -n '__fish_seen_subcommand_from export' -l output -d 'The name of the output file.'
complete -c poetry -A -n '__fish_seen_subcommand_from export' -l with-credentials -d 'Include credentials for extra indices.'
complete -c poetry -A -n '__fish_seen_subcommand_from export' -l without-hashes -d 'Exclude hashes from the exported file.'
# help
# init
complete -c poetry -A -n '__fish_seen_subcommand_from init' -l author -d 'Author name of the package.'
complete -c poetry -A -n '__fish_seen_subcommand_from init' -l dependency -d 'Package to require, with an optional version constraint, e.g. requests:^2.10.0 or requests=2.11.1.'
complete -c poetry -A -n '__fish_seen_subcommand_from init' -l description -d 'Description of the package.'
complete -c poetry -A -n '__fish_seen_subcommand_from init' -l dev-dependency -d 'Package to require for development, with an optional version constraint, e.g. requests:^2.10.0 or requests=2.11.1.'
complete -c poetry -A -n '__fish_seen_subcommand_from init' -l license -d 'License of the package.'
complete -c poetry -A -n '__fish_seen_subcommand_from init' -l name -d 'Name of the package.'
complete -c poetry -A -n '__fish_seen_subcommand_from init' -l python -d 'Compatible Python versions.'
# install
complete -c poetry -A -n '__fish_seen_subcommand_from install' -l dry-run -d 'Output the operations but do not execute anything (implicitly enables --verbose).'
complete -c poetry -A -n '__fish_seen_subcommand_from install' -l extras -d 'Extra sets of dependencies to install.'
complete -c poetry -A -n '__fish_seen_subcommand_from install' -l no-dev -d 'Do not install the development dependencies.'
complete -c poetry -A -n '__fish_seen_subcommand_from install' -l no-root -d 'Do not install the root package (the current project).'
complete -c poetry -A -n '__fish_seen_subcommand_from install' -l remove-untracked -d 'Removes packages not present in the lock file.'
# lock
complete -c poetry -A -n '__fish_seen_subcommand_from lock' -l no-update -d 'Do not update locked versions, only refresh lock file.'
# new
complete -c poetry -A -n '__fish_seen_subcommand_from new' -l name -d 'Set the resulting package name.'
complete -c poetry -A -n '__fish_seen_subcommand_from new' -l src -d 'Use the src layout for the project.'
# publish
complete -c poetry -A -n '__fish_seen_subcommand_from publish' -l build -d 'Build the package before publishing.'
complete -c poetry -A -n '__fish_seen_subcommand_from publish' -l cert -d 'Certificate authority to access the repository.'
complete -c poetry -A -n '__fish_seen_subcommand_from publish' -l client-cert -d 'Client certificate to access the repository.'
complete -c poetry -A -n '__fish_seen_subcommand_from publish' -l dry-run -d 'Perform all actions except upload the package.'
complete -c poetry -A -n '__fish_seen_subcommand_from publish' -l password -d 'The password to access the repository.'
complete -c poetry -A -n '__fish_seen_subcommand_from publish' -l repository -d 'The repository to publish the package to.'
complete -c poetry -A -n '__fish_seen_subcommand_from publish' -l username -d 'The username to access the repository.'
# remove
complete -c poetry -A -n '__fish_seen_subcommand_from remove' -l dev -d 'Remove a package from the development dependencies.'
complete -c poetry -A -n '__fish_seen_subcommand_from remove' -l dry-run -d 'Output the operations but do not execute anything (implicitly enables --verbose).'
# run
# search
# self
# shell
# show
complete -c poetry -A -n '__fish_seen_subcommand_from show' -l all -d 'Show all packages (even those not compatible with current system).'
complete -c poetry -A -n '__fish_seen_subcommand_from show' -l latest -d 'Show the latest version.'
complete -c poetry -A -n '__fish_seen_subcommand_from show' -l no-dev -d 'Do not list the development dependencies.'
complete -c poetry -A -n '__fish_seen_subcommand_from show' -l outdated -d 'Show the latest version but only for packages that are outdated.'
complete -c poetry -A -n '__fish_seen_subcommand_from show' -l tree -d 'List the dependencies as a tree.'
# update
complete -c poetry -A -n '__fish_seen_subcommand_from update' -l dry-run -d 'Output the operations but do not execute anything (implicitly enables --verbose).'
complete -c poetry -A -n '__fish_seen_subcommand_from update' -l lock -d 'Do not perform operations (only update the lockfile).'
complete -c poetry -A -n '__fish_seen_subcommand_from update' -l no-dev -d 'Do not update the development dependencies.'
# version
complete -c poetry -A -n '__fish_seen_subcommand_from version' -l short -d 'Output the version number only'

View File

@ -1,23 +1,28 @@
set --query XDG_DATA_HOME \ function _nvm_install --on-event nvm_install
&& set --global nvm_data $XDG_DATA_HOME/nvm \ set --query XDG_DATA_HOME || set --local XDG_DATA_HOME ~/.local/share
|| set --global nvm_data ~/.local/share/nvm set --universal nvm_data $XDG_DATA_HOME/nvm
set --query nvm_mirror || set --global nvm_mirror https://nodejs.org/dist set --query nvm_mirror || set --universal nvm_mirror https://nodejs.org/dist
if set --query nvm_default_version && ! set --query nvm_current_version
nvm use $nvm_default_version >/dev/null
end
function _nvm_install -e nvm_install
test ! -d $nvm_data && command mkdir -p $nvm_data test ! -d $nvm_data && command mkdir -p $nvm_data
echo "Downloading the Node distribution index for the first time..." 2>/dev/null echo "Downloading the Node distribution index for the first time..." 2>/dev/null
_nvm_index_update $nvm_mirror/index.tab $nvm_data/.index _nvm_index_update $nvm_mirror $nvm_data/.index
end end
function _nvm_uninstall -e nvm_uninstall function _nvm_update --on-event nvm_update
set --query XDG_DATA_HOME || set --local XDG_DATA_HOME ~/.local/share
set --universal nvm_data $XDG_DATA_HOME/nvm
set --query nvm_mirror || set --universal nvm_mirror https://nodejs.org/dist
end
function _nvm_uninstall --on-event nvm_uninstall
command rm -rf $nvm_data command rm -rf $nvm_data
set --query nvm_current_version && _nvm_version_deactivate $nvm_current_version set --query nvm_current_version && _nvm_version_deactivate $nvm_current_version
set --names | string replace --filter --regex "^nvm_" -- "set --erase nvm_" | source set --names | string replace --filter --regex -- "^nvm" "set --erase nvm" | source
functions --erase (functions --all | string match --entire --regex "^_nvm_") functions --erase (functions --all | string match --entire --regex -- "^_nvm_")
complete --erase --command nvm end
end
status is-interactive &&
set --query nvm_default_version && ! set --query nvm_current_version &&
nvm use $nvm_default_version >/dev/null

View File

@ -5,3 +5,4 @@ tuvistavie/fish-completion-helpers
~/.config/fish/fisher/fish-audio ~/.config/fish/fisher/fish-audio
~/.config/fish/fisher/fish-fzf ~/.config/fish/fisher/fish-fzf
danhper/fish-fastdir danhper/fish-fastdir
edc/bass

View File

@ -0,0 +1,138 @@
"""
To be used with a companion fish function like this:
function refish
set -l _x (python /tmp/bass.py source ~/.nvm/nvim.sh ';' nvm use iojs); source $_x; and rm -f $_x
end
"""
from __future__ import print_function
import json
import os
import signal
import subprocess
import sys
import traceback
BASH = 'bash'
FISH_READONLY = [
'PWD', 'SHLVL', 'history', 'pipestatus', 'status', 'version',
'FISH_VERSION', 'fish_pid', 'hostname', '_', 'fish_private_mode'
]
IGNORED = [
'PS1', 'XPC_SERVICE_NAME'
]
def ignored(name):
if name == 'PWD': # this is read only, but has special handling
return False
# ignore other read only variables
if name in FISH_READONLY:
return True
if name in IGNORED or name.startswith("BASH_FUNC"):
return True
return False
def escape(string):
# use json.dumps to reliably escape quotes and backslashes
return json.dumps(string).replace(r'$', r'\$')
def escape_identifier(word):
return escape(word.replace('?', '\\?'))
def comment(string):
return '\n'.join(['# ' + line for line in string.split('\n')])
def gen_script():
# Use the following instead of /usr/bin/env to read environment so we can
# deal with multi-line environment variables (and other odd cases).
env_reader = "%s -c 'import os,json; print(json.dumps({k:v for k,v in os.environ.items()}))'" % (sys.executable)
args = [BASH, '-c', env_reader]
output = subprocess.check_output(args, universal_newlines=True)
old_env = output.strip()
pipe_r, pipe_w = os.pipe()
if sys.version_info >= (3, 4):
os.set_inheritable(pipe_w, True)
command = 'eval $1 && ({}; alias) >&{}'.format(
env_reader,
pipe_w
)
args = [BASH, '-c', command, 'bass', ' '.join(sys.argv[1:])]
p = subprocess.Popen(args, universal_newlines=True, close_fds=False)
os.close(pipe_w)
with os.fdopen(pipe_r) as f:
new_env = f.readline()
alias_str = f.read()
if p.wait() != 0:
raise subprocess.CalledProcessError(
returncode=p.returncode,
cmd=' '.join(sys.argv[1:]),
output=new_env + alias_str
)
new_env = new_env.strip()
old_env = json.loads(old_env)
new_env = json.loads(new_env)
script_lines = []
for k, v in new_env.items():
if ignored(k):
continue
v1 = old_env.get(k)
if not v1:
script_lines.append(comment('adding %s=%s' % (k, v)))
elif v1 != v:
script_lines.append(comment('updating %s=%s -> %s' % (k, v1, v)))
# process special variables
if k == 'PWD':
script_lines.append('cd %s' % escape(v))
continue
else:
continue
if k == 'PATH':
value = ' '.join([escape(directory)
for directory in v.split(':')])
else:
value = escape(v)
script_lines.append('set -g -x %s %s' % (k, value))
for var in set(old_env.keys()) - set(new_env.keys()):
script_lines.append(comment('removing %s' % var))
script_lines.append('set -e %s' % var)
script = '\n'.join(script_lines)
alias_lines = []
for line in alias_str.splitlines():
_, rest = line.split(None, 1)
k, v = rest.split("=", 1)
alias_lines.append("alias " + escape_identifier(k) + "=" + v)
alias = '\n'.join(alias_lines)
return script + '\n' + alias
script_file = os.fdopen(3, 'w')
if not sys.argv[1:]:
print('__bass_usage', file=script_file, end='')
sys.exit(0)
try:
script = gen_script()
except subprocess.CalledProcessError as e:
sys.exit(e.returncode)
except Exception:
print('Bass internal error!', file=sys.stderr)
raise # traceback will output to stderr
except KeyboardInterrupt:
signal.signal(signal.SIGINT, signal.SIG_DFL)
os.kill(os.getpid(), signal.SIGINT)
else:
script_file.write(script)

View File

@ -1,12 +1,12 @@
function _nvm_index_update -a mirror index function _nvm_index_update --argument-names mirror index
command curl --location --silent $mirror | command awk -v OFS=\t ' command curl --location --silent $mirror/index.tab | command awk -v OFS=\t '
/v0.9.12/ { exit } # Unsupported /v0.9.12/ { exit } # Unsupported
NR > 1 { NR > 1 {
print $1 (NR == 2 ? " latest" : $10 != "-" ? " lts/" tolower($10) : "") print $1 (NR == 2 ? " latest" : $10 != "-" ? " lts/" tolower($10) : "")
} }
' > $index.temp && command mv $index.temp $index && return ' >$index.temp 2>/dev/null && command mv $index.temp $index && return
command rm -f $index.temp command rm -f $index.temp
echo "nvm: Invalid index or unavailable host: \"$mirror\"" >&2 echo "nvm: Invalid index or unavailable host: \"$mirror\"" >&2
return 1 return 1
end end

View File

@ -1,11 +1,11 @@
function _nvm_list function _nvm_list
set --local versions $nvm_data/* set --local versions $nvm_data/*
set --query versions[1] \ set --query versions[1] &&
&& string match --entire --regex (string match --regex "v\d.+" $versions \ string match --entire --regex -- (string match --regex -- "v\d.+" $versions |
| string escape --style=regex \ string escape --style=regex |
| string join "|" string join "|"
) <$nvm_data/.index ) <$nvm_data/.index
command --all node | string match --quiet --invert --regex "^$nvm_data" \ command --all node |
&& echo system string match --quiet --invert --regex -- "^$nvm_data" && echo system
end end

View File

@ -1,4 +1,4 @@
function _nvm_version_activate -a v function _nvm_version_activate --argument-names v
set --global --export nvm_current_version $v set --global --export nvm_current_version $v
set --prepend PATH $nvm_data/$v/bin set --prepend PATH $nvm_data/$v/bin
end end

View File

@ -1,5 +1,5 @@
function _nvm_version_deactivate -a v function _nvm_version_deactivate --argument-names v
test "$nvm_current_version" = "$v" && set --erase nvm_current_version test "$nvm_current_version" = "$v" && set --erase nvm_current_version
set --local index (contains --index -- $nvm_data/$v/bin $PATH) \ set --local index (contains --index -- $nvm_data/$v/bin $PATH) &&
&& set --erase PATH[$index] set --erase PATH[$index]
end end

View File

@ -0,0 +1,29 @@
function bass
set -l bash_args $argv
set -l bass_debug
if test "$bash_args[1]_" = '-d_'
set bass_debug true
set -e bash_args[1]
end
set -l script_file (mktemp)
if command -v python3 >/dev/null 2>&1
command python3 -sS (dirname (status -f))/__bass.py $bash_args 3>$script_file
else
command python -sS (dirname (status -f))/__bass.py $bash_args 3>$script_file
end
set -l bass_status $status
if test $bass_status -ne 0
return $bass_status
end
if test -n "$bass_debug"
cat $script_file
end
source $script_file
command rm $script_file
end
function __bass_usage
echo "Usage: bass [-d] <bash-command>"
end

View File

@ -1 +1 @@
/home/shawn/.config/fish/fisher/fish-fzf/fzf_key_bindings.fish /home/shawn/.fzf/shell/key-bindings.fish

View File

@ -1,198 +1,237 @@
function nvm -a cmd v -d "Node version manager" # ~/.config/fish/functions/nvm.fish
if test -z "$v" && contains -- "$cmd" install use function nvm
for file in .nvmrc .node-version bass source ~/.nvm/nvm.sh --no-use ';' nvm $argv
set file (_nvm_find_up $PWD $file) && read v <$file && break end
end
if test -z "$v" # ~/.config/fish/functions/nvm_find_nvmrc.fish
echo "nvm: Invalid version or missing \".nvmrc\" file" >&2 function nvm_find_nvmrc
return 1 bass source ~/.nvm/nvm.sh --no-use ';' nvm_find_nvmrc
end end
end
# ~/.config/fish/functions/load_nvm.fish
switch "$cmd" function load_nvm --on-variable="PWD"
case -v --version set -l default_node_version (nvm version default)
echo "nvm, version 2.0.1" set -l node_version (nvm version)
case "" -h --help set -l nvmrc_path (nvm_find_nvmrc)
echo "Usage: nvm install <version> Download and activate the specified Node version" if test -n "$nvmrc_path"
echo " nvm install Install version from nearest .nvmrc file" set -l nvmrc_node_version (nvm version (cat $nvmrc_path))
echo " nvm use <version> Activate a version in the current shell" if test "$nvmrc_node_version" = "N/A"
echo " nvm use Activate version from nearest .nvmrc file" nvm install (cat $nvmrc_path)
echo " nvm list List installed versions" else if test nvmrc_node_version != node_version
echo " nvm list-remote List versions available to install" nvm use $nvmrc_node_version
echo " nvm list-remote <regex> List versions matching a given regular expression"
echo " nvm current Print the currently-active version"
echo " nvm uninstall <version> Uninstall a version"
echo "Options:"
echo " -v or --version Print version"
echo " -h or --help Print this help message"
echo "Variables:"
echo " nvm_mirror Set mirror for Node binaries"
echo " nvm_default_version Set the default version for new shells"
case install
_nvm_index_update $nvm_mirror/index.tab $nvm_data/.index || return
string match --entire --regex (_nvm_version_match $v) <$nvm_data/.index | read v alias
if ! set --query v[1]
echo "nvm: Invalid version number or alias: \"$argv[2..-1]\"" >&2
return 1
end
if test ! -e $nvm_data/$v
set --local os (uname -s | string lower)
set --local ext tar.gz
set --local arch (uname -m)
switch $os
case aix
set arch ppc64
case sunos
case linux
case darwin
case {MSYS_NT,MINGW\*_NT}\*
set os win
set ext zip
case \*
echo "nvm: Unsupported operating system: \"$os\"" >&2
return 1
end
switch $arch
case i\*86
set arch x86
case x86_64
set arch x64
case armv6 armv6l
set arch armv6l
case armv7 armv7l
set arch armv7l
case armv8 armv8l aarch64
set arch arm64
end
set --local dir "node-$v-$os-$arch"
set --local url $nvm_mirror/$v/$dir.$ext
command mkdir -p $nvm_data/$v
echo -e "Installing Node \x1b[1m$v\x1b[22m $alias"
echo -e "Fetching \x1b[4m$url\x1b[24m\x1b[7m"
if ! command curl --progress-bar --location $url \
| command tar --extract --gzip --directory $nvm_data/$v 2>/dev/null
command rm -rf $nvm_data/$v
echo -e "\033[F\33[2K\x1b[0mnvm: Invalid mirror or host unavailable: \"$url\"" >&2
return 1
end
echo -en "\033[F\33[2K\x1b[0m"
if test "$os" = "win"
command mv $nvm_data/$v/$dir $nvm_data/$v/bin
else
command mv $nvm_data/$v/$dir/* $nvm_data/$v
command rm -rf $nvm_data/$v/$dir
end
end
if test $v != "$nvm_current_version"
set --query nvm_current_version && _nvm_version_deactivate $nvm_current_version
_nvm_version_activate $v
end
printf "Now using Node %s (npm %s) %s\n" (_nvm_node_info)
case use
test $v = default && set v $nvm_default_version
_nvm_list | string match --entire --regex (_nvm_version_match $v) | read v __
if ! set --query v[1]
echo "nvm: Node version not installed or invalid: \"$argv[2..-1]\"" >&2
return 1
end
if test $v != "$nvm_current_version"
set --query nvm_current_version && _nvm_version_deactivate $nvm_current_version
test $v != system && _nvm_version_activate $v
end
printf "Now using Node %s (npm %s) %s\n" (_nvm_node_info)
case uninstall
if test -z "$v"
echo "nvm: Not enough arguments for command: \"$cmd\"" >&2
return 1
end
test $v = default && test ! -z "$nvm_default_version" && set v $nvm_default_version
_nvm_list | string match --entire --regex (_nvm_version_match $v) | read v __
if ! set -q v[1]
echo "nvm: Node version not installed or invalid: \"$argv[2..-1]\"" >&2
return 1
end
echo -e "Uninstalling Node $v "(command --search node | string replace ~ \~)
_nvm_version_deactivate $v
command rm -rf $nvm_data/$v
case current
_nvm_current
case ls list
_nvm_list | _nvm_list_format (_nvm_current) $argv[2]
case lsr {ls,list}-remote
_nvm_index_update $nvm_mirror/index.tab $nvm_data/.index || return
_nvm_list | command awk '
FNR == NR && FILENAME == "-" {
is_local[$1]++
next
} { print $0 (is_local[$1] ? " ✓" : "") }
' - $nvm_data/.index | _nvm_list_format (_nvm_current) $argv[2]
case \*
echo "nvm: Unknown flag or command: \"$cmd\" (see `nvm -h`)" >&2
return 1
end end
else if test "$node_version" != "$default_node_version"
echo "Reverting to default Node version"
nvm use default
end
end end
function _nvm_find_up -a path file # ~/.config/fish/config.fish
test -e "$path/$file" && echo $path/$file || begin # You must call it on initialization or listening to directory switching won't work
test "$path" != / || return load_nvm
_nvm_find_up (command dirname $path) $file #function nvm --argument-names cmd v --description "Node version manager"
end #if test -z "$v" && contains -- "$cmd" install use
end #for file in .nvmrc .node-version
#set file (_nvm_find_up $PWD $file) && read v <$file && break
#end
#if test -z "$v"
#echo "nvm: Invalid version or missing \".nvmrc\" file" >&2
#return 1
#end
#end
function _nvm_version_match -a v #switch "$cmd"
string replace --regex '^v?(\d+|\d+\.\d+)$' 'v$1.' $v \ #case -v --version
| string replace --filter --regex '^v?(\d+)' 'v$1' \ #echo "nvm, version 2.2.5"
| string escape --style=regex || string lower '\b'$v'(?:/\w+)?$' #case "" -h --help
end #echo "Usage: nvm install <version> Download and activate the specified Node version"
#echo " nvm install Install version from nearest .nvmrc file"
#echo " nvm use <version> Activate a version in the current shell"
#echo " nvm use Activate version from nearest .nvmrc file"
#echo " nvm list List installed versions"
#echo " nvm list-remote List versions available to install"
#echo " nvm list-remote <regex> List versions matching a given regular expression"
#echo " nvm current Print the currently-active version"
#echo " nvm uninstall <version> Uninstall a version"
#echo "Options:"
#echo " -v or --version Print version"
#echo " -h or --help Print this help message"
#echo "Variables:"
#echo " nvm_arch Override architecture, e.g. x64-musl"
#echo " nvm_mirror Set the Node download mirror"
#echo " nvm_default_version Set the default version for new shells"
#case install
#_nvm_index_update $nvm_mirror $nvm_data/.index || return
function _nvm_list_format -a current filter #string match --entire --regex -- (_nvm_version_match $v) <$nvm_data/.index | read v alias
command awk -v current="$current" -v filter="$filter" '
$0 ~ filter {
len = ++i
indent = (n = length($1)) > indent ? n : indent
versions[len] = $1
aliases[len] = $2 " " $3
}
END {
for (i = len; i > 0; i--) {
printf((current == versions[i] ? " ▶ " : " ") "%"indent"s %s\n", versions[i], aliases[i])
}
exit (len == 0)
}
'
end
function _nvm_current #if ! set --query v[1]
command --search --quiet node || return #echo "nvm: Invalid version number or alias: \"$argv[2..-1]\"" >&2
set --query nvm_current_version && echo $nvm_current_version || echo system #return 1
end #end
function _nvm_node_info #if test ! -e $nvm_data/$v
set --local npm_pkg_json (realpath (command --search npm)) #set --local os (command uname -s | string lower)
command node --eval " #set --local ext tar.gz
console.log(process.version) #set --local arch (command uname -m)
console.log(require('"(string replace bin/npm-cli.js package.json $npm_pkg_json)"').version)"
command --search node | string replace ~ \~ #switch $os
end #case aix
#set arch ppc64
#case sunos
#case linux
#case darwin
#case {MSYS_NT,MINGW\*_NT}\*
#set os win
#set ext zip
#case \*
#echo "nvm: Unsupported operating system: \"$os\"" >&2
#return 1
#end
#switch $arch
#case i\*86
#set arch x86
#case x86_64
#set arch x64
#case arm64
#string match --regex --quiet "v(?<major>\d+)" $v
#if test "$os" = darwin -a $major -lt 16
#set arch x64
#end
#case armv6 armv6l
#set arch armv6l
#case armv7 armv7l
#set arch armv7l
#case armv8 armv8l aarch64
#set arch arm64
#end
#set --query nvm_arch && set arch $nvm_arch
#set --local dir "node-$v-$os-$arch"
#set --local url $nvm_mirror/$v/$dir.$ext
#command mkdir -p $nvm_data/$v
#echo -e "Installing Node \x1b[1m$v\x1b[22m $alias"
#echo -e "Fetching \x1b[4m$url\x1b[24m\x1b[7m"
#if ! command curl --progress-bar --location $url \
#| command tar --extract --gzip --directory $nvm_data/$v 2>/dev/null
#command rm -rf $nvm_data/$v
#echo -e "\033[F\33[2K\x1b[0mnvm: Invalid mirror or host unavailable: \"$url\"" >&2
#return 1
#end
#echo -en "\033[F\33[2K\x1b[0m"
#if test "$os" = win
#command mv $nvm_data/$v/$dir $nvm_data/$v/bin
#else
#command mv $nvm_data/$v/$dir/* $nvm_data/$v
#command rm -rf $nvm_data/$v/$dir
#end
#end
#if test $v != "$nvm_current_version"
#set --query nvm_current_version && _nvm_version_deactivate $nvm_current_version
#_nvm_version_activate $v
#end
#printf "Now using Node %s (npm %s) %s\n" (_nvm_node_info)
#case use
#test $v = default && set v $nvm_default_version
#_nvm_list | string match --entire --regex -- (_nvm_version_match $v) | read v __
#if ! set --query v[1]
#echo "nvm: Node version not installed or invalid: \"$argv[2..-1]\"" >&2
#return 1
#end
#if test $v != "$nvm_current_version"
#set --query nvm_current_version && _nvm_version_deactivate $nvm_current_version
#test $v != system && _nvm_version_activate $v
#end
#printf "Now using Node %s (npm %s) %s\n" (_nvm_node_info)
#case uninstall
#if test -z "$v"
#echo "nvm: Not enough arguments for command: \"$cmd\"" >&2
#return 1
#end
#test $v = default && test ! -z "$nvm_default_version" && set v $nvm_default_version
#_nvm_list | string match --entire --regex -- (_nvm_version_match $v) | read v __
#if ! set -q v[1]
#echo "nvm: Node version not installed or invalid: \"$argv[2..-1]\"" >&2
#return 1
#end
#printf "Uninstalling Node %s %s\n" $v (string replace ~ \~ "$nvm_data/$v/bin/node")
#_nvm_version_deactivate $v
#command rm -rf $nvm_data/$v
#case current
#_nvm_current
#case ls list
#_nvm_list | _nvm_list_format (_nvm_current) $argv[2]
#case lsr {ls,list}-remote
#_nvm_index_update $nvm_mirror $nvm_data/.index || return
#_nvm_list | command awk '
#FILENAME == "-" && (is_local[$1] = FNR == NR) { next } {
#print $0 (is_local[$1] ? " ✓" : "")
#}
#' - $nvm_data/.index | _nvm_list_format (_nvm_current) $argv[2]
#case \*
#echo "nvm: Unknown command or option: \"$cmd\" (see nvm -h)" >&2
#return 1
#end
#end
#function _nvm_find_up --argument-names path file
#test -e "$path/$file" && echo $path/$file || begin
#test "$path" != / || return
#_nvm_find_up (command dirname $path) $file
#end
#end
#function _nvm_version_match --argument-names v
#string replace --regex -- '^v?(\d+|\d+\.\d+)$' 'v$1.' $v |
#string replace --filter --regex -- '^v?(\d+)' 'v$1' |
#string escape --style=regex ||
#string lower '\b'$v'(?:/\w+)?$'
#end
#function _nvm_list_format --argument-names current regex
#command awk -v current="$current" -v regex="$regex" '
#$0 ~ regex {
#aliases[versions[i++] = $1] = $2 " " $3
#pad = (n = length($1)) > pad ? n : pad
#}
#END {
#if (!i) exit 1
#while (i--)
#printf((current == versions[i] ? " ▶ " : " ") "%"pad"s %s\n",
#versions[i], aliases[versions[i]])
#}
#'
#end
#function _nvm_current
#command --search --quiet node || return
#set --query nvm_current_version && echo $nvm_current_version || echo system
#end
#function _nvm_node_info
#set --local npm_path (string replace bin/npm-cli.js "" (realpath (command --search npm)))
#test -f $npm_path/package.json || set --local npm_version_default (command npm --version)
#command node --eval "
#console.log(process.version)
#console.log('$npm_version_default' ? '$npm_version_default': require('$npm_path/package.json').version)
#console.log(process.execPath.replace(require('os').homedir(), '~'))
#"
#end

View File

@ -25,7 +25,7 @@
" Plug 'scrooloose/nerdtree', { 'on': 'NERDTreeToggle' } " Plug 'scrooloose/nerdtree', { 'on': 'NERDTreeToggle' }
" Plug 'tpope/vim-fireplace', { 'for': 'clojure' } " Plug 'tpope/vim-fireplace', { 'for': 'clojure' }
" "
" " Using a non-master branch " " Using a non-default branch
" Plug 'rdnetto/YCM-Generator', { 'branch': 'stable' } " Plug 'rdnetto/YCM-Generator', { 'branch': 'stable' }
" "
" " Using a tagged release; wildcard allowed (requires git 1.9.2 or above) " " Using a tagged release; wildcard allowed (requires git 1.9.2 or above)
@ -106,7 +106,7 @@ if s:is_win && &shellslash
else else
let s:me = resolve(expand('<sfile>:p')) let s:me = resolve(expand('<sfile>:p'))
endif endif
let s:base_spec = { 'branch': 'master', 'frozen': 0 } let s:base_spec = { 'branch': '', 'frozen': 0 }
let s:TYPE = { let s:TYPE = {
\ 'string': type(''), \ 'string': type(''),
\ 'list': type([]), \ 'list': type([]),
@ -116,6 +116,94 @@ let s:TYPE = {
let s:loaded = get(s:, 'loaded', {}) let s:loaded = get(s:, 'loaded', {})
let s:triggers = get(s:, 'triggers', {}) let s:triggers = get(s:, 'triggers', {})
function! s:is_powershell(shell)
return a:shell =~# 'powershell\(\.exe\)\?$' || a:shell =~# 'pwsh\(\.exe\)\?$'
endfunction
function! s:isabsolute(dir) abort
return a:dir =~# '^/' || (has('win32') && a:dir =~? '^\%(\\\|[A-Z]:\)')
endfunction
function! s:git_dir(dir) abort
let gitdir = s:trim(a:dir) . '/.git'
if isdirectory(gitdir)
return gitdir
endif
if !filereadable(gitdir)
return ''
endif
let gitdir = matchstr(get(readfile(gitdir), 0, ''), '^gitdir: \zs.*')
if len(gitdir) && !s:isabsolute(gitdir)
let gitdir = a:dir . '/' . gitdir
endif
return isdirectory(gitdir) ? gitdir : ''
endfunction
function! s:git_origin_url(dir) abort
let gitdir = s:git_dir(a:dir)
let config = gitdir . '/config'
if empty(gitdir) || !filereadable(config)
return ''
endif
return matchstr(join(readfile(config)), '\[remote "origin"\].\{-}url\s*=\s*\zs\S*\ze')
endfunction
function! s:git_revision(dir) abort
let gitdir = s:git_dir(a:dir)
let head = gitdir . '/HEAD'
if empty(gitdir) || !filereadable(head)
return ''
endif
let line = get(readfile(head), 0, '')
let ref = matchstr(line, '^ref: \zs.*')
if empty(ref)
return line
endif
if filereadable(gitdir . '/' . ref)
return get(readfile(gitdir . '/' . ref), 0, '')
endif
if filereadable(gitdir . '/packed-refs')
for line in readfile(gitdir . '/packed-refs')
if line =~# ' ' . ref
return matchstr(line, '^[0-9a-f]*')
endif
endfor
endif
return ''
endfunction
function! s:git_local_branch(dir) abort
let gitdir = s:git_dir(a:dir)
let head = gitdir . '/HEAD'
if empty(gitdir) || !filereadable(head)
return ''
endif
let branch = matchstr(get(readfile(head), 0, ''), '^ref: refs/heads/\zs.*')
return len(branch) ? branch : 'HEAD'
endfunction
function! s:git_origin_branch(spec)
if len(a:spec.branch)
return a:spec.branch
endif
" The file may not be present if this is a local repository
let gitdir = s:git_dir(a:spec.dir)
let origin_head = gitdir.'/refs/remotes/origin/HEAD'
if len(gitdir) && filereadable(origin_head)
return matchstr(get(readfile(origin_head), 0, ''),
\ '^ref: refs/remotes/origin/\zs.*')
endif
" The command may not return the name of a branch in detached HEAD state
let result = s:lines(s:system('git symbolic-ref --short HEAD', a:spec.dir))
return v:shell_error ? '' : result[-1]
endfunction
if s:is_win if s:is_win
function! s:plug_call(fn, ...) function! s:plug_call(fn, ...)
let shellslash = &shellslash let shellslash = &shellslash
@ -179,7 +267,7 @@ function! s:define_commands()
endif endif
if has('win32') if has('win32')
\ && &shellslash \ && &shellslash
\ && (&shell =~# 'cmd\.exe' || &shell =~# 'powershell\.exe') \ && (&shell =~# 'cmd\(\.exe\)\?$' || s:is_powershell(&shell))
return s:err('vim-plug does not support shell, ' . &shell . ', when shellslash is set.') return s:err('vim-plug does not support shell, ' . &shell . ', when shellslash is set.')
endif endif
if !has('nvim') if !has('nvim')
@ -251,7 +339,7 @@ endfunction
function! plug#end() function! plug#end()
if !exists('g:plugs') if !exists('g:plugs')
return s:err('Call plug#begin() first') return s:err('plug#end() called without calling plug#begin() first')
endif endif
if exists('#PlugLOD') if exists('#PlugLOD')
@ -372,7 +460,7 @@ endfunction
function! s:git_version_requirement(...) function! s:git_version_requirement(...)
if !exists('s:git_version') if !exists('s:git_version')
let s:git_version = map(split(split(s:system('git --version'))[2], '\.'), 'str2nr(v:val)') let s:git_version = map(split(split(s:system(['git', '--version']))[2], '\.'), 'str2nr(v:val)')
endif endif
return s:version_requirement(s:git_version, a:000) return s:version_requirement(s:git_version, a:000)
endfunction endfunction
@ -419,7 +507,7 @@ if s:is_win
let batchfile = s:plug_tempname().'.bat' let batchfile = s:plug_tempname().'.bat'
call writefile(s:wrap_cmds(a:cmd), batchfile) call writefile(s:wrap_cmds(a:cmd), batchfile)
let cmd = plug#shellescape(batchfile, {'shell': &shell, 'script': 0}) let cmd = plug#shellescape(batchfile, {'shell': &shell, 'script': 0})
if &shell =~# 'powershell\.exe' if s:is_powershell(&shell)
let cmd = '& ' . cmd let cmd = '& ' . cmd
endif endif
return [batchfile, cmd] return [batchfile, cmd]
@ -632,16 +720,38 @@ function! plug#(repo, ...)
let g:plugs[name] = spec let g:plugs[name] = spec
let s:loaded[name] = get(s:loaded, name, 0) let s:loaded[name] = get(s:loaded, name, 0)
catch catch
return s:err(v:exception) return s:err(repo . ' ' . v:exception)
endtry endtry
endfunction endfunction
function! s:parse_options(arg) function! s:parse_options(arg)
let opts = copy(s:base_spec) let opts = copy(s:base_spec)
let type = type(a:arg) let type = type(a:arg)
let opt_errfmt = 'Invalid argument for "%s" option of :Plug (expected: %s)'
if type == s:TYPE.string if type == s:TYPE.string
if empty(a:arg)
throw printf(opt_errfmt, 'tag', 'string')
endif
let opts.tag = a:arg let opts.tag = a:arg
elseif type == s:TYPE.dict elseif type == s:TYPE.dict
for opt in ['branch', 'tag', 'commit', 'rtp', 'dir', 'as']
if has_key(a:arg, opt)
\ && (type(a:arg[opt]) != s:TYPE.string || empty(a:arg[opt]))
throw printf(opt_errfmt, opt, 'string')
endif
endfor
for opt in ['on', 'for']
if has_key(a:arg, opt)
\ && type(a:arg[opt]) != s:TYPE.list
\ && (type(a:arg[opt]) != s:TYPE.string || empty(a:arg[opt]))
throw printf(opt_errfmt, opt, 'string or list')
endif
endfor
if has_key(a:arg, 'do')
\ && type(a:arg.do) != s:TYPE.funcref
\ && (type(a:arg.do) != s:TYPE.string || empty(a:arg.do))
throw printf(opt_errfmt, 'do', 'string or funcref')
endif
call extend(opts, a:arg) call extend(opts, a:arg)
if has_key(opts, 'dir') if has_key(opts, 'dir')
let opts.dir = s:dirpath(s:plug_expand(opts.dir)) let opts.dir = s:dirpath(s:plug_expand(opts.dir))
@ -698,7 +808,7 @@ function! s:syntax()
syn match plugNumber /[0-9]\+[0-9.]*/ contained syn match plugNumber /[0-9]\+[0-9.]*/ contained
syn match plugBracket /[[\]]/ contained syn match plugBracket /[[\]]/ contained
syn match plugX /x/ contained syn match plugX /x/ contained
syn match plugDash /^-/ syn match plugDash /^-\{1}\ /
syn match plugPlus /^+/ syn match plugPlus /^+/
syn match plugStar /^*/ syn match plugStar /^*/
syn match plugMessage /\(^- \)\@<=.*/ syn match plugMessage /\(^- \)\@<=.*/
@ -716,6 +826,7 @@ function! s:syntax()
syn match plugError /^x.*/ syn match plugError /^x.*/
syn region plugDeleted start=/^\~ .*/ end=/^\ze\S/ syn region plugDeleted start=/^\~ .*/ end=/^\ze\S/
syn match plugH2 /^.*:\n-\+$/ syn match plugH2 /^.*:\n-\+$/
syn match plugH2 /^-\{2,}/
syn keyword Function PlugInstall PlugStatus PlugUpdate PlugClean syn keyword Function PlugInstall PlugStatus PlugUpdate PlugClean
hi def link plug1 Title hi def link plug1 Title
hi def link plug2 Repeat hi def link plug2 Repeat
@ -828,7 +939,7 @@ function! s:prepare(...)
call s:new_window() call s:new_window()
endif endif
nnoremap <silent> <buffer> q :if b:plug_preview==1<bar>pc<bar>endif<bar>bd<cr> nnoremap <silent> <buffer> q :call <SID>close_pane()<cr>
if a:0 == 0 if a:0 == 0
call s:finish_bindings() call s:finish_bindings()
endif endif
@ -850,6 +961,15 @@ function! s:prepare(...)
endif endif
endfunction endfunction
function! s:close_pane()
if b:plug_preview == 1
pc
let b:plug_preview = -1
else
bd
endif
endfunction
function! s:assign_name() function! s:assign_name()
" Assign buffer name " Assign buffer name
let prefix = '[Plugins]' let prefix = '[Plugins]'
@ -864,8 +984,15 @@ endfunction
function! s:chsh(swap) function! s:chsh(swap)
let prev = [&shell, &shellcmdflag, &shellredir] let prev = [&shell, &shellcmdflag, &shellredir]
if !s:is_win && a:swap if !s:is_win
set shell=sh shellredir=>%s\ 2>&1 set shell=sh
endif
if a:swap
if s:is_powershell(&shell)
let &shellredir = '2>&1 | Out-File -Encoding UTF8 %s'
elseif &shell =~# 'sh' || &shell =~# 'cmd\(\.exe\)\?$'
set shellredir=>%s\ 2>&1
endif
endif endif
return prev return prev
endfunction endfunction
@ -898,7 +1025,7 @@ function! s:regress_bar()
endfunction endfunction
function! s:is_updated(dir) function! s:is_updated(dir)
return !empty(s:system_chomp('git log --pretty=format:"%h" "HEAD...HEAD@{1}"', a:dir)) return !empty(s:system_chomp(['git', 'log', '--pretty=format:%h', 'HEAD...HEAD@{1}'], a:dir))
endfunction endfunction
function! s:do(pull, force, todo) function! s:do(pull, force, todo)
@ -935,6 +1062,7 @@ function! s:do(pull, force, todo)
endif endif
elseif type == s:TYPE.funcref elseif type == s:TYPE.funcref
try try
call s:load_plugin(spec)
let status = installed ? 'installed' : (updated ? 'updated' : 'unchanged') let status = installed ? 'installed' : (updated ? 'updated' : 'unchanged')
call spec.do({ 'name': name, 'status': status, 'force': a:force }) call spec.do({ 'name': name, 'status': status, 'force': a:force })
catch catch
@ -961,10 +1089,11 @@ endfunction
function! s:checkout(spec) function! s:checkout(spec)
let sha = a:spec.commit let sha = a:spec.commit
let output = s:system('git rev-parse HEAD', a:spec.dir) let output = s:git_revision(a:spec.dir)
if !v:shell_error && !s:hash_match(sha, s:lines(output)[0]) if !empty(output) && !s:hash_match(sha, s:lines(output)[0])
let credential_helper = s:git_version_requirement(2) ? '-c credential.helper= ' : ''
let output = s:system( let output = s:system(
\ 'git fetch --depth 999999 && git checkout '.plug#shellescape(sha).' --', a:spec.dir) \ 'git '.credential_helper.'fetch --depth 999999 && git checkout '.plug#shellescape(sha).' --', a:spec.dir)
endif endif
return output return output
endfunction endfunction
@ -1079,11 +1208,16 @@ function! s:update_impl(pull, force, args) abort
normal! 2G normal! 2G
silent! redraw silent! redraw
let s:clone_opt = get(g:, 'plug_shallow', 1) ? let s:clone_opt = []
\ '--depth 1' . (s:git_version_requirement(1, 7, 10) ? ' --no-single-branch' : '') : '' if get(g:, 'plug_shallow', 1)
call extend(s:clone_opt, ['--depth', '1'])
if s:git_version_requirement(1, 7, 10)
call add(s:clone_opt, '--no-single-branch')
endif
endif
if has('win32unix') || has('wsl') if has('win32unix') || has('wsl')
let s:clone_opt .= ' -c core.eol=lf -c core.autocrlf=input' call extend(s:clone_opt, ['-c', 'core.eol=lf', '-c', 'core.autocrlf=input'])
endif endif
let s:submodule_opt = s:git_version_requirement(2, 8) ? ' --jobs='.threads : '' let s:submodule_opt = s:git_version_requirement(2, 8) ? ' --jobs='.threads : ''
@ -1171,7 +1305,7 @@ function! s:update_finish()
call s:log4(name, 'Checking out '.tag) call s:log4(name, 'Checking out '.tag)
let out = s:system('git checkout -q '.plug#shellescape(tag).' -- 2>&1', spec.dir) let out = s:system('git checkout -q '.plug#shellescape(tag).' -- 2>&1', spec.dir)
else else
let branch = get(spec, 'branch', 'master') let branch = s:git_origin_branch(spec)
call s:log4(name, 'Merging origin/'.s:esc(branch)) call s:log4(name, 'Merging origin/'.s:esc(branch))
let out = s:system('git checkout -q '.plug#shellescape(branch).' -- 2>&1' let out = s:system('git checkout -q '.plug#shellescape(branch).' -- 2>&1'
\. (has_key(s:update.new, name) ? '' : ('&& git merge --ff-only '.plug#shellescape('origin/'.branch).' 2>&1')), spec.dir) \. (has_key(s:update.new, name) ? '' : ('&& git merge --ff-only '.plug#shellescape('origin/'.branch).' 2>&1')), spec.dir)
@ -1264,7 +1398,7 @@ function! s:job_cb(fn, job, ch, data)
endfunction endfunction
function! s:nvim_cb(job_id, data, event) dict abort function! s:nvim_cb(job_id, data, event) dict abort
return a:event == 'stdout' ? return (a:event == 'stdout' || a:event == 'stderr') ?
\ s:job_cb('s:job_out_cb', self, 0, join(a:data, "\n")) : \ s:job_cb('s:job_out_cb', self, 0, join(a:data, "\n")) :
\ s:job_cb('s:job_exit_cb', self, 0, a:data) \ s:job_cb('s:job_exit_cb', self, 0, a:data)
endfunction endfunction
@ -1273,12 +1407,15 @@ function! s:spawn(name, cmd, opts)
let job = { 'name': a:name, 'running': 1, 'error': 0, 'lines': [''], let job = { 'name': a:name, 'running': 1, 'error': 0, 'lines': [''],
\ 'new': get(a:opts, 'new', 0) } \ 'new': get(a:opts, 'new', 0) }
let s:jobs[a:name] = job let s:jobs[a:name] = job
let cmd = has_key(a:opts, 'dir') ? s:with_cd(a:cmd, a:opts.dir, 0) : a:cmd
let argv = s:is_win ? ['cmd', '/s', '/c', '"'.cmd.'"'] : ['sh', '-c', cmd]
if s:nvim if s:nvim
if has_key(a:opts, 'dir')
let job.cwd = a:opts.dir
endif
let argv = a:cmd
call extend(job, { call extend(job, {
\ 'on_stdout': function('s:nvim_cb'), \ 'on_stdout': function('s:nvim_cb'),
\ 'on_stderr': function('s:nvim_cb'),
\ 'on_exit': function('s:nvim_cb'), \ 'on_exit': function('s:nvim_cb'),
\ }) \ })
let jid = s:plug_call('jobstart', argv, job) let jid = s:plug_call('jobstart', argv, job)
@ -1291,9 +1428,16 @@ function! s:spawn(name, cmd, opts)
\ 'Invalid arguments (or job table is full)'] \ 'Invalid arguments (or job table is full)']
endif endif
elseif s:vim8 elseif s:vim8
let cmd = join(map(copy(a:cmd), 'plug#shellescape(v:val, {"script": 0})'))
if has_key(a:opts, 'dir')
let cmd = s:with_cd(cmd, a:opts.dir, 0)
endif
let argv = s:is_win ? ['cmd', '/s', '/c', '"'.cmd.'"'] : ['sh', '-c', cmd]
let jid = job_start(s:is_win ? join(argv, ' ') : argv, { let jid = job_start(s:is_win ? join(argv, ' ') : argv, {
\ 'out_cb': function('s:job_cb', ['s:job_out_cb', job]), \ 'out_cb': function('s:job_cb', ['s:job_out_cb', job]),
\ 'err_cb': function('s:job_cb', ['s:job_out_cb', job]),
\ 'exit_cb': function('s:job_cb', ['s:job_exit_cb', job]), \ 'exit_cb': function('s:job_cb', ['s:job_exit_cb', job]),
\ 'err_mode': 'raw',
\ 'out_mode': 'raw' \ 'out_mode': 'raw'
\}) \})
if job_status(jid) == 'run' if job_status(jid) == 'run'
@ -1304,7 +1448,7 @@ function! s:spawn(name, cmd, opts)
let job.lines = ['Failed to start job'] let job.lines = ['Failed to start job']
endif endif
else else
let job.lines = s:lines(call('s:system', [cmd])) let job.lines = s:lines(call('s:system', has_key(a:opts, 'dir') ? [a:cmd, a:opts.dir] : [a:cmd]))
let job.error = v:shell_error != 0 let job.error = v:shell_error != 0
let job.running = 0 let job.running = 0
endif endif
@ -1401,8 +1545,14 @@ while 1 " Without TCO, Vim stack is bound to explode
let [error, _] = s:git_validate(spec, 0) let [error, _] = s:git_validate(spec, 0)
if empty(error) if empty(error)
if pull if pull
let fetch_opt = (has_tag && !empty(globpath(spec.dir, '.git/shallow'))) ? '--depth 99999999' : '' let cmd = s:git_version_requirement(2) ? ['git', '-c', 'credential.helper=', 'fetch'] : ['git', 'fetch']
call s:spawn(name, printf('git fetch %s %s 2>&1', fetch_opt, prog), { 'dir': spec.dir }) if has_tag && !empty(globpath(spec.dir, '.git/shallow'))
call extend(cmd, ['--depth', '99999999'])
endif
if !empty(prog)
call add(cmd, prog)
endif
call s:spawn(name, cmd, { 'dir': spec.dir })
else else
let s:jobs[name] = { 'running': 0, 'lines': ['Already installed'], 'error': 0 } let s:jobs[name] = { 'running': 0, 'lines': ['Already installed'], 'error': 0 }
endif endif
@ -1410,12 +1560,14 @@ while 1 " Without TCO, Vim stack is bound to explode
let s:jobs[name] = { 'running': 0, 'lines': s:lines(error), 'error': 1 } let s:jobs[name] = { 'running': 0, 'lines': s:lines(error), 'error': 1 }
endif endif
else else
call s:spawn(name, let cmd = ['git', 'clone']
\ printf('git clone %s %s %s %s 2>&1', if !has_tag
\ has_tag ? '' : s:clone_opt, call extend(cmd, s:clone_opt)
\ prog, endif
\ plug#shellescape(spec.uri, {'script': 0}), if !empty(prog)
\ plug#shellescape(s:trim(spec.dir), {'script': 0})), { 'new': 1 }) call add(cmd, prog)
endif
call s:spawn(name, extend(cmd, [spec.uri, s:trim(spec.dir)]), { 'new': 1 })
endif endif
if !s:jobs[name].running if !s:jobs[name].running
@ -1452,7 +1604,7 @@ G_NVIM = vim.eval("has('nvim')") == '1'
G_PULL = vim.eval('s:update.pull') == '1' G_PULL = vim.eval('s:update.pull') == '1'
G_RETRIES = int(vim.eval('get(g:, "plug_retries", 2)')) + 1 G_RETRIES = int(vim.eval('get(g:, "plug_retries", 2)')) + 1
G_TIMEOUT = int(vim.eval('get(g:, "plug_timeout", 60)')) G_TIMEOUT = int(vim.eval('get(g:, "plug_timeout", 60)'))
G_CLONE_OPT = vim.eval('s:clone_opt') G_CLONE_OPT = ' '.join(vim.eval('s:clone_opt'))
G_PROGRESS = vim.eval('s:progress_opt(1)') G_PROGRESS = vim.eval('s:progress_opt(1)')
G_LOG_PROB = 1.0 / int(vim.eval('s:update.threads')) G_LOG_PROB = 1.0 / int(vim.eval('s:update.threads'))
G_STOP = thr.Event() G_STOP = thr.Event()
@ -1989,7 +2141,7 @@ function! s:update_ruby()
end end
} if VIM::evaluate('s:mac_gui') == 1 } if VIM::evaluate('s:mac_gui') == 1
clone_opt = VIM::evaluate('s:clone_opt') clone_opt = VIM::evaluate('s:clone_opt').join(' ')
progress = VIM::evaluate('s:progress_opt(1)') progress = VIM::evaluate('s:progress_opt(1)')
nthr.times do nthr.times do
mtx.synchronize do mtx.synchronize do
@ -2055,13 +2207,29 @@ function! s:shellesc_sh(arg)
return "'".substitute(a:arg, "'", "'\\\\''", 'g')."'" return "'".substitute(a:arg, "'", "'\\\\''", 'g')."'"
endfunction endfunction
" Escape the shell argument based on the shell.
" Vim and Neovim's shellescape() are insufficient.
" 1. shellslash determines whether to use single/double quotes.
" Double-quote escaping is fragile for cmd.exe.
" 2. It does not work for powershell.
" 3. It does not work for *sh shells if the command is executed
" via cmd.exe (ie. cmd.exe /c sh -c command command_args)
" 4. It does not support batchfile syntax.
"
" Accepts an optional dictionary with the following keys:
" - shell: same as Vim/Neovim 'shell' option.
" If unset, fallback to 'cmd.exe' on Windows or 'sh'.
" - script: If truthy and shell is cmd.exe, escape for batchfile syntax.
function! plug#shellescape(arg, ...) function! plug#shellescape(arg, ...)
if a:arg =~# '^[A-Za-z0-9_/:.-]\+$'
return a:arg
endif
let opts = a:0 > 0 && type(a:1) == s:TYPE.dict ? a:1 : {} let opts = a:0 > 0 && type(a:1) == s:TYPE.dict ? a:1 : {}
let shell = get(opts, 'shell', s:is_win ? 'cmd.exe' : 'sh') let shell = get(opts, 'shell', s:is_win ? 'cmd.exe' : 'sh')
let script = get(opts, 'script', 1) let script = get(opts, 'script', 1)
if shell =~# 'cmd\.exe' if shell =~# 'cmd\(\.exe\)\?$'
return s:shellesc_cmd(a:arg, script) return s:shellesc_cmd(a:arg, script)
elseif shell =~# 'powershell\.exe' || shell =~# 'pwsh$' elseif s:is_powershell(shell)
return s:shellesc_ps1(a:arg) return s:shellesc_ps1(a:arg)
endif endif
return s:shellesc_sh(a:arg) return s:shellesc_sh(a:arg)
@ -2105,8 +2273,24 @@ function! s:system(cmd, ...)
let batchfile = '' let batchfile = ''
try try
let [sh, shellcmdflag, shrd] = s:chsh(1) let [sh, shellcmdflag, shrd] = s:chsh(1)
let cmd = a:0 > 0 ? s:with_cd(a:cmd, a:1) : a:cmd if type(a:cmd) == s:TYPE.list
if s:is_win " Neovim's system() supports list argument to bypass the shell
" but it cannot set the working directory for the command.
" Assume that the command does not rely on the shell.
if has('nvim') && a:0 == 0
return system(a:cmd)
endif
let cmd = join(map(copy(a:cmd), 'plug#shellescape(v:val, {"shell": &shell, "script": 0})'))
if s:is_powershell(&shell)
let cmd = '& ' . cmd
endif
else
let cmd = a:cmd
endif
if a:0 > 0
let cmd = s:with_cd(cmd, a:1, type(a:cmd) != s:TYPE.list)
endif
if s:is_win && type(a:cmd) != s:TYPE.list
let [batchfile, cmd] = s:batchfile(cmd) let [batchfile, cmd] = s:batchfile(cmd)
endif endif
return system(cmd) return system(cmd)
@ -2126,18 +2310,17 @@ endfunction
function! s:git_validate(spec, check_branch) function! s:git_validate(spec, check_branch)
let err = '' let err = ''
if isdirectory(a:spec.dir) if isdirectory(a:spec.dir)
let result = s:lines(s:system('git rev-parse --abbrev-ref HEAD 2>&1 && git config -f .git/config remote.origin.url', a:spec.dir)) let result = [s:git_local_branch(a:spec.dir), s:git_origin_url(a:spec.dir)]
let remote = result[-1] let remote = result[-1]
if v:shell_error if empty(remote)
let err = join([remote, 'PlugClean required.'], "\n") let err = join([remote, 'PlugClean required.'], "\n")
elseif !s:compare_git_uri(remote, a:spec.uri) elseif !s:compare_git_uri(remote, a:spec.uri)
let err = join(['Invalid URI: '.remote, let err = join(['Invalid URI: '.remote,
\ 'Expected: '.a:spec.uri, \ 'Expected: '.a:spec.uri,
\ 'PlugClean required.'], "\n") \ 'PlugClean required.'], "\n")
elseif a:check_branch && has_key(a:spec, 'commit') elseif a:check_branch && has_key(a:spec, 'commit')
let result = s:lines(s:system('git rev-parse HEAD 2>&1', a:spec.dir)) let sha = s:git_revision(a:spec.dir)
let sha = result[-1] if empty(sha)
if v:shell_error
let err = join(add(result, 'PlugClean required.'), "\n") let err = join(add(result, 'PlugClean required.'), "\n")
elseif !s:hash_match(sha, a:spec.commit) elseif !s:hash_match(sha, a:spec.commit)
let err = join([printf('Invalid HEAD (expected: %s, actual: %s)', let err = join([printf('Invalid HEAD (expected: %s, actual: %s)',
@ -2145,8 +2328,9 @@ function! s:git_validate(spec, check_branch)
\ 'PlugUpdate required.'], "\n") \ 'PlugUpdate required.'], "\n")
endif endif
elseif a:check_branch elseif a:check_branch
let branch = result[0] let current_branch = result[0]
" Check tag " Check tag
let origin_branch = s:git_origin_branch(a:spec)
if has_key(a:spec, 'tag') if has_key(a:spec, 'tag')
let tag = s:system_chomp('git describe --exact-match --tags HEAD 2>&1', a:spec.dir) let tag = s:system_chomp('git describe --exact-match --tags HEAD 2>&1', a:spec.dir)
if a:spec.tag !=# tag && a:spec.tag !~ '\*' if a:spec.tag !=# tag && a:spec.tag !~ '\*'
@ -2154,25 +2338,26 @@ function! s:git_validate(spec, check_branch)
\ (empty(tag) ? 'N/A' : tag), a:spec.tag) \ (empty(tag) ? 'N/A' : tag), a:spec.tag)
endif endif
" Check branch " Check branch
elseif a:spec.branch !=# branch elseif origin_branch !=# current_branch
let err = printf('Invalid branch: %s (expected: %s). Try PlugUpdate.', let err = printf('Invalid branch: %s (expected: %s). Try PlugUpdate.',
\ branch, a:spec.branch) \ current_branch, origin_branch)
endif endif
if empty(err) if empty(err)
let [ahead, behind] = split(s:lastline(s:system(printf( let [ahead, behind] = split(s:lastline(s:system([
\ 'git rev-list --count --left-right HEAD...origin/%s', \ 'git', 'rev-list', '--count', '--left-right',
\ a:spec.branch), a:spec.dir)), '\t') \ printf('HEAD...origin/%s', origin_branch)
\ ], a:spec.dir)), '\t')
if !v:shell_error && ahead if !v:shell_error && ahead
if behind if behind
" Only mention PlugClean if diverged, otherwise it's likely to be " Only mention PlugClean if diverged, otherwise it's likely to be
" pushable (and probably not that messed up). " pushable (and probably not that messed up).
let err = printf( let err = printf(
\ "Diverged from origin/%s (%d commit(s) ahead and %d commit(s) behind!\n" \ "Diverged from origin/%s (%d commit(s) ahead and %d commit(s) behind!\n"
\ .'Backup local changes and run PlugClean and PlugUpdate to reinstall it.', a:spec.branch, ahead, behind) \ .'Backup local changes and run PlugClean and PlugUpdate to reinstall it.', origin_branch, ahead, behind)
else else
let err = printf("Ahead of origin/%s by %d commit(s).\n" let err = printf("Ahead of origin/%s by %d commit(s).\n"
\ .'Cannot update until local changes are pushed.', \ .'Cannot update until local changes are pushed.',
\ a:spec.branch, ahead) \ origin_branch, ahead)
endif endif
endif endif
endif endif
@ -2185,7 +2370,9 @@ endfunction
function! s:rm_rf(dir) function! s:rm_rf(dir)
if isdirectory(a:dir) if isdirectory(a:dir)
call s:system((s:is_win ? 'rmdir /S /Q ' : 'rm -rf ') . plug#shellescape(a:dir)) return s:system(s:is_win
\ ? 'rmdir /S /Q '.plug#shellescape(a:dir)
\ : ['rm', '-rf', a:dir])
endif endif
endfunction endfunction
@ -2267,6 +2454,7 @@ endfunction
function! s:delete(range, force) function! s:delete(range, force)
let [l1, l2] = a:range let [l1, l2] = a:range
let force = a:force let force = a:force
let err_count = 0
while l1 <= l2 while l1 <= l2
let line = getline(l1) let line = getline(l1)
if line =~ '^- ' && isdirectory(line[2:]) if line =~ '^- ' && isdirectory(line[2:])
@ -2275,11 +2463,22 @@ function! s:delete(range, force)
let answer = force ? 1 : s:ask('Delete '.line[2:].'?', 1) let answer = force ? 1 : s:ask('Delete '.line[2:].'?', 1)
let force = force || answer > 1 let force = force || answer > 1
if answer if answer
call s:rm_rf(line[2:]) let err = s:rm_rf(line[2:])
setlocal modifiable setlocal modifiable
call setline(l1, '~'.line[1:]) if empty(err)
let s:clean_count += 1 call setline(l1, '~'.line[1:])
call setline(4, printf('Removed %d directories.', s:clean_count)) let s:clean_count += 1
else
delete _
call append(l1 - 1, s:format_message('x', line[1:], err))
let l2 += len(s:lines(err))
let err_count += 1
endif
let msg = printf('Removed %d directories.', s:clean_count)
if err_count > 0
let msg .= printf(' Failed to remove %d directories.', err_count)
endif
call setline(4, msg)
setlocal nomodifiable setlocal nomodifiable
endif endif
endif endif
@ -2294,7 +2493,7 @@ function! s:upgrade()
let new = tmp . '/plug.vim' let new = tmp . '/plug.vim'
try try
let out = s:system(printf('git clone --depth 1 %s %s', plug#shellescape(s:plug_src), plug#shellescape(tmp))) let out = s:system(['git', 'clone', '--depth', '1', s:plug_src, tmp])
if v:shell_error if v:shell_error
return s:err('Error upgrading vim-plug: '. out) return s:err('Error upgrading vim-plug: '. out)
endif endif
@ -2488,18 +2687,23 @@ function! s:diff()
endif endif
call s:append_ul(2, origin ? 'Pending updates:' : 'Last update:') call s:append_ul(2, origin ? 'Pending updates:' : 'Last update:')
for [k, v] in plugs for [k, v] in plugs
let range = origin ? '..origin/'.v.branch : 'HEAD@{1}..' let branch = s:git_origin_branch(v)
let cmd = 'git log --graph --color=never ' if len(branch)
\ . (s:git_version_requirement(2, 10, 0) ? '--no-show-signature ' : '') let range = origin ? '..origin/'.branch : 'HEAD@{1}..'
\ . join(map(['--pretty=format:%x01%h%x01%d%x01%s%x01%cr', range], 'plug#shellescape(v:val)')) let cmd = ['git', 'log', '--graph', '--color=never']
if has_key(v, 'rtp') if s:git_version_requirement(2, 10, 0)
let cmd .= ' -- '.plug#shellescape(v.rtp) call add(cmd, '--no-show-signature')
endif endif
let diff = s:system_chomp(cmd, v.dir) call extend(cmd, ['--pretty=format:%x01%h%x01%d%x01%s%x01%cr', range])
if !empty(diff) if has_key(v, 'rtp')
let ref = has_key(v, 'tag') ? (' (tag: '.v.tag.')') : has_key(v, 'commit') ? (' '.v.commit) : '' call extend(cmd, ['--', v.rtp])
call append(5, extend(['', '- '.k.':'.ref], map(s:lines(diff), 's:format_git_log(v:val)'))) endif
let cnts[origin] += 1 let diff = s:system_chomp(cmd, v.dir)
if !empty(diff)
let ref = has_key(v, 'tag') ? (' (tag: '.v.tag.')') : has_key(v, 'commit') ? (' '.v.commit) : ''
call append(5, extend(['', '- '.k.':'.ref], map(s:lines(diff), 's:format_git_log(v:val)')))
let cnts[origin] += 1
endif
endif endif
let bar .= '=' let bar .= '='
call s:progress_bar(2, bar, len(total)) call s:progress_bar(2, bar, len(total))
@ -2561,7 +2765,7 @@ function! s:snapshot(force, ...) abort
let names = sort(keys(filter(copy(g:plugs), let names = sort(keys(filter(copy(g:plugs),
\'has_key(v:val, "uri") && !has_key(v:val, "commit") && isdirectory(v:val.dir)'))) \'has_key(v:val, "uri") && !has_key(v:val, "commit") && isdirectory(v:val.dir)')))
for name in reverse(names) for name in reverse(names)
let sha = s:system_chomp('git rev-parse --short HEAD', g:plugs[name].dir) let sha = s:git_revision(g:plugs[name].dir)
if !empty(sha) if !empty(sha)
call append(anchor, printf("silent! let g:plugs['%s'].commit = '%s'", name, sha)) call append(anchor, printf("silent! let g:plugs['%s'].commit = '%s'", name, sha))
redraw redraw

View File

@ -99,7 +99,13 @@ let s:mac_gui = has('gui_macvim') && has('gui_running')
let s:is_win = has('win32') let s:is_win = has('win32')
let s:nvim = has('nvim-0.2') || (has('nvim') && exists('*jobwait') && !s:is_win) let s:nvim = has('nvim-0.2') || (has('nvim') && exists('*jobwait') && !s:is_win)
let s:vim8 = has('patch-8.0.0039') && exists('*job_start') let s:vim8 = has('patch-8.0.0039') && exists('*job_start')
let s:me = resolve(expand('<sfile>:p')) if s:is_win && &shellslash
set noshellslash
let s:me = resolve(expand('<sfile>:p'))
set shellslash
else
let s:me = resolve(expand('<sfile>:p'))
endif
let s:base_spec = { 'branch': 'master', 'frozen': 0 } let s:base_spec = { 'branch': 'master', 'frozen': 0 }
let s:TYPE = { let s:TYPE = {
\ 'string': type(''), \ 'string': type(''),
@ -110,10 +116,42 @@ let s:TYPE = {
let s:loaded = get(s:, 'loaded', {}) let s:loaded = get(s:, 'loaded', {})
let s:triggers = get(s:, 'triggers', {}) let s:triggers = get(s:, 'triggers', {})
if s:is_win
function! s:plug_call(fn, ...)
let shellslash = &shellslash
try
set noshellslash
return call(a:fn, a:000)
finally
let &shellslash = shellslash
endtry
endfunction
else
function! s:plug_call(fn, ...)
return call(a:fn, a:000)
endfunction
endif
function! s:plug_getcwd()
return s:plug_call('getcwd')
endfunction
function! s:plug_fnamemodify(fname, mods)
return s:plug_call('fnamemodify', a:fname, a:mods)
endfunction
function! s:plug_expand(fmt)
return s:plug_call('expand', a:fmt, 1)
endfunction
function! s:plug_tempname()
return s:plug_call('tempname')
endfunction
function! plug#begin(...) function! plug#begin(...)
if a:0 > 0 if a:0 > 0
let s:plug_home_org = a:1 let s:plug_home_org = a:1
let home = s:path(fnamemodify(expand(a:1), ':p')) let home = s:path(s:plug_fnamemodify(s:plug_expand(a:1), ':p'))
elseif exists('g:plug_home') elseif exists('g:plug_home')
let home = s:path(g:plug_home) let home = s:path(g:plug_home)
elseif !empty(&rtp) elseif !empty(&rtp)
@ -121,7 +159,7 @@ function! plug#begin(...)
else else
return s:err('Unable to determine plug home. Try calling plug#begin() with a path argument.') return s:err('Unable to determine plug home. Try calling plug#begin() with a path argument.')
endif endif
if fnamemodify(home, ':t') ==# 'plugin' && fnamemodify(home, ':h') ==# s:first_rtp if s:plug_fnamemodify(home, ':t') ==# 'plugin' && s:plug_fnamemodify(home, ':h') ==# s:first_rtp
return s:err('Invalid plug home. '.home.' is a standard Vim runtime path and is not allowed.') return s:err('Invalid plug home. '.home.' is a standard Vim runtime path and is not allowed.')
endif endif
@ -139,6 +177,16 @@ function! s:define_commands()
if !executable('git') if !executable('git')
return s:err('`git` executable not found. Most commands will not be available. To suppress this message, prepend `silent!` to `call plug#begin(...)`.') return s:err('`git` executable not found. Most commands will not be available. To suppress this message, prepend `silent!` to `call plug#begin(...)`.')
endif endif
if has('win32')
\ && &shellslash
\ && (&shell =~# 'cmd\.exe' || &shell =~# 'powershell\.exe')
return s:err('vim-plug does not support shell, ' . &shell . ', when shellslash is set.')
endif
if !has('nvim')
\ && (has('win32') || has('win32unix'))
\ && !has('multi_byte')
return s:err('Vim needs +multi_byte feature on Windows to run shell commands. Enable +iconv for best results.')
endif
command! -nargs=* -bar -bang -complete=customlist,s:names PlugInstall call s:install(<bang>0, [<f-args>]) command! -nargs=* -bar -bang -complete=customlist,s:names PlugInstall call s:install(<bang>0, [<f-args>])
command! -nargs=* -bar -bang -complete=customlist,s:names PlugUpdate call s:update(<bang>0, [<f-args>]) command! -nargs=* -bar -bang -complete=customlist,s:names PlugUpdate call s:update(<bang>0, [<f-args>])
command! -nargs=0 -bar -bang PlugClean call s:clean(<bang>0) command! -nargs=0 -bar -bang PlugClean call s:clean(<bang>0)
@ -334,11 +382,11 @@ function! s:progress_opt(base)
\ s:git_version_requirement(1, 7, 1) ? '--progress' : '' \ s:git_version_requirement(1, 7, 1) ? '--progress' : ''
endfunction endfunction
if s:is_win function! s:rtp(spec)
function! s:rtp(spec) return s:path(a:spec.dir . get(a:spec, 'rtp', ''))
return s:path(a:spec.dir . get(a:spec, 'rtp', '')) endfunction
endfunction
if s:is_win
function! s:path(path) function! s:path(path)
return s:trim(substitute(a:path, '/', '\', 'g')) return s:trim(substitute(a:path, '/', '\', 'g'))
endfunction endfunction
@ -350,11 +398,33 @@ if s:is_win
function! s:is_local_plug(repo) function! s:is_local_plug(repo)
return a:repo =~? '^[a-z]:\|^[%~]' return a:repo =~? '^[a-z]:\|^[%~]'
endfunction endfunction
else
function! s:rtp(spec) " Copied from fzf
return s:dirpath(a:spec.dir . get(a:spec, 'rtp', '')) function! s:wrap_cmds(cmds)
let cmds = [
\ '@echo off',
\ 'setlocal enabledelayedexpansion']
\ + (type(a:cmds) == type([]) ? a:cmds : [a:cmds])
\ + ['endlocal']
if has('iconv')
if !exists('s:codepage')
let s:codepage = libcallnr('kernel32.dll', 'GetACP', 0)
endif
return map(cmds, printf('iconv(v:val."\r", "%s", "cp%d")', &encoding, s:codepage))
endif
return map(cmds, 'v:val."\r"')
endfunction endfunction
function! s:batchfile(cmd)
let batchfile = s:plug_tempname().'.bat'
call writefile(s:wrap_cmds(a:cmd), batchfile)
let cmd = plug#shellescape(batchfile, {'shell': &shell, 'script': 0})
if &shell =~# 'powershell\.exe'
let cmd = '& ' . cmd
endif
return [batchfile, cmd]
endfunction
else
function! s:path(path) function! s:path(path)
return s:trim(a:path) return s:trim(a:path)
endfunction endfunction
@ -434,8 +504,8 @@ endfunction
function! s:dobufread(names) function! s:dobufread(names)
for name in a:names for name in a:names
let path = s:rtp(g:plugs[name]).'/**' let path = s:rtp(g:plugs[name])
for dir in ['ftdetect', 'ftplugin'] for dir in ['ftdetect', 'ftplugin', 'after/ftdetect', 'after/ftplugin']
if len(finddir(dir, path)) if len(finddir(dir, path))
if exists('#BufRead') if exists('#BufRead')
doautocmd BufRead doautocmd BufRead
@ -554,7 +624,7 @@ function! plug#(repo, ...)
try try
let repo = s:trim(a:repo) let repo = s:trim(a:repo)
let opts = a:0 == 1 ? s:parse_options(a:1) : s:base_spec let opts = a:0 == 1 ? s:parse_options(a:1) : s:base_spec
let name = get(opts, 'as', fnamemodify(repo, ':t:s?\.git$??')) let name = get(opts, 'as', s:plug_fnamemodify(repo, ':t:s?\.git$??'))
let spec = extend(s:infer_properties(name, repo), opts) let spec = extend(s:infer_properties(name, repo), opts)
if !has_key(g:plugs, name) if !has_key(g:plugs, name)
call add(g:plugs_order, name) call add(g:plugs_order, name)
@ -574,7 +644,7 @@ function! s:parse_options(arg)
elseif type == s:TYPE.dict elseif type == s:TYPE.dict
call extend(opts, a:arg) call extend(opts, a:arg)
if has_key(opts, 'dir') if has_key(opts, 'dir')
let opts.dir = s:dirpath(expand(opts.dir)) let opts.dir = s:dirpath(s:plug_expand(opts.dir))
endif endif
else else
throw 'Invalid argument type (expected: string or dictionary)' throw 'Invalid argument type (expected: string or dictionary)'
@ -585,7 +655,7 @@ endfunction
function! s:infer_properties(name, repo) function! s:infer_properties(name, repo)
let repo = a:repo let repo = a:repo
if s:is_local_plug(repo) if s:is_local_plug(repo)
return { 'dir': s:dirpath(expand(repo)) } return { 'dir': s:dirpath(s:plug_expand(repo)) }
else else
if repo =~ ':' if repo =~ ':'
let uri = repo let uri = repo
@ -738,7 +808,7 @@ function! s:finish_bindings()
endfunction endfunction
function! s:prepare(...) function! s:prepare(...)
if empty(getcwd()) if empty(s:plug_getcwd())
throw 'Invalid current working directory. Cannot proceed.' throw 'Invalid current working directory. Cannot proceed.'
endif endif
@ -794,31 +864,28 @@ endfunction
function! s:chsh(swap) function! s:chsh(swap)
let prev = [&shell, &shellcmdflag, &shellredir] let prev = [&shell, &shellcmdflag, &shellredir]
if s:is_win if !s:is_win && a:swap
set shell=cmd.exe shellcmdflag=/c shellredir=>%s\ 2>&1
elseif a:swap
set shell=sh shellredir=>%s\ 2>&1 set shell=sh shellredir=>%s\ 2>&1
endif endif
return prev return prev
endfunction endfunction
function! s:bang(cmd, ...) function! s:bang(cmd, ...)
let batchfile = ''
try try
let [sh, shellcmdflag, shrd] = s:chsh(a:0) let [sh, shellcmdflag, shrd] = s:chsh(a:0)
" FIXME: Escaping is incomplete. We could use shellescape with eval, " FIXME: Escaping is incomplete. We could use shellescape with eval,
" but it won't work on Windows. " but it won't work on Windows.
let cmd = a:0 ? s:with_cd(a:cmd, a:1) : a:cmd let cmd = a:0 ? s:with_cd(a:cmd, a:1) : a:cmd
if s:is_win if s:is_win
let batchfile = tempname().'.bat' let [batchfile, cmd] = s:batchfile(cmd)
call writefile(["@echo off\r", cmd . "\r"], batchfile)
let cmd = batchfile
endif endif
let g:_plug_bang = (s:is_win && has('gui_running') ? 'silent ' : '').'!'.escape(cmd, '#!%') let g:_plug_bang = (s:is_win && has('gui_running') ? 'silent ' : '').'!'.escape(cmd, '#!%')
execute "normal! :execute g:_plug_bang\<cr>\<cr>" execute "normal! :execute g:_plug_bang\<cr>\<cr>"
finally finally
unlet g:_plug_bang unlet g:_plug_bang
let [&shell, &shellcmdflag, &shellredir] = [sh, shellcmdflag, shrd] let [&shell, &shellcmdflag, &shellredir] = [sh, shellcmdflag, shrd]
if s:is_win if s:is_win && filereadable(batchfile)
call delete(batchfile) call delete(batchfile)
endif endif
endtry endtry
@ -897,7 +964,7 @@ function! s:checkout(spec)
let output = s:system('git rev-parse HEAD', a:spec.dir) let output = s:system('git rev-parse HEAD', a:spec.dir)
if !v:shell_error && !s:hash_match(sha, s:lines(output)[0]) if !v:shell_error && !s:hash_match(sha, s:lines(output)[0])
let output = s:system( let output = s:system(
\ 'git fetch --depth 999999 && git checkout '.s:esc(sha).' --', a:spec.dir) \ 'git fetch --depth 999999 && git checkout '.plug#shellescape(sha).' --', a:spec.dir)
endif endif
return output return output
endfunction endfunction
@ -1015,7 +1082,7 @@ function! s:update_impl(pull, force, args) abort
let s:clone_opt = get(g:, 'plug_shallow', 1) ? let s:clone_opt = get(g:, 'plug_shallow', 1) ?
\ '--depth 1' . (s:git_version_requirement(1, 7, 10) ? ' --no-single-branch' : '') : '' \ '--depth 1' . (s:git_version_requirement(1, 7, 10) ? ' --no-single-branch' : '') : ''
if has('win32unix') if has('win32unix') || has('wsl')
let s:clone_opt .= ' -c core.eol=lf -c core.autocrlf=input' let s:clone_opt .= ' -c core.eol=lf -c core.autocrlf=input'
endif endif
@ -1094,7 +1161,7 @@ function! s:update_finish()
elseif has_key(spec, 'tag') elseif has_key(spec, 'tag')
let tag = spec.tag let tag = spec.tag
if tag =~ '\*' if tag =~ '\*'
let tags = s:lines(s:system('git tag --list '.s:shellesc(tag).' --sort -version:refname 2>&1', spec.dir)) let tags = s:lines(s:system('git tag --list '.plug#shellescape(tag).' --sort -version:refname 2>&1', spec.dir))
if !v:shell_error && !empty(tags) if !v:shell_error && !empty(tags)
let tag = tags[0] let tag = tags[0]
call s:log4(name, printf('Latest tag for %s -> %s', spec.tag, tag)) call s:log4(name, printf('Latest tag for %s -> %s', spec.tag, tag))
@ -1102,12 +1169,12 @@ function! s:update_finish()
endif endif
endif endif
call s:log4(name, 'Checking out '.tag) call s:log4(name, 'Checking out '.tag)
let out = s:system('git checkout -q '.s:esc(tag).' -- 2>&1', spec.dir) let out = s:system('git checkout -q '.plug#shellescape(tag).' -- 2>&1', spec.dir)
else else
let branch = s:esc(get(spec, 'branch', 'master')) let branch = get(spec, 'branch', 'master')
call s:log4(name, 'Merging origin/'.branch) call s:log4(name, 'Merging origin/'.s:esc(branch))
let out = s:system('git checkout -q '.branch.' -- 2>&1' let out = s:system('git checkout -q '.plug#shellescape(branch).' -- 2>&1'
\. (has_key(s:update.new, name) ? '' : ('&& git merge --ff-only origin/'.branch.' 2>&1')), spec.dir) \. (has_key(s:update.new, name) ? '' : ('&& git merge --ff-only '.plug#shellescape('origin/'.branch).' 2>&1')), spec.dir)
endif endif
if !v:shell_error && filereadable(spec.dir.'/.gitmodules') && if !v:shell_error && filereadable(spec.dir.'/.gitmodules') &&
\ (s:update.force || has_key(s:update.new, name) || s:is_updated(spec.dir)) \ (s:update.force || has_key(s:update.new, name) || s:is_updated(spec.dir))
@ -1151,7 +1218,7 @@ function! s:job_abort()
silent! call job_stop(j.jobid) silent! call job_stop(j.jobid)
endif endif
if j.new if j.new
call s:system('rm -rf ' . s:shellesc(g:plugs[name].dir)) call s:rm_rf(g:plugs[name].dir)
endif endif
endfor endfor
let s:jobs = {} let s:jobs = {}
@ -1204,22 +1271,17 @@ endfunction
function! s:spawn(name, cmd, opts) function! s:spawn(name, cmd, opts)
let job = { 'name': a:name, 'running': 1, 'error': 0, 'lines': [''], let job = { 'name': a:name, 'running': 1, 'error': 0, 'lines': [''],
\ 'batchfile': (s:is_win && (s:nvim || s:vim8)) ? tempname().'.bat' : '',
\ 'new': get(a:opts, 'new', 0) } \ 'new': get(a:opts, 'new', 0) }
let s:jobs[a:name] = job let s:jobs[a:name] = job
let cmd = has_key(a:opts, 'dir') ? s:with_cd(a:cmd, a:opts.dir) : a:cmd let cmd = has_key(a:opts, 'dir') ? s:with_cd(a:cmd, a:opts.dir, 0) : a:cmd
if !empty(job.batchfile) let argv = s:is_win ? ['cmd', '/s', '/c', '"'.cmd.'"'] : ['sh', '-c', cmd]
call writefile(["@echo off\r", cmd . "\r"], job.batchfile)
let cmd = job.batchfile
endif
let argv = add(s:is_win ? ['cmd', '/c'] : ['sh', '-c'], cmd)
if s:nvim if s:nvim
call extend(job, { call extend(job, {
\ 'on_stdout': function('s:nvim_cb'), \ 'on_stdout': function('s:nvim_cb'),
\ 'on_exit': function('s:nvim_cb'), \ 'on_exit': function('s:nvim_cb'),
\ }) \ })
let jid = jobstart(argv, job) let jid = s:plug_call('jobstart', argv, job)
if jid > 0 if jid > 0
let job.jobid = jid let job.jobid = jid
else else
@ -1262,9 +1324,6 @@ function! s:reap(name)
call s:log(bullet, a:name, empty(result) ? 'OK' : result) call s:log(bullet, a:name, empty(result) ? 'OK' : result)
call s:bar() call s:bar()
if has_key(job, 'batchfile') && !empty(job.batchfile)
call delete(job.batchfile)
endif
call remove(s:jobs, a:name) call remove(s:jobs, a:name)
endfunction endfunction
@ -1279,9 +1338,10 @@ function! s:bar()
endfunction endfunction
function! s:logpos(name) function! s:logpos(name)
for i in range(4, line('$')) let max = line('$')
for i in range(4, max > 4 ? max : 4)
if getline(i) =~# '^[-+x*] '.a:name.':' if getline(i) =~# '^[-+x*] '.a:name.':'
for j in range(i + 1, line('$')) for j in range(i + 1, max > 5 ? max : 5)
if getline(j) !~ '^ ' if getline(j) !~ '^ '
return [i, j - 1] return [i, j - 1]
endif endif
@ -1354,8 +1414,8 @@ while 1 " Without TCO, Vim stack is bound to explode
\ printf('git clone %s %s %s %s 2>&1', \ printf('git clone %s %s %s %s 2>&1',
\ has_tag ? '' : s:clone_opt, \ has_tag ? '' : s:clone_opt,
\ prog, \ prog,
\ s:shellesc(spec.uri), \ plug#shellescape(spec.uri, {'script': 0}),
\ s:shellesc(s:trim(spec.dir))), { 'new': 1 }) \ plug#shellescape(s:trim(spec.dir), {'script': 0})), { 'new': 1 })
endif endif
if !s:jobs[name].running if !s:jobs[name].running
@ -1982,19 +2042,29 @@ function! s:update_ruby()
EOF EOF
endfunction endfunction
function! s:shellesc_cmd(arg) function! s:shellesc_cmd(arg, script)
let escaped = substitute(a:arg, '[&|<>()@^]', '^&', 'g') let escaped = substitute('"'.a:arg.'"', '[&|<>()@^!"]', '^&', 'g')
let escaped = substitute(escaped, '%', '%%', 'g') return substitute(escaped, '%', (a:script ? '%' : '^') . '&', 'g')
let escaped = substitute(escaped, '"', '\\^&', 'g')
let escaped = substitute(escaped, '\(\\\+\)\(\\^\)', '\1\1\2', 'g')
return '^"'.substitute(escaped, '\(\\\+\)$', '\1\1', '').'^"'
endfunction endfunction
function! s:shellesc(arg) function! s:shellesc_ps1(arg)
if &shell =~# 'cmd.exe$' return "'".substitute(escape(a:arg, '\"'), "'", "''", 'g')."'"
return s:shellesc_cmd(a:arg) endfunction
function! s:shellesc_sh(arg)
return "'".substitute(a:arg, "'", "'\\\\''", 'g')."'"
endfunction
function! plug#shellescape(arg, ...)
let opts = a:0 > 0 && type(a:1) == s:TYPE.dict ? a:1 : {}
let shell = get(opts, 'shell', s:is_win ? 'cmd.exe' : 'sh')
let script = get(opts, 'script', 1)
if shell =~# 'cmd\.exe'
return s:shellesc_cmd(a:arg, script)
elseif shell =~# 'powershell\.exe' || shell =~# 'pwsh$'
return s:shellesc_ps1(a:arg)
endif endif
return shellescape(a:arg) return s:shellesc_sh(a:arg)
endfunction endfunction
function! s:glob_dir(path) function! s:glob_dir(path)
@ -2026,23 +2096,23 @@ function! s:format_message(bullet, name, message)
endif endif
endfunction endfunction
function! s:with_cd(cmd, dir) function! s:with_cd(cmd, dir, ...)
return printf('cd%s %s && %s', s:is_win ? ' /d' : '', s:shellesc(a:dir), a:cmd) let script = a:0 > 0 ? a:1 : 1
return printf('cd%s %s && %s', s:is_win ? ' /d' : '', plug#shellescape(a:dir, {'script': script}), a:cmd)
endfunction endfunction
function! s:system(cmd, ...) function! s:system(cmd, ...)
let batchfile = ''
try try
let [sh, shellcmdflag, shrd] = s:chsh(1) let [sh, shellcmdflag, shrd] = s:chsh(1)
let cmd = a:0 > 0 ? s:with_cd(a:cmd, a:1) : a:cmd let cmd = a:0 > 0 ? s:with_cd(a:cmd, a:1) : a:cmd
if s:is_win if s:is_win
let batchfile = tempname().'.bat' let [batchfile, cmd] = s:batchfile(cmd)
call writefile(["@echo off\r", cmd . "\r"], batchfile)
let cmd = batchfile
endif endif
return system(s:is_win ? '('.cmd.')' : cmd) return system(cmd)
finally finally
let [&shell, &shellcmdflag, &shellredir] = [sh, shellcmdflag, shrd] let [&shell, &shellcmdflag, &shellredir] = [sh, shellcmdflag, shrd]
if s:is_win if s:is_win && filereadable(batchfile)
call delete(batchfile) call delete(batchfile)
endif endif
endtry endtry
@ -2115,7 +2185,7 @@ endfunction
function! s:rm_rf(dir) function! s:rm_rf(dir)
if isdirectory(a:dir) if isdirectory(a:dir)
call s:system((s:is_win ? 'rmdir /S /Q ' : 'rm -rf ') . s:shellesc(a:dir)) call s:system((s:is_win ? 'rmdir /S /Q ' : 'rm -rf ') . plug#shellescape(a:dir))
endif endif
endfunction endfunction
@ -2147,7 +2217,7 @@ function! s:clean(force)
let allowed = {} let allowed = {}
for dir in dirs for dir in dirs
let allowed[s:dirpath(fnamemodify(dir, ':h:h'))] = 1 let allowed[s:dirpath(s:plug_fnamemodify(dir, ':h:h'))] = 1
let allowed[dir] = 1 let allowed[dir] = 1
for child in s:glob_dir(dir) for child in s:glob_dir(dir)
let allowed[child] = 1 let allowed[child] = 1
@ -2220,11 +2290,11 @@ endfunction
function! s:upgrade() function! s:upgrade()
echo 'Downloading the latest version of vim-plug' echo 'Downloading the latest version of vim-plug'
redraw redraw
let tmp = tempname() let tmp = s:plug_tempname()
let new = tmp . '/plug.vim' let new = tmp . '/plug.vim'
try try
let out = s:system(printf('git clone --depth 1 %s %s', s:shellesc(s:plug_src), s:shellesc(tmp))) let out = s:system(printf('git clone --depth 1 %s %s', plug#shellescape(s:plug_src), plug#shellescape(tmp)))
if v:shell_error if v:shell_error
return s:err('Error upgrading vim-plug: '. out) return s:err('Error upgrading vim-plug: '. out)
endif endif
@ -2365,18 +2435,17 @@ function! s:preview_commit()
wincmd P wincmd P
endif endif
setlocal previewwindow filetype=git buftype=nofile nobuflisted modifiable setlocal previewwindow filetype=git buftype=nofile nobuflisted modifiable
let batchfile = ''
try try
let [sh, shellcmdflag, shrd] = s:chsh(1) let [sh, shellcmdflag, shrd] = s:chsh(1)
let cmd = 'cd '.s:shellesc(g:plugs[name].dir).' && git show --no-color --pretty=medium '.sha let cmd = 'cd '.plug#shellescape(g:plugs[name].dir).' && git show --no-color --pretty=medium '.sha
if s:is_win if s:is_win
let batchfile = tempname().'.bat' let [batchfile, cmd] = s:batchfile(cmd)
call writefile(["@echo off\r", cmd . "\r"], batchfile)
let cmd = batchfile
endif endif
execute 'silent %!' cmd execute 'silent %!' cmd
finally finally
let [&shell, &shellcmdflag, &shellredir] = [sh, shellcmdflag, shrd] let [&shell, &shellcmdflag, &shellredir] = [sh, shellcmdflag, shrd]
if s:is_win if s:is_win && filereadable(batchfile)
call delete(batchfile) call delete(batchfile)
endif endif
endtry endtry
@ -2420,9 +2489,11 @@ function! s:diff()
call s:append_ul(2, origin ? 'Pending updates:' : 'Last update:') call s:append_ul(2, origin ? 'Pending updates:' : 'Last update:')
for [k, v] in plugs for [k, v] in plugs
let range = origin ? '..origin/'.v.branch : 'HEAD@{1}..' let range = origin ? '..origin/'.v.branch : 'HEAD@{1}..'
let cmd = 'git log --graph --color=never '.join(map(['--pretty=format:%x01%h%x01%d%x01%s%x01%cr', range], 's:shellesc(v:val)')) let cmd = 'git log --graph --color=never '
\ . (s:git_version_requirement(2, 10, 0) ? '--no-show-signature ' : '')
\ . join(map(['--pretty=format:%x01%h%x01%d%x01%s%x01%cr', range], 'plug#shellescape(v:val)'))
if has_key(v, 'rtp') if has_key(v, 'rtp')
let cmd .= ' -- '.s:shellesc(v.rtp) let cmd .= ' -- '.plug#shellescape(v.rtp)
endif endif
let diff = s:system_chomp(cmd, v.dir) let diff = s:system_chomp(cmd, v.dir)
if !empty(diff) if !empty(diff)
@ -2470,7 +2541,7 @@ function! s:revert()
return return
endif endif
call s:system('git reset --hard HEAD@{1} && git checkout '.s:esc(g:plugs[name].branch).' --', g:plugs[name].dir) call s:system('git reset --hard HEAD@{1} && git checkout '.plug#shellescape(g:plugs[name].branch).' --', g:plugs[name].dir)
setlocal modifiable setlocal modifiable
normal! "_dap normal! "_dap
setlocal nomodifiable setlocal nomodifiable
@ -2498,7 +2569,7 @@ function! s:snapshot(force, ...) abort
endfor endfor
if a:0 > 0 if a:0 > 0
let fn = expand(a:1) let fn = s:plug_expand(a:1)
if filereadable(fn) && !(a:force || s:ask(a:1.' already exists. Overwrite?')) if filereadable(fn) && !(a:force || s:ask(a:1.' already exists. Overwrite?'))
return return
endif endif

View File

@ -5,6 +5,8 @@ Plug 'junegunn/fzf', { 'dir': '~/.fzf', 'do': './install --all' }
" Fzf.vim ------------------------------ " Fzf.vim ------------------------------
Plug 'junegunn/fzf.vim' Plug 'junegunn/fzf.vim'
" From https://github.com/antoinemadec/coc-fzf
Plug 'antoinemadec/coc-fzf'
"COMMANDS *fzf-vim-commands* "COMMANDS *fzf-vim-commands*
"============================================================================== "==============================================================================

View File

@ -183,6 +183,19 @@ Plug 'esamattis/slimux'
map <M-s> :SlimuxREPLSendLine<CR>j map <M-s> :SlimuxREPLSendLine<CR>j
vmap <M-s> :SlimuxREPLSendSelection<CR> vmap <M-s> :SlimuxREPLSendSelection<CR>
Plug 'pangloss/vim-javascript'
Plug 'iamcco/markdown-preview.nvim', { 'do': 'cd app && yarn install' }
Plug 'neoclide/coc.nvim', {'branch': 'release'}
Plug 'neoclide/jsonc.vim'
Plug 'ludovicchabant/vim-gutentags'
Plug 'vimwiki/vimwiki'
Plug 'bfredl/nvim-ipy'
" Tell vim-plug we finished declaring plugins, so it can load them " Tell vim-plug we finished declaring plugins, so it can load them
call plug#end() call plug#end()

View File

@ -4,8 +4,8 @@ set -g @plugin 'tmux-plugins/tmux-sensible'
# Tmux Power # Tmux Power
set -g @plugin 'wfxr/tmux-power' set -g @plugin 'wfxr/tmux-power'
set -g @tmux_power_theme 'sky' # dark slate blue set -g @tmux_power_theme 'forest' # dark slate blue
set -g @tmux_power_date_icon '🎄' # set it to a blank will disable the icon set -g @tmux_power_date_icon '🥥' # set it to a blank will disable the icon
set -g @tmux_power_time_icon '🕘' # emoji can be used if your terminal supports set -g @tmux_power_time_icon '🕘' # emoji can be used if your terminal supports
set -g @tmux_power_user_icon '🍄' set -g @tmux_power_user_icon '🍄'
set -g @tmux_power_session_icon '' set -g @tmux_power_session_icon ''