├── .gitignore
├── LICENSE
├── Makefile
├── README.md
├── aws
└── .aws
│ └── cli
│ └── alias
├── bash
├── .bash_profile
├── .bashrc
├── .curlrc
├── .hushlogin
├── .inputrc
├── .stow-local-ignore
├── dots
│ ├── aliases
│ ├── env
│ ├── func
│ ├── git
│ └── prompt
├── neofetch-all.conf
└── neofetch.conf
├── git
├── .gitconfig
└── .gitignore_global
├── gpg
└── .gnupg
│ ├── gpg-agent.conf
│ └── gpg.conf
├── linux
└── .Brewfile
├── macos
├── .Brewfile
├── .lldbinit
├── .skhdrc
├── .stow-local-ignore
├── .yabairc
├── README.md
├── defaults.sh
├── duti
│ ├── iina.txt
│ ├── openemu.txt
│ ├── set.sh
│ └── sourcecode.txt
├── iterm
│ ├── com.googlecode.iterm2.plist
│ └── glacier-black.itermcolors
└── kitty.conf
└── vim
├── .ctags
├── .vim
└── autoload
│ └── plug.vim
└── .vimrc
/.gitignore:
--------------------------------------------------------------------------------
1 | .netrwhist
2 | .proxy
3 | /vim/.vim/plugs
4 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | CC0 1.0 Universal
2 |
3 | Statement of Purpose
4 |
5 | The laws of most jurisdictions throughout the world automatically confer
6 | exclusive Copyright and Related Rights (defined below) upon the creator
7 | and subsequent owner(s) (each and all, an "owner") of an original work of
8 | authorship and/or a database (each, a "Work").
9 |
10 | Certain owners wish to permanently relinquish those rights to a Work for
11 | the purpose of contributing to a commons of creative, cultural and
12 | scientific works ("Commons") that the public can reliably and without fear
13 | of later claims of infringement build upon, modify, incorporate in other
14 | works, reuse and redistribute as freely as possible in any form whatsoever
15 | and for any purposes, including without limitation commercial purposes.
16 | These owners may contribute to the Commons to promote the ideal of a free
17 | culture and the further production of creative, cultural and scientific
18 | works, or to gain reputation or greater distribution for their Work in
19 | part through the use and efforts of others.
20 |
21 | For these and/or other purposes and motivations, and without any
22 | expectation of additional consideration or compensation, the person
23 | associating CC0 with a Work (the "Affirmer"), to the extent that he or she
24 | is an owner of Copyright and Related Rights in the Work, voluntarily
25 | elects to apply CC0 to the Work and publicly distribute the Work under its
26 | terms, with knowledge of his or her Copyright and Related Rights in the
27 | Work and the meaning and intended legal effect of CC0 on those rights.
28 |
29 | 1. Copyright and Related Rights. A Work made available under CC0 may be
30 | protected by copyright and related or neighboring rights ("Copyright and
31 | Related Rights"). Copyright and Related Rights include, but are not
32 | limited to, the following:
33 |
34 | i. the right to reproduce, adapt, distribute, perform, display,
35 | communicate, and translate a Work;
36 | ii. moral rights retained by the original author(s) and/or performer(s);
37 | iii. publicity and privacy rights pertaining to a person's image or
38 | likeness depicted in a Work;
39 | iv. rights protecting against unfair competition in regards to a Work,
40 | subject to the limitations in paragraph 4(a), below;
41 | v. rights protecting the extraction, dissemination, use and reuse of data
42 | in a Work;
43 | vi. database rights (such as those arising under Directive 96/9/EC of the
44 | European Parliament and of the Council of 11 March 1996 on the legal
45 | protection of databases, and under any national implementation
46 | thereof, including any amended or successor version of such
47 | directive); and
48 | vii. other similar, equivalent or corresponding rights throughout the
49 | world based on applicable law or treaty, and any national
50 | implementations thereof.
51 |
52 | 2. Waiver. To the greatest extent permitted by, but not in contravention
53 | of, applicable law, Affirmer hereby overtly, fully, permanently,
54 | irrevocably and unconditionally waives, abandons, and surrenders all of
55 | Affirmer's Copyright and Related Rights and associated claims and causes
56 | of action, whether now known or unknown (including existing as well as
57 | future claims and causes of action), in the Work (i) in all territories
58 | worldwide, (ii) for the maximum duration provided by applicable law or
59 | treaty (including future time extensions), (iii) in any current or future
60 | medium and for any number of copies, and (iv) for any purpose whatsoever,
61 | including without limitation commercial, advertising or promotional
62 | purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each
63 | member of the public at large and to the detriment of Affirmer's heirs and
64 | successors, fully intending that such Waiver shall not be subject to
65 | revocation, rescission, cancellation, termination, or any other legal or
66 | equitable action to disrupt the quiet enjoyment of the Work by the public
67 | as contemplated by Affirmer's express Statement of Purpose.
68 |
69 | 3. Public License Fallback. Should any part of the Waiver for any reason
70 | be judged legally invalid or ineffective under applicable law, then the
71 | Waiver shall be preserved to the maximum extent permitted taking into
72 | account Affirmer's express Statement of Purpose. In addition, to the
73 | extent the Waiver is so judged Affirmer hereby grants to each affected
74 | person a royalty-free, non transferable, non sublicensable, non exclusive,
75 | irrevocable and unconditional license to exercise Affirmer's Copyright and
76 | Related Rights in the Work (i) in all territories worldwide, (ii) for the
77 | maximum duration provided by applicable law or treaty (including future
78 | time extensions), (iii) in any current or future medium and for any number
79 | of copies, and (iv) for any purpose whatsoever, including without
80 | limitation commercial, advertising or promotional purposes (the
81 | "License"). The License shall be deemed effective as of the date CC0 was
82 | applied by Affirmer to the Work. Should any part of the License for any
83 | reason be judged legally invalid or ineffective under applicable law, such
84 | partial invalidity or ineffectiveness shall not invalidate the remainder
85 | of the License, and in such case Affirmer hereby affirms that he or she
86 | will not (i) exercise any of his or her remaining Copyright and Related
87 | Rights in the Work or (ii) assert any associated claims and causes of
88 | action with respect to the Work, in either case contrary to Affirmer's
89 | express Statement of Purpose.
90 |
91 | 4. Limitations and Disclaimers.
92 |
93 | a. No trademark or patent rights held by Affirmer are waived, abandoned,
94 | surrendered, licensed or otherwise affected by this document.
95 | b. Affirmer offers the Work as-is and makes no representations or
96 | warranties of any kind concerning the Work, express, implied,
97 | statutory or otherwise, including without limitation warranties of
98 | title, merchantability, fitness for a particular purpose, non
99 | infringement, or the absence of latent or other defects, accuracy, or
100 | the present or absence of errors, whether or not discoverable, all to
101 | the greatest extent permissible under applicable law.
102 | c. Affirmer disclaims responsibility for clearing rights of other persons
103 | that may apply to the Work or any use thereof, including without
104 | limitation any person's Copyright and Related Rights in the Work.
105 | Further, Affirmer disclaims responsibility for obtaining any necessary
106 | consents, permissions or other rights required for any use of the
107 | Work.
108 | d. Affirmer understands and acknowledges that Creative Commons is not a
109 | party to this document and has no duty or obligation with respect to
110 | this CC0 or use of the Work.
111 |
112 | For more information, please see
113 |
114 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | DOTFILES_DIR := $(shell echo $(HOME)/dotfiles)
2 | SHELL := /bin/sh
3 | UNAME_M := $(shell uname -m)
4 | UNAME_S := $(shell uname -s)
5 | USER := $(shell whoami)
6 |
7 | ifeq ($(UNAME_S), Darwin)
8 | BASE := macos
9 | BREWFILE := macos/.Brewfile
10 | ifeq ($(UNAME_M), arm64)
11 | BREW_PREFIX := /opt/homebrew
12 | else ifeq ($(UNAME_M), x86_64)
13 | BREW_PREFIX := /usr/local
14 | endif
15 |
16 | else
17 | BREW_PREFIX := /home/linuxbrew/.linuxbrew
18 |
19 | # ParallelCluster
20 | ifneq ($(wildcard /etc/parallelcluster),)
21 | BASE := pcluster
22 | BREWFILE := linux/pcluster.brewfile
23 | else ifeq ($(UNAME_S), Linux)
24 | BASE := linux
25 | BREWFILE := linux/.Brewfile
26 | endif
27 | endif
28 |
29 | .PHONY: all install
30 |
31 | all: install
32 |
33 | install: $(BASE)
34 |
35 | .PHONY: help usage
36 | .SILENT: help usage
37 |
38 | help: usage
39 |
40 | usage:
41 | printf "\\n\
42 | \\033[1mDOTFILES\\033[0m\\n\
43 | \\n\
44 | Custom settings and configurations for Unix-like environments.\\n\
45 | See README.md for detailed usage information.\\n\
46 | \\n\
47 | \\033[1mUSAGE:\\033[0m make [target]\\n\
48 | \\n\
49 | make Install all configurations and applications.\\n\
50 | \\n\
51 | "
52 |
53 | .PHONY: linux macos pcluster
54 |
55 | linux: stow vim
56 | sudo apt install build-essential
57 |
58 | macos: brew stow vim
59 | bash $(DOTFILES_DIR)/macos/defaults.sh
60 | bash $(DOTFILES_DIR)/macos/duti/set.sh
61 | $(BREW_PREFIX)/bin/stow gpg
62 | $(BREW_PREFIX)/bin/stow macos
63 | $(BREW_PREFIX)/bin/brew services start yabai
64 | $(BREW_PREFIX)/bin/brew services start skhd
65 | echo $(BREW_PREFIX)/bin/bash | sudo tee -a /etc/shells
66 | chsh -s $(BREW_PREFIX)/bin/bash
67 | ln -s /System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport /usr/local/bin/airport
68 | softwareupdate -aiR
69 |
70 | # Install iTerm shell integ first since it may write to ~/.bash_profile
71 | pcluster: iterm stow vim
72 | sudo yum install -y python3-devel
73 |
74 | .PHONY: brew stow
75 |
76 | brew:
77 | ifeq ($(shell which brew),)
78 | @printf "Homebrew not detected; running install script\\n"
79 | NONINTERACTIVE=1 /bin/bash -c "$$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
80 | else
81 | @printf "Homebrew already installed; skipping installation\\n"
82 | endif
83 | $(BREW_PREFIX)/bin/brew bundle --file=$(DOTFILES_DIR)/$(BREWFILE)
84 | $(BREW_PREFIX)/bin/brew analytics off
85 |
86 | iterm:
87 | curl -L https://iterm2.com/shell_integration/install_shell_integration.sh | bash
88 |
89 | stow:
90 | [ -f ~/.bash_profile ] && [ ! -L ~/.bash_profile ] && mv ~/.bash_profile ~/.bash_profile.bak
91 | [ -f ~/.bashrc ] && [ ! -L ~/.bashrc ] && mv ~/.bashrc ~/.bashrc.bak
92 | stow aws
93 | stow bash
94 | stow git
95 | stow vim
96 |
97 | vim:
98 | vim +PlugInstall +qall
99 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # dotfiles
2 |
3 | Files for configuring a terminal environment and other various system settings. Largely centered around macOS, as well as other Unix-like systems. See [Github does dotfiles](https://dotfiles.github.io) for more info
4 |
5 | ## Installation
6 |
7 | ### `curl` method (easiest)
8 |
9 | ```bash
10 | curl get.darryl.cx | sh && make -C dotfiles
11 | ```
12 |
13 | Source code for the script is [here](https://github.com/darrylabbate/get-dotfiles/blob/master/src/dotfiles.sh). Checksums can be found in the [tag notes](https://github.com/darrylabbate/get-dotfiles/tags).
14 |
15 | The `curl` method will install everything automatically. This is really useful for quickly setting up a new machine.
16 |
17 | ### Manual method
18 |
19 | You can also manually clone the repository and invoke the `Makefile`
20 |
21 | ```bash
22 | git clone https://github.com/darrylabbate/dotfiles && make -C dotfiles
23 | ```
24 |
25 | ## Makefile
26 |
27 | ### `make`
28 |
29 | * Installs [Homebrew](https://brew.sh) on macOS and installs all packages defined in the [Brewfile](macos/.Brewfile).
30 | * Sets Homebrew-installed Bash (4.4+) as the default shell
31 | * Updates macOS and configures preferred system defaults defined in [`/macos/defaults.sh`](macos/defaults.sh)
32 | * Configures [yabai](https://github.com/koekeishiya/yabai) and [skhd](https://github.com/koekeishiya/skhd) to run at system startup
33 | * Creates necessary symlinks via [GNU Stow](https://www.gnu.org/software/stow/)
34 | * Runs [`/macos/duti/set.sh`](macos/duti/set.sh), which sets defaults handlers/programs for file extensions via [duti](http://duti.org).
35 |
36 | ### `make link`
37 |
38 | * Symlinks only Bash and Vim configuration files to the home directory using `ln` commands. Useful for temporarily configuring a shared computer. Nothing new is installed to the machine, but files *may* be overwritten since the Makefile recipe passes the `-f` flag for every `ln` command.
39 | * Run `make unlink` to remove these symlinks.
40 |
41 | ## How it Works
42 |
43 | ### Symlinks
44 |
45 | All necessary symlinks ( [`.bash_profile`](bash/.bash_profile), [`.vimrc`](vim/.vimrc), among others) are managed with GNU Stow (installed with Homebrew). Files you wish to be symlinked to the home directory need to be placed in a folder within `~/dotfiles`. Using the `stow` command from the `~/dotfiles` directory will symlink the contents of the folder you choose (`/bash`, `/vim`, etc) to the grandparent directory, which is wherever the `/dotfiles` folder is contained.
46 |
47 | Assuming you clone the dotfiles repository in your home directory, executing the commands:
48 |
49 | ```bash
50 | $ cd dotfiles
51 | $ stow bash
52 | ```
53 | will symlink the contents of [`/bash`](bash) to the home directory.
54 |
55 | You can use the `stow` command anytime you add a new file to a folder you wish to symlink directly to the home directory. This can all be done without Stow using the `ln -s` command, but I find GNU Stow with folder management to be cleaner and easier to maintain.
56 |
57 | ### Bash
58 |
59 | `.bash_profile` automatically sources configurations defined in the files contained in the [`/bash/dots`](bash/dots) folder. Any changes to any existing file, as well as any new files in `/bash/dots/` will be loaded into the shell upon opening a new Terminal window or [reloading](https://github.com/darrylabbate/dotfiles/blob/db902b9ac0c466d09672f58549bff4107ba53861/dots/aliases#L4) the `.bash_profile`.
60 |
61 | ### Vim
62 |
63 | - [Plug](https://github.com/junegunn/vim-plug)
64 |
65 | ### Window Management
66 |
67 | - [yabai](https://github.com/koekeishiya/yabai)
68 | - [skhd](https://github.com/koekeishiya/skhd)
69 |
--------------------------------------------------------------------------------
/aws/.aws/cli/alias:
--------------------------------------------------------------------------------
1 | [toplevel]
2 |
3 | cfn = cloudformation
4 | conf = configure
5 | regions = ec2 describe-regions --query 'Regions[].RegionName[]' --output text
6 | whoami = sts get-caller-identity
7 |
8 |
9 | [command cloudformation]
10 |
11 | ls = describe-stacks --query 'Stacks[].[StackName,StackStatus]'
12 |
13 | rm = delete-stack --stack-name
14 |
15 | head = describe-stack-events \
16 | --max-items 10 \
17 | --query 'StackEvents[].[
18 | Timestamp,
19 | ResourceType,
20 | ResourceStatus
21 | ]' \
22 | --stack-name
23 |
24 |
25 | [command configure]
26 |
27 | ls = list-profiles
28 |
29 |
30 | [command ec2]
31 |
32 | keys = describe-key-pairs --query 'KeyPairs[].[KeyName,KeyPairId,KeyType,KeyFingerprint]'
33 |
34 | find = !f() {
35 | instance=${1:?expected instance type argument}
36 | echo "Locating regions with ${instance}..."
37 | for region in $(aws regions); do
38 | aws ec2 describe-instance-types --region $region --instance-types $instance &> /dev/null
39 | [[ $? -eq 0 ]] && echo $region
40 | done
41 | }; f
42 |
43 | ls = describe-instances \
44 | --query 'Reservations[].Instances[].[
45 | InstanceType,
46 | InstanceId,
47 | Tags[?Key==`Name`]|[0].Value,
48 | PublicIpAddress || `-`,
49 | PrivateIpAddress,
50 | NetworkInterfaces[?InterfaceType==`efa`]|[0].InterfaceType || `-`,
51 | Placement.AvailabilityZone,
52 | State.Name
53 | ] | sort_by(@, &[0])'
54 |
55 | lsefa = describe-instance-types \
56 | --filters Name=network-info.efa-supported,Values=true \
57 | --query 'InstanceTypes[].[
58 | InstanceType,
59 | [VCpuInfo.DefaultVCpus.to_string(@), `vCPUs`].join(`\u0020`,@),
60 | ProcessorInfo.[
61 | [SustainedClockSpeedInGhz.to_string(@), `GHz`].join(`\u0020`,@),
62 | SupportedArchitectures[0]
63 | ],
64 | [MemoryInfo.SizeInMiB.to_string(@), `MiB`].join(`\u0020`,@),
65 | FpgaInfo && `FPGA` || GpuInfo && `GPU` || InferenceAcceleratorInfo && `Inf` || `-`,
66 | (FpgaInfo.Fpgas || GpuInfo.Gpus || InferenceAcceleratorInfo.Accelerators)[0].[
67 | Count,
68 | [Manufacturer, Name].join(`\u0020`,@),
69 | MemoryInfo && [MemoryInfo.SizeInMiB.to_string(@), `MiB`].join(`\u0020`,@) || `-`
70 | ] || [`-`,`-`,`-`],
71 | NetworkInfo.[
72 | [EfaInfo.MaximumEfaInterfaces.to_string(@), `EFA`].join(`\u0020`,@),
73 | NetworkPerformance
74 | ]
75 | ] | map(&[], @) | sort_by(@, &[0])'
76 |
77 | lsefa-global = !f() {
78 | echo "Finding instance types with EFA support in all regions (this may take a while)..."
79 | for region in $(aws regions); do
80 | echo "${region}:"
81 | aws ec2 lsefa --region $region
82 | echo ""
83 | done
84 | }; f
85 |
86 | lspc = describe-instances \
87 | --filters 'Name=tag-key,Values=parallelcluster:version' \
88 | --query 'Reservations[].Instances[].[
89 | Tags[?Key==`parallelcluster:cluster-name`]|[0].Value,
90 | InstanceType,
91 | Tags[?Key==`parallelcluster:node-type`&&Value==`HeadNode`] && `-` || [
92 | Tags[?Key==`parallelcluster:queue-name`]|[0].Value,
93 | Tags[?Key==`parallelcluster:compute-resource-name`]|[0].Value
94 | ].join(`:`,@),
95 | PublicIpAddress || PrivateIpAddress,
96 | Placement.AvailabilityZone,
97 | InstanceId,
98 | Tags[?Key==`parallelcluster:version`]|[0].Value,
99 | State.Name
100 | ] | sort_by(sort_by(@, &[1]), &[0])'
101 |
--------------------------------------------------------------------------------
/bash/.bash_profile:
--------------------------------------------------------------------------------
1 | case $(uname -s) in
2 | Darwin) brew_prefix=/opt/homebrew ;;
3 | Linux) brew_prefix=/home/linuxbrew/.linuxbrew ;;
4 | esac
5 |
6 | [[ $(uname -s) == Linux ]] && ulimit -c unlimited
7 |
8 | PATH=/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin
9 |
10 | if [[ $(uname -s) == Darwin ]]; then
11 | PATH=$brew_prefix/opt/coreutils/libexec/gnubin:/usr/local/texlive/2024basic/bin/universal-darwin${PATH:+:$PATH}
12 | fi
13 |
14 | [[ -d $brew_prefix ]] && eval "$($brew_prefix/bin/brew shellenv)"
15 |
16 | export PATH=$HOME/.local/bin${PATH:+:$PATH}
17 |
18 | # Search path for manual pages on macOS is deduced from $PATH
19 | # On Linux, appending a colon to $MANPATH prepends the value to the search path
20 | # See: manpath(1)
21 | if [[ $(uname -s) == Linux ]]; then
22 | export MANPATH=$HOME/.local/share/man:
23 | fi
24 |
25 | for file in \
26 | $HOME/dotfiles/bash/dots/* \
27 | $HOME/.aocrc \
28 | $HOME/.iterm_shell_integration.bash
29 | do
30 | [[ -r $file ]] && [[ -f $file ]] && source $file
31 | done
32 | unset file
33 |
--------------------------------------------------------------------------------
/bash/.bashrc:
--------------------------------------------------------------------------------
1 | # Source ~/.bash_profile in the event of a shell
2 | # looking for a .bashrc
3 |
4 | source ~/.bash_profile
5 |
--------------------------------------------------------------------------------
/bash/.curlrc:
--------------------------------------------------------------------------------
1 | progress-bar
2 |
--------------------------------------------------------------------------------
/bash/.hushlogin:
--------------------------------------------------------------------------------
1 | # Shh no login only dreams now
2 |
--------------------------------------------------------------------------------
/bash/.inputrc:
--------------------------------------------------------------------------------
1 | # Use vi/vim keybindings in the terminal
2 | set editing-mode vi
3 |
4 | # Show all matching filenames for tab-completion
5 | set show-all-if-ambiguous on
6 |
7 | # Ignore case for tab auto-completion
8 | set completion-ignore-case on
9 |
10 | # Exit normal/command mode by typing 'jk' or 'kj'
11 | "jk":"\e"
12 | "kj":"\e"
13 |
--------------------------------------------------------------------------------
/bash/.stow-local-ignore:
--------------------------------------------------------------------------------
1 | /dots
2 | .DS_Store
3 | neofetch.conf
4 | neofetch-all.conf
5 |
--------------------------------------------------------------------------------
/bash/dots/aliases:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | alias ..="cd .." # Up one level
4 | alias ...="cd ../.." # Up two levels
5 | alias ....="cd ../../.." # Up three levels
6 |
7 |
8 | # Single-letter aliases
9 | # ---------------------
10 |
11 | alias a="cd ~/apps"
12 | alias b="cd -" # Return to previous directory
13 | alias c="clear"
14 | alias d="cd ~/dotfiles"
15 | alias f="open ." # Open current directory in Finder
16 | alias k="pkill -i" # Kill app by name
17 | alias h="cd ~" # Home directory
18 | alias p="cd ~/projects"
19 | alias t="type"
20 | alias v="vim"
21 |
22 |
23 | # Two and three letter aliases
24 | # ----------------------------
25 |
26 | alias cpu="top -F -R -o cpu"
27 | alias dl="youtube-dl"
28 | alias nf="neofetch --config ~/dotfiles/bash/neofetch.conf"
29 | alias nff="neofetch --config ~/dotfiles/bash/neofetch-all.conf"
30 | alias spd="speedtest-cli"
31 | alias ta="type -a"
32 | alias tl="cd /"
33 | alias vol="cd /volumes"
34 |
35 | # Use GNU `ls` if installed (gls via Homebrew on macOS)
36 | if [[ "$(uname -s)" == "Linux" ]]; then
37 | alias l="ls -Fh --color --group-directories-first"
38 | alias la="ls -AFh --color --group-directories-first"
39 | alias ll="ls -AFhlo --color --group-directories-first"
40 | elif [[ "$(command -v gls)" ]]; then
41 | alias l="gls -Fh --color --group-directories-first"
42 | alias la="gls -AFh --color --group-directories-first"
43 | alias ll="gls -AFhlo --color --group-directories-first"
44 | else
45 | alias l="ls -F"
46 | alias la="ls -AF"
47 | alias ll="ls -AFlo"
48 | fi
49 |
50 |
51 | # Longer aliases
52 | # --------------
53 |
54 | alias cmdkill="pkill -i"
55 | alias empty="sudo rm -rf ~/.Trash/*" # Empty macOS trash
56 | alias ffmon="yabai -m config focus_follows_mouse autofocus" # Enable focus follow mouse
57 | alias ffmoff="yabai -m config focus_follows_mouse off" # Disable focus follow mouse
58 | alias fkill="killall Finder"
59 | alias egrep="egrep --color=auto"
60 | alias grep="grep --color=auto"
61 | alias kill="kill -9"
62 | alias nawk="/usr/bin/awk" # One True AWK
63 | alias rebash="source ~/.bash_profile" # Reload .bash_profile
64 | alias reyabai="yabai --restart-service" # Restart yabai
65 | alias rekey="skhd --restart-service" # Restart skhd
66 | alias pgrep="pgrep -i"
67 | alias temp="osx-cpu-temp"
68 | alias tempf="osx-cpu-temp -F"
69 | alias tidy="find . -type f -name '*.DS_Store' -ls -delete" # Delete all `.DS_Store` files
70 | alias tree="tree -C" # Always use colored `tree` output
71 | alias update="sudo softwareupdate -aiR" # Install all macOS updates and restart system
72 |
--------------------------------------------------------------------------------
/bash/dots/env:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | # Silence message about zsh on macOS
4 | export BASH_SILENCE_DEPRECATION_WARNING=1
5 |
6 | export HISTCONTROL=ignoredups
7 |
8 | # Ignores all one-word and two-word commands for more efficient
9 | # bash history searching
10 | export HISTIGNORE=?:??
11 |
12 | # ls colors
13 | export CLICOLOR=1
14 | export LSCOLORS=exgxbxbxCxfxfxCaCaeaea
15 |
16 | export EDITOR='vim'
17 | export GPG_TTY=$(tty)
18 |
19 | export HOMEBREW_CURLRC=1
20 | export HOMEBREW_FORCE_BREWED_CURL=1
21 | export HOMEBREW_NO_AUTO_UPDATE=1
22 |
--------------------------------------------------------------------------------
/bash/dots/func:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | function rf() {
4 | local CODE
5 | CODE="print(${1})"
6 |
7 | riff -e "$CODE"
8 | }
9 | # Print Lua disassembly of provided code
10 | function luad() {
11 | local CODE
12 | CODE=$1
13 |
14 | echo $1 | luac -l -
15 | }
16 |
17 | # Print a single Lua expression
18 | function luap() {
19 | local CODE
20 | CODE="print(${1})"
21 |
22 | lua -e "$CODE"
23 | }
24 |
25 | # Print mawk disassembly of provided code
26 | function mawkd() {
27 | local CODE
28 | CODE="BEGIN{${1}}"
29 |
30 | mawk -W dump "$CODE"
31 | }
32 |
33 | # Print a single AWK expression, using mawk
34 | function mawkp() {
35 | local CODE
36 | CODE="BEGIN{print ${1}}"
37 |
38 | mawk "$CODE"
39 | }
40 |
41 | # Print a single Perl expression
42 | function perlp() {
43 | local CODE
44 | CODE="print(${1})"
45 |
46 | perl -le "$CODE"
47 | }
48 |
49 | # Print a single Python expression
50 | function pyp() {
51 | local CODE
52 | CODE="print(${1})"
53 |
54 | python3 -c "$CODE"
55 | }
56 |
57 | # Print a single Ruby expression
58 | function rubyp() {
59 | local CODE
60 | CODE="puts ${1}"
61 |
62 | ruby -e "$CODE"
63 | }
64 |
65 | function aocinput() {
66 | local YEAR=$(pwd | awk -F/ '{printf "%s\n", $(NF-1)}')
67 | local DAY=$(pwd | awk -F/ '{printf "%d\n", $(NF)}')
68 | curl --cookie session=$AOC_COOKIE https://adventofcode.com/20$YEAR/day/$DAY/input > input
69 | }
70 |
--------------------------------------------------------------------------------
/bash/dots/git:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | # Git
4 | # ---
5 |
6 | alias ga="git add"
7 | alias gall="git add --all"
8 | alias gb="git branch"
9 | alias gba="git branch --all"
10 | alias gc="git commit"
11 | alias gca="git commit --amend"
12 | alias gcl="git clone --recursive"
13 | alias gco="git checkout"
14 | alias gcp="git cherry-pick"
15 | alias gd="git diff"
16 | alias grd="git --no-pager diff"
17 | alias gf="git fetch --dry-run --verbose"
18 | alias gg="git grep"
19 | alias gge="git grep -P"
20 | alias ggei="git grep -Pi"
21 | alias gl="git log --oneline -n 10"
22 | alias gp="git push"
23 | alias gpl="git pull"
24 | alias grb="git rebase"
25 | alias gs="git status -sb"
26 |
27 | # Quick commit with message without quotes
28 | function qc() {
29 | message=$*
30 |
31 | if [[ $message ]]; then
32 | git commit -m "${message}"
33 | else
34 | printf "\\033[31mERROR:\\033[0m Commit message required\\n"
35 | return 1
36 | fi
37 | }
38 |
--------------------------------------------------------------------------------
/bash/dots/prompt:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | PS1="\W \[$(tput -T xterm-256color bold)\]\$\[$(tput -T xterm-256color sgr0)\] "
4 |
--------------------------------------------------------------------------------
/bash/neofetch-all.conf:
--------------------------------------------------------------------------------
1 | # Neofetch full config file
2 | # Displays all available functions. Mainly for piping into grep.
3 | # Runs all functions asynchronously; expect unordered output if run by itself.
4 | # https://github.com/dylanaraps/neofetch
5 |
6 | # See this wiki page for more info:
7 | # https://github.com/dylanaraps/neofetch/wiki/Customizing-Info
8 | print_info() {
9 | info title
10 | info underline
11 |
12 | info "OS" distro &
13 | info "Host" model &
14 | info "Kernel" kernel &
15 | info "Uptime" uptime &
16 | info "Packages" packages &
17 | info "Shell" shell &
18 | info "Resolution" resolution &
19 | info "DE" de &
20 | info "WM" wm &
21 | info "WM Theme" wm_theme &
22 | info "Theme" theme &
23 | info "Icons" icons &
24 | info "Terminal" term &
25 | info "Terminal Font" term_font &
26 | info "CPU" cpu &
27 | info "GPU" gpu &
28 | info "Memory" memory &
29 | info "GPU Driver" gpu_driver &
30 | info "CPU Usage" cpu_usage &
31 | info "Disk" disk &
32 | info "Battery" battery &
33 | info "Font" font &
34 | info "Song" song &
35 | info "Local IP" local_ip &
36 | info "Public IP" public_ip &
37 | info "Users" users &
38 | info "Install Date" install_date &
39 | info "Locale" locale &
40 |
41 | wait
42 | }
43 |
44 |
45 | # Kernel
46 |
47 |
48 | # Shorten the output of the kernel function.
49 | #
50 | # Default: 'on'
51 | # Values: 'on', 'off'
52 | # Flag: --kernel_shorthand
53 | # Supports: Everything except *BSDs (except PacBSD and PC-BSD)
54 | #
55 | # Example:
56 | # on: '4.8.9-1-ARCH'
57 | # off: 'Linux 4.8.9-1-ARCH'
58 | kernel_shorthand="off"
59 |
60 |
61 | # Distro
62 |
63 |
64 | # Shorten the output of the distro function
65 | #
66 | # Default: 'off'
67 | # Values: 'on', 'off', 'tiny'
68 | # Flag: --distro_shorthand
69 | # Supports: Everything except Windows and Haiku
70 | distro_shorthand="off"
71 |
72 | # Show/Hide OS Architecture.
73 | # Show 'x86_64', 'x86' and etc in 'Distro:' output.
74 | #
75 | # Default: 'on'
76 | # Values: 'on', 'off'
77 | # Flag: --os_arch
78 | #
79 | # Example:
80 | # on: 'Arch Linux x86_64'
81 | # off: 'Arch Linux'
82 | os_arch="on"
83 |
84 |
85 | # Uptime
86 |
87 |
88 | # Shorten the output of the uptime function
89 | #
90 | # Default: 'on'
91 | # Values: 'on', 'off', 'tiny'
92 | # Flag: --uptime_shorthand
93 | #
94 | # Example:
95 | # on: '2 days, 10 hours, 3 mins'
96 | # off: '2 days, 10 hours, 3 minutes'
97 | # tiny: '2d 10h 3m'
98 | uptime_shorthand="off"
99 |
100 |
101 | # Shell
102 |
103 |
104 | # Show the path to $SHELL
105 | #
106 | # Default: 'off'
107 | # Values: 'on', 'off'
108 | # Flag: --shell_path
109 | #
110 | # Example:
111 | # on: '/bin/bash'
112 | # off: 'bash'
113 | shell_path="on"
114 |
115 | # Show $SHELL version
116 | #
117 | # Default: 'on'
118 | # Values: 'on', 'off'
119 | # Flag: --shell_version
120 | #
121 | # Example:
122 | # on: 'bash 4.4.5'
123 | # off: 'bash'
124 | shell_version="on"
125 |
126 |
127 | # CPU
128 |
129 |
130 | # CPU speed type
131 | #
132 | # Default: 'bios_limit'
133 | # Values: 'scaling_cur_freq', 'scaling_min_freq', 'scaling_max_freq', 'bios_limit'.
134 | # Flag: --speed_type
135 | # Supports: Linux with 'cpufreq'
136 | # NOTE: Any file in '/sys/devices/system/cpu/cpu0/cpufreq' can be used as a value.
137 | speed_type="bios_limit"
138 |
139 | # CPU speed shorthand
140 | #
141 | # Default: 'off'
142 | # Values: 'on', 'off'.
143 | # Flag: --speed_shorthand.
144 | # NOTE: This flag is not supported in systems with CPU speed less than 1 GHz
145 | #
146 | # Example:
147 | # on: 'i7-6500U (4) @ 3.1GHz'
148 | # off: 'i7-6500U (4) @ 3.100GHz'
149 | speed_shorthand="off"
150 |
151 | # Enable/Disable CPU brand in output.
152 | #
153 | # Default: 'on'
154 | # Values: 'on', 'off'
155 | # Flag: --cpu_brand
156 | #
157 | # Example:
158 | # on: 'Intel i7-6500U'
159 | # off: 'i7-6500U (4)'
160 | cpu_brand="on"
161 |
162 | # CPU Speed
163 | # Hide/Show CPU speed.
164 | #
165 | # Default: 'on'
166 | # Values: 'on', 'off'
167 | # Flag: --cpu_speed
168 | #
169 | # Example:
170 | # on: 'Intel i7-6500U (4) @ 3.1GHz'
171 | # off: 'Intel i7-6500U (4)'
172 | cpu_speed="on"
173 |
174 | # CPU Cores
175 | # Display CPU cores in output
176 | #
177 | # Default: 'logical'
178 | # Values: 'logical', 'physical', 'off'
179 | # Flag: --cpu_cores
180 | # Support: 'physical' doesn't work on BSD.
181 | #
182 | # Example:
183 | # logical: 'Intel i7-6500U (4) @ 3.1GHz' (All virtual cores)
184 | # physical: 'Intel i7-6500U (2) @ 3.1GHz' (All physical cores)
185 | # off: 'Intel i7-6500U @ 3.1GHz'
186 | cpu_cores="logical"
187 |
188 | # CPU Temperature
189 | # Hide/Show CPU temperature.
190 | # Note the temperature is added to the regular CPU function.
191 | #
192 | # Default: 'off'
193 | # Values: 'C', 'F', 'off'
194 | # Flag: --cpu_temp
195 | # Supports: Linux, BSD
196 | # NOTE: For FreeBSD and NetBSD-based systems, you'll need to enable
197 | # coretemp kernel module. This only supports newer Intel processors.
198 | #
199 | # Example:
200 | # C: 'Intel i7-6500U (4) @ 3.1GHz [27.2°C]'
201 | # F: 'Intel i7-6500U (4) @ 3.1GHz [82.0°F]'
202 | # off: 'Intel i7-6500U (4) @ 3.1GHz'
203 | cpu_temp="F"
204 |
205 |
206 | # GPU
207 |
208 |
209 | # Enable/Disable GPU Brand
210 | #
211 | # Default: 'on'
212 | # Values: 'on', 'off'
213 | # Flag: --gpu_brand
214 | #
215 | # Example:
216 | # on: 'AMD HD 7950'
217 | # off: 'HD 7950'
218 | gpu_brand="on"
219 |
220 | # Which GPU to display
221 | #
222 | # Default: 'all'
223 | # Values: 'all', 'dedicated', 'integrated'
224 | # Flag: --gpu_type
225 | # Supports: Linux
226 | #
227 | # Example:
228 | # all:
229 | # GPU1: AMD HD 7950
230 | # GPU2: Intel Integrated Graphics
231 | #
232 | # dedicated:
233 | # GPU1: AMD HD 7950
234 | #
235 | # integrated:
236 | # GPU1: Intel Integrated Graphics
237 | gpu_type="all"
238 |
239 |
240 | # Resolution
241 |
242 |
243 | # Display refresh rate next to each monitor
244 | # Default: 'off'
245 | # Values: 'on', 'off'
246 | # Flag: --refresh_rate
247 | # Supports: Doesn't work on Windows.
248 | #
249 | # Example:
250 | # on: '1920x1080 @ 60Hz'
251 | # off: '1920x1080'
252 | refresh_rate="on"
253 |
254 |
255 | # Gtk Theme / Icons / Font
256 |
257 |
258 | # Shorten output of GTK Theme / Icons / Font
259 | #
260 | # Default: 'off'
261 | # Values: 'on', 'off'
262 | # Flag: --gtk_shorthand
263 | #
264 | # Example:
265 | # on: 'Numix, Adwaita'
266 | # off: 'Numix [GTK2], Adwaita [GTK3]'
267 | gtk_shorthand="off"
268 |
269 |
270 | # Enable/Disable gtk2 Theme / Icons / Font
271 | #
272 | # Default: 'on'
273 | # Values: 'on', 'off'
274 | # Flag: --gtk2
275 | #
276 | # Example:
277 | # on: 'Numix [GTK2], Adwaita [GTK3]'
278 | # off: 'Adwaita [GTK3]'
279 | gtk2="on"
280 |
281 | # Enable/Disable gtk3 Theme / Icons / Font
282 | #
283 | # Default: 'on'
284 | # Values: 'on', 'off'
285 | # Flag: --gtk3
286 | #
287 | # Example:
288 | # on: 'Numix [GTK2], Adwaita [GTK3]'
289 | # off: 'Numix [GTK2]'
290 | gtk3="on"
291 |
292 |
293 | # IP Address
294 |
295 |
296 | # Website to ping for the public IP
297 | #
298 | # Default: 'http://ident.me'
299 | # Values: 'url'
300 | # Flag: --ip_host
301 | public_ip_host="ipinfo.io/ip"
302 |
303 |
304 | # Disk
305 |
306 |
307 | # Which disks to display.
308 | # The values can be any /dev/sdXX, mount point or directory.
309 | # NOTE: By default we only show the disk info for '/'.
310 | #
311 | # Default: '/'
312 | # Values: '/', '/dev/sdXX', '/path/to/drive'.
313 | # Flag: --disk_show
314 | #
315 | # Example:
316 | # disk_show=('/' '/dev/sdb1'):
317 | # 'Disk (/): 74G / 118G (66%)'
318 | # 'Disk (/mnt/Videos): 823G / 893G (93%)'
319 | #
320 | # disk_show=('/'):
321 | # 'Disk (/): 74G / 118G (66%)'
322 | #
323 | disk_show=('/')
324 |
325 | # Disk subtitle.
326 | # What to append to the Disk subtitle.
327 | #
328 | # Default: 'mount'
329 | # Values: 'mount', 'name', 'dir'
330 | # Flag: --disk_subtitle
331 | #
332 | # Example:
333 | # name: 'Disk (/dev/sda1): 74G / 118G (66%)'
334 | # 'Disk (/dev/sdb2): 74G / 118G (66%)'
335 | #
336 | # mount: 'Disk (/): 74G / 118G (66%)'
337 | # 'Disk (/mnt/Local Disk): 74G / 118G (66%)'
338 | # 'Disk (/mnt/Videos): 74G / 118G (66%)'
339 | #
340 | # dir: 'Disk (/): 74G / 118G (66%)'
341 | # 'Disk (Local Disk): 74G / 118G (66%)'
342 | # 'Disk (Videos): 74G / 118G (66%)'
343 | disk_subtitle="mount"
344 |
345 |
346 | # Song
347 |
348 |
349 | # Print the Artist and Title on separate lines
350 | #
351 | # Default: 'off'
352 | # Values: 'on', 'off'
353 | # Flag: --song_shorthand
354 | #
355 | # Example:
356 | # on: 'Artist: The Fratellis'
357 | # 'Song: Chelsea Dagger'
358 | #
359 | # off: 'Song: The Fratellis - Chelsea Dagger'
360 | song_shorthand="off"
361 |
362 |
363 | # Install Date
364 |
365 |
366 | # Whether to show the time in the output
367 | #
368 | # Default: 'on'
369 | # Values: 'on', 'off'
370 | # Flag: --install_time
371 | #
372 | # Example:
373 | # on: 'Thu 14 Apr 2016 11:50 PM'
374 | # off: 'Thu 14 Apr 2016'
375 | install_time="on"
376 |
377 | # Set time format in the output
378 | #
379 | # Default: '24h'
380 | # Values: '12h', '24h'
381 | # Flag: --install_time_format
382 | #
383 | # Example:
384 | # 12h: 'Thu 14 Apr 2016 11:50 PM'
385 | # 24h: 'Thu 14 Apr 2016 23:50'
386 | install_time_format="12h"
387 |
388 |
389 | # Text Colors
390 |
391 |
392 | # Text Colors
393 | #
394 | # Default: 'distro'
395 | # Values: 'distro', 'num' 'num' 'num' 'num' 'num' 'num'
396 | # Flag: --colors
397 | #
398 | # Each number represents a different part of the text in
399 | # this order: 'title', '@', 'underline', 'subtitle', 'colon', 'info'
400 | #
401 | # Example:
402 | # colors=(distro) - Text is colored based on Distro colors.
403 | # colors=(4 6 1 8 8 6) - Text is colored in the order above.
404 | colors=(distro)
405 |
406 |
407 | # Text Options
408 |
409 |
410 | # Toggle bold text
411 | #
412 | # Default: 'on'
413 | # Values: 'on', 'off'
414 | # Flag: --bold
415 | bold="off"
416 |
417 | # Enable/Disable Underline
418 | #
419 | # Default: 'on'
420 | # Values: 'on', 'off'
421 | # Flag: --underline
422 | underline_enabled="on"
423 |
424 | # Underline character
425 | #
426 | # Default: '-'
427 | # Values: 'string'
428 | # Flag: --underline_char
429 | underline_char="-"
430 |
431 |
432 | # Color Blocks
433 |
434 |
435 | # Color block range
436 | # The range of colors to print.
437 | #
438 | # Default: '0', '7'
439 | # Values: 'num'
440 | # Flag: --block_range
441 | #
442 | # Example:
443 | #
444 | # Display colors 0-7 in the blocks. (8 colors)
445 | # neofetch --block_range 0 7
446 | #
447 | # Display colors 0-15 in the blocks. (16 colors)
448 | # neofetch --block_range 0 15
449 | block_range=(1 6)
450 |
451 | # Toggle color blocks
452 | #
453 | # Default: 'on'
454 | # Values: 'on', 'off'
455 | # Flag: --color_blocks
456 | color_blocks="off"
457 |
458 | # Color block width in spaces
459 | #
460 | # Default: '3'
461 | # Values: 'num'
462 | # Flag: --block_width
463 | block_width=4
464 |
465 | # Color block height in lines
466 | #
467 | # Default: '1'
468 | # Values: 'num'
469 | # Flag: --block_height
470 | block_height=1
471 |
472 |
473 | # Progress Bars
474 |
475 |
476 | # Bar characters
477 | #
478 | # Default: '-', '='
479 | # Values: 'string', 'string'
480 | # Flag: --bar_char
481 | #
482 | # Example:
483 | # neofetch --bar_char 'elapsed' 'total'
484 | # neofetch --bar_char '-' '='
485 | bar_char_elapsed="-"
486 | bar_char_total="="
487 |
488 | # Toggle Bar border
489 | #
490 | # Default: 'on'
491 | # Values: 'on', 'off'
492 | # Flag: --bar_border
493 | bar_border="on"
494 |
495 | # Progress bar length in spaces
496 | # Number of chars long to make the progress bars.
497 | #
498 | # Default: '15'
499 | # Values: 'num'
500 | # Flag: --bar_length
501 | bar_length=15
502 |
503 | # Progress bar colors
504 | # When set to distro, uses your distro's logo colors.
505 | #
506 | # Default: 'distro', 'distro'
507 | # Values: 'distro', 'num'
508 | # Flag: --bar_colors
509 | #
510 | # Example:
511 | # neofetch --bar_colors 3 4
512 | # neofetch --bar_colors distro 5
513 | bar_color_elapsed="distro"
514 | bar_color_total="distro"
515 |
516 |
517 | # Info display
518 | # Display a bar with the info.
519 | #
520 | # Default: 'off'
521 | # Values: 'bar', 'infobar', 'barinfo', 'off'
522 | # Flags: --cpu_display
523 | # --memory_display
524 | # --battery_display
525 | # --disk_display
526 | #
527 | # Example:
528 | # bar: '[---=======]'
529 | # infobar: 'info [---=======]'
530 | # barinfo: '[---=======] info'
531 | # off: 'info'
532 | cpu_display="off"
533 | memory_display="off"
534 | battery_display="off"
535 | disk_display="off"
536 |
537 |
538 | # Backend Settings
539 |
540 |
541 | # Image backend.
542 | #
543 | # Default: 'ascii'
544 | # Values: 'ascii', 'caca', 'catimg', 'jp2a', 'iterm2', 'off', 'tycat', 'w3m'
545 | # Flag: --backend
546 | image_backend="off"
547 |
548 | # Image Source
549 | #
550 | # Which image or ascii file to display.
551 | #
552 | # Default: 'auto'
553 | # Values: 'auto', 'ascii', 'wallpaper', '/path/to/img', '/path/to/ascii', '/path/to/dir/'
554 | # Flag: --source
555 | #
556 | # NOTE: 'auto' will pick the best image source for whatever image backend is used.
557 | # In ascii mode, distro ascii art will be used and in an image mode, your
558 | # wallpaper will be used.
559 | image_source="auto"
560 |
561 |
562 | # Ascii Options
563 |
564 |
565 | # Ascii distro
566 | # Which distro's ascii art to display.
567 | #
568 | # Default: 'auto'
569 | # Values: 'auto', 'distro_name'
570 | # Flag: --ascii_distro
571 | #
572 | # NOTE: Arch and Ubuntu have 'old' logo variants.
573 | # Change this to 'arch_old' or 'ubuntu_old' to use the old logos.
574 | # NOTE: Ubuntu has flavor variants.
575 | # Change this to 'Lubuntu', 'Xubuntu', 'Ubuntu-GNOME' or 'Ubuntu-Budgie' to use the flavors.
576 | # NOTE: Arch, Crux and Gentoo have a smaller logo variant.
577 | # Change this to 'arch_small', 'crux_small' or 'gentoo_small' to use the small logos.
578 | ascii_distro="auto"
579 |
580 | # Ascii Colors
581 | #
582 | # Default: 'distro'
583 | # Values: 'distro', 'num' 'num' 'num' 'num' 'num' 'num'
584 | # Flag: --ascii_colors
585 | #
586 | # Example:
587 | # ascii_colors=(distro) - Ascii is colored based on Distro colors.
588 | # ascii_colors=(4 6 1 8 8 6) - Ascii is colored using these colors.
589 | ascii_colors=(distro)
590 |
591 | # Bold ascii logo
592 | # Whether or not to bold the ascii logo.
593 | #
594 | # Default: 'on'
595 | # Values: 'on', 'off'
596 | # Flag: --ascii_bold
597 | ascii_bold="off"
598 |
599 |
600 | # Image Options
601 |
602 |
603 | # Image loop
604 | # Setting this to on will make neofetch redraw the image constantly until
605 | # Ctrl+C is pressed. This fixes display issues in some terminal emulators.
606 | #
607 | # Default: 'off'
608 | # Values: 'on', 'off'
609 | # Flag: --loop
610 | image_loop="off"
611 |
612 | # Thumbnail directory
613 | #
614 | # Default: '~/.cache/thumbnails/neofetch'
615 | # Values: 'dir'
616 | thumbnail_dir="${XDG_CACHE_HOME:-${HOME}/.cache}/thumbnails/neofetch"
617 |
618 | # Crop mode
619 | #
620 | # Default: 'normal'
621 | # Values: 'normal', 'fit', 'fill'
622 | # Flag: --crop_mode
623 | #
624 | # See this wiki page to learn about the fit and fill options.
625 | # https://github.com/dylanaraps/neofetch/wiki/What-is-Waifu-Crop%3F
626 | crop_mode="normal"
627 |
628 | # Crop offset
629 | # Note: Only affects 'normal' crop mode.
630 | #
631 | # Default: 'center'
632 | # Values: 'northwest', 'north', 'northeast', 'west', 'center'
633 | # 'east', 'southwest', 'south', 'southeast'
634 | # Flag: --crop_offset
635 | crop_offset="center"
636 |
637 | # Image size
638 | # The image is half the terminal width by default.
639 | #
640 | # Default: 'auto'
641 | # Values: 'auto', '00px', '00%', 'none'
642 | # Flags: --image_size
643 | # --size
644 | image_size="auto"
645 |
646 | # Ggap between image and text
647 | #
648 | # Default: '3'
649 | # Values: 'num', '-num'
650 | # Flag: --gap
651 | gap=3
652 |
653 | # Image offsets
654 | # Only works with the w3m backend.
655 | #
656 | # Default: '0'
657 | # Values: 'px'
658 | # Flags: --xoffset
659 | # --yoffset
660 | yoffset=0
661 | xoffset=0
662 |
663 | # Image background color
664 | # Only works with the w3m backend.
665 | #
666 | # Default: ''
667 | # Values: 'color', 'blue'
668 | # Flag: --bg_color
669 | background_color=
670 |
671 |
672 | # Scrot Options
673 |
674 |
675 | # Whether or not to always take a screenshot
676 | # You can manually take a screenshot with "--scrot" or "-s"
677 | #
678 | # Default: 'off'
679 | # Values: 'on', 'off'
680 | # Flags: --scrot
681 | # -s
682 | scrot="off"
683 |
684 | # Screenshot Program
685 | # Neofetch will automatically use whatever screenshot tool
686 | # is installed on your system.
687 | #
688 | # If 'neofetch -v' says that it couldn't find a screenshot
689 | # tool or you're using a custom tool then you can change
690 | # the option below to a custom command.
691 | #
692 | # Default: 'auto'
693 | # Values: 'auto' 'cmd -flags'
694 | # Flag: --scrot_cmd
695 | scrot_cmd="auto"
696 |
697 | # Screenshot Filename
698 | # What to name the screenshots
699 | #
700 | # Default: 'neofetch-$(date +%F-%I-%M-%S-${RANDOM}).png'
701 | # Values: 'string'
702 | # Flag: --scrot_name
703 | scrot_name="neofetch-$(date +%F-%I-%M-%S-${RANDOM}).png"
704 |
705 | # Image upload host
706 | # Where to upload the image.
707 | #
708 | # Default: 'teknik'
709 | # Values: 'imgur', 'teknik'
710 | # Flag: --image_host
711 | #
712 | # NOTE: If you'd like another image host to be added to Neofetch.
713 | # Open an issue on github.
714 | image_host="teknik"
715 |
716 |
717 | # Misc Options
718 |
719 | # Stdout mode
720 | # Turn off all colors and disables image backend (ASCII/Image).
721 | # Useful for piping into another command.
722 | # Default: 'off'
723 | # Values: 'on', 'off'
724 | stdout="off"
725 |
726 | # Config version.
727 | #
728 | # NOTE: Don't change this value, neofetch reads this to determine
729 | # how to handle backwards compatibility.
730 | config_version="3.3.0"
731 |
--------------------------------------------------------------------------------
/bash/neofetch.conf:
--------------------------------------------------------------------------------
1 | # Neofetch config file
2 | # https://github.com/dylanaraps/neofetch
3 |
4 | # See this wiki page for more info:
5 | # https://github.com/dylanaraps/neofetch/wiki/Customizing-Info
6 | print_info() {
7 | info title
8 | info line_break
9 |
10 | info "OS" distro
11 | info "Host" model
12 | # info "Kernel" kernel
13 | info "Uptime" uptime
14 | info "Packages" packages
15 | info "Shell" shell
16 | info "Resolution" resolution
17 | # info "DE" de
18 | info "WM" wm
19 | # info "WM Theme" wm_theme
20 | # info "Theme" theme
21 | # info "Icons" icons
22 | info "Terminal" term
23 | info "Terminal Font" term_font
24 | info "CPU" cpu
25 | # info "GPU" gpu
26 | info "Memory" memory
27 |
28 | # info "GPU Driver" gpu_driver # Linux/macOS only
29 | # info "CPU Usage" cpu_usage
30 | info "Disk" disk
31 | # info "Battery" battery
32 | # info "Font" font
33 | # info "Song" song
34 | info "Local IP" local_ip
35 | info "Public IP" public_ip
36 | # info "Users" users
37 | # info "Install Date" install_date
38 | info "Locale" locale # This only works on glibc systems.
39 | }
40 |
41 |
42 | # Kernel
43 |
44 |
45 | # Shorten the output of the kernel function.
46 | #
47 | # Default: 'on'
48 | # Values: 'on', 'off'
49 | # Flag: --kernel_shorthand
50 | # Supports: Everything except *BSDs (except PacBSD and PC-BSD)
51 | #
52 | # Example:
53 | # on: '4.8.9-1-ARCH'
54 | # off: 'Linux 4.8.9-1-ARCH'
55 | kernel_shorthand="off"
56 |
57 |
58 | # Distro
59 |
60 |
61 | # Shorten the output of the distro function
62 | #
63 | # Default: 'off'
64 | # Values: 'on', 'off', 'tiny'
65 | # Flag: --distro_shorthand
66 | # Supports: Everything except Windows and Haiku
67 | distro_shorthand="tiny"
68 |
69 | # Show/Hide OS Architecture.
70 | # Show 'x86_64', 'x86' and etc in 'Distro:' output.
71 | #
72 | # Default: 'on'
73 | # Values: 'on', 'off'
74 | # Flag: --os_arch
75 | #
76 | # Example:
77 | # on: 'Arch Linux x86_64'
78 | # off: 'Arch Linux'
79 | os_arch="off"
80 |
81 |
82 | # Uptime
83 |
84 |
85 | # Shorten the output of the uptime function
86 | #
87 | # Default: 'on'
88 | # Values: 'on', 'off', 'tiny'
89 | # Flag: --uptime_shorthand
90 | #
91 | # Example:
92 | # on: '2 days, 10 hours, 3 mins'
93 | # off: '2 days, 10 hours, 3 minutes'
94 | # tiny: '2d 10h 3m'
95 | uptime_shorthand="tiny"
96 |
97 |
98 | # Shell
99 |
100 |
101 | # Show the path to $SHELL
102 | #
103 | # Default: 'off'
104 | # Values: 'on', 'off'
105 | # Flag: --shell_path
106 | #
107 | # Example:
108 | # on: '/bin/bash'
109 | # off: 'bash'
110 | shell_path="on"
111 |
112 | # Show $SHELL version
113 | #
114 | # Default: 'on'
115 | # Values: 'on', 'off'
116 | # Flag: --shell_version
117 | #
118 | # Example:
119 | # on: 'bash 4.4.5'
120 | # off: 'bash'
121 | shell_version="on"
122 |
123 |
124 | # CPU
125 |
126 |
127 | # CPU speed type
128 | #
129 | # Default: 'bios_limit'
130 | # Values: 'scaling_cur_freq', 'scaling_min_freq', 'scaling_max_freq', 'bios_limit'.
131 | # Flag: --speed_type
132 | # Supports: Linux with 'cpufreq'
133 | # NOTE: Any file in '/sys/devices/system/cpu/cpu0/cpufreq' can be used as a value.
134 | speed_type="bios_limit"
135 |
136 | # CPU speed shorthand
137 | #
138 | # Default: 'off'
139 | # Values: 'on', 'off'.
140 | # Flag: --speed_shorthand.
141 | # NOTE: This flag is not supported in systems with CPU speed less than 1 GHz
142 | #
143 | # Example:
144 | # on: 'i7-6500U (4) @ 3.1GHz'
145 | # off: 'i7-6500U (4) @ 3.100GHz'
146 | speed_shorthand="on"
147 |
148 | # Enable/Disable CPU brand in output.
149 | #
150 | # Default: 'on'
151 | # Values: 'on', 'off'
152 | # Flag: --cpu_brand
153 | #
154 | # Example:
155 | # on: 'Intel i7-6500U'
156 | # off: 'i7-6500U (4)'
157 | cpu_brand="on"
158 |
159 | # CPU Speed
160 | # Hide/Show CPU speed.
161 | #
162 | # Default: 'on'
163 | # Values: 'on', 'off'
164 | # Flag: --cpu_speed
165 | #
166 | # Example:
167 | # on: 'Intel i7-6500U (4) @ 3.1GHz'
168 | # off: 'Intel i7-6500U (4)'
169 | cpu_speed="on"
170 |
171 | # CPU Cores
172 | # Display CPU cores in output
173 | #
174 | # Default: 'logical'
175 | # Values: 'logical', 'physical', 'off'
176 | # Flag: --cpu_cores
177 | # Support: 'physical' doesn't work on BSD.
178 | #
179 | # Example:
180 | # logical: 'Intel i7-6500U (4) @ 3.1GHz' (All virtual cores)
181 | # physical: 'Intel i7-6500U (2) @ 3.1GHz' (All physical cores)
182 | # off: 'Intel i7-6500U @ 3.1GHz'
183 | cpu_cores="logical"
184 |
185 | # CPU Temperature
186 | # Hide/Show CPU temperature.
187 | # Note the temperature is added to the regular CPU function.
188 | #
189 | # Default: 'off'
190 | # Values: 'C', 'F', 'off'
191 | # Flag: --cpu_temp
192 | # Supports: Linux, BSD
193 | # NOTE: For FreeBSD and NetBSD-based systems, you'll need to enable
194 | # coretemp kernel module. This only supports newer Intel processors.
195 | #
196 | # Example:
197 | # C: 'Intel i7-6500U (4) @ 3.1GHz [27.2°C]'
198 | # F: 'Intel i7-6500U (4) @ 3.1GHz [82.0°F]'
199 | # off: 'Intel i7-6500U (4) @ 3.1GHz'
200 | cpu_temp="F"
201 |
202 |
203 | # GPU
204 |
205 |
206 | # Enable/Disable GPU Brand
207 | #
208 | # Default: 'on'
209 | # Values: 'on', 'off'
210 | # Flag: --gpu_brand
211 | #
212 | # Example:
213 | # on: 'AMD HD 7950'
214 | # off: 'HD 7950'
215 | gpu_brand="on"
216 |
217 | # Which GPU to display
218 | #
219 | # Default: 'all'
220 | # Values: 'all', 'dedicated', 'integrated'
221 | # Flag: --gpu_type
222 | # Supports: Linux
223 | #
224 | # Example:
225 | # all:
226 | # GPU1: AMD HD 7950
227 | # GPU2: Intel Integrated Graphics
228 | #
229 | # dedicated:
230 | # GPU1: AMD HD 7950
231 | #
232 | # integrated:
233 | # GPU1: Intel Integrated Graphics
234 | gpu_type="all"
235 |
236 |
237 | # Resolution
238 |
239 |
240 | # Display refresh rate next to each monitor
241 | # Default: 'off'
242 | # Values: 'on', 'off'
243 | # Flag: --refresh_rate
244 | # Supports: Doesn't work on Windows.
245 | #
246 | # Example:
247 | # on: '1920x1080 @ 60Hz'
248 | # off: '1920x1080'
249 | refresh_rate="on"
250 |
251 |
252 | # Gtk Theme / Icons / Font
253 |
254 |
255 | # Shorten output of GTK Theme / Icons / Font
256 | #
257 | # Default: 'off'
258 | # Values: 'on', 'off'
259 | # Flag: --gtk_shorthand
260 | #
261 | # Example:
262 | # on: 'Numix, Adwaita'
263 | # off: 'Numix [GTK2], Adwaita [GTK3]'
264 | gtk_shorthand="off"
265 |
266 |
267 | # Enable/Disable gtk2 Theme / Icons / Font
268 | #
269 | # Default: 'on'
270 | # Values: 'on', 'off'
271 | # Flag: --gtk2
272 | #
273 | # Example:
274 | # on: 'Numix [GTK2], Adwaita [GTK3]'
275 | # off: 'Adwaita [GTK3]'
276 | gtk2="on"
277 |
278 | # Enable/Disable gtk3 Theme / Icons / Font
279 | #
280 | # Default: 'on'
281 | # Values: 'on', 'off'
282 | # Flag: --gtk3
283 | #
284 | # Example:
285 | # on: 'Numix [GTK2], Adwaita [GTK3]'
286 | # off: 'Numix [GTK2]'
287 | gtk3="on"
288 |
289 |
290 | # IP Address
291 |
292 |
293 | # Website to ping for the public IP
294 | #
295 | # Default: 'http://ident.me'
296 | # Values: 'url'
297 | # Flag: --ip_host
298 | public_ip_host="ipinfo.io/ip"
299 |
300 |
301 | # Disk
302 |
303 |
304 | # Which disks to display.
305 | # The values can be any /dev/sdXX, mount point or directory.
306 | # NOTE: By default we only show the disk info for '/'.
307 | #
308 | # Default: '/'
309 | # Values: '/', '/dev/sdXX', '/path/to/drive'.
310 | # Flag: --disk_show
311 | #
312 | # Example:
313 | # disk_show=('/' '/dev/sdb1'):
314 | # 'Disk (/): 74G / 118G (66%)'
315 | # 'Disk (/mnt/Videos): 823G / 893G (93%)'
316 | #
317 | # disk_show=('/'):
318 | # 'Disk (/): 74G / 118G (66%)'
319 | #
320 | disk_show=('/')
321 |
322 | # Disk subtitle.
323 | # What to append to the Disk subtitle.
324 | #
325 | # Default: 'mount'
326 | # Values: 'mount', 'name', 'dir'
327 | # Flag: --disk_subtitle
328 | #
329 | # Example:
330 | # name: 'Disk (/dev/sda1): 74G / 118G (66%)'
331 | # 'Disk (/dev/sdb2): 74G / 118G (66%)'
332 | #
333 | # mount: 'Disk (/): 74G / 118G (66%)'
334 | # 'Disk (/mnt/Local Disk): 74G / 118G (66%)'
335 | # 'Disk (/mnt/Videos): 74G / 118G (66%)'
336 | #
337 | # dir: 'Disk (/): 74G / 118G (66%)'
338 | # 'Disk (Local Disk): 74G / 118G (66%)'
339 | # 'Disk (Videos): 74G / 118G (66%)'
340 | disk_subtitle="mount"
341 |
342 |
343 | # Song
344 |
345 |
346 | # Print the Artist and Title on separate lines
347 | #
348 | # Default: 'off'
349 | # Values: 'on', 'off'
350 | # Flag: --song_shorthand
351 | #
352 | # Example:
353 | # on: 'Artist: The Fratellis'
354 | # 'Song: Chelsea Dagger'
355 | #
356 | # off: 'Song: The Fratellis - Chelsea Dagger'
357 | song_shorthand="off"
358 |
359 |
360 | # Install Date
361 |
362 |
363 | # Whether to show the time in the output
364 | #
365 | # Default: 'on'
366 | # Values: 'on', 'off'
367 | # Flag: --install_time
368 | #
369 | # Example:
370 | # on: 'Thu 14 Apr 2016 11:50 PM'
371 | # off: 'Thu 14 Apr 2016'
372 | install_time="on"
373 |
374 | # Set time format in the output
375 | #
376 | # Default: '24h'
377 | # Values: '12h', '24h'
378 | # Flag: --install_time_format
379 | #
380 | # Example:
381 | # 12h: 'Thu 14 Apr 2016 11:50 PM'
382 | # 24h: 'Thu 14 Apr 2016 23:50'
383 | install_time_format="12h"
384 |
385 |
386 | # Text Colors
387 |
388 |
389 | # Text Colors
390 | #
391 | # Default: 'distro'
392 | # Values: 'distro', 'num' 'num' 'num' 'num' 'num' 'num'
393 | # Flag: --colors
394 | #
395 | # Each number represents a different part of the text in
396 | # this order: 'title', '@', 'underline', 'subtitle', 'colon', 'info'
397 | #
398 | # Example:
399 | # colors=(distro) - Text is colored based on Distro colors.
400 | # colors=(4 6 1 8 8 6) - Text is colored in the order above.
401 | colors=(4 3 0 5 5 6)
402 |
403 |
404 | # Text Options
405 |
406 |
407 | # Toggle bold text
408 | #
409 | # Default: 'on'
410 | # Values: 'on', 'off'
411 | # Flag: --bold
412 | bold="off"
413 |
414 | # Enable/Disable Underline
415 | #
416 | # Default: 'on'
417 | # Values: 'on', 'off'
418 | # Flag: --underline
419 | underline_enabled="off"
420 |
421 | # Underline character
422 | #
423 | # Default: '-'
424 | # Values: 'string'
425 | # Flag: --underline_char
426 | underline_char="-"
427 |
428 |
429 | # Color Blocks
430 |
431 |
432 | # Color block range
433 | # The range of colors to print.
434 | #
435 | # Default: '0', '7'
436 | # Values: 'num'
437 | # Flag: --block_range
438 | #
439 | # Example:
440 | #
441 | # Display colors 0-7 in the blocks. (8 colors)
442 | # neofetch --block_range 0 7
443 | #
444 | # Display colors 0-15 in the blocks. (16 colors)
445 | # neofetch --block_range 0 15
446 | block_range=(1 6)
447 |
448 | # Toggle color blocks
449 | #
450 | # Default: 'on'
451 | # Values: 'on', 'off'
452 | # Flag: --color_blocks
453 | color_blocks="on"
454 |
455 | # Color block width in spaces
456 | #
457 | # Default: '3'
458 | # Values: 'num'
459 | # Flag: --block_width
460 | block_width=4
461 |
462 | # Color block height in lines
463 | #
464 | # Default: '1'
465 | # Values: 'num'
466 | # Flag: --block_height
467 | block_height=1
468 |
469 |
470 | # Progress Bars
471 |
472 |
473 | # Bar characters
474 | #
475 | # Default: '-', '='
476 | # Values: 'string', 'string'
477 | # Flag: --bar_char
478 | #
479 | # Example:
480 | # neofetch --bar_char 'elapsed' 'total'
481 | # neofetch --bar_char '-' '='
482 | bar_char_elapsed="-"
483 | bar_char_total="="
484 |
485 | # Toggle Bar border
486 | #
487 | # Default: 'on'
488 | # Values: 'on', 'off'
489 | # Flag: --bar_border
490 | bar_border="on"
491 |
492 | # Progress bar length in spaces
493 | # Number of chars long to make the progress bars.
494 | #
495 | # Default: '15'
496 | # Values: 'num'
497 | # Flag: --bar_length
498 | bar_length=15
499 |
500 | # Progress bar colors
501 | # When set to distro, uses your distro's logo colors.
502 | #
503 | # Default: 'distro', 'distro'
504 | # Values: 'distro', 'num'
505 | # Flag: --bar_colors
506 | #
507 | # Example:
508 | # neofetch --bar_colors 3 4
509 | # neofetch --bar_colors distro 5
510 | bar_color_elapsed="distro"
511 | bar_color_total="distro"
512 |
513 |
514 | # Info display
515 | # Display a bar with the info.
516 | #
517 | # Default: 'off'
518 | # Values: 'bar', 'infobar', 'barinfo', 'off'
519 | # Flags: --cpu_display
520 | # --memory_display
521 | # --battery_display
522 | # --disk_display
523 | #
524 | # Example:
525 | # bar: '[---=======]'
526 | # infobar: 'info [---=======]'
527 | # barinfo: '[---=======] info'
528 | # off: 'info'
529 | cpu_display="off"
530 | memory_display="off"
531 | battery_display="off"
532 | disk_display="off"
533 |
534 |
535 | # Backend Settings
536 |
537 |
538 | # Image backend.
539 | #
540 | # Default: 'ascii'
541 | # Values: 'ascii', 'caca', 'catimg', 'jp2a', 'iterm2', 'off', 'tycat', 'w3m'
542 | # Flag: --backend
543 | image_backend="ascii"
544 |
545 | # Image Source
546 | #
547 | # Which image or ascii file to display.
548 | #
549 | # Default: 'auto'
550 | # Values: 'auto', 'ascii', 'wallpaper', '/path/to/img', '/path/to/ascii', '/path/to/dir/'
551 | # Flag: --source
552 | #
553 | # NOTE: 'auto' will pick the best image source for whatever image backend is used.
554 | # In ascii mode, distro ascii art will be used and in an image mode, your
555 | # wallpaper will be used.
556 | image_source="auto"
557 |
558 |
559 | # Ascii Options
560 |
561 |
562 | # Ascii distro
563 | # Which distro's ascii art to display.
564 | #
565 | # Default: 'auto'
566 | # Values: 'auto', 'distro_name'
567 | # Flag: --ascii_distro
568 | #
569 | # NOTE: Arch and Ubuntu have 'old' logo variants.
570 | # Change this to 'arch_old' or 'ubuntu_old' to use the old logos.
571 | # NOTE: Ubuntu has flavor variants.
572 | # Change this to 'Lubuntu', 'Xubuntu', 'Ubuntu-GNOME' or 'Ubuntu-Budgie' to use the flavors.
573 | # NOTE: Arch, Crux and Gentoo have a smaller logo variant.
574 | # Change this to 'arch_small', 'crux_small' or 'gentoo_small' to use the small logos.
575 | ascii_distro="auto"
576 |
577 | # Ascii Colors
578 | #
579 | # Default: 'distro'
580 | # Values: 'distro', 'num' 'num' 'num' 'num' 'num' 'num'
581 | # Flag: --ascii_colors
582 | #
583 | # Example:
584 | # ascii_colors=(distro) - Ascii is colored based on Distro colors.
585 | # ascii_colors=(4 6 1 8 8 6) - Ascii is colored using these colors.
586 | ascii_colors=(distro)
587 |
588 | # Bold ascii logo
589 | # Whether or not to bold the ascii logo.
590 | #
591 | # Default: 'on'
592 | # Values: 'on', 'off'
593 | # Flag: --ascii_bold
594 | ascii_bold="off"
595 |
596 |
597 | # Image Options
598 |
599 |
600 | # Image loop
601 | # Setting this to on will make neofetch redraw the image constantly until
602 | # Ctrl+C is pressed. This fixes display issues in some terminal emulators.
603 | #
604 | # Default: 'off'
605 | # Values: 'on', 'off'
606 | # Flag: --loop
607 | image_loop="off"
608 |
609 | # Thumbnail directory
610 | #
611 | # Default: '~/.cache/thumbnails/neofetch'
612 | # Values: 'dir'
613 | thumbnail_dir="${XDG_CACHE_HOME:-${HOME}/.cache}/thumbnails/neofetch"
614 |
615 | # Crop mode
616 | #
617 | # Default: 'normal'
618 | # Values: 'normal', 'fit', 'fill'
619 | # Flag: --crop_mode
620 | #
621 | # See this wiki page to learn about the fit and fill options.
622 | # https://github.com/dylanaraps/neofetch/wiki/What-is-Waifu-Crop%3F
623 | crop_mode="normal"
624 |
625 | # Crop offset
626 | # Note: Only affects 'normal' crop mode.
627 | #
628 | # Default: 'center'
629 | # Values: 'northwest', 'north', 'northeast', 'west', 'center'
630 | # 'east', 'southwest', 'south', 'southeast'
631 | # Flag: --crop_offset
632 | crop_offset="center"
633 |
634 | # Image size
635 | # The image is half the terminal width by default.
636 | #
637 | # Default: 'auto'
638 | # Values: 'auto', '00px', '00%', 'none'
639 | # Flags: --image_size
640 | # --size
641 | image_size="auto"
642 |
643 | # Ggap between image and text
644 | #
645 | # Default: '3'
646 | # Values: 'num', '-num'
647 | # Flag: --gap
648 | gap=3
649 |
650 | # Image offsets
651 | # Only works with the w3m backend.
652 | #
653 | # Default: '0'
654 | # Values: 'px'
655 | # Flags: --xoffset
656 | # --yoffset
657 | yoffset=0
658 | xoffset=0
659 |
660 | # Image background color
661 | # Only works with the w3m backend.
662 | #
663 | # Default: ''
664 | # Values: 'color', 'blue'
665 | # Flag: --bg_color
666 | background_color=
667 |
668 |
669 | # Scrot Options
670 |
671 |
672 | # Whether or not to always take a screenshot
673 | # You can manually take a screenshot with "--scrot" or "-s"
674 | #
675 | # Default: 'off'
676 | # Values: 'on', 'off'
677 | # Flags: --scrot
678 | # -s
679 | scrot="off"
680 |
681 | # Screenshot Program
682 | # Neofetch will automatically use whatever screenshot tool
683 | # is installed on your system.
684 | #
685 | # If 'neofetch -v' says that it couldn't find a screenshot
686 | # tool or you're using a custom tool then you can change
687 | # the option below to a custom command.
688 | #
689 | # Default: 'auto'
690 | # Values: 'auto' 'cmd -flags'
691 | # Flag: --scrot_cmd
692 | scrot_cmd="auto"
693 |
694 | # Screenshot Filename
695 | # What to name the screenshots
696 | #
697 | # Default: 'neofetch-$(date +%F-%I-%M-%S-${RANDOM}).png'
698 | # Values: 'string'
699 | # Flag: --scrot_name
700 | scrot_name="neofetch-$(date +%F-%I-%M-%S-${RANDOM}).png"
701 |
702 | # Image upload host
703 | # Where to upload the image.
704 | #
705 | # Default: 'teknik'
706 | # Values: 'imgur', 'teknik'
707 | # Flag: --image_host
708 | #
709 | # NOTE: If you'd like another image host to be added to Neofetch.
710 | # Open an issue on github.
711 | image_host="teknik"
712 |
713 |
714 | # Misc Options
715 |
716 | # Stdout mode
717 | # Turn off all colors and disables image backend (ASCII/Image).
718 | # Useful for piping into another command.
719 | # Default: 'off'
720 | # Values: 'on', 'off'
721 | stdout="off"
722 |
723 | # Config version.
724 | #
725 | # NOTE: Don't change this value, neofetch reads this to determine
726 | # how to handle backwards compatibility.
727 | config_version="3.3.0"
728 |
--------------------------------------------------------------------------------
/git/.gitconfig:
--------------------------------------------------------------------------------
1 | [user]
2 | name = Darryl Abbate
3 | email = darrylabbate@gmail.com
4 | signingkey = A03538CDABBA7E00
5 | [color]
6 | ui = true
7 | [commit]
8 | gpgsign = true
9 | [core]
10 | excludesfile = ~/.gitignore_global
11 | ignorecase = true
12 | pager = diff-so-fancy | less --tabs=2 -RFX
13 | [credential]
14 | helper = osxkeychain
15 | [pull]
16 | rebase = true
17 | [init]
18 | defaultBranch = master
19 | [tag]
20 | gpgSign = true
21 | [filter "lfs"]
22 | clean = git-lfs clean -- %f
23 | smudge = git-lfs smudge -- %f
24 | process = git-lfs filter-process
25 | required = true
26 | [push]
27 | autoSetupRemote = true
28 |
--------------------------------------------------------------------------------
/git/.gitignore_global:
--------------------------------------------------------------------------------
1 | *~
2 | .DS_Store
3 | .DocumentRevisions-V100
4 | .fseventsd
5 | .Spotlight-V100
6 | .TemporaryItems
7 | .Trashes
8 | .VolumeIcon.icns
9 | .com.apple.timemachine.donotpresent
10 | cscope.*
11 | secring.*
12 |
--------------------------------------------------------------------------------
/gpg/.gnupg/gpg-agent.conf:
--------------------------------------------------------------------------------
1 | default-cache-ttl 2592000
2 | max-cache-ttl 2592000
3 |
--------------------------------------------------------------------------------
/gpg/.gnupg/gpg.conf:
--------------------------------------------------------------------------------
1 | no-greeting
2 | use-agent
3 | default-key A03538CDABBA7E00
4 | keyid-format long
5 | with-fingerprint
6 |
--------------------------------------------------------------------------------
/linux/.Brewfile:
--------------------------------------------------------------------------------
1 | brew "curl"
2 | brew "git"
3 | brew "hub"
4 | brew "make"
5 | brew "neofetch"
6 | brew "nginx"
7 | brew "pandoc"
8 | brew "sass/sass/sass"
9 | brew "stow"
10 | brew "tree"
11 |
--------------------------------------------------------------------------------
/macos/.Brewfile:
--------------------------------------------------------------------------------
1 | tap "cjbassi/gotop"
2 | tap "homebrew/bundle"
3 | tap "homebrew/cask"
4 | tap "homebrew/cask-fonts"
5 | tap "homebrew/cask-versions"
6 | tap "homebrew/core"
7 | tap "homebrew/services"
8 | tap "koekeishiya/formulae"
9 | tap "sass/sass"
10 | brew "autoconf"
11 | brew "automake"
12 | brew "bash"
13 | brew "bats-core"
14 | brew "cask"
15 | brew "cmake"
16 | brew "coreutils"
17 | brew "cscope"
18 | brew "ctags"
19 | brew "curl"
20 | brew "dash"
21 | brew "diff-so-fancy"
22 | brew "doctl"
23 | brew "duti"
24 | brew "emscripten", args: ["HEAD"]
25 | brew "exercism"
26 | brew "ffmpeg"
27 | brew "fswatch"
28 | brew "gawk"
29 | brew "gettext"
30 | brew "gibo"
31 | brew "git"
32 | brew "gh"
33 | brew "gnupg"
34 | brew "gotop"
35 | brew "hyperfine"
36 | brew "jq"
37 | brew "lighttpd"
38 | brew "llvm"
39 | brew "lua"
40 | brew "luajit"
41 | brew "mas"
42 | brew "mawk"
43 | brew "nasm"
44 | brew "neofetch"
45 | brew "nmap"
46 | brew "pandoc"
47 | brew "pcre2"
48 | brew "perl"
49 | brew "python@3"
50 | brew "rename"
51 | brew "sass"
52 | brew "shc"
53 | brew "shellcheck"
54 | brew "skhd"
55 | brew "speedtest-cli"
56 | brew "stow"
57 | brew "svn"
58 | brew "tldr"
59 | brew "tree"
60 | brew "unar"
61 | brew "utm"
62 | brew "wabt"
63 | brew "watch"
64 | brew "wget"
65 | brew "yabai"
66 | brew "youtube-dl"
67 | cask "basictex"
68 | cask "discord"
69 | cask "font-hasklig"
70 | cask "font-open-sans"
71 | cask "font-open-sans-condensed"
72 | cask "font-source-code-pro"
73 | cask "font-source-sans-pro"
74 | cask "font-source-serif-pro"
75 | cask "google-chrome"
76 | cask "iina"
77 | cask "iterm2"
78 | cask "marked"
79 | cask "qlcolorcode"
80 | cask "qlstephen"
81 | cask "slack"
82 | cask "spotify"
83 | cask "transmission"
84 | mas "Cascadea", id: 1432182561
85 | mas "Microsoft Excel", id: 462058435
86 | mas "Microsoft PowerPoint", id: 462062816
87 | mas "Microsoft Word", id: 462054704
88 | mas "Spillo", id: 873245660
89 | mas "Wipr", id: 1320666476
90 |
--------------------------------------------------------------------------------
/macos/.lldbinit:
--------------------------------------------------------------------------------
1 | command script import ~/resources/lldbinit/lldbinit.py
2 |
--------------------------------------------------------------------------------
/macos/.skhdrc:
--------------------------------------------------------------------------------
1 | # ---------------------------------------
2 | # skhdrc
3 | # ---------------------------------------
4 |
5 | # --grid guide
6 | #
7 | # X:Y:A:B:C:D
8 | #
9 | # X:Y defines the rows:columns of the virtual grid
10 | #
11 | # A:B defines the placement of the window on the grid
12 | # 1:0 places window in topmost row and 2nd leftmost column
13 | #
14 | # C:D defines the size of the window
15 | # 2:1 would resize the window to 2 times width and 1 times height
16 | # of the grid defined in X:Y
17 |
18 |
19 | # Change tiling mode of space
20 | alt + cmd - b : yabai -m space --layout bsp
21 | alt + cmd - n : yabai -m space --layout float
22 |
23 |
24 | ### BSP mode shortcuts ###
25 |
26 | # Detach focused window from bsp
27 | alt - d : yabai -m window --toggle float
28 |
29 | # Increase/decrease window size
30 | alt + cmd - h : yabai -m window --resize left:-20:0; \
31 | yabai -m window --resize right:-20:0
32 | alt + cmd - j : yabai -m window --resize top:0:20; \
33 | yabai -m window --resize bottom:0:20
34 | alt + cmd - k : yabai -m window --resize top:0:-20; \
35 | yabai -m window --resize bottom:0:-20
36 | alt + cmd - l : yabai -m window --resize right:20:0; \
37 | yabai -m window --resize left:20:0
38 |
39 | alt + cmd - p : yabai -m space --gap rel:5; \
40 | yabai -m space --padding rel:5:5:5:5
41 | alt + cmd - o : yabai -m space --gap rel:-5; \
42 | yabai -m space --padding rel:-5:-5:-5:-5
43 |
44 | # Warp focused container
45 | alt - h : yabai -m window --warp west
46 | alt - j : yabai -m window --warp south
47 | alt - k : yabai -m window --warp north
48 | alt - l : yabai -m window --warp east
49 |
50 | # Rotate window arrangement 90 degrees
51 | alt + cmd - r : yabai -m space --rotate 90
52 |
53 | # Rotate window arrangement 180 degrees (flip)
54 | alt + cmd - f : yabai -m space --rotate 180
55 |
56 | # Equalize size of windows
57 | alt + cmd - e : yabai -m space --balance
58 |
59 | # Toggle split
60 | alt + cmd - x : yabai -m window --toggle split
61 |
62 |
63 | ### Float mode shortcuts ###
64 |
65 | # Make focused window fill screen
66 | alt + cmd - m : yabai -m window --grid 1:1:0:0:1:1
67 |
68 | # Move focused window to center (mainly to set iTerm hotkey window)
69 | alt + cmd - g : yabai -m window --grid 7:9:2:2:5:3
70 |
71 | # Move focused window to middle (ideal readability)
72 | alt + cmd - t : yabai -m window --grid 5:5:1:0:3:5
73 |
--------------------------------------------------------------------------------
/macos/.stow-local-ignore:
--------------------------------------------------------------------------------
1 | # This file tells GNU Stow to ignore these files and folders
2 | # This allows us to bundle all macOS-specific configuration
3 | # files in one subdirectory, as opposed to having a separate folder
4 | # in the root dotfiles directory for the sake of Stow
5 |
6 | /duti
7 | /iterm
8 | .DS_Store
9 | defaults.sh
10 | kitty.conf
11 | README.md
12 |
--------------------------------------------------------------------------------
/macos/.yabairc:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | # Set default mode to float
4 | yabai -m config layout float
5 |
6 | # Set default padding/gaps between windows
7 | for param in \
8 | {top,bottom,left,right}_padding \
9 | window_gap ; do
10 | yabai -m config $param 5
11 | done
12 |
13 | yabai -m config split_ratio 0.5
14 | yabai -m config focus_follows_mouse off
15 | yabai -m config mouse_follows_focus off
16 | yabai -m config mouse_modifier fn
17 | yabai -m config normal_window_border_color 0xffd75f5f
18 | yabai -m config normal_window_border_width 5
19 | yabai -m config active_window_border_color 0xff8AFAFB
20 | yabai -m config active_window_border_width 5
21 |
22 | # Explicitly define which apps can be managed
23 | managed=(
24 | 'iTerm'
25 | 'Firefox'
26 | 'Safari'
27 | 'Google Chrome'
28 | )
29 | printf -v regex "%s|" "${managed[@]}"
30 | regex="(${regex%|})"
31 |
32 | yabai -m rule --add app!=$regex manage=off
33 |
34 | # Always float iTerm hotkey window
35 | yabai -m rule --add app='^iTerm$' title='^Hotkey Window$' manage=off
36 |
--------------------------------------------------------------------------------
/macos/README.md:
--------------------------------------------------------------------------------
1 | This README contains info for configurations which need to be done manually
2 |
3 | ## Change computer name
4 |
5 | Changing the computer's name via `scutil` allows you to remove the `.local` extension that macOS appends by default. This annoyingly shows up in things like SSH keys.
6 |
7 | ```
8 | scutil --set ComputerName
9 | scutil --set HostName
10 | ```
11 |
--------------------------------------------------------------------------------
/macos/defaults.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | # Close System Preferences just in case
4 | osascript -e 'tell application "System Preferences" to quit'
5 |
6 | # Disable startup noise
7 | sudo nvram SystemAudioVolume=%01
8 |
9 | # Enable SSH
10 | sudo launchctl load -w /System/Library/LaunchDaemons/ssh.plist
11 |
12 | # Enable tab in modal dialogs
13 | defaults write NSGlobalDomain AppleKeyboardUIMode -int 3
14 |
15 | # Scrollbars visible when scrolling
16 | defaults write NSGlobalDomain AppleShowScrollBars -string "WhenScrolling"
17 |
18 | # Expand save panel by default
19 | defaults write NSGlobalDomain NSNavPanelExpandedStateForSaveMode -bool true
20 | defaults write NSGlobalDomain NSNavPanelExpandedStateForSaveMode2 -bool true
21 |
22 | # Expand print panel by default
23 | defaults write NSGlobalDomain PMPrintingExpandedStateForPrint -bool true
24 | defaults write NSGlobalDomain PMPrintingExpandedStateForPrint2 -bool true
25 |
26 | # Automatically quit printer app once the print jobs complete
27 | defaults write com.apple.print.PrintingPrefs "Quit When Finished" -bool true
28 |
29 | # Save to disk (not to iCloud) by default
30 | defaults write NSGlobalDomain NSDocumentSaveNewDocumentsToCloud -bool false
31 |
32 | # Disable the “Are you sure you want to open this application?” dialog
33 | defaults write com.apple.LaunchServices LSQuarantine -bool false
34 |
35 | # Reveal IP address, hostname, OS version, etc. when clicking the clock
36 | # in the login window
37 | sudo defaults write /Library/Preferences/com.apple.loginwindow AdminHostInfo HostName
38 |
39 | # Set dark theme
40 | sudo defaults write /Library/Preferences/.GlobalPreferences AppleInterfaceTheme Dark
41 |
42 | # Set minimal autohide/show delay for hidden dock
43 | defaults write com.apple.dock autohide-delay -float 0
44 | defaults write com.apple.dock autohide-time-modifier -float 0.5
45 |
46 | # Enable scroll gestures for Dock icons
47 | defaults write com.apple.dock scroll-to-open -bool true
48 |
49 | # Show only active apps in Dock
50 | defaults write com.apple.dock static-only -bool true
51 |
52 | # Disable smart quotes
53 | defaults write NSGlobalDomain NSAutomaticQuoteSubstitutionEnabled -bool false
54 |
55 | # Disable autocorrect
56 | defaults write NSGlobalDomain NSAutomaticSpellingCorrectionEnabled -bool false
57 |
58 | # Disable auto-capitalization
59 | defaults write NSGlobalDomain NSAutomaticCapitalizationEnabled -bool false
60 |
61 | # Disable smart dashes
62 | defaults write NSGlobalDomain NSAutomaticDashSubstitutionEnabled -bool false
63 |
64 | # Diable automatic period substitution
65 | defaults write NSGlobalDomain NSAutomaticPeriodSubstitutionEnabled -bool false
66 |
67 | # Enable tap-to-click
68 | defaults write com.apple.driver.AppleBluetoothMultitouch.trackpad Clicking -bool true
69 | defaults -currentHost write NSGlobalDomain com.apple.mouse.tapBehavior -int 1
70 | defaults write NSGlobalDomain com.apple.mouse.tapBehavior -int 1
71 |
72 | # Three-finger drag
73 | defaults write com.apple.AppleMultitouchTrackpad TrackpadThreeFingerDrag -bool true
74 | defaults write com.apple.driver.AppleBluetoothMultitouch.trackpad TrackpadThreeFingerDrag -bool true
75 |
76 | # Save screenshots as PNG
77 | defaults write com.apple.screencapture type -string "png"
78 |
79 | # Set plain text as default format in TextEdit
80 | defaults write com.apple.TextEdit RichText -int 0
81 |
82 | # Disable Dock magnification
83 | defaults write com.apple.dock magnification -bool false
84 |
85 | # Minimize windows into their application's icon
86 | defaults write com.apple.dock minimize-to-application -bool true
87 |
88 | # Show indicator lights for open apps in Dock
89 | defaults write com.apple.dock show-process-indicators -bool true
90 |
91 | # Disable Dashboard
92 | defaults write com.apple.dashboard mcx-disabled -bool true
93 |
94 | # Hot corners
95 | # Possible values:
96 | # 0: no-op
97 | # 2: Mission Control
98 | # 3: Show application windows
99 | # 4: Desktop
100 | # 5: Start screen saver
101 | # 6: Disable screen saver
102 | # 7: Dashboard
103 | # 10: Put display to sleep
104 | # 11: Launchpad
105 | # 12: Notification Center
106 | # Bottom left >> Put display to sleep
107 | defaults write com.apple.dock wvous-bl-corner -int 10
108 | defaults write com.apple.dock wvous-bl-modifier -int 0
109 |
110 | ### Finder ###
111 |
112 | # Don't show Finder status bar
113 | defaults write com.apple.finder ShowStatusBar -bool false
114 |
115 | # Don't show Finder path bar
116 | defaults write com.apple.finder ShowPathbar -bool false
117 |
118 | # Disable Quick Look animation
119 | defaults write -g QLPanelAnimationDuration -float 0
120 |
121 | # Disable Get Info animation (cmd + i)
122 | defaults write com.apple.finder DisableAllAnimations -bool true
123 |
124 | # Show ~/Library
125 | chflags nohidden ~/Library
126 |
127 | # Show /Volumes
128 | sudo chflags nohidden /Volumes
129 |
130 | # Use column view in Finder by default
131 | defaults write com.apple.finder FXPreferredViewStyle -string "clmv"
132 |
133 | # New Finder window opens in home directory
134 | defaults write com.apple.finder NewWindowTarget -string "PfLo"
135 | defaults write com.apple.finder NewWindowTargetPath -string "file://${HOME}/"
136 |
137 | # Keep folders on top when sorting by name
138 | defaults write com.apple.finder _FXSortFoldersFirst -bool true
139 |
140 | # Disable warning when emptying trash
141 | defaults write com.apple.finder WarnOnEmptyTrash -bool false
142 |
143 | # Remove Dropbox's green checkmarks in Finder
144 | file=/Applications/Dropbox.app/Contents/Resources/emblem-dropbox-uptodate.icns
145 | [ -e "${file}" ] && mv -f "${file}" "${file}.bak"
146 | unset file
147 |
148 | ### Safari ###
149 |
150 | # Privacy: don’t send search queries to Apple
151 | defaults write com.apple.Safari UniversalSearchEnabled -bool false
152 | defaults write com.apple.Safari SuppressSearchSuggestions -bool true
153 |
154 | # Disable delay when rendering web pages
155 | defaults write com.apple.Safari WebKitInitialTimedLayoutDelay 0.25
156 |
157 | # Prevent Safari from opening files automatically after downloading
158 | defaults write com.apple.Safari AutoOpenSafeDownloads -bool false
159 |
160 | # Hide Safari’s bookmarks bar by default
161 | defaults write com.apple.Safari ShowFavoritesBar -bool false
162 |
163 | # Enable the Develop menu and the Web Inspector in Safari
164 | defaults write com.apple.Safari IncludeInternalDebugMenu -bool true && \
165 | defaults write com.apple.Safari IncludeDevelopMenu -bool true && \
166 | defaults write com.apple.Safari WebKitDeveloperExtrasEnabledPreferenceKey -bool true && \
167 | defaults write com.apple.Safari com.apple.Safari.ContentPageGroupIdentifier.WebKit2DeveloperExtrasEnabled -bool true && \
168 | defaults write -g WebKitDeveloperExtras -bool true
169 |
170 | # Add a context menu item for showing the Web Inspector in web views
171 | defaults write NSGlobalDomain WebKitDeveloperExtras -bool true
172 |
173 | # Disable autocorrect in Safari
174 | defaults write com.apple.Safari WebAutomaticSpellingCorrectionEnabled -bool false
175 |
176 | # Block pop-up windows
177 | defaults write com.apple.Safari WebKitJavaScriptCanOpenWindowsAutomatically -bool false
178 | defaults write com.apple.Safari com.apple.Safari.ContentPageGroupIdentifier.WebKit2JavaScriptCanOpenWindowsAutomatically -bool false
179 |
180 | # Enable “Do Not Track”
181 | defaults write com.apple.Safari SendDoNotTrackHTTPHeader -bool true
182 |
183 | # Disable auto-playing video
184 | #defaults write com.apple.Safari WebKitMediaPlaybackAllowsInline -bool false
185 | #defaults write com.apple.SafariTechnologyPreview WebKitMediaPlaybackAllowsInline -bool false
186 | #defaults write com.apple.Safari com.apple.Safari.ContentPageGroupIdentifier.WebKit2AllowsInlineMediaPlayback -bool false
187 | #defaults write com.apple.SafariTechnologyPreview com.apple.Safari.ContentPageGroupIdentifier.WebKit2AllowsInlineMediaPlayback -bool false
188 |
189 | ### iTerm ###
190 |
191 | # Don’t display prompt when quitting iTerm
192 | defaults write com.googlecode.iterm2 PromptOnQuit -bool false
193 |
194 | ### Activity Monitor ###
195 |
196 | # Show the main window when launching Activity Monitor
197 | defaults write com.apple.ActivityMonitor OpenMainWindow -bool true
198 |
199 | # Visualize CPU usage in the Activity Monitor Dock icon
200 | defaults write com.apple.ActivityMonitor IconType -int 5
201 |
202 | # Show all processes in Activity Monitor
203 | defaults write com.apple.ActivityMonitor ShowCategory -int 0
204 |
205 | # Sort Activity Monitor results by CPU usage
206 | defaults write com.apple.ActivityMonitor SortColumn -string "CPUUsage"
207 | defaults write com.apple.ActivityMonitor SortDirection -int 0
208 |
209 | ### QLColorCode ###
210 |
211 | defaults write org.n8gray.QLColorCode font Hasklig
212 | defaults write org.n8gray.QLColorCode hlTheme zenburn
213 |
214 | # Force dark/native UI in some "legacy" apps.
215 | # This only changes context menus and Finder windows when opening/saving files
216 | # Syntax: defaults write com.adobe.illustrator NSRequiresAquaSystemAppearance 0
217 | defaults write org.m0k.transmission NSRequiresAquaSystemAppearance 0
218 |
219 | killall Dock
220 | killall Finder
221 |
--------------------------------------------------------------------------------
/macos/duti/iina.txt:
--------------------------------------------------------------------------------
1 | .3gp
2 | .aac
3 | .avi
4 | .flac
5 | .flv
6 | .m4a
7 | .m4v
8 | .mkv
9 | .mov
10 | .mp3
11 | .mp4
12 | .mpeg
13 | .mpg
14 | .wav
15 | .webm
16 | .wma
17 | .wmv
18 |
--------------------------------------------------------------------------------
/macos/duti/openemu.txt:
--------------------------------------------------------------------------------
1 | .agb
2 | .g64
3 | .gb
4 | .gba
5 | .gbc
6 | .gen
7 | .n64
8 | .nds
9 | .nes
10 | .sgb
11 | .smc
12 | .smd
13 | .snes
14 | .srm
15 | .v64
16 | .z64
17 |
--------------------------------------------------------------------------------
/macos/duti/set.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | # Set default handlers/programs for file-types
4 | # Dependency: duti (brew install duti)
5 |
6 | DUTI_DIR=$HOME/dotfiles/macos/duti
7 |
8 | # IINA (media files)
9 | while read -r ext; do
10 | duti -s com.colliderli.iina "$ext" all
11 | done <"${DUTI_DIR}/iina.txt"
12 |
13 | # OpenEmu
14 | while read -r ext; do
15 | duti -s org.openemu.OpenEmu "$ext" all
16 | done <"${DUTI_DIR}/openemu.txt"
17 |
18 | # Sublime Text
19 | while read -r ext; do
20 | duti -s com.apple.TextEdit "$ext" all
21 | done <"${DUTI_DIR}/sourcecode.txt"
22 |
--------------------------------------------------------------------------------
/macos/duti/sourcecode.txt:
--------------------------------------------------------------------------------
1 | .bash
2 | .c
3 | .cabal
4 | .conf
5 | .cpp
6 | .css
7 | .erb
8 | .go
9 | .h
10 | .hs
11 | .js
12 | .json
13 | .map
14 | .md
15 | .nginxconf
16 | .pl
17 | .plist
18 | .py
19 | .rb
20 | .sass
21 | .scss
22 | .sh
23 | .slim
24 | .swift
25 | .toml
26 | .txt
27 | .xml
28 | .yaml
29 | .yml
30 |
--------------------------------------------------------------------------------
/macos/iterm/glacier-black.itermcolors:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Ansi 0 Color
6 |
7 | Alpha Component
8 | 1
9 | Blue Component
10 | 0.061397381126880646
11 | Color Space
12 | sRGB
13 | Green Component
14 | 0.047185309231281281
15 | Red Component
16 | 0.030243547633290291
17 |
18 | Ansi 1 Color
19 |
20 | Alpha Component
21 | 1
22 | Blue Component
23 | 0.23946309089660645
24 | Color Space
25 | sRGB
26 | Green Component
27 | 0.14576846361160278
28 | Red Component
29 | 0.79648000001907349
30 |
31 | Ansi 10 Color
32 |
33 | Alpha Component
34 | 1
35 | Blue Component
36 | 0.66058838367462158
37 | Color Space
38 | sRGB
39 | Green Component
40 | 0.91665995121002197
41 | Red Component
42 | 0.32429736852645874
43 |
44 | Ansi 11 Color
45 |
46 | Alpha Component
47 | 1
48 | Blue Component
49 | 0.50425171852111816
50 | Color Space
51 | sRGB
52 | Green Component
53 | 0.89166313409805298
54 | Red Component
55 | 0.9957006573677063
56 |
57 | Ansi 12 Color
58 |
59 | Alpha Component
60 | 1
61 | Blue Component
62 | 0.80189782381057739
63 | Color Space
64 | sRGB
65 | Green Component
66 | 0.61681145429611206
67 | Red Component
68 | 0.19569060206413269
69 |
70 | Ansi 13 Color
71 |
72 | Alpha Component
73 | 1
74 | Blue Component
75 | 0.19807377457618713
76 | Color Space
77 | sRGB
78 | Green Component
79 | 0.36973872780799866
80 | Red Component
81 | 0.94323086738586426
82 |
83 | Ansi 14 Color
84 |
85 | Alpha Component
86 | 1
87 | Blue Component
88 | 0.86068230867385864
89 | Color Space
90 | sRGB
91 | Green Component
92 | 0.7662385106086731
93 | Red Component
94 | 0.68687814474105835
95 |
96 | Ansi 15 Color
97 |
98 | Alpha Component
99 | 1
100 | Blue Component
101 | 0.99999994039535522
102 | Color Space
103 | sRGB
104 | Green Component
105 | 0.99999994039535522
106 | Red Component
107 | 1
108 |
109 | Ansi 2 Color
110 |
111 | Alpha Component
112 | 1
113 | Blue Component
114 | 0.51414585113525391
115 | Color Space
116 | sRGB
117 | Green Component
118 | 0.7021636962890625
119 | Red Component
120 | 0.24409565329551697
121 |
122 | Ansi 3 Color
123 |
124 | Alpha Component
125 | 1
126 | Blue Component
127 | 0.26498657464981079
128 | Color Space
129 | sRGB
130 | Green Component
131 | 0.64750337600708008
132 | Red Component
133 | 0.99407893419265747
134 |
135 | Ansi 4 Color
136 |
137 | Alpha Component
138 | 1
139 | Blue Component
140 | 0.52231192588806152
141 | Color Space
142 | sRGB
143 | Green Component
144 | 0.42059248685836792
145 | Red Component
146 | 0.14948835968971252
147 |
148 | Ansi 5 Color
149 |
150 | Alpha Component
151 | 1
152 | Blue Component
153 | 0.17939043045043945
154 | Color Space
155 | sRGB
156 | Green Component
157 | 0.2254403829574585
158 | Red Component
159 | 0.79607290029525757
160 |
161 | Ansi 6 Color
162 |
163 | Alpha Component
164 | 1
165 | Blue Component
166 | 0.65744233131408691
167 | Color Space
168 | sRGB
169 | Green Component
170 | 0.58688652515411377
171 | Red Component
172 | 0.53960049152374268
173 |
174 | Ansi 7 Color
175 |
176 | Alpha Component
177 | 1
178 | Blue Component
179 | 0.99999994039535522
180 | Color Space
181 | sRGB
182 | Green Component
183 | 0.99999994039535522
184 | Red Component
185 | 1
186 |
187 | Ansi 8 Color
188 |
189 | Alpha Component
190 | 1
191 | Blue Component
192 | 0.40801632404327393
193 | Color Space
194 | sRGB
195 | Green Component
196 | 0.36295801401138306
197 | Red Component
198 | 0.31799283623695374
199 |
200 | Ansi 9 Color
201 |
202 | Alpha Component
203 | 1
204 | Blue Component
205 | 0.23946309089660645
206 | Color Space
207 | sRGB
208 | Green Component
209 | 0.14576846361160278
210 | Red Component
211 | 0.79648000001907349
212 |
213 | Background Color
214 |
215 | Alpha Component
216 | 1
217 | Blue Component
218 | 0.079999998211860657
219 | Color Space
220 | sRGB
221 | Green Component
222 | 0.079999998211860657
223 | Red Component
224 | 0.079999998211860657
225 |
226 | Badge Color
227 |
228 | Alpha Component
229 | 0.5
230 | Blue Component
231 | 0.0
232 | Color Space
233 | sRGB
234 | Green Component
235 | 0.14910027384757996
236 | Red Component
237 | 1
238 |
239 | Bold Color
240 |
241 | Alpha Component
242 | 1
243 | Blue Component
244 | 0.19866347312927246
245 | Color Space
246 | sRGB
247 | Green Component
248 | 0.37061417102813721
249 | Red Component
250 | 0.94185739755630493
251 |
252 | Cursor Color
253 |
254 | Alpha Component
255 | 1
256 | Blue Component
257 | 0.49887937307357788
258 | Color Space
259 | sRGB
260 | Green Component
261 | 0.49887937307357788
262 | Red Component
263 | 0.49887937307357788
264 |
265 | Cursor Guide Color
266 |
267 | Alpha Component
268 | 0.25
269 | Blue Component
270 | 1
271 | Color Space
272 | sRGB
273 | Green Component
274 | 0.92681378126144409
275 | Red Component
276 | 0.70214027166366577
277 |
278 | Cursor Text Color
279 |
280 | Alpha Component
281 | 1
282 | Blue Component
283 | 0.06012948602437973
284 | Color Space
285 | sRGB
286 | Green Component
287 | 0.047664321959018707
288 | Red Component
289 | 0.027743341401219368
290 |
291 | Foreground Color
292 |
293 | Alpha Component
294 | 1
295 | Blue Component
296 | 0.99999994039535522
297 | Color Space
298 | sRGB
299 | Green Component
300 | 0.99999994039535522
301 | Red Component
302 | 1
303 |
304 | Link Color
305 |
306 | Alpha Component
307 | 1
308 | Blue Component
309 | 0.73422712087631226
310 | Color Space
311 | sRGB
312 | Green Component
313 | 0.35915297269821167
314 | Red Component
315 | 0.0
316 |
317 | Selected Text Color
318 |
319 | Alpha Component
320 | 1
321 | Blue Component
322 | 0.99999994039535522
323 | Color Space
324 | sRGB
325 | Green Component
326 | 0.99999994039535522
327 | Red Component
328 | 1
329 |
330 | Selection Color
331 |
332 | Alpha Component
333 | 1
334 | Blue Component
335 | 0.40842074155807495
336 | Color Space
337 | sRGB
338 | Green Component
339 | 0.36218035221099854
340 | Red Component
341 | 0.31688991189002991
342 |
343 | Tab Color
344 |
345 | Alpha Component
346 | 1
347 | Blue Component
348 | 0.57046490907669067
349 | Color Space
350 | sRGB
351 | Green Component
352 | 0.5704723596572876
353 | Red Component
354 | 0.57045853137969971
355 |
356 |
357 |
358 |
--------------------------------------------------------------------------------
/macos/kitty.conf:
--------------------------------------------------------------------------------
1 | # vim:fileencoding=utf-8:ft=conf:foldmethod=marker
2 |
3 |
4 | # Cursor
5 | # shape = block | beam | outline
6 | # blink_interval = measured in seconds, with 0 disabling
7 |
8 | cursor_shape block
9 | cursor_blink_interval 0
10 | # cursor_stop_blinking_after 15.0
11 |
12 |
13 | # Colors
14 | # color0,8 = black
15 | # color1,9 = red
16 | # color2,10 = green
17 | # color3,11 = yellow
18 | # color4,12 = blue
19 | # color5,13 = magenta
20 | # color6,14 = cyan
21 | # color7,15 = white
22 |
23 | cursor #dddddd
24 | cursor_text_color #111111
25 | foreground #ffffff
26 | background #202020
27 | color0 #101010
28 | color1 #D96C9B
29 | color2 #5DCCB8
30 | color3 #9e9ecb
31 | color4 #5F91BF
32 | color5 #7e62b3
33 | color6 #6096bf
34 | color7 #cccccc
35 | color8 #777777
36 | color9 #bf4d80
37 | color10 #7EE4E6
38 | color11 #B2B4EE
39 | color12 #477ab3
40 | color13 #A288D6
41 | color14 #8EDDFF
42 | color15 #cccccc
43 |
44 |
45 | # Fonts
46 | # -----
47 |
48 | font_size 14.0
49 | font_family Hasklig
50 | bold_font Hasklig Regular
51 | italic_font Hasklig Italic
52 | bold_italic_font Hasklig Italic
53 | disable_ligatures never
54 |
55 | # Use slashed zeros
56 | # Requires font's PostScript name: `kitty + list-fonts --psnames`
57 | font_features Hasklig-Regular +zero
58 |
59 |
60 | # adjust_line_height 0
61 | # adjust_column_width 0
62 |
63 | #: Change the size of each character cell kitty renders. You can use
64 | #: either numbers, which are interpreted as pixels or percentages
65 | #: (number followed by %), which are interpreted as percentages of the
66 | #: unmodified values. You can use negative pixels or percentages less
67 | #: than 100% to reduce sizes (but this might cause rendering
68 | #: artifacts).
69 |
70 | # symbol_map U+E0A0-U+E0A2,U+E0B0-U+E0B3 PowerlineSymbols
71 |
72 | #: Map the specified unicode codepoints to a particular font. Useful
73 | #: if you need special rendering for some symbols, such as for
74 | #: Powerline. Avoids the need for patched fonts. Each unicode code
75 | #: point is specified in the form U+. You
76 | #: can specify multiple code points, separated by commas and ranges
77 | #: separated by hyphens. symbol_map itself can be specified multiple
78 | #: times. Syntax is::
79 |
80 | #: symbol_map codepoints Font Family Name
81 |
82 |
83 | #: Choose how you want to handle multi-character ligatures. The
84 | #: default is to always render them. You can tell kitty to not render
85 | #: them when the cursor is over them by using cursor to make editing
86 | #: easier, or have kitty never render them at all by using always, if
87 | #: you don't like them. The ligature strategy can be set per-window
88 | #: either using the kitty remote control facility or by defining
89 | #: shortcuts for it in kitty.conf, for example::
90 |
91 | #: map alt+1 disable_ligatures_in active always
92 | #: map alt+2 disable_ligatures_in all never
93 | #: map alt+3 disable_ligatures_in tab cursor
94 |
95 | # box_drawing_scale 0.001, 1, 1.5, 2
96 |
97 | #: Change the sizes of the lines used for the box drawing unicode
98 | #: characters These values are in pts. They will be scaled by the
99 | #: monitor DPI to arrive at a pixel value. There must be four values
100 | #: corresponding to thin, normal, thick, and very thick lines.
101 |
102 |
103 | #: Scrollback {{{
104 |
105 | # scrollback_lines 2000
106 |
107 | #: Number of lines of history to keep in memory for scrolling back.
108 | #: Memory is allocated on demand. Negative numbers are (effectively)
109 | #: infinite scrollback. Note that using very large scrollback is not
110 | #: recommended as it can slow down resizing of the terminal and also
111 | #: use large amounts of RAM.
112 |
113 | # scrollback_pager less --chop-long-lines --RAW-CONTROL-CHARS +INPUT_LINE_NUMBER
114 |
115 | #: Program with which to view scrollback in a new window. The
116 | #: scrollback buffer is passed as STDIN to this program. If you change
117 | #: it, make sure the program you use can handle ANSI escape sequences
118 | #: for colors and text formatting. INPUT_LINE_NUMBER in the command
119 | #: line above will be replaced by an integer representing which line
120 | #: should be at the top of the screen.
121 |
122 | # scrollback_pager_history_size 0
123 |
124 | #: Separate scrollback history size, used only for browsing the
125 | #: scrollback buffer (in MB). This separate buffer is not available
126 | #: for interactive scrolling but will be piped to the pager program
127 | #: when viewing scrollback buffer in a separate window. The current
128 | #: implementation stores one character in 4 bytes, so approximatively
129 | #: 2500 lines per megabyte at 100 chars per line. A value of zero or
130 | #: less disables this feature. The maximum allowed size is 4GB.
131 |
132 | # wheel_scroll_multiplier 5.0
133 |
134 | #: Modify the amount scrolled by the mouse wheel. Note this is only
135 | #: used for low precision scrolling devices, not for high precision
136 | #: scrolling on platforms such as macOS and Wayland. Use negative
137 | #: numbers to change scroll direction.
138 |
139 | # touch_scroll_multiplier 1.0
140 |
141 | #: Modify the amount scrolled by a touchpad. Note this is only used
142 | #: for high precision scrolling devices on platforms such as macOS and
143 | #: Wayland. Use negative numbers to change scroll direction.
144 |
145 |
146 | #: Mouse {{{
147 |
148 | # mouse_hide_wait 3.0
149 |
150 | #: Hide mouse cursor after the specified number of seconds of the
151 | #: mouse not being used. Set to zero to disable mouse cursor hiding.
152 | #: Set to a negative value to hide the mouse cursor immediately when
153 | #: typing text.
154 |
155 | # url_color #0087bd
156 | # url_style curly
157 |
158 | #: The color and style for highlighting URLs on mouse-over. url_style
159 | #: can be one of: none, single, double, curly
160 |
161 | # open_url_modifiers kitty_mod
162 |
163 | #: The modifier keys to press when clicking with the mouse on URLs to
164 | #: open the URL
165 |
166 | # open_url_with default
167 |
168 | #: The program with which to open URLs that are clicked on. The
169 | #: special value default means to use the operating system's default
170 | #: URL handler.
171 |
172 | # copy_on_select no
173 |
174 | #: map cmd+shift+v paste_from_buffer a1
175 |
176 | #: Note that copying to the clipboard is a security risk, as all
177 | #: programs, including websites open in your browser can read the
178 | #: contents of the system clipboard.
179 |
180 | # strip_trailing_spaces never
181 |
182 | #: Remove spaces at the end of lines when copying to clipboard. A
183 | #: value of smart will do it when using normal selections, but not
184 | #: rectangle selections. always will always do it.
185 |
186 | # rectangle_select_modifiers ctrl+alt
187 |
188 | #: The modifiers to use rectangular selection (i.e. to select text in
189 | #: a rectangular block with the mouse)
190 |
191 | # select_by_word_characters :@-./_~?&=%+#
192 |
193 | #: Characters considered part of a word when double clicking. In
194 | #: addition to these characters any character that is marked as an
195 | #: alpha-numeric character in the unicode database will be matched.
196 |
197 | # click_interval -1.0
198 |
199 | #: The interval between successive clicks to detect double/triple
200 | #: clicks (in seconds). Negative numbers will use the system default
201 | #: instead, if available, or fallback to 0.5.
202 |
203 | # focus_follows_mouse no
204 |
205 |
206 | #: Performance tuning {{{
207 |
208 | # repaint_delay 10
209 |
210 | #: Delay (in milliseconds) between screen updates. Decreasing it,
211 | #: increases frames-per-second (FPS) at the cost of more CPU usage.
212 | #: The default value yields ~100 FPS which is more than sufficient for
213 | #: most uses. Note that to actually achieve 100 FPS you have to either
214 | #: set sync_to_monitor to no or use a monitor with a high refresh
215 | #: rate.
216 |
217 | # input_delay 3
218 |
219 | #: Delay (in milliseconds) before input from the program running in
220 | #: the terminal is processed. Note that decreasing it will increase
221 | #: responsiveness, but also increase CPU usage and might cause flicker
222 | #: in full screen programs that redraw the entire screen on each loop,
223 | #: because kitty is so fast that partial screen updates will be drawn.
224 |
225 | sync_to_monitor no
226 |
227 | #: Sync screen updates to the refresh rate of the monitor. This
228 | #: prevents tearing (https://en.wikipedia.org/wiki/Screen_tearing)
229 | #: when scrolling. However, it limits the rendering speed to the
230 | #: refresh rate of your monitor. With a very high speed mouse/high
231 | #: keyboard repeat rate, you may notice some slight input latency. If
232 | #: so, set this to no.
233 |
234 |
235 | #: Terminal bell {{{
236 |
237 | enable_audio_bell no
238 |
239 | #: Enable/disable the audio bell. Useful in environments that require
240 | #: silence.
241 |
242 | # visual_bell_duration 0.0
243 |
244 | #: Visual bell duration. Flash the screen when a bell occurs for the
245 | #: specified number of seconds. Set to zero to disable.
246 |
247 | # window_alert_on_bell yes
248 |
249 | #: Request window attention on bell. Makes the dock icon bounce on
250 | #: macOS or the taskbar flash on linux.
251 |
252 | # bell_on_tab yes
253 |
254 | #: Show a bell symbol on the tab if a bell occurs in one of the
255 | #: windows in the tab and the window is not the currently focused
256 | #: window
257 |
258 | # command_on_bell none
259 |
260 | #: Program to run when a bell occurs.
261 |
262 | #: }}}
263 |
264 | #: Window layout {{{
265 |
266 | remember_window_size no
267 | # initial_window_width 640
268 | # initial_window_height 400
269 |
270 | #: If enabled, the window size will be remembered so that new
271 | #: instances of kitty will have the same size as the previous
272 | #: instance. If disabled, the window will initially have size
273 | #: configured by initial_window_width/height, in pixels. You can use a
274 | #: suffix of "c" on the width/height values to have them interpreted
275 | #: as number of cells instead of pixels.
276 |
277 | # enabled_layouts
278 |
279 | #: The enabled window layouts. A comma separated list of layout names.
280 | #: The special value all means all layouts. The first listed layout
281 | #: will be used as the startup layout. For a list of available
282 | #: layouts, see the
283 | #: https://sw.kovidgoyal.net/kitty/index.html#layouts.
284 |
285 | # window_resize_step_cells 2
286 | # window_resize_step_lines 2
287 |
288 | #: The step size (in units of cell width/cell height) to use when
289 | #: resizing windows. The cells value is used for horizontal resizing
290 | #: and the lines value for vertical resizing.
291 |
292 | # window_border_width 1.0
293 |
294 | #: The width (in pts) of window borders. Will be rounded to the
295 | #: nearest number of pixels based on screen resolution. Note that
296 | #: borders are displayed only when more than one window is visible.
297 | #: They are meant to separate multiple windows.
298 |
299 | # draw_minimal_borders yes
300 |
301 | #: Draw only the minimum borders needed. This means that only the
302 | #: minimum needed borders for inactive windows are drawn. That is only
303 | #: the borders that separate the inactive window from a neighbor. Note
304 | #: that setting a non-zero window margin overrides this and causes all
305 | #: borders to be drawn.
306 |
307 | # window_margin_width 0.0
308 |
309 | #: The window margin (in pts) (blank area outside the border)
310 |
311 | # single_window_margin_width -1000.0
312 |
313 | #: The window margin (in pts) to use when only a single window is
314 | #: visible. Negative values will cause the value of
315 | #: window_margin_width to be used instead.
316 |
317 | window_padding_width 4.0
318 |
319 | #: The window padding (in pts) (blank area between the text and the
320 | #: window border)
321 |
322 | # placement_strategy center
323 |
324 | #: When the window size is not an exact multiple of the cell size, the
325 | #: cell area of the terminal window will have some extra padding on
326 | #: the sides. You can control how that padding is distributed with
327 | #: this option. Using a value of center means the cell area will be
328 | #: placed centrally. A value of top-left means the padding will be on
329 | #: only the bottom and right edges.
330 |
331 | # active_border_color #00ff00
332 |
333 | #: The color for the border of the active window. Set this to none to
334 | #: not draw borders around the active window.
335 |
336 | # inactive_border_color #cccccc
337 |
338 | #: The color for the border of inactive windows
339 |
340 | # bell_border_color #ff5a00
341 |
342 | #: The color for the border of inactive windows in which a bell has
343 | #: occurred
344 |
345 | # inactive_text_alpha 1.0
346 |
347 | #: Fade the text in inactive windows by the specified amount (a number
348 | #: between zero and one, with zero being fully faded).
349 |
350 | hide_window_decorations yes
351 |
352 | #: Hide the window decorations (title-bar and window borders). Whether
353 | #: this works and exactly what effect it has depends on the window
354 | #: manager/operating system.
355 |
356 | # resize_debounce_time 0.1
357 |
358 | #: The time (in seconds) to wait before redrawing the screen when a
359 | #: resize event is received. On platforms such as macOS, where the
360 | #: operating system sends events corresponding to the start and end of
361 | #: a resize, this number is ignored.
362 |
363 | # resize_draw_strategy static
364 |
365 | #: Choose how kitty draws a window while a resize is in progress. A
366 | #: value of static means draw the current window contents, mostly
367 | #: unchanged. A value of scale means draw the current window contents
368 | #: scaled. A value of blank means draw a blank window. A value of size
369 | #: means show the window size in cells.
370 |
371 | #: }}}
372 |
373 | #: Tab bar {{{
374 |
375 | # tab_bar_edge bottom
376 |
377 | #: Which edge to show the tab bar on, top or bottom
378 |
379 | # tab_bar_margin_width 0.0
380 |
381 | #: The margin to the left and right of the tab bar (in pts)
382 |
383 | # tab_bar_style fade
384 |
385 | #: The tab bar style, can be one of: fade, separator or hidden. In the
386 | #: fade style, each tab's edges fade into the background color, in the
387 | #: separator style, tabs are separated by a configurable separator.
388 |
389 | # tab_bar_min_tabs 2
390 |
391 | #: The minimum number of tabs that must exist before the tab bar is
392 | #: shown
393 |
394 | # tab_switch_strategy previous
395 |
396 | #: The algorithm to use when switching to a tab when the current tab
397 | #: is closed. The default of previous will switch to the last used
398 | #: tab. A value of left will switch to the tab to the left of the
399 | #: closed tab. A value of last will switch to the right-most tab.
400 |
401 | # tab_fade 0.25 0.5 0.75 1
402 |
403 | #: Control how each tab fades into the background when using fade for
404 | #: the tab_bar_style. Each number is an alpha (between zero and one)
405 | #: that controls how much the corresponding cell fades into the
406 | #: background, with zero being no fade and one being full fade. You
407 | #: can change the number of cells used by adding/removing entries to
408 | #: this list.
409 |
410 | #: The separator between tabs in the tab bar when using separator as
411 | #: the tab_bar_style.
412 |
413 | # tab_title_template {title}
414 |
415 | #: A template to render the tab title. The default just renders the
416 | #: title. If you wish to include the tab-index as well, use something
417 | #: like: {index}: {title}. Useful if you have shortcuts mapped for
418 | #: goto_tab N.
419 |
420 | # active_tab_foreground #000
421 | # active_tab_background #eee
422 | # active_tab_font_style bold-italic
423 | # inactive_tab_foreground #444
424 | # inactive_tab_background #999
425 | # inactive_tab_font_style normal
426 |
427 | #: Tab bar colors and styles
428 |
429 |
430 | # background_opacity 1.0
431 |
432 | #: The opacity of the background. A number between 0 and 1, where 1 is
433 | #: opaque and 0 is fully transparent. This will only work if
434 | #: supported by the OS (for instance, when using a compositor under
435 | #: X11). Note that it only sets the default background color's
436 | #: opacity. This is so that things like the status bar in vim,
437 | #: powerline prompts, etc. still look good. But it means that if you
438 | #: use a color theme with a background color in your editor, it will
439 | #: not be rendered as transparent. Instead you should change the
440 | #: default background color in your kitty config and not use a
441 | #: background color in the editor color scheme. Or use the escape
442 | #: codes to set the terminals default colors in a shell script to
443 | #: launch your editor. Be aware that using a value less than 1.0 is a
444 | #: (possibly significant) performance hit. If you want to dynamically
445 | #: change transparency of windows set dynamic_background_opacity to
446 | #: yes (this is off by default as it has a performance cost)
447 |
448 | # dynamic_background_opacity no
449 |
450 | #: Allow changing of the background_opacity dynamically, using either
451 | #: keyboard shortcuts (increase_background_opacity and
452 | #: decrease_background_opacity) or the remote control facility.
453 |
454 | # dim_opacity 0.75
455 |
456 | #: How much to dim text that has the DIM/FAINT attribute set. One
457 | #: means no dimming and zero means fully dimmed (i.e. invisible).
458 |
459 | # selection_foreground #000000
460 |
461 | #: The foreground for text selected with the mouse. A value of none
462 | #: means to leave the color unchanged.
463 |
464 | # selection_background #fffacd
465 |
466 | #: The background for text selected with the mouse.
467 |
468 |
469 | #: Advanced {{{
470 |
471 | # shell .
472 |
473 | #: The shell program to execute. The default value of . means to use
474 | #: whatever shell is set as the default shell for the current user.
475 | #: Note that on macOS if you change this, you might need to add
476 | #: --login to ensure that the shell starts in interactive mode and
477 | #: reads its startup rc files.
478 |
479 | # editor .
480 |
481 | #: The console editor to use when editing the kitty config file or
482 | #: similar tasks. A value of . means to use the environment variable
483 | #: EDITOR. Note that this environment variable has to be set not just
484 | #: in your shell startup scripts but system-wide, otherwise kitty will
485 | #: not see it.
486 |
487 | # close_on_child_death no
488 |
489 | #: Close the window when the child process (shell) exits. If no (the
490 | #: default), the terminal will remain open when the child exits as
491 | #: long as there are still processes outputting to the terminal (for
492 | #: example disowned or backgrounded processes). If yes, the window
493 | #: will close as soon as the child process exits. Note that setting it
494 | #: to yes means that any background processes still using the terminal
495 | #: can fail silently because their stdout/stderr/stdin no longer work.
496 |
497 | allow_remote_control yes
498 |
499 | #: Allow other programs to control kitty. If you turn this on other
500 | #: programs can control all aspects of kitty, including sending text
501 | #: to kitty windows, opening new windows, closing windows, reading the
502 | #: content of windows, etc. Note that this even works over ssh
503 | #: connections.
504 |
505 | # env
506 |
507 | #: Specify environment variables to set in all child processes. Note
508 | #: that environment variables are expanded recursively, so if you
509 | #: use::
510 |
511 | #: env MYVAR1=a
512 | #: env MYVAR2=${MYVAR1}/${HOME}/b
513 |
514 | #: The value of MYVAR2 will be a//b.
515 |
516 | # update_check_interval 24
517 |
518 | #: Periodically check if an update to kitty is available. If an update
519 | #: is found a system notification is displayed informing you of the
520 | #: available update. The default is to check every 24 hrs, set to zero
521 | #: to disable.
522 |
523 | # startup_session none
524 |
525 | #: Path to a session file to use for all kitty instances. Can be
526 | #: overridden by using the kitty --session command line option for
527 | #: individual instances. See
528 | #: https://sw.kovidgoyal.net/kitty/index.html#sessions in the kitty
529 | #: documentation for details. Note that relative paths are interpreted
530 | #: with respect to the kitty config directory. Environment variables
531 | #: in the path are expanded.
532 |
533 | # clipboard_control write-clipboard write-primary
534 |
535 | #: Allow programs running in kitty to read and write from the
536 | #: clipboard. You can control exactly which actions are allowed. The
537 | #: set of possible actions is: write-clipboard read-clipboard write-
538 | #: primary read-primary. You can additionally specify no-append to
539 | #: disable kitty's protocol extension for clipboard concatenation. The
540 | #: default is to allow writing to the clipboard and primary selection
541 | #: with concatenation enabled. Note that enabling the read
542 | #: functionality is a security risk as it means that any program, even
543 | #: one running on a remote server via SSH can read your clipboard.
544 |
545 | # term xterm-kitty
546 |
547 | #: The value of the TERM environment variable to set. Changing this
548 | #: can break many terminal programs, only change it if you know what
549 | #: you are doing, not because you read some advice on Stack Overflow
550 | #: to change it. The TERM variable is used by various programs to get
551 | #: information about the capabilities and behavior of the terminal. If
552 | #: you change it, depending on what programs you run, and how
553 | #: different the terminal you are changing it to is, various things
554 | #: from key-presses, to colors, to various advanced features may not
555 | #: work.
556 |
557 |
558 | #: OS specific tweaks {{{
559 |
560 | macos_titlebar_color background
561 |
562 | #: Change the color of the kitty window's titlebar on macOS. A value
563 | #: of system means to use the default system color, a value of
564 | #: background means to use the background color of the currently
565 | #: active window and finally you can use an arbitrary color, such as
566 | #: #12af59 or red. WARNING: This option works by using a hack, as
567 | #: there is no proper Cocoa API for it. It sets the background color
568 | #: of the entire window and makes the titlebar transparent. As such it
569 | #: is incompatible with background_opacity. If you want to use both,
570 | #: you are probably better off just hiding the titlebar with
571 | #: hide_window_decorations.
572 |
573 | # macos_option_as_alt no
574 |
575 | #: Use the option key as an alt key. With this set to no, kitty will
576 | #: use the macOS native Option+Key = unicode character behavior. This
577 | #: will break any Alt+key keyboard shortcuts in your terminal
578 | #: programs, but you can use the macOS unicode input technique. You
579 | #: can use the values: left, right, or both to use only the left,
580 | #: right or both Option keys as Alt, instead.
581 |
582 | # macos_hide_from_tasks no
583 |
584 | #: Hide the kitty window from running tasks (Option+Tab) on macOS.
585 |
586 | # macos_quit_when_last_window_closed no
587 |
588 | #: Have kitty quit when all the top-level windows are closed. By
589 | #: default, kitty will stay running, even with no open windows, as is
590 | #: the expected behavior on macOS.
591 |
592 | # macos_window_resizable yes
593 |
594 | #: Disable this if you want kitty top-level (OS) windows to not be
595 | #: resizable on macOS.
596 |
597 | # macos_thicken_font 0
598 |
599 | #: Draw an extra border around the font with the given width, to
600 | #: increase legibility at small font sizes. For example, a value of
601 | #: 0.75 will result in rendering that looks similar to sub-pixel
602 | #: antialiasing at common font sizes.
603 |
604 | # macos_traditional_fullscreen no
605 |
606 | #: Use the traditional full-screen transition, that is faster, but
607 | #: less pretty.
608 |
609 | macos_show_window_title_in_menubar no
610 |
611 | #: Show the title of the currently active window in the macOS menu-
612 | #: bar, making use of otherwise wasted space.
613 |
614 | # macos_custom_beam_cursor no
615 |
616 | #: Enable/disable custom mouse cursor for macOS that is easier to see
617 | #: on both light and dark backgrounds. WARNING: this might make your
618 | #: mouse cursor invisible on dual GPU machines.
619 |
620 | #: }}}
621 |
622 | #: Keyboard shortcuts {{{
623 |
624 | #: For a list of key names, see: GLFW keys
625 | #: . The name to
626 | #: use is the part after the GLFW_KEY_ prefix. For a list of modifier
627 | #: names, see: GLFW mods
628 | #:
629 |
630 | #: Finally, you can use raw system key codes to map keys. To see the
631 | #: system key code for a key, start kitty with the kitty --debug-
632 | #: keyboard option. Then kitty will output some debug text for every
633 | #: key event. In that text look for ``native_code`` the value of that
634 | #: becomes the key name in the shortcut. For example:
635 |
636 | #: .. code-block:: none
637 |
638 | #: on_key_input: glfw key: 65 native_code: 0x61 action: PRESS mods: 0x0 text: 'a'
639 |
640 | #: Here, the key name for the A key is 0x61 and you can use it with::
641 |
642 | #: map ctrl+0x61 something
643 |
644 | #: to map ctrl+a to something.
645 |
646 | #: You can use the special action no_op to unmap a keyboard shortcut
647 | #: that is assigned in the default configuration.
648 |
649 | #: You can combine multiple actions to be triggered by a single
650 | #: shortcut, using the syntax below::
651 |
652 | #: map key combine action1 action2 action3 ...
653 |
654 | #: For example::
655 |
656 | #: map kitty_mod+e combine : new_window : next_layout
657 |
658 | #: this will create a new window and switch to the next available
659 | #: layout
660 |
661 | #: You can use multi-key shortcuts using the syntax shown below::
662 |
663 | #: map key1>key2>key3 action
664 |
665 | #: For example::
666 |
667 | #: map ctrl+f>2 set_font_size 20
668 |
669 | # kitty_mod ctrl+shift
670 |
671 | #: The value of kitty_mod is used as the modifier for all default
672 | #: shortcuts, you can change it in your kitty.conf to change the
673 | #: modifiers for all the default shortcuts.
674 |
675 | # clear_all_shortcuts no
676 |
677 | #: You can have kitty remove all shortcut definition seen up to this
678 | #: point. Useful, for instance, to remove the default shortcuts.
679 |
680 | #: Clipboard {{{
681 |
682 | # map kitty_mod+c copy_to_clipboard
683 |
684 | #: There is also a copy_or_interrupt action that can be optionally
685 | #: mapped to Ctrl+c. It will copy only if there is a selection and
686 | #: send an interrupt otherwise.
687 |
688 | # map cmd+c copy_to_clipboard
689 | # map kitty_mod+v paste_from_clipboard
690 | # map cmd+v paste_from_clipboard
691 | # map kitty_mod+s paste_from_selection
692 | # map shift+insert paste_from_selection
693 | # map kitty_mod+o pass_selection_to_program
694 |
695 | #: You can also pass the contents of the current selection to any
696 | #: program using pass_selection_to_program. By default, the system's
697 | #: open program is used, but you can specify your own, the selection
698 | #: will be passed as a command line argument to the program, for
699 | #: example::
700 |
701 | #: map kitty_mod+o pass_selection_to_program firefox
702 |
703 | #: You can pass the current selection to a terminal program running in
704 | #: a new kitty window, by using the @selection placeholder::
705 |
706 | #: map kitty_mod+y new_window less @selection
707 |
708 | #: }}}
709 |
710 | #: Scrolling {{{
711 |
712 | # map kitty_mod+up scroll_line_up
713 | # map alt+cmd+page_up scroll_line_up
714 | # map cmd+up scroll_line_up
715 | # map kitty_mod+k scroll_line_up
716 | # map kitty_mod+down scroll_line_down
717 | # map kitty_mod+j scroll_line_down
718 | # map alt+cmd+page_down scroll_line_down
719 | # map cmd+down scroll_line_down
720 | # map kitty_mod+page_up scroll_page_up
721 | # map cmd+page_up scroll_page_up
722 | # map kitty_mod+page_down scroll_page_down
723 | # map cmd+page_down scroll_page_down
724 | # map kitty_mod+home scroll_home
725 | # map cmd+home scroll_home
726 | # map kitty_mod+end scroll_end
727 | # map cmd+end scroll_end
728 | # map kitty_mod+h show_scrollback
729 |
730 | #: You can pipe the contents of the current screen + history buffer as
731 | #: STDIN to an arbitrary program using the ``pipe`` function. For
732 | #: example, the following opens the scrollback buffer in less in an
733 | #: overlay window::
734 |
735 | #: map f1 pipe @ansi overlay less +G -R
736 |
737 | #: For more details on piping screen and buffer contents to external
738 | #: programs, see pipe.
739 |
740 | #: }}}
741 |
742 | #: Window management {{{
743 |
744 | # map kitty_mod+enter new_window
745 |
746 | #: You can open a new window running an arbitrary program, for
747 | #: example::
748 |
749 | #: map kitty_mod+y new_window mutt
750 |
751 | #: You can open a new window with the current working directory set to
752 | #: the working directory of the current window using::
753 |
754 | #: map ctrl+alt+enter new_window_with_cwd
755 |
756 | #: You can open a new window that is allowed to control kitty via the
757 | #: kitty remote control facility by prefixing the command line with @.
758 | #: Any programs running in that window will be allowed to control
759 | #: kitty. For example::
760 |
761 | #: map ctrl+enter new_window @ some_program
762 |
763 | # map cmd+enter new_window
764 | # map kitty_mod+n new_os_window
765 | # map cmd+n kitty -1
766 | # map kitty_mod+w close_window
767 | # map shift+cmd+d close_window
768 | # map kitty_mod+] next_window
769 | # map kitty_mod+[ previous_window
770 | # map kitty_mod+f move_window_forward
771 | # map kitty_mod+b move_window_backward
772 | # map kitty_mod+` move_window_to_top
773 | # map kitty_mod+r start_resizing_window
774 | # map cmd+r start_resizing_window
775 | # map kitty_mod+1 first_window
776 | # map cmd+1 first_window
777 | # map kitty_mod+2 second_window
778 | # map cmd+2 second_window
779 | # map kitty_mod+3 third_window
780 | # map cmd+3 third_window
781 | # map kitty_mod+4 fourth_window
782 | # map cmd+4 fourth_window
783 | # map kitty_mod+5 fifth_window
784 | # map cmd+5 fifth_window
785 | # map kitty_mod+6 sixth_window
786 | # map cmd+6 sixth_window
787 | # map kitty_mod+7 seventh_window
788 | # map cmd+7 seventh_window
789 | # map kitty_mod+8 eighth_window
790 | # map cmd+8 eighth_window
791 | # map kitty_mod+9 ninth_window
792 | # map cmd+9 ninth_window
793 | # map kitty_mod+0 tenth_window
794 | #: }}}
795 |
796 | #: Layout management {{{
797 |
798 | # map kitty_mod+l next_layout
799 |
800 | #: You can also create shortcuts to switch to specific layouts::
801 |
802 | #: map ctrl+alt+t goto_layout tall
803 | #: map ctrl+alt+s goto_layout stack
804 |
805 | #: Similarly, to switch back to the previous layout::
806 |
807 | #: map ctrl+alt+p last_used_layout
808 | #: }}}
809 |
810 | #: Font sizes {{{
811 |
812 | #: You can change the font size for all top-level kitty OS windows at
813 | #: a time or only the current one.
814 |
815 | # map kitty_mod+equal change_font_size all +2.0
816 | # map cmd+plus change_font_size all +2.0
817 | # map kitty_mod+minus change_font_size all -2.0
818 | # map cmd+minus change_font_size all -2.0
819 | # map kitty_mod+backspace change_font_size all 0
820 | # map cmd+0 change_font_size all 0
821 |
822 | #: To setup shortcuts for specific font sizes::
823 |
824 | #: map kitty_mod+f6 change_font_size all 10.0
825 |
826 | #: To setup shortcuts to change only the current OS window's font
827 | #: size::
828 |
829 | #: map kitty_mod+f6 change_font_size current 10.0
830 | #: }}}
831 |
832 | #: Select and act on visible text {{{
833 |
834 | #: Use the hints kitten to select text and either pass it to an
835 | #: external program or insert it into the terminal or copy it to the
836 | #: clipboard.
837 |
838 | # map kitty_mod+e kitten hints
839 |
840 | #: Open a currently visible URL using the keyboard. The program used
841 | #: to open the URL is specified in open_url_with.
842 |
843 | # map kitty_mod+p>f kitten hints --type path --program -
844 |
845 | #: Select a path/filename and insert it into the terminal. Useful, for
846 | #: instance to run git commands on a filename output from a previous
847 | #: git command.
848 |
849 | # map kitty_mod+p>shift+f kitten hints --type path
850 |
851 | #: Select a path/filename and open it with the default open program.
852 |
853 | # map kitty_mod+p>l kitten hints --type line --program -
854 |
855 | #: Select a line of text and insert it into the terminal. Use for the
856 | #: output of things like: ls -1
857 |
858 | # map kitty_mod+p>w kitten hints --type word --program -
859 |
860 | #: Select words and insert into terminal.
861 |
862 | # map kitty_mod+p>h kitten hints --type hash --program -
863 |
864 | #: Select something that looks like a hash and insert it into the
865 | #: terminal. Useful with git, which uses sha1 hashes to identify
866 | #: commits
867 |
868 |
869 | #: The hints kitten has many more modes of operation that you can map
870 | #: to different shortcuts. For a full description see kittens/hints.
871 | #: }}}
872 |
873 | #: Miscellaneous {{{
874 |
875 | # map kitty_mod+f11 toggle_fullscreen
876 | # map kitty_mod+f10 toggle_maximized
877 | # map kitty_mod+u kitten unicode_input
878 | # map kitty_mod+f2 edit_config_file
879 | # map kitty_mod+escape kitty_shell window
880 |
881 | #: Open the kitty shell in a new window/tab/overlay/os_window to
882 | #: control kitty using commands.
883 |
884 | # map kitty_mod+a>m set_background_opacity +0.1
885 | # map kitty_mod+a>l set_background_opacity -0.1
886 | # map kitty_mod+a>1 set_background_opacity 1
887 | # map kitty_mod+a>d set_background_opacity default
888 | # map kitty_mod+delete clear_terminal reset active
889 |
890 | #: You can create shortcuts to clear/reset the terminal. For example::
891 |
892 | #: # Reset the terminal
893 | #: map kitty_mod+f9 clear_terminal reset active
894 | #: # Clear the terminal screen by erasing all contents
895 | #: map kitty_mod+f10 clear_terminal clear active
896 | #: # Clear the terminal scrollback by erasing it
897 | #: map kitty_mod+f11 clear_terminal scrollback active
898 | #: # Scroll the contents of the screen into the scrollback
899 | #: map kitty_mod+f12 clear_terminal scroll active
900 |
901 | #: If you want to operate on all windows instead of just the current
902 | #: one, use all instead of :italic`active`.
903 |
904 | #: It is also possible to remap Ctrl+L to both scroll the current
905 | #: screen contents into the scrollback buffer and clear the screen,
906 | #: instead of just clearing the screen::
907 |
908 | #: map ctrl+l combine : clear_terminal scroll active : send_text normal,application \x0c
909 |
910 |
911 | #: You can tell kitty to send arbitrary (UTF-8) encoded text to the
912 | #: client program when pressing specified shortcut keys. For example::
913 |
914 | #: map ctrl+alt+a send_text all Special text
915 |
916 | #: This will send "Special text" when you press the ctrl+alt+a key
917 | #: combination. The text to be sent is a python string literal so you
918 | #: can use escapes like \x1b to send control codes or \u21fb to send
919 | #: unicode characters (or you can just input the unicode characters
920 | #: directly as UTF-8 text). The first argument to send_text is the
921 | #: keyboard modes in which to activate the shortcut. The possible
922 | #: values are normal or application or kitty or a comma separated
923 | #: combination of them. The special keyword all means all modes. The
924 | #: modes normal and application refer to the DECCKM cursor key mode
925 | #: for terminals, and kitty refers to the special kitty extended
926 | #: keyboard protocol.
927 |
928 | #: Another example, that outputs a word and then moves the cursor to
929 | #: the start of the line (same as pressing the Home key)::
930 |
931 | #: map ctrl+alt+a send_text normal Word\x1b[H
932 | #: map ctrl+alt+a send_text application Word\x1bOH
933 |
--------------------------------------------------------------------------------
/vim/.ctags:
--------------------------------------------------------------------------------
1 | --recurse=yes
2 | --tag-relative=yes
3 |
4 | --exclude=.build
5 | --exclude=.DS_Store
6 | --exclude=.git
7 | --exclude=build
8 |
--------------------------------------------------------------------------------
/vim/.vim/autoload/plug.vim:
--------------------------------------------------------------------------------
1 | " vim-plug: Vim plugin manager
2 | " ============================
3 | "
4 | " Download plug.vim and put it in ~/.vim/autoload
5 | "
6 | " curl -fLo ~/.vim/autoload/plug.vim --create-dirs \
7 | " https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim
8 | "
9 | " Edit your .vimrc
10 | "
11 | " call plug#begin('~/.vim/plugged')
12 | "
13 | " " Make sure you use single quotes
14 | "
15 | " " Shorthand notation; fetches https://github.com/junegunn/vim-easy-align
16 | " Plug 'junegunn/vim-easy-align'
17 | "
18 | " " Any valid git URL is allowed
19 | " Plug 'https://github.com/junegunn/vim-github-dashboard.git'
20 | "
21 | " " Multiple Plug commands can be written in a single line using | separators
22 | " Plug 'SirVer/ultisnips' | Plug 'honza/vim-snippets'
23 | "
24 | " " On-demand loading
25 | " Plug 'scrooloose/nerdtree', { 'on': 'NERDTreeToggle' }
26 | " Plug 'tpope/vim-fireplace', { 'for': 'clojure' }
27 | "
28 | " " Using a non-default branch
29 | " Plug 'rdnetto/YCM-Generator', { 'branch': 'stable' }
30 | "
31 | " " Using a tagged release; wildcard allowed (requires git 1.9.2 or above)
32 | " Plug 'fatih/vim-go', { 'tag': '*' }
33 | "
34 | " " Plugin options
35 | " Plug 'nsf/gocode', { 'tag': 'v.20150303', 'rtp': 'vim' }
36 | "
37 | " " Plugin outside ~/.vim/plugged with post-update hook
38 | " Plug 'junegunn/fzf', { 'dir': '~/.fzf', 'do': './install --all' }
39 | "
40 | " " Unmanaged plugin (manually installed and updated)
41 | " Plug '~/my-prototype-plugin'
42 | "
43 | " " Initialize plugin system
44 | " call plug#end()
45 | "
46 | " Then reload .vimrc and :PlugInstall to install plugins.
47 | "
48 | " Plug options:
49 | "
50 | "| Option | Description |
51 | "| ----------------------- | ------------------------------------------------ |
52 | "| `branch`/`tag`/`commit` | Branch/tag/commit of the repository to use |
53 | "| `rtp` | Subdirectory that contains Vim plugin |
54 | "| `dir` | Custom directory for the plugin |
55 | "| `as` | Use different name for the plugin |
56 | "| `do` | Post-update hook (string or funcref) |
57 | "| `on` | On-demand loading: Commands or ``-mappings |
58 | "| `for` | On-demand loading: File types |
59 | "| `frozen` | Do not update unless explicitly specified |
60 | "
61 | " More information: https://github.com/junegunn/vim-plug
62 | "
63 | "
64 | " Copyright (c) 2017 Junegunn Choi
65 | "
66 | " MIT License
67 | "
68 | " Permission is hereby granted, free of charge, to any person obtaining
69 | " a copy of this software and associated documentation files (the
70 | " "Software"), to deal in the Software without restriction, including
71 | " without limitation the rights to use, copy, modify, merge, publish,
72 | " distribute, sublicense, and/or sell copies of the Software, and to
73 | " permit persons to whom the Software is furnished to do so, subject to
74 | " the following conditions:
75 | "
76 | " The above copyright notice and this permission notice shall be
77 | " included in all copies or substantial portions of the Software.
78 | "
79 | " THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
80 | " EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
81 | " MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
82 | " NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
83 | " LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
84 | " OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
85 | " WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
86 |
87 | if exists('g:loaded_plug')
88 | finish
89 | endif
90 | let g:loaded_plug = 1
91 |
92 | let s:cpo_save = &cpo
93 | set cpo&vim
94 |
95 | let s:plug_src = 'https://github.com/junegunn/vim-plug.git'
96 | let s:plug_tab = get(s:, 'plug_tab', -1)
97 | let s:plug_buf = get(s:, 'plug_buf', -1)
98 | let s:mac_gui = has('gui_macvim') && has('gui_running')
99 | let s:is_win = has('win32')
100 | let s:nvim = has('nvim-0.2') || (has('nvim') && exists('*jobwait') && !s:is_win)
101 | let s:vim8 = has('patch-8.0.0039') && exists('*job_start')
102 | if s:is_win && &shellslash
103 | set noshellslash
104 | let s:me = resolve(expand(':p'))
105 | set shellslash
106 | else
107 | let s:me = resolve(expand(':p'))
108 | endif
109 | let s:base_spec = { 'branch': '', 'frozen': 0 }
110 | let s:TYPE = {
111 | \ 'string': type(''),
112 | \ 'list': type([]),
113 | \ 'dict': type({}),
114 | \ 'funcref': type(function('call'))
115 | \ }
116 | let s:loaded = get(s:, 'loaded', {})
117 | let s:triggers = get(s:, 'triggers', {})
118 |
119 | function! s:is_powershell(shell)
120 | return a:shell =~# 'powershell\(\.exe\)\?$' || a:shell =~# 'pwsh\(\.exe\)\?$'
121 | endfunction
122 |
123 | function! s:isabsolute(dir) abort
124 | return a:dir =~# '^/' || (has('win32') && a:dir =~? '^\%(\\\|[A-Z]:\)')
125 | endfunction
126 |
127 | function! s:git_dir(dir) abort
128 | let gitdir = s:trim(a:dir) . '/.git'
129 | if isdirectory(gitdir)
130 | return gitdir
131 | endif
132 | if !filereadable(gitdir)
133 | return ''
134 | endif
135 | let gitdir = matchstr(get(readfile(gitdir), 0, ''), '^gitdir: \zs.*')
136 | if len(gitdir) && !s:isabsolute(gitdir)
137 | let gitdir = a:dir . '/' . gitdir
138 | endif
139 | return isdirectory(gitdir) ? gitdir : ''
140 | endfunction
141 |
142 | function! s:git_origin_url(dir) abort
143 | let gitdir = s:git_dir(a:dir)
144 | let config = gitdir . '/config'
145 | if empty(gitdir) || !filereadable(config)
146 | return ''
147 | endif
148 | return matchstr(join(readfile(config)), '\[remote "origin"\].\{-}url\s*=\s*\zs\S*\ze')
149 | endfunction
150 |
151 | function! s:git_revision(dir) abort
152 | let gitdir = s:git_dir(a:dir)
153 | let head = gitdir . '/HEAD'
154 | if empty(gitdir) || !filereadable(head)
155 | return ''
156 | endif
157 |
158 | let line = get(readfile(head), 0, '')
159 | let ref = matchstr(line, '^ref: \zs.*')
160 | if empty(ref)
161 | return line
162 | endif
163 |
164 | if filereadable(gitdir . '/' . ref)
165 | return get(readfile(gitdir . '/' . ref), 0, '')
166 | endif
167 |
168 | if filereadable(gitdir . '/packed-refs')
169 | for line in readfile(gitdir . '/packed-refs')
170 | if line =~# ' ' . ref
171 | return matchstr(line, '^[0-9a-f]*')
172 | endif
173 | endfor
174 | endif
175 |
176 | return ''
177 | endfunction
178 |
179 | function! s:git_local_branch(dir) abort
180 | let gitdir = s:git_dir(a:dir)
181 | let head = gitdir . '/HEAD'
182 | if empty(gitdir) || !filereadable(head)
183 | return ''
184 | endif
185 | let branch = matchstr(get(readfile(head), 0, ''), '^ref: refs/heads/\zs.*')
186 | return len(branch) ? branch : 'HEAD'
187 | endfunction
188 |
189 | function! s:git_origin_branch(spec)
190 | if len(a:spec.branch)
191 | return a:spec.branch
192 | endif
193 |
194 | " The file may not be present if this is a local repository
195 | let gitdir = s:git_dir(a:spec.dir)
196 | let origin_head = gitdir.'/refs/remotes/origin/HEAD'
197 | if len(gitdir) && filereadable(origin_head)
198 | return matchstr(get(readfile(origin_head), 0, ''),
199 | \ '^ref: refs/remotes/origin/\zs.*')
200 | endif
201 |
202 | " The command may not return the name of a branch in detached HEAD state
203 | let result = s:lines(s:system('git symbolic-ref --short HEAD', a:spec.dir))
204 | return v:shell_error ? '' : result[-1]
205 | endfunction
206 |
207 | if s:is_win
208 | function! s:plug_call(fn, ...)
209 | let shellslash = &shellslash
210 | try
211 | set noshellslash
212 | return call(a:fn, a:000)
213 | finally
214 | let &shellslash = shellslash
215 | endtry
216 | endfunction
217 | else
218 | function! s:plug_call(fn, ...)
219 | return call(a:fn, a:000)
220 | endfunction
221 | endif
222 |
223 | function! s:plug_getcwd()
224 | return s:plug_call('getcwd')
225 | endfunction
226 |
227 | function! s:plug_fnamemodify(fname, mods)
228 | return s:plug_call('fnamemodify', a:fname, a:mods)
229 | endfunction
230 |
231 | function! s:plug_expand(fmt)
232 | return s:plug_call('expand', a:fmt, 1)
233 | endfunction
234 |
235 | function! s:plug_tempname()
236 | return s:plug_call('tempname')
237 | endfunction
238 |
239 | function! plug#begin(...)
240 | if a:0 > 0
241 | let s:plug_home_org = a:1
242 | let home = s:path(s:plug_fnamemodify(s:plug_expand(a:1), ':p'))
243 | elseif exists('g:plug_home')
244 | let home = s:path(g:plug_home)
245 | elseif has('nvim')
246 | let home = stdpath('data') . '/plugged'
247 | elseif !empty(&rtp)
248 | let home = s:path(split(&rtp, ',')[0]) . '/plugged'
249 | else
250 | return s:err('Unable to determine plug home. Try calling plug#begin() with a path argument.')
251 | endif
252 | if s:plug_fnamemodify(home, ':t') ==# 'plugin' && s:plug_fnamemodify(home, ':h') ==# s:first_rtp
253 | return s:err('Invalid plug home. '.home.' is a standard Vim runtime path and is not allowed.')
254 | endif
255 |
256 | let g:plug_home = home
257 | let g:plugs = {}
258 | let g:plugs_order = []
259 | let s:triggers = {}
260 |
261 | call s:define_commands()
262 | return 1
263 | endfunction
264 |
265 | function! s:define_commands()
266 | command! -nargs=+ -bar Plug call plug#()
267 | if !executable('git')
268 | return s:err('`git` executable not found. Most commands will not be available. To suppress this message, prepend `silent!` to `call plug#begin(...)`.')
269 | endif
270 | if has('win32')
271 | \ && &shellslash
272 | \ && (&shell =~# 'cmd\(\.exe\)\?$' || s:is_powershell(&shell))
273 | return s:err('vim-plug does not support shell, ' . &shell . ', when shellslash is set.')
274 | endif
275 | if !has('nvim')
276 | \ && (has('win32') || has('win32unix'))
277 | \ && !has('multi_byte')
278 | return s:err('Vim needs +multi_byte feature on Windows to run shell commands. Enable +iconv for best results.')
279 | endif
280 | command! -nargs=* -bar -bang -complete=customlist,s:names PlugInstall call s:install(0, [])
281 | command! -nargs=* -bar -bang -complete=customlist,s:names PlugUpdate call s:update(0, [])
282 | command! -nargs=0 -bar -bang PlugClean call s:clean(0)
283 | command! -nargs=0 -bar PlugUpgrade if s:upgrade() | execute 'source' s:esc(s:me) | endif
284 | command! -nargs=0 -bar PlugStatus call s:status()
285 | command! -nargs=0 -bar PlugDiff call s:diff()
286 | command! -nargs=? -bar -bang -complete=file PlugSnapshot call s:snapshot(0, )
287 | endfunction
288 |
289 | function! s:to_a(v)
290 | return type(a:v) == s:TYPE.list ? a:v : [a:v]
291 | endfunction
292 |
293 | function! s:to_s(v)
294 | return type(a:v) == s:TYPE.string ? a:v : join(a:v, "\n") . "\n"
295 | endfunction
296 |
297 | function! s:glob(from, pattern)
298 | return s:lines(globpath(a:from, a:pattern))
299 | endfunction
300 |
301 | function! s:source(from, ...)
302 | let found = 0
303 | for pattern in a:000
304 | for vim in s:glob(a:from, pattern)
305 | execute 'source' s:esc(vim)
306 | let found = 1
307 | endfor
308 | endfor
309 | return found
310 | endfunction
311 |
312 | function! s:assoc(dict, key, val)
313 | let a:dict[a:key] = add(get(a:dict, a:key, []), a:val)
314 | endfunction
315 |
316 | function! s:ask(message, ...)
317 | call inputsave()
318 | echohl WarningMsg
319 | let answer = input(a:message.(a:0 ? ' (y/N/a) ' : ' (y/N) '))
320 | echohl None
321 | call inputrestore()
322 | echo "\r"
323 | return (a:0 && answer =~? '^a') ? 2 : (answer =~? '^y') ? 1 : 0
324 | endfunction
325 |
326 | function! s:ask_no_interrupt(...)
327 | try
328 | return call('s:ask', a:000)
329 | catch
330 | return 0
331 | endtry
332 | endfunction
333 |
334 | function! s:lazy(plug, opt)
335 | return has_key(a:plug, a:opt) &&
336 | \ (empty(s:to_a(a:plug[a:opt])) ||
337 | \ !isdirectory(a:plug.dir) ||
338 | \ len(s:glob(s:rtp(a:plug), 'plugin')) ||
339 | \ len(s:glob(s:rtp(a:plug), 'after/plugin')))
340 | endfunction
341 |
342 | function! plug#end()
343 | if !exists('g:plugs')
344 | return s:err('plug#end() called without calling plug#begin() first')
345 | endif
346 |
347 | if exists('#PlugLOD')
348 | augroup PlugLOD
349 | autocmd!
350 | augroup END
351 | augroup! PlugLOD
352 | endif
353 | let lod = { 'ft': {}, 'map': {}, 'cmd': {} }
354 |
355 | if get(g:, 'did_load_filetypes', 0)
356 | filetype off
357 | endif
358 | for name in g:plugs_order
359 | if !has_key(g:plugs, name)
360 | continue
361 | endif
362 | let plug = g:plugs[name]
363 | if get(s:loaded, name, 0) || !s:lazy(plug, 'on') && !s:lazy(plug, 'for')
364 | let s:loaded[name] = 1
365 | continue
366 | endif
367 |
368 | if has_key(plug, 'on')
369 | let s:triggers[name] = { 'map': [], 'cmd': [] }
370 | for cmd in s:to_a(plug.on)
371 | if cmd =~? '^.\+'
372 | if empty(mapcheck(cmd)) && empty(mapcheck(cmd, 'i'))
373 | call s:assoc(lod.map, cmd, name)
374 | endif
375 | call add(s:triggers[name].map, cmd)
376 | elseif cmd =~# '^[A-Z]'
377 | let cmd = substitute(cmd, '!*$', '', '')
378 | if exists(':'.cmd) != 2
379 | call s:assoc(lod.cmd, cmd, name)
380 | endif
381 | call add(s:triggers[name].cmd, cmd)
382 | else
383 | call s:err('Invalid `on` option: '.cmd.
384 | \ '. Should start with an uppercase letter or ``.')
385 | endif
386 | endfor
387 | endif
388 |
389 | if has_key(plug, 'for')
390 | let types = s:to_a(plug.for)
391 | if !empty(types)
392 | augroup filetypedetect
393 | call s:source(s:rtp(plug), 'ftdetect/**/*.vim', 'after/ftdetect/**/*.vim')
394 | augroup END
395 | endif
396 | for type in types
397 | call s:assoc(lod.ft, type, name)
398 | endfor
399 | endif
400 | endfor
401 |
402 | for [cmd, names] in items(lod.cmd)
403 | execute printf(
404 | \ 'command! -nargs=* -range -bang -complete=file %s call s:lod_cmd(%s, "", , , , %s)',
405 | \ cmd, string(cmd), string(names))
406 | endfor
407 |
408 | for [map, names] in items(lod.map)
409 | for [mode, map_prefix, key_prefix] in
410 | \ [['i', '', ''], ['n', '', ''], ['v', '', 'gv'], ['o', '', '']]
411 | execute printf(
412 | \ '%snoremap %s %s:call lod_map(%s, %s, %s, "%s")',
413 | \ mode, map, map_prefix, string(map), string(names), mode != 'i', key_prefix)
414 | endfor
415 | endfor
416 |
417 | for [ft, names] in items(lod.ft)
418 | augroup PlugLOD
419 | execute printf('autocmd FileType %s call lod_ft(%s, %s)',
420 | \ ft, string(ft), string(names))
421 | augroup END
422 | endfor
423 |
424 | call s:reorg_rtp()
425 | filetype plugin indent on
426 | if has('vim_starting')
427 | if has('syntax') && !exists('g:syntax_on')
428 | syntax enable
429 | end
430 | else
431 | call s:reload_plugins()
432 | endif
433 | endfunction
434 |
435 | function! s:loaded_names()
436 | return filter(copy(g:plugs_order), 'get(s:loaded, v:val, 0)')
437 | endfunction
438 |
439 | function! s:load_plugin(spec)
440 | call s:source(s:rtp(a:spec), 'plugin/**/*.vim', 'after/plugin/**/*.vim')
441 | endfunction
442 |
443 | function! s:reload_plugins()
444 | for name in s:loaded_names()
445 | call s:load_plugin(g:plugs[name])
446 | endfor
447 | endfunction
448 |
449 | function! s:trim(str)
450 | return substitute(a:str, '[\/]\+$', '', '')
451 | endfunction
452 |
453 | function! s:version_requirement(val, min)
454 | for idx in range(0, len(a:min) - 1)
455 | let v = get(a:val, idx, 0)
456 | if v < a:min[idx] | return 0
457 | elseif v > a:min[idx] | return 1
458 | endif
459 | endfor
460 | return 1
461 | endfunction
462 |
463 | function! s:git_version_requirement(...)
464 | if !exists('s:git_version')
465 | let s:git_version = map(split(split(s:system(['git', '--version']))[2], '\.'), 'str2nr(v:val)')
466 | endif
467 | return s:version_requirement(s:git_version, a:000)
468 | endfunction
469 |
470 | function! s:progress_opt(base)
471 | return a:base && !s:is_win &&
472 | \ s:git_version_requirement(1, 7, 1) ? '--progress' : ''
473 | endfunction
474 |
475 | function! s:rtp(spec)
476 | return s:path(a:spec.dir . get(a:spec, 'rtp', ''))
477 | endfunction
478 |
479 | if s:is_win
480 | function! s:path(path)
481 | return s:trim(substitute(a:path, '/', '\', 'g'))
482 | endfunction
483 |
484 | function! s:dirpath(path)
485 | return s:path(a:path) . '\'
486 | endfunction
487 |
488 | function! s:is_local_plug(repo)
489 | return a:repo =~? '^[a-z]:\|^[%~]'
490 | endfunction
491 |
492 | " Copied from fzf
493 | function! s:wrap_cmds(cmds)
494 | let cmds = [
495 | \ '@echo off',
496 | \ 'setlocal enabledelayedexpansion']
497 | \ + (type(a:cmds) == type([]) ? a:cmds : [a:cmds])
498 | \ + ['endlocal']
499 | if has('iconv')
500 | if !exists('s:codepage')
501 | let s:codepage = libcallnr('kernel32.dll', 'GetACP', 0)
502 | endif
503 | return map(cmds, printf('iconv(v:val."\r", "%s", "cp%d")', &encoding, s:codepage))
504 | endif
505 | return map(cmds, 'v:val."\r"')
506 | endfunction
507 |
508 | function! s:batchfile(cmd)
509 | let batchfile = s:plug_tempname().'.bat'
510 | call writefile(s:wrap_cmds(a:cmd), batchfile)
511 | let cmd = plug#shellescape(batchfile, {'shell': &shell, 'script': 0})
512 | if s:is_powershell(&shell)
513 | let cmd = '& ' . cmd
514 | endif
515 | return [batchfile, cmd]
516 | endfunction
517 | else
518 | function! s:path(path)
519 | return s:trim(a:path)
520 | endfunction
521 |
522 | function! s:dirpath(path)
523 | return substitute(a:path, '[/\\]*$', '/', '')
524 | endfunction
525 |
526 | function! s:is_local_plug(repo)
527 | return a:repo[0] =~ '[/$~]'
528 | endfunction
529 | endif
530 |
531 | function! s:err(msg)
532 | echohl ErrorMsg
533 | echom '[vim-plug] '.a:msg
534 | echohl None
535 | endfunction
536 |
537 | function! s:warn(cmd, msg)
538 | echohl WarningMsg
539 | execute a:cmd 'a:msg'
540 | echohl None
541 | endfunction
542 |
543 | function! s:esc(path)
544 | return escape(a:path, ' ')
545 | endfunction
546 |
547 | function! s:escrtp(path)
548 | return escape(a:path, ' ,')
549 | endfunction
550 |
551 | function! s:remove_rtp()
552 | for name in s:loaded_names()
553 | let rtp = s:rtp(g:plugs[name])
554 | execute 'set rtp-='.s:escrtp(rtp)
555 | let after = globpath(rtp, 'after')
556 | if isdirectory(after)
557 | execute 'set rtp-='.s:escrtp(after)
558 | endif
559 | endfor
560 | endfunction
561 |
562 | function! s:reorg_rtp()
563 | if !empty(s:first_rtp)
564 | execute 'set rtp-='.s:first_rtp
565 | execute 'set rtp-='.s:last_rtp
566 | endif
567 |
568 | " &rtp is modified from outside
569 | if exists('s:prtp') && s:prtp !=# &rtp
570 | call s:remove_rtp()
571 | unlet! s:middle
572 | endif
573 |
574 | let s:middle = get(s:, 'middle', &rtp)
575 | let rtps = map(s:loaded_names(), 's:rtp(g:plugs[v:val])')
576 | let afters = filter(map(copy(rtps), 'globpath(v:val, "after")'), '!empty(v:val)')
577 | let rtp = join(map(rtps, 'escape(v:val, ",")'), ',')
578 | \ . ','.s:middle.','
579 | \ . join(map(afters, 'escape(v:val, ",")'), ',')
580 | let &rtp = substitute(substitute(rtp, ',,*', ',', 'g'), '^,\|,$', '', 'g')
581 | let s:prtp = &rtp
582 |
583 | if !empty(s:first_rtp)
584 | execute 'set rtp^='.s:first_rtp
585 | execute 'set rtp+='.s:last_rtp
586 | endif
587 | endfunction
588 |
589 | function! s:doautocmd(...)
590 | if exists('#'.join(a:000, '#'))
591 | execute 'doautocmd' ((v:version > 703 || has('patch442')) ? '' : '') join(a:000)
592 | endif
593 | endfunction
594 |
595 | function! s:dobufread(names)
596 | for name in a:names
597 | let path = s:rtp(g:plugs[name])
598 | for dir in ['ftdetect', 'ftplugin', 'after/ftdetect', 'after/ftplugin']
599 | if len(finddir(dir, path))
600 | if exists('#BufRead')
601 | doautocmd BufRead
602 | endif
603 | return
604 | endif
605 | endfor
606 | endfor
607 | endfunction
608 |
609 | function! plug#load(...)
610 | if a:0 == 0
611 | return s:err('Argument missing: plugin name(s) required')
612 | endif
613 | if !exists('g:plugs')
614 | return s:err('plug#begin was not called')
615 | endif
616 | let names = a:0 == 1 && type(a:1) == s:TYPE.list ? a:1 : a:000
617 | let unknowns = filter(copy(names), '!has_key(g:plugs, v:val)')
618 | if !empty(unknowns)
619 | let s = len(unknowns) > 1 ? 's' : ''
620 | return s:err(printf('Unknown plugin%s: %s', s, join(unknowns, ', ')))
621 | end
622 | let unloaded = filter(copy(names), '!get(s:loaded, v:val, 0)')
623 | if !empty(unloaded)
624 | for name in unloaded
625 | call s:lod([name], ['ftdetect', 'after/ftdetect', 'plugin', 'after/plugin'])
626 | endfor
627 | call s:dobufread(unloaded)
628 | return 1
629 | end
630 | return 0
631 | endfunction
632 |
633 | function! s:remove_triggers(name)
634 | if !has_key(s:triggers, a:name)
635 | return
636 | endif
637 | for cmd in s:triggers[a:name].cmd
638 | execute 'silent! delc' cmd
639 | endfor
640 | for map in s:triggers[a:name].map
641 | execute 'silent! unmap' map
642 | execute 'silent! iunmap' map
643 | endfor
644 | call remove(s:triggers, a:name)
645 | endfunction
646 |
647 | function! s:lod(names, types, ...)
648 | for name in a:names
649 | call s:remove_triggers(name)
650 | let s:loaded[name] = 1
651 | endfor
652 | call s:reorg_rtp()
653 |
654 | for name in a:names
655 | let rtp = s:rtp(g:plugs[name])
656 | for dir in a:types
657 | call s:source(rtp, dir.'/**/*.vim')
658 | endfor
659 | if a:0
660 | if !s:source(rtp, a:1) && !empty(s:glob(rtp, a:2))
661 | execute 'runtime' a:1
662 | endif
663 | call s:source(rtp, a:2)
664 | endif
665 | call s:doautocmd('User', name)
666 | endfor
667 | endfunction
668 |
669 | function! s:lod_ft(pat, names)
670 | let syn = 'syntax/'.a:pat.'.vim'
671 | call s:lod(a:names, ['plugin', 'after/plugin'], syn, 'after/'.syn)
672 | execute 'autocmd! PlugLOD FileType' a:pat
673 | call s:doautocmd('filetypeplugin', 'FileType')
674 | call s:doautocmd('filetypeindent', 'FileType')
675 | endfunction
676 |
677 | function! s:lod_cmd(cmd, bang, l1, l2, args, names)
678 | call s:lod(a:names, ['ftdetect', 'after/ftdetect', 'plugin', 'after/plugin'])
679 | call s:dobufread(a:names)
680 | execute printf('%s%s%s %s', (a:l1 == a:l2 ? '' : (a:l1.','.a:l2)), a:cmd, a:bang, a:args)
681 | endfunction
682 |
683 | function! s:lod_map(map, names, with_prefix, prefix)
684 | call s:lod(a:names, ['ftdetect', 'after/ftdetect', 'plugin', 'after/plugin'])
685 | call s:dobufread(a:names)
686 | let extra = ''
687 | while 1
688 | let c = getchar(0)
689 | if c == 0
690 | break
691 | endif
692 | let extra .= nr2char(c)
693 | endwhile
694 |
695 | if a:with_prefix
696 | let prefix = v:count ? v:count : ''
697 | let prefix .= '"'.v:register.a:prefix
698 | if mode(1) == 'no'
699 | if v:operator == 'c'
700 | let prefix = "\" . prefix
701 | endif
702 | let prefix .= v:operator
703 | endif
704 | call feedkeys(prefix, 'n')
705 | endif
706 | call feedkeys(substitute(a:map, '^', "\", '') . extra)
707 | endfunction
708 |
709 | function! plug#(repo, ...)
710 | if a:0 > 1
711 | return s:err('Invalid number of arguments (1..2)')
712 | endif
713 |
714 | try
715 | let repo = s:trim(a:repo)
716 | let opts = a:0 == 1 ? s:parse_options(a:1) : s:base_spec
717 | let name = get(opts, 'as', s:plug_fnamemodify(repo, ':t:s?\.git$??'))
718 | let spec = extend(s:infer_properties(name, repo), opts)
719 | if !has_key(g:plugs, name)
720 | call add(g:plugs_order, name)
721 | endif
722 | let g:plugs[name] = spec
723 | let s:loaded[name] = get(s:loaded, name, 0)
724 | catch
725 | return s:err(repo . ' ' . v:exception)
726 | endtry
727 | endfunction
728 |
729 | function! s:parse_options(arg)
730 | let opts = copy(s:base_spec)
731 | let type = type(a:arg)
732 | let opt_errfmt = 'Invalid argument for "%s" option of :Plug (expected: %s)'
733 | if type == s:TYPE.string
734 | if empty(a:arg)
735 | throw printf(opt_errfmt, 'tag', 'string')
736 | endif
737 | let opts.tag = a:arg
738 | elseif type == s:TYPE.dict
739 | for opt in ['branch', 'tag', 'commit', 'rtp', 'dir', 'as']
740 | if has_key(a:arg, opt)
741 | \ && (type(a:arg[opt]) != s:TYPE.string || empty(a:arg[opt]))
742 | throw printf(opt_errfmt, opt, 'string')
743 | endif
744 | endfor
745 | for opt in ['on', 'for']
746 | if has_key(a:arg, opt)
747 | \ && type(a:arg[opt]) != s:TYPE.list
748 | \ && (type(a:arg[opt]) != s:TYPE.string || empty(a:arg[opt]))
749 | throw printf(opt_errfmt, opt, 'string or list')
750 | endif
751 | endfor
752 | if has_key(a:arg, 'do')
753 | \ && type(a:arg.do) != s:TYPE.funcref
754 | \ && (type(a:arg.do) != s:TYPE.string || empty(a:arg.do))
755 | throw printf(opt_errfmt, 'do', 'string or funcref')
756 | endif
757 | call extend(opts, a:arg)
758 | if has_key(opts, 'dir')
759 | let opts.dir = s:dirpath(s:plug_expand(opts.dir))
760 | endif
761 | else
762 | throw 'Invalid argument type (expected: string or dictionary)'
763 | endif
764 | return opts
765 | endfunction
766 |
767 | function! s:infer_properties(name, repo)
768 | let repo = a:repo
769 | if s:is_local_plug(repo)
770 | return { 'dir': s:dirpath(s:plug_expand(repo)) }
771 | else
772 | if repo =~ ':'
773 | let uri = repo
774 | else
775 | if repo !~ '/'
776 | throw printf('Invalid argument: %s (implicit `vim-scripts'' expansion is deprecated)', repo)
777 | endif
778 | let fmt = get(g:, 'plug_url_format', 'https://git::@github.com/%s.git')
779 | let uri = printf(fmt, repo)
780 | endif
781 | return { 'dir': s:dirpath(g:plug_home.'/'.a:name), 'uri': uri }
782 | endif
783 | endfunction
784 |
785 | function! s:install(force, names)
786 | call s:update_impl(0, a:force, a:names)
787 | endfunction
788 |
789 | function! s:update(force, names)
790 | call s:update_impl(1, a:force, a:names)
791 | endfunction
792 |
793 | function! plug#helptags()
794 | if !exists('g:plugs')
795 | return s:err('plug#begin was not called')
796 | endif
797 | for spec in values(g:plugs)
798 | let docd = join([s:rtp(spec), 'doc'], '/')
799 | if isdirectory(docd)
800 | silent! execute 'helptags' s:esc(docd)
801 | endif
802 | endfor
803 | return 1
804 | endfunction
805 |
806 | function! s:syntax()
807 | syntax clear
808 | syntax region plug1 start=/\%1l/ end=/\%2l/ contains=plugNumber
809 | syntax region plug2 start=/\%2l/ end=/\%3l/ contains=plugBracket,plugX
810 | syn match plugNumber /[0-9]\+[0-9.]*/ contained
811 | syn match plugBracket /[[\]]/ contained
812 | syn match plugX /x/ contained
813 | syn match plugDash /^-\{1}\ /
814 | syn match plugPlus /^+/
815 | syn match plugStar /^*/
816 | syn match plugMessage /\(^- \)\@<=.*/
817 | syn match plugName /\(^- \)\@<=[^ ]*:/
818 | syn match plugSha /\%(: \)\@<=[0-9a-f]\{4,}$/
819 | syn match plugTag /(tag: [^)]\+)/
820 | syn match plugInstall /\(^+ \)\@<=[^:]*/
821 | syn match plugUpdate /\(^* \)\@<=[^:]*/
822 | syn match plugCommit /^ \X*[0-9a-f]\{7,9} .*/ contains=plugRelDate,plugEdge,plugTag
823 | syn match plugEdge /^ \X\+$/
824 | syn match plugEdge /^ \X*/ contained nextgroup=plugSha
825 | syn match plugSha /[0-9a-f]\{7,9}/ contained
826 | syn match plugRelDate /([^)]*)$/ contained
827 | syn match plugNotLoaded /(not loaded)$/
828 | syn match plugError /^x.*/
829 | syn region plugDeleted start=/^\~ .*/ end=/^\ze\S/
830 | syn match plugH2 /^.*:\n-\+$/
831 | syn match plugH2 /^-\{2,}/
832 | syn keyword Function PlugInstall PlugStatus PlugUpdate PlugClean
833 | hi def link plug1 Title
834 | hi def link plug2 Repeat
835 | hi def link plugH2 Type
836 | hi def link plugX Exception
837 | hi def link plugBracket Structure
838 | hi def link plugNumber Number
839 |
840 | hi def link plugDash Special
841 | hi def link plugPlus Constant
842 | hi def link plugStar Boolean
843 |
844 | hi def link plugMessage Function
845 | hi def link plugName Label
846 | hi def link plugInstall Function
847 | hi def link plugUpdate Type
848 |
849 | hi def link plugError Error
850 | hi def link plugDeleted Ignore
851 | hi def link plugRelDate Comment
852 | hi def link plugEdge PreProc
853 | hi def link plugSha Identifier
854 | hi def link plugTag Constant
855 |
856 | hi def link plugNotLoaded Comment
857 | endfunction
858 |
859 | function! s:lpad(str, len)
860 | return a:str . repeat(' ', a:len - len(a:str))
861 | endfunction
862 |
863 | function! s:lines(msg)
864 | return split(a:msg, "[\r\n]")
865 | endfunction
866 |
867 | function! s:lastline(msg)
868 | return get(s:lines(a:msg), -1, '')
869 | endfunction
870 |
871 | function! s:new_window()
872 | execute get(g:, 'plug_window', 'vertical topleft new')
873 | endfunction
874 |
875 | function! s:plug_window_exists()
876 | let buflist = tabpagebuflist(s:plug_tab)
877 | return !empty(buflist) && index(buflist, s:plug_buf) >= 0
878 | endfunction
879 |
880 | function! s:switch_in()
881 | if !s:plug_window_exists()
882 | return 0
883 | endif
884 |
885 | if winbufnr(0) != s:plug_buf
886 | let s:pos = [tabpagenr(), winnr(), winsaveview()]
887 | execute 'normal!' s:plug_tab.'gt'
888 | let winnr = bufwinnr(s:plug_buf)
889 | execute winnr.'wincmd w'
890 | call add(s:pos, winsaveview())
891 | else
892 | let s:pos = [winsaveview()]
893 | endif
894 |
895 | setlocal modifiable
896 | return 1
897 | endfunction
898 |
899 | function! s:switch_out(...)
900 | call winrestview(s:pos[-1])
901 | setlocal nomodifiable
902 | if a:0 > 0
903 | execute a:1
904 | endif
905 |
906 | if len(s:pos) > 1
907 | execute 'normal!' s:pos[0].'gt'
908 | execute s:pos[1] 'wincmd w'
909 | call winrestview(s:pos[2])
910 | endif
911 | endfunction
912 |
913 | function! s:finish_bindings()
914 | nnoremap R :call retry()
915 | nnoremap D :PlugDiff
916 | nnoremap S :PlugStatus
917 | nnoremap U :call status_update()
918 | xnoremap U :call status_update()
919 | nnoremap ]] :silent! call section('')
920 | nnoremap [[ :silent! call section('b')
921 | endfunction
922 |
923 | function! s:prepare(...)
924 | if empty(s:plug_getcwd())
925 | throw 'Invalid current working directory. Cannot proceed.'
926 | endif
927 |
928 | for evar in ['$GIT_DIR', '$GIT_WORK_TREE']
929 | if exists(evar)
930 | throw evar.' detected. Cannot proceed.'
931 | endif
932 | endfor
933 |
934 | call s:job_abort()
935 | if s:switch_in()
936 | if b:plug_preview == 1
937 | pc
938 | endif
939 | enew
940 | else
941 | call s:new_window()
942 | endif
943 |
944 | nnoremap q :call close_pane()
945 | if a:0 == 0
946 | call s:finish_bindings()
947 | endif
948 | let b:plug_preview = -1
949 | let s:plug_tab = tabpagenr()
950 | let s:plug_buf = winbufnr(0)
951 | call s:assign_name()
952 |
953 | for k in ['', 'L', 'o', 'X', 'd', 'dd']
954 | execute 'silent! unmap ' k
955 | endfor
956 | setlocal buftype=nofile bufhidden=wipe nobuflisted nolist noswapfile nowrap cursorline modifiable nospell
957 | if exists('+colorcolumn')
958 | setlocal colorcolumn=
959 | endif
960 | setf vim-plug
961 | if exists('g:syntax_on')
962 | call s:syntax()
963 | endif
964 | endfunction
965 |
966 | function! s:close_pane()
967 | if b:plug_preview == 1
968 | pc
969 | let b:plug_preview = -1
970 | else
971 | bd
972 | endif
973 | endfunction
974 |
975 | function! s:assign_name()
976 | " Assign buffer name
977 | let prefix = '[Plugins]'
978 | let name = prefix
979 | let idx = 2
980 | while bufexists(name)
981 | let name = printf('%s (%s)', prefix, idx)
982 | let idx = idx + 1
983 | endwhile
984 | silent! execute 'f' fnameescape(name)
985 | endfunction
986 |
987 | function! s:chsh(swap)
988 | let prev = [&shell, &shellcmdflag, &shellredir]
989 | if !s:is_win
990 | set shell=sh
991 | endif
992 | if a:swap
993 | if s:is_powershell(&shell)
994 | let &shellredir = '2>&1 | Out-File -Encoding UTF8 %s'
995 | elseif &shell =~# 'sh' || &shell =~# 'cmd\(\.exe\)\?$'
996 | set shellredir=>%s\ 2>&1
997 | endif
998 | endif
999 | return prev
1000 | endfunction
1001 |
1002 | function! s:bang(cmd, ...)
1003 | let batchfile = ''
1004 | try
1005 | let [sh, shellcmdflag, shrd] = s:chsh(a:0)
1006 | " FIXME: Escaping is incomplete. We could use shellescape with eval,
1007 | " but it won't work on Windows.
1008 | let cmd = a:0 ? s:with_cd(a:cmd, a:1) : a:cmd
1009 | if s:is_win
1010 | let [batchfile, cmd] = s:batchfile(cmd)
1011 | endif
1012 | let g:_plug_bang = (s:is_win && has('gui_running') ? 'silent ' : '').'!'.escape(cmd, '#!%')
1013 | execute "normal! :execute g:_plug_bang\\"
1014 | finally
1015 | unlet g:_plug_bang
1016 | let [&shell, &shellcmdflag, &shellredir] = [sh, shellcmdflag, shrd]
1017 | if s:is_win && filereadable(batchfile)
1018 | call delete(batchfile)
1019 | endif
1020 | endtry
1021 | return v:shell_error ? 'Exit status: ' . v:shell_error : ''
1022 | endfunction
1023 |
1024 | function! s:regress_bar()
1025 | let bar = substitute(getline(2)[1:-2], '.*\zs=', 'x', '')
1026 | call s:progress_bar(2, bar, len(bar))
1027 | endfunction
1028 |
1029 | function! s:is_updated(dir)
1030 | return !empty(s:system_chomp(['git', 'log', '--pretty=format:%h', 'HEAD...HEAD@{1}'], a:dir))
1031 | endfunction
1032 |
1033 | function! s:do(pull, force, todo)
1034 | for [name, spec] in items(a:todo)
1035 | if !isdirectory(spec.dir)
1036 | continue
1037 | endif
1038 | let installed = has_key(s:update.new, name)
1039 | let updated = installed ? 0 :
1040 | \ (a:pull && index(s:update.errors, name) < 0 && s:is_updated(spec.dir))
1041 | if a:force || installed || updated
1042 | execute 'cd' s:esc(spec.dir)
1043 | call append(3, '- Post-update hook for '. name .' ... ')
1044 | let error = ''
1045 | let type = type(spec.do)
1046 | if type == s:TYPE.string
1047 | if spec.do[0] == ':'
1048 | if !get(s:loaded, name, 0)
1049 | let s:loaded[name] = 1
1050 | call s:reorg_rtp()
1051 | endif
1052 | call s:load_plugin(spec)
1053 | try
1054 | execute spec.do[1:]
1055 | catch
1056 | let error = v:exception
1057 | endtry
1058 | if !s:plug_window_exists()
1059 | cd -
1060 | throw 'Warning: vim-plug was terminated by the post-update hook of '.name
1061 | endif
1062 | else
1063 | let error = s:bang(spec.do)
1064 | endif
1065 | elseif type == s:TYPE.funcref
1066 | try
1067 | call s:load_plugin(spec)
1068 | let status = installed ? 'installed' : (updated ? 'updated' : 'unchanged')
1069 | call spec.do({ 'name': name, 'status': status, 'force': a:force })
1070 | catch
1071 | let error = v:exception
1072 | endtry
1073 | else
1074 | let error = 'Invalid hook type'
1075 | endif
1076 | call s:switch_in()
1077 | call setline(4, empty(error) ? (getline(4) . 'OK')
1078 | \ : ('x' . getline(4)[1:] . error))
1079 | if !empty(error)
1080 | call add(s:update.errors, name)
1081 | call s:regress_bar()
1082 | endif
1083 | cd -
1084 | endif
1085 | endfor
1086 | endfunction
1087 |
1088 | function! s:hash_match(a, b)
1089 | return stridx(a:a, a:b) == 0 || stridx(a:b, a:a) == 0
1090 | endfunction
1091 |
1092 | function! s:checkout(spec)
1093 | let sha = a:spec.commit
1094 | let output = s:git_revision(a:spec.dir)
1095 | if !empty(output) && !s:hash_match(sha, s:lines(output)[0])
1096 | let credential_helper = s:git_version_requirement(2) ? '-c credential.helper= ' : ''
1097 | let output = s:system(
1098 | \ 'git '.credential_helper.'fetch --depth 999999 && git checkout '.plug#shellescape(sha).' --', a:spec.dir)
1099 | endif
1100 | return output
1101 | endfunction
1102 |
1103 | function! s:finish(pull)
1104 | let new_frozen = len(filter(keys(s:update.new), 'g:plugs[v:val].frozen'))
1105 | if new_frozen
1106 | let s = new_frozen > 1 ? 's' : ''
1107 | call append(3, printf('- Installed %d frozen plugin%s', new_frozen, s))
1108 | endif
1109 | call append(3, '- Finishing ... ') | 4
1110 | redraw
1111 | call plug#helptags()
1112 | call plug#end()
1113 | call setline(4, getline(4) . 'Done!')
1114 | redraw
1115 | let msgs = []
1116 | if !empty(s:update.errors)
1117 | call add(msgs, "Press 'R' to retry.")
1118 | endif
1119 | if a:pull && len(s:update.new) < len(filter(getline(5, '$'),
1120 | \ "v:val =~ '^- ' && v:val !~# 'Already up.to.date'"))
1121 | call add(msgs, "Press 'D' to see the updated changes.")
1122 | endif
1123 | echo join(msgs, ' ')
1124 | call s:finish_bindings()
1125 | endfunction
1126 |
1127 | function! s:retry()
1128 | if empty(s:update.errors)
1129 | return
1130 | endif
1131 | echo
1132 | call s:update_impl(s:update.pull, s:update.force,
1133 | \ extend(copy(s:update.errors), [s:update.threads]))
1134 | endfunction
1135 |
1136 | function! s:is_managed(name)
1137 | return has_key(g:plugs[a:name], 'uri')
1138 | endfunction
1139 |
1140 | function! s:names(...)
1141 | return sort(filter(keys(g:plugs), 'stridx(v:val, a:1) == 0 && s:is_managed(v:val)'))
1142 | endfunction
1143 |
1144 | function! s:check_ruby()
1145 | silent! ruby require 'thread'; VIM::command("let g:plug_ruby = '#{RUBY_VERSION}'")
1146 | if !exists('g:plug_ruby')
1147 | redraw!
1148 | return s:warn('echom', 'Warning: Ruby interface is broken')
1149 | endif
1150 | let ruby_version = split(g:plug_ruby, '\.')
1151 | unlet g:plug_ruby
1152 | return s:version_requirement(ruby_version, [1, 8, 7])
1153 | endfunction
1154 |
1155 | function! s:update_impl(pull, force, args) abort
1156 | let sync = index(a:args, '--sync') >= 0 || has('vim_starting')
1157 | let args = filter(copy(a:args), 'v:val != "--sync"')
1158 | let threads = (len(args) > 0 && args[-1] =~ '^[1-9][0-9]*$') ?
1159 | \ remove(args, -1) : get(g:, 'plug_threads', 16)
1160 |
1161 | let managed = filter(copy(g:plugs), 's:is_managed(v:key)')
1162 | let todo = empty(args) ? filter(managed, '!v:val.frozen || !isdirectory(v:val.dir)') :
1163 | \ filter(managed, 'index(args, v:key) >= 0')
1164 |
1165 | if empty(todo)
1166 | return s:warn('echo', 'No plugin to '. (a:pull ? 'update' : 'install'))
1167 | endif
1168 |
1169 | if !s:is_win && s:git_version_requirement(2, 3)
1170 | let s:git_terminal_prompt = exists('$GIT_TERMINAL_PROMPT') ? $GIT_TERMINAL_PROMPT : ''
1171 | let $GIT_TERMINAL_PROMPT = 0
1172 | for plug in values(todo)
1173 | let plug.uri = substitute(plug.uri,
1174 | \ '^https://git::@github\.com', 'https://github.com', '')
1175 | endfor
1176 | endif
1177 |
1178 | if !isdirectory(g:plug_home)
1179 | try
1180 | call mkdir(g:plug_home, 'p')
1181 | catch
1182 | return s:err(printf('Invalid plug directory: %s. '.
1183 | \ 'Try to call plug#begin with a valid directory', g:plug_home))
1184 | endtry
1185 | endif
1186 |
1187 | if has('nvim') && !exists('*jobwait') && threads > 1
1188 | call s:warn('echom', '[vim-plug] Update Neovim for parallel installer')
1189 | endif
1190 |
1191 | let use_job = s:nvim || s:vim8
1192 | let python = (has('python') || has('python3')) && !use_job
1193 | let ruby = has('ruby') && !use_job && (v:version >= 703 || v:version == 702 && has('patch374')) && !(s:is_win && has('gui_running')) && threads > 1 && s:check_ruby()
1194 |
1195 | let s:update = {
1196 | \ 'start': reltime(),
1197 | \ 'all': todo,
1198 | \ 'todo': copy(todo),
1199 | \ 'errors': [],
1200 | \ 'pull': a:pull,
1201 | \ 'force': a:force,
1202 | \ 'new': {},
1203 | \ 'threads': (python || ruby || use_job) ? min([len(todo), threads]) : 1,
1204 | \ 'bar': '',
1205 | \ 'fin': 0
1206 | \ }
1207 |
1208 | call s:prepare(1)
1209 | call append(0, ['', ''])
1210 | normal! 2G
1211 | silent! redraw
1212 |
1213 | " Set remote name, overriding a possible user git config's clone.defaultRemoteName
1214 | let s:clone_opt = ['--origin', 'origin']
1215 | if get(g:, 'plug_shallow', 1)
1216 | call extend(s:clone_opt, ['--depth', '1'])
1217 | if s:git_version_requirement(1, 7, 10)
1218 | call add(s:clone_opt, '--no-single-branch')
1219 | endif
1220 | endif
1221 |
1222 | if has('win32unix') || has('wsl')
1223 | call extend(s:clone_opt, ['-c', 'core.eol=lf', '-c', 'core.autocrlf=input'])
1224 | endif
1225 |
1226 | let s:submodule_opt = s:git_version_requirement(2, 8) ? ' --jobs='.threads : ''
1227 |
1228 | " Python version requirement (>= 2.7)
1229 | if python && !has('python3') && !ruby && !use_job && s:update.threads > 1
1230 | redir => pyv
1231 | silent python import platform; print platform.python_version()
1232 | redir END
1233 | let python = s:version_requirement(
1234 | \ map(split(split(pyv)[0], '\.'), 'str2nr(v:val)'), [2, 6])
1235 | endif
1236 |
1237 | if (python || ruby) && s:update.threads > 1
1238 | try
1239 | let imd = &imd
1240 | if s:mac_gui
1241 | set noimd
1242 | endif
1243 | if ruby
1244 | call s:update_ruby()
1245 | else
1246 | call s:update_python()
1247 | endif
1248 | catch
1249 | let lines = getline(4, '$')
1250 | let printed = {}
1251 | silent! 4,$d _
1252 | for line in lines
1253 | let name = s:extract_name(line, '.', '')
1254 | if empty(name) || !has_key(printed, name)
1255 | call append('$', line)
1256 | if !empty(name)
1257 | let printed[name] = 1
1258 | if line[0] == 'x' && index(s:update.errors, name) < 0
1259 | call add(s:update.errors, name)
1260 | end
1261 | endif
1262 | endif
1263 | endfor
1264 | finally
1265 | let &imd = imd
1266 | call s:update_finish()
1267 | endtry
1268 | else
1269 | call s:update_vim()
1270 | while use_job && sync
1271 | sleep 100m
1272 | if s:update.fin
1273 | break
1274 | endif
1275 | endwhile
1276 | endif
1277 | endfunction
1278 |
1279 | function! s:log4(name, msg)
1280 | call setline(4, printf('- %s (%s)', a:msg, a:name))
1281 | redraw
1282 | endfunction
1283 |
1284 | function! s:update_finish()
1285 | if exists('s:git_terminal_prompt')
1286 | let $GIT_TERMINAL_PROMPT = s:git_terminal_prompt
1287 | endif
1288 | if s:switch_in()
1289 | call append(3, '- Updating ...') | 4
1290 | for [name, spec] in items(filter(copy(s:update.all), 'index(s:update.errors, v:key) < 0 && (s:update.force || s:update.pull || has_key(s:update.new, v:key))'))
1291 | let [pos, _] = s:logpos(name)
1292 | if !pos
1293 | continue
1294 | endif
1295 | if has_key(spec, 'commit')
1296 | call s:log4(name, 'Checking out '.spec.commit)
1297 | let out = s:checkout(spec)
1298 | elseif has_key(spec, 'tag')
1299 | let tag = spec.tag
1300 | if tag =~ '\*'
1301 | let tags = s:lines(s:system('git tag --list '.plug#shellescape(tag).' --sort -version:refname 2>&1', spec.dir))
1302 | if !v:shell_error && !empty(tags)
1303 | let tag = tags[0]
1304 | call s:log4(name, printf('Latest tag for %s -> %s', spec.tag, tag))
1305 | call append(3, '')
1306 | endif
1307 | endif
1308 | call s:log4(name, 'Checking out '.tag)
1309 | let out = s:system('git checkout -q '.plug#shellescape(tag).' -- 2>&1', spec.dir)
1310 | else
1311 | let branch = s:git_origin_branch(spec)
1312 | call s:log4(name, 'Merging origin/'.s:esc(branch))
1313 | let out = s:system('git checkout -q '.plug#shellescape(branch).' -- 2>&1'
1314 | \. (has_key(s:update.new, name) ? '' : ('&& git merge --ff-only '.plug#shellescape('origin/'.branch).' 2>&1')), spec.dir)
1315 | endif
1316 | if !v:shell_error && filereadable(spec.dir.'/.gitmodules') &&
1317 | \ (s:update.force || has_key(s:update.new, name) || s:is_updated(spec.dir))
1318 | call s:log4(name, 'Updating submodules. This may take a while.')
1319 | let out .= s:bang('git submodule update --init --recursive'.s:submodule_opt.' 2>&1', spec.dir)
1320 | endif
1321 | let msg = s:format_message(v:shell_error ? 'x': '-', name, out)
1322 | if v:shell_error
1323 | call add(s:update.errors, name)
1324 | call s:regress_bar()
1325 | silent execute pos 'd _'
1326 | call append(4, msg) | 4
1327 | elseif !empty(out)
1328 | call setline(pos, msg[0])
1329 | endif
1330 | redraw
1331 | endfor
1332 | silent 4 d _
1333 | try
1334 | call s:do(s:update.pull, s:update.force, filter(copy(s:update.all), 'index(s:update.errors, v:key) < 0 && has_key(v:val, "do")'))
1335 | catch
1336 | call s:warn('echom', v:exception)
1337 | call s:warn('echo', '')
1338 | return
1339 | endtry
1340 | call s:finish(s:update.pull)
1341 | call setline(1, 'Updated. Elapsed time: ' . split(reltimestr(reltime(s:update.start)))[0] . ' sec.')
1342 | call s:switch_out('normal! gg')
1343 | endif
1344 | endfunction
1345 |
1346 | function! s:job_abort()
1347 | if (!s:nvim && !s:vim8) || !exists('s:jobs')
1348 | return
1349 | endif
1350 |
1351 | for [name, j] in items(s:jobs)
1352 | if s:nvim
1353 | silent! call jobstop(j.jobid)
1354 | elseif s:vim8
1355 | silent! call job_stop(j.jobid)
1356 | endif
1357 | if j.new
1358 | call s:rm_rf(g:plugs[name].dir)
1359 | endif
1360 | endfor
1361 | let s:jobs = {}
1362 | endfunction
1363 |
1364 | function! s:last_non_empty_line(lines)
1365 | let len = len(a:lines)
1366 | for idx in range(len)
1367 | let line = a:lines[len-idx-1]
1368 | if !empty(line)
1369 | return line
1370 | endif
1371 | endfor
1372 | return ''
1373 | endfunction
1374 |
1375 | function! s:job_out_cb(self, data) abort
1376 | let self = a:self
1377 | let data = remove(self.lines, -1) . a:data
1378 | let lines = map(split(data, "\n", 1), 'split(v:val, "\r", 1)[-1]')
1379 | call extend(self.lines, lines)
1380 | " To reduce the number of buffer updates
1381 | let self.tick = get(self, 'tick', -1) + 1
1382 | if !self.running || self.tick % len(s:jobs) == 0
1383 | let bullet = self.running ? (self.new ? '+' : '*') : (self.error ? 'x' : '-')
1384 | let result = self.error ? join(self.lines, "\n") : s:last_non_empty_line(self.lines)
1385 | call s:log(bullet, self.name, result)
1386 | endif
1387 | endfunction
1388 |
1389 | function! s:job_exit_cb(self, data) abort
1390 | let a:self.running = 0
1391 | let a:self.error = a:data != 0
1392 | call s:reap(a:self.name)
1393 | call s:tick()
1394 | endfunction
1395 |
1396 | function! s:job_cb(fn, job, ch, data)
1397 | if !s:plug_window_exists() " plug window closed
1398 | return s:job_abort()
1399 | endif
1400 | call call(a:fn, [a:job, a:data])
1401 | endfunction
1402 |
1403 | function! s:nvim_cb(job_id, data, event) dict abort
1404 | return (a:event == 'stdout' || a:event == 'stderr') ?
1405 | \ s:job_cb('s:job_out_cb', self, 0, join(a:data, "\n")) :
1406 | \ s:job_cb('s:job_exit_cb', self, 0, a:data)
1407 | endfunction
1408 |
1409 | function! s:spawn(name, cmd, opts)
1410 | let job = { 'name': a:name, 'running': 1, 'error': 0, 'lines': [''],
1411 | \ 'new': get(a:opts, 'new', 0) }
1412 | let s:jobs[a:name] = job
1413 |
1414 | if s:nvim
1415 | if has_key(a:opts, 'dir')
1416 | let job.cwd = a:opts.dir
1417 | endif
1418 | let argv = a:cmd
1419 | call extend(job, {
1420 | \ 'on_stdout': function('s:nvim_cb'),
1421 | \ 'on_stderr': function('s:nvim_cb'),
1422 | \ 'on_exit': function('s:nvim_cb'),
1423 | \ })
1424 | let jid = s:plug_call('jobstart', argv, job)
1425 | if jid > 0
1426 | let job.jobid = jid
1427 | else
1428 | let job.running = 0
1429 | let job.error = 1
1430 | let job.lines = [jid < 0 ? argv[0].' is not executable' :
1431 | \ 'Invalid arguments (or job table is full)']
1432 | endif
1433 | elseif s:vim8
1434 | let cmd = join(map(copy(a:cmd), 'plug#shellescape(v:val, {"script": 0})'))
1435 | if has_key(a:opts, 'dir')
1436 | let cmd = s:with_cd(cmd, a:opts.dir, 0)
1437 | endif
1438 | let argv = s:is_win ? ['cmd', '/s', '/c', '"'.cmd.'"'] : ['sh', '-c', cmd]
1439 | let jid = job_start(s:is_win ? join(argv, ' ') : argv, {
1440 | \ 'out_cb': function('s:job_cb', ['s:job_out_cb', job]),
1441 | \ 'err_cb': function('s:job_cb', ['s:job_out_cb', job]),
1442 | \ 'exit_cb': function('s:job_cb', ['s:job_exit_cb', job]),
1443 | \ 'err_mode': 'raw',
1444 | \ 'out_mode': 'raw'
1445 | \})
1446 | if job_status(jid) == 'run'
1447 | let job.jobid = jid
1448 | else
1449 | let job.running = 0
1450 | let job.error = 1
1451 | let job.lines = ['Failed to start job']
1452 | endif
1453 | else
1454 | let job.lines = s:lines(call('s:system', has_key(a:opts, 'dir') ? [a:cmd, a:opts.dir] : [a:cmd]))
1455 | let job.error = v:shell_error != 0
1456 | let job.running = 0
1457 | endif
1458 | endfunction
1459 |
1460 | function! s:reap(name)
1461 | let job = s:jobs[a:name]
1462 | if job.error
1463 | call add(s:update.errors, a:name)
1464 | elseif get(job, 'new', 0)
1465 | let s:update.new[a:name] = 1
1466 | endif
1467 | let s:update.bar .= job.error ? 'x' : '='
1468 |
1469 | let bullet = job.error ? 'x' : '-'
1470 | let result = job.error ? join(job.lines, "\n") : s:last_non_empty_line(job.lines)
1471 | call s:log(bullet, a:name, empty(result) ? 'OK' : result)
1472 | call s:bar()
1473 |
1474 | call remove(s:jobs, a:name)
1475 | endfunction
1476 |
1477 | function! s:bar()
1478 | if s:switch_in()
1479 | let total = len(s:update.all)
1480 | call setline(1, (s:update.pull ? 'Updating' : 'Installing').
1481 | \ ' plugins ('.len(s:update.bar).'/'.total.')')
1482 | call s:progress_bar(2, s:update.bar, total)
1483 | call s:switch_out()
1484 | endif
1485 | endfunction
1486 |
1487 | function! s:logpos(name)
1488 | let max = line('$')
1489 | for i in range(4, max > 4 ? max : 4)
1490 | if getline(i) =~# '^[-+x*] '.a:name.':'
1491 | for j in range(i + 1, max > 5 ? max : 5)
1492 | if getline(j) !~ '^ '
1493 | return [i, j - 1]
1494 | endif
1495 | endfor
1496 | return [i, i]
1497 | endif
1498 | endfor
1499 | return [0, 0]
1500 | endfunction
1501 |
1502 | function! s:log(bullet, name, lines)
1503 | if s:switch_in()
1504 | let [b, e] = s:logpos(a:name)
1505 | if b > 0
1506 | silent execute printf('%d,%d d _', b, e)
1507 | if b > winheight('.')
1508 | let b = 4
1509 | endif
1510 | else
1511 | let b = 4
1512 | endif
1513 | " FIXME For some reason, nomodifiable is set after :d in vim8
1514 | setlocal modifiable
1515 | call append(b - 1, s:format_message(a:bullet, a:name, a:lines))
1516 | call s:switch_out()
1517 | endif
1518 | endfunction
1519 |
1520 | function! s:update_vim()
1521 | let s:jobs = {}
1522 |
1523 | call s:bar()
1524 | call s:tick()
1525 | endfunction
1526 |
1527 | function! s:tick()
1528 | let pull = s:update.pull
1529 | let prog = s:progress_opt(s:nvim || s:vim8)
1530 | while 1 " Without TCO, Vim stack is bound to explode
1531 | if empty(s:update.todo)
1532 | if empty(s:jobs) && !s:update.fin
1533 | call s:update_finish()
1534 | let s:update.fin = 1
1535 | endif
1536 | return
1537 | endif
1538 |
1539 | let name = keys(s:update.todo)[0]
1540 | let spec = remove(s:update.todo, name)
1541 | let new = empty(globpath(spec.dir, '.git', 1))
1542 |
1543 | call s:log(new ? '+' : '*', name, pull ? 'Updating ...' : 'Installing ...')
1544 | redraw
1545 |
1546 | let has_tag = has_key(spec, 'tag')
1547 | if !new
1548 | let [error, _] = s:git_validate(spec, 0)
1549 | if empty(error)
1550 | if pull
1551 | let cmd = s:git_version_requirement(2) ? ['git', '-c', 'credential.helper=', 'fetch'] : ['git', 'fetch']
1552 | if has_tag && !empty(globpath(spec.dir, '.git/shallow'))
1553 | call extend(cmd, ['--depth', '99999999'])
1554 | endif
1555 | if !empty(prog)
1556 | call add(cmd, prog)
1557 | endif
1558 | call s:spawn(name, cmd, { 'dir': spec.dir })
1559 | else
1560 | let s:jobs[name] = { 'running': 0, 'lines': ['Already installed'], 'error': 0 }
1561 | endif
1562 | else
1563 | let s:jobs[name] = { 'running': 0, 'lines': s:lines(error), 'error': 1 }
1564 | endif
1565 | else
1566 | let cmd = ['git', 'clone']
1567 | if !has_tag
1568 | call extend(cmd, s:clone_opt)
1569 | endif
1570 | if !empty(prog)
1571 | call add(cmd, prog)
1572 | endif
1573 | call s:spawn(name, extend(cmd, [spec.uri, s:trim(spec.dir)]), { 'new': 1 })
1574 | endif
1575 |
1576 | if !s:jobs[name].running
1577 | call s:reap(name)
1578 | endif
1579 | if len(s:jobs) >= s:update.threads
1580 | break
1581 | endif
1582 | endwhile
1583 | endfunction
1584 |
1585 | function! s:update_python()
1586 | let py_exe = has('python') ? 'python' : 'python3'
1587 | execute py_exe "<< EOF"
1588 | import datetime
1589 | import functools
1590 | import os
1591 | try:
1592 | import queue
1593 | except ImportError:
1594 | import Queue as queue
1595 | import random
1596 | import re
1597 | import shutil
1598 | import signal
1599 | import subprocess
1600 | import tempfile
1601 | import threading as thr
1602 | import time
1603 | import traceback
1604 | import vim
1605 |
1606 | G_NVIM = vim.eval("has('nvim')") == '1'
1607 | G_PULL = vim.eval('s:update.pull') == '1'
1608 | G_RETRIES = int(vim.eval('get(g:, "plug_retries", 2)')) + 1
1609 | G_TIMEOUT = int(vim.eval('get(g:, "plug_timeout", 60)'))
1610 | G_CLONE_OPT = ' '.join(vim.eval('s:clone_opt'))
1611 | G_PROGRESS = vim.eval('s:progress_opt(1)')
1612 | G_LOG_PROB = 1.0 / int(vim.eval('s:update.threads'))
1613 | G_STOP = thr.Event()
1614 | G_IS_WIN = vim.eval('s:is_win') == '1'
1615 |
1616 | class PlugError(Exception):
1617 | def __init__(self, msg):
1618 | self.msg = msg
1619 | class CmdTimedOut(PlugError):
1620 | pass
1621 | class CmdFailed(PlugError):
1622 | pass
1623 | class InvalidURI(PlugError):
1624 | pass
1625 | class Action(object):
1626 | INSTALL, UPDATE, ERROR, DONE = ['+', '*', 'x', '-']
1627 |
1628 | class Buffer(object):
1629 | def __init__(self, lock, num_plugs, is_pull):
1630 | self.bar = ''
1631 | self.event = 'Updating' if is_pull else 'Installing'
1632 | self.lock = lock
1633 | self.maxy = int(vim.eval('winheight(".")'))
1634 | self.num_plugs = num_plugs
1635 |
1636 | def __where(self, name):
1637 | """ Find first line with name in current buffer. Return line num. """
1638 | found, lnum = False, 0
1639 | matcher = re.compile('^[-+x*] {0}:'.format(name))
1640 | for line in vim.current.buffer:
1641 | if matcher.search(line) is not None:
1642 | found = True
1643 | break
1644 | lnum += 1
1645 |
1646 | if not found:
1647 | lnum = -1
1648 | return lnum
1649 |
1650 | def header(self):
1651 | curbuf = vim.current.buffer
1652 | curbuf[0] = self.event + ' plugins ({0}/{1})'.format(len(self.bar), self.num_plugs)
1653 |
1654 | num_spaces = self.num_plugs - len(self.bar)
1655 | curbuf[1] = '[{0}{1}]'.format(self.bar, num_spaces * ' ')
1656 |
1657 | with self.lock:
1658 | vim.command('normal! 2G')
1659 | vim.command('redraw')
1660 |
1661 | def write(self, action, name, lines):
1662 | first, rest = lines[0], lines[1:]
1663 | msg = ['{0} {1}{2}{3}'.format(action, name, ': ' if first else '', first)]
1664 | msg.extend([' ' + line for line in rest])
1665 |
1666 | try:
1667 | if action == Action.ERROR:
1668 | self.bar += 'x'
1669 | vim.command("call add(s:update.errors, '{0}')".format(name))
1670 | elif action == Action.DONE:
1671 | self.bar += '='
1672 |
1673 | curbuf = vim.current.buffer
1674 | lnum = self.__where(name)
1675 | if lnum != -1: # Found matching line num
1676 | del curbuf[lnum]
1677 | if lnum > self.maxy and action in set([Action.INSTALL, Action.UPDATE]):
1678 | lnum = 3
1679 | else:
1680 | lnum = 3
1681 | curbuf.append(msg, lnum)
1682 |
1683 | self.header()
1684 | except vim.error:
1685 | pass
1686 |
1687 | class Command(object):
1688 | CD = 'cd /d' if G_IS_WIN else 'cd'
1689 |
1690 | def __init__(self, cmd, cmd_dir=None, timeout=60, cb=None, clean=None):
1691 | self.cmd = cmd
1692 | if cmd_dir:
1693 | self.cmd = '{0} {1} && {2}'.format(Command.CD, cmd_dir, self.cmd)
1694 | self.timeout = timeout
1695 | self.callback = cb if cb else (lambda msg: None)
1696 | self.clean = clean if clean else (lambda: None)
1697 | self.proc = None
1698 |
1699 | @property
1700 | def alive(self):
1701 | """ Returns true only if command still running. """
1702 | return self.proc and self.proc.poll() is None
1703 |
1704 | def execute(self, ntries=3):
1705 | """ Execute the command with ntries if CmdTimedOut.
1706 | Returns the output of the command if no Exception.
1707 | """
1708 | attempt, finished, limit = 0, False, self.timeout
1709 |
1710 | while not finished:
1711 | try:
1712 | attempt += 1
1713 | result = self.try_command()
1714 | finished = True
1715 | return result
1716 | except CmdTimedOut:
1717 | if attempt != ntries:
1718 | self.notify_retry()
1719 | self.timeout += limit
1720 | else:
1721 | raise
1722 |
1723 | def notify_retry(self):
1724 | """ Retry required for command, notify user. """
1725 | for count in range(3, 0, -1):
1726 | if G_STOP.is_set():
1727 | raise KeyboardInterrupt
1728 | msg = 'Timeout. Will retry in {0} second{1} ...'.format(
1729 | count, 's' if count != 1 else '')
1730 | self.callback([msg])
1731 | time.sleep(1)
1732 | self.callback(['Retrying ...'])
1733 |
1734 | def try_command(self):
1735 | """ Execute a cmd & poll for callback. Returns list of output.
1736 | Raises CmdFailed -> return code for Popen isn't 0
1737 | Raises CmdTimedOut -> command exceeded timeout without new output
1738 | """
1739 | first_line = True
1740 |
1741 | try:
1742 | tfile = tempfile.NamedTemporaryFile(mode='w+b')
1743 | preexec_fn = not G_IS_WIN and os.setsid or None
1744 | self.proc = subprocess.Popen(self.cmd, stdout=tfile,
1745 | stderr=subprocess.STDOUT,
1746 | stdin=subprocess.PIPE, shell=True,
1747 | preexec_fn=preexec_fn)
1748 | thrd = thr.Thread(target=(lambda proc: proc.wait()), args=(self.proc,))
1749 | thrd.start()
1750 |
1751 | thread_not_started = True
1752 | while thread_not_started:
1753 | try:
1754 | thrd.join(0.1)
1755 | thread_not_started = False
1756 | except RuntimeError:
1757 | pass
1758 |
1759 | while self.alive:
1760 | if G_STOP.is_set():
1761 | raise KeyboardInterrupt
1762 |
1763 | if first_line or random.random() < G_LOG_PROB:
1764 | first_line = False
1765 | line = '' if G_IS_WIN else nonblock_read(tfile.name)
1766 | if line:
1767 | self.callback([line])
1768 |
1769 | time_diff = time.time() - os.path.getmtime(tfile.name)
1770 | if time_diff > self.timeout:
1771 | raise CmdTimedOut(['Timeout!'])
1772 |
1773 | thrd.join(0.5)
1774 |
1775 | tfile.seek(0)
1776 | result = [line.decode('utf-8', 'replace').rstrip() for line in tfile]
1777 |
1778 | if self.proc.returncode != 0:
1779 | raise CmdFailed([''] + result)
1780 |
1781 | return result
1782 | except:
1783 | self.terminate()
1784 | raise
1785 |
1786 | def terminate(self):
1787 | """ Terminate process and cleanup. """
1788 | if self.alive:
1789 | if G_IS_WIN:
1790 | os.kill(self.proc.pid, signal.SIGINT)
1791 | else:
1792 | os.killpg(self.proc.pid, signal.SIGTERM)
1793 | self.clean()
1794 |
1795 | class Plugin(object):
1796 | def __init__(self, name, args, buf_q, lock):
1797 | self.name = name
1798 | self.args = args
1799 | self.buf_q = buf_q
1800 | self.lock = lock
1801 | self.tag = args.get('tag', 0)
1802 |
1803 | def manage(self):
1804 | try:
1805 | if os.path.exists(self.args['dir']):
1806 | self.update()
1807 | else:
1808 | self.install()
1809 | with self.lock:
1810 | thread_vim_command("let s:update.new['{0}'] = 1".format(self.name))
1811 | except PlugError as exc:
1812 | self.write(Action.ERROR, self.name, exc.msg)
1813 | except KeyboardInterrupt:
1814 | G_STOP.set()
1815 | self.write(Action.ERROR, self.name, ['Interrupted!'])
1816 | except:
1817 | # Any exception except those above print stack trace
1818 | msg = 'Trace:\n{0}'.format(traceback.format_exc().rstrip())
1819 | self.write(Action.ERROR, self.name, msg.split('\n'))
1820 | raise
1821 |
1822 | def install(self):
1823 | target = self.args['dir']
1824 | if target[-1] == '\\':
1825 | target = target[0:-1]
1826 |
1827 | def clean(target):
1828 | def _clean():
1829 | try:
1830 | shutil.rmtree(target)
1831 | except OSError:
1832 | pass
1833 | return _clean
1834 |
1835 | self.write(Action.INSTALL, self.name, ['Installing ...'])
1836 | callback = functools.partial(self.write, Action.INSTALL, self.name)
1837 | cmd = 'git clone {0} {1} {2} {3} 2>&1'.format(
1838 | '' if self.tag else G_CLONE_OPT, G_PROGRESS, self.args['uri'],
1839 | esc(target))
1840 | com = Command(cmd, None, G_TIMEOUT, callback, clean(target))
1841 | result = com.execute(G_RETRIES)
1842 | self.write(Action.DONE, self.name, result[-1:])
1843 |
1844 | def repo_uri(self):
1845 | cmd = 'git rev-parse --abbrev-ref HEAD 2>&1 && git config -f .git/config remote.origin.url'
1846 | command = Command(cmd, self.args['dir'], G_TIMEOUT,)
1847 | result = command.execute(G_RETRIES)
1848 | return result[-1]
1849 |
1850 | def update(self):
1851 | actual_uri = self.repo_uri()
1852 | expect_uri = self.args['uri']
1853 | regex = re.compile(r'^(?:\w+://)?(?:[^@/]*@)?([^:/]*(?::[0-9]*)?)[:/](.*?)(?:\.git)?/?$')
1854 | ma = regex.match(actual_uri)
1855 | mb = regex.match(expect_uri)
1856 | if ma is None or mb is None or ma.groups() != mb.groups():
1857 | msg = ['',
1858 | 'Invalid URI: {0}'.format(actual_uri),
1859 | 'Expected {0}'.format(expect_uri),
1860 | 'PlugClean required.']
1861 | raise InvalidURI(msg)
1862 |
1863 | if G_PULL:
1864 | self.write(Action.UPDATE, self.name, ['Updating ...'])
1865 | callback = functools.partial(self.write, Action.UPDATE, self.name)
1866 | fetch_opt = '--depth 99999999' if self.tag and os.path.isfile(os.path.join(self.args['dir'], '.git/shallow')) else ''
1867 | cmd = 'git fetch {0} {1} 2>&1'.format(fetch_opt, G_PROGRESS)
1868 | com = Command(cmd, self.args['dir'], G_TIMEOUT, callback)
1869 | result = com.execute(G_RETRIES)
1870 | self.write(Action.DONE, self.name, result[-1:])
1871 | else:
1872 | self.write(Action.DONE, self.name, ['Already installed'])
1873 |
1874 | def write(self, action, name, msg):
1875 | self.buf_q.put((action, name, msg))
1876 |
1877 | class PlugThread(thr.Thread):
1878 | def __init__(self, tname, args):
1879 | super(PlugThread, self).__init__()
1880 | self.tname = tname
1881 | self.args = args
1882 |
1883 | def run(self):
1884 | thr.current_thread().name = self.tname
1885 | buf_q, work_q, lock = self.args
1886 |
1887 | try:
1888 | while not G_STOP.is_set():
1889 | name, args = work_q.get_nowait()
1890 | plug = Plugin(name, args, buf_q, lock)
1891 | plug.manage()
1892 | work_q.task_done()
1893 | except queue.Empty:
1894 | pass
1895 |
1896 | class RefreshThread(thr.Thread):
1897 | def __init__(self, lock):
1898 | super(RefreshThread, self).__init__()
1899 | self.lock = lock
1900 | self.running = True
1901 |
1902 | def run(self):
1903 | while self.running:
1904 | with self.lock:
1905 | thread_vim_command('noautocmd normal! a')
1906 | time.sleep(0.33)
1907 |
1908 | def stop(self):
1909 | self.running = False
1910 |
1911 | if G_NVIM:
1912 | def thread_vim_command(cmd):
1913 | vim.session.threadsafe_call(lambda: vim.command(cmd))
1914 | else:
1915 | def thread_vim_command(cmd):
1916 | vim.command(cmd)
1917 |
1918 | def esc(name):
1919 | return '"' + name.replace('"', '\"') + '"'
1920 |
1921 | def nonblock_read(fname):
1922 | """ Read a file with nonblock flag. Return the last line. """
1923 | fread = os.open(fname, os.O_RDONLY | os.O_NONBLOCK)
1924 | buf = os.read(fread, 100000).decode('utf-8', 'replace')
1925 | os.close(fread)
1926 |
1927 | line = buf.rstrip('\r\n')
1928 | left = max(line.rfind('\r'), line.rfind('\n'))
1929 | if left != -1:
1930 | left += 1
1931 | line = line[left:]
1932 |
1933 | return line
1934 |
1935 | def main():
1936 | thr.current_thread().name = 'main'
1937 | nthreads = int(vim.eval('s:update.threads'))
1938 | plugs = vim.eval('s:update.todo')
1939 | mac_gui = vim.eval('s:mac_gui') == '1'
1940 |
1941 | lock = thr.Lock()
1942 | buf = Buffer(lock, len(plugs), G_PULL)
1943 | buf_q, work_q = queue.Queue(), queue.Queue()
1944 | for work in plugs.items():
1945 | work_q.put(work)
1946 |
1947 | start_cnt = thr.active_count()
1948 | for num in range(nthreads):
1949 | tname = 'PlugT-{0:02}'.format(num)
1950 | thread = PlugThread(tname, (buf_q, work_q, lock))
1951 | thread.start()
1952 | if mac_gui:
1953 | rthread = RefreshThread(lock)
1954 | rthread.start()
1955 |
1956 | while not buf_q.empty() or thr.active_count() != start_cnt:
1957 | try:
1958 | action, name, msg = buf_q.get(True, 0.25)
1959 | buf.write(action, name, ['OK'] if not msg else msg)
1960 | buf_q.task_done()
1961 | except queue.Empty:
1962 | pass
1963 | except KeyboardInterrupt:
1964 | G_STOP.set()
1965 |
1966 | if mac_gui:
1967 | rthread.stop()
1968 | rthread.join()
1969 |
1970 | main()
1971 | EOF
1972 | endfunction
1973 |
1974 | function! s:update_ruby()
1975 | ruby << EOF
1976 | module PlugStream
1977 | SEP = ["\r", "\n", nil]
1978 | def get_line
1979 | buffer = ''
1980 | loop do
1981 | char = readchar rescue return
1982 | if SEP.include? char.chr
1983 | buffer << $/
1984 | break
1985 | else
1986 | buffer << char
1987 | end
1988 | end
1989 | buffer
1990 | end
1991 | end unless defined?(PlugStream)
1992 |
1993 | def esc arg
1994 | %["#{arg.gsub('"', '\"')}"]
1995 | end
1996 |
1997 | def killall pid
1998 | pids = [pid]
1999 | if /mswin|mingw|bccwin/ =~ RUBY_PLATFORM
2000 | pids.each { |pid| Process.kill 'INT', pid.to_i rescue nil }
2001 | else
2002 | unless `which pgrep 2> /dev/null`.empty?
2003 | children = pids
2004 | until children.empty?
2005 | children = children.map { |pid|
2006 | `pgrep -P #{pid}`.lines.map { |l| l.chomp }
2007 | }.flatten
2008 | pids += children
2009 | end
2010 | end
2011 | pids.each { |pid| Process.kill 'TERM', pid.to_i rescue nil }
2012 | end
2013 | end
2014 |
2015 | def compare_git_uri a, b
2016 | regex = %r{^(?:\w+://)?(?:[^@/]*@)?([^:/]*(?::[0-9]*)?)[:/](.*?)(?:\.git)?/?$}
2017 | regex.match(a).to_a.drop(1) == regex.match(b).to_a.drop(1)
2018 | end
2019 |
2020 | require 'thread'
2021 | require 'fileutils'
2022 | require 'timeout'
2023 | running = true
2024 | iswin = VIM::evaluate('s:is_win').to_i == 1
2025 | pull = VIM::evaluate('s:update.pull').to_i == 1
2026 | base = VIM::evaluate('g:plug_home')
2027 | all = VIM::evaluate('s:update.todo')
2028 | limit = VIM::evaluate('get(g:, "plug_timeout", 60)')
2029 | tries = VIM::evaluate('get(g:, "plug_retries", 2)') + 1
2030 | nthr = VIM::evaluate('s:update.threads').to_i
2031 | maxy = VIM::evaluate('winheight(".")').to_i
2032 | vim7 = VIM::evaluate('v:version').to_i <= 703 && RUBY_PLATFORM =~ /darwin/
2033 | cd = iswin ? 'cd /d' : 'cd'
2034 | tot = VIM::evaluate('len(s:update.todo)') || 0
2035 | bar = ''
2036 | skip = 'Already installed'
2037 | mtx = Mutex.new
2038 | take1 = proc { mtx.synchronize { running && all.shift } }
2039 | logh = proc {
2040 | cnt = bar.length
2041 | $curbuf[1] = "#{pull ? 'Updating' : 'Installing'} plugins (#{cnt}/#{tot})"
2042 | $curbuf[2] = '[' + bar.ljust(tot) + ']'
2043 | VIM::command('normal! 2G')
2044 | VIM::command('redraw')
2045 | }
2046 | where = proc { |name| (1..($curbuf.length)).find { |l| $curbuf[l] =~ /^[-+x*] #{name}:/ } }
2047 | log = proc { |name, result, type|
2048 | mtx.synchronize do
2049 | ing = ![true, false].include?(type)
2050 | bar += type ? '=' : 'x' unless ing
2051 | b = case type
2052 | when :install then '+' when :update then '*'
2053 | when true, nil then '-' else
2054 | VIM::command("call add(s:update.errors, '#{name}')")
2055 | 'x'
2056 | end
2057 | result =
2058 | if type || type.nil?
2059 | ["#{b} #{name}: #{result.lines.to_a.last || 'OK'}"]
2060 | elsif result =~ /^Interrupted|^Timeout/
2061 | ["#{b} #{name}: #{result}"]
2062 | else
2063 | ["#{b} #{name}"] + result.lines.map { |l| " " << l }
2064 | end
2065 | if lnum = where.call(name)
2066 | $curbuf.delete lnum
2067 | lnum = 4 if ing && lnum > maxy
2068 | end
2069 | result.each_with_index do |line, offset|
2070 | $curbuf.append((lnum || 4) - 1 + offset, line.gsub(/\e\[./, '').chomp)
2071 | end
2072 | logh.call
2073 | end
2074 | }
2075 | bt = proc { |cmd, name, type, cleanup|
2076 | tried = timeout = 0
2077 | begin
2078 | tried += 1
2079 | timeout += limit
2080 | fd = nil
2081 | data = ''
2082 | if iswin
2083 | Timeout::timeout(timeout) do
2084 | tmp = VIM::evaluate('tempname()')
2085 | system("(#{cmd}) > #{tmp}")
2086 | data = File.read(tmp).chomp
2087 | File.unlink tmp rescue nil
2088 | end
2089 | else
2090 | fd = IO.popen(cmd).extend(PlugStream)
2091 | first_line = true
2092 | log_prob = 1.0 / nthr
2093 | while line = Timeout::timeout(timeout) { fd.get_line }
2094 | data << line
2095 | log.call name, line.chomp, type if name && (first_line || rand < log_prob)
2096 | first_line = false
2097 | end
2098 | fd.close
2099 | end
2100 | [$? == 0, data.chomp]
2101 | rescue Timeout::Error, Interrupt => e
2102 | if fd && !fd.closed?
2103 | killall fd.pid
2104 | fd.close
2105 | end
2106 | cleanup.call if cleanup
2107 | if e.is_a?(Timeout::Error) && tried < tries
2108 | 3.downto(1) do |countdown|
2109 | s = countdown > 1 ? 's' : ''
2110 | log.call name, "Timeout. Will retry in #{countdown} second#{s} ...", type
2111 | sleep 1
2112 | end
2113 | log.call name, 'Retrying ...', type
2114 | retry
2115 | end
2116 | [false, e.is_a?(Interrupt) ? "Interrupted!" : "Timeout!"]
2117 | end
2118 | }
2119 | main = Thread.current
2120 | threads = []
2121 | watcher = Thread.new {
2122 | if vim7
2123 | while VIM::evaluate('getchar(1)')
2124 | sleep 0.1
2125 | end
2126 | else
2127 | require 'io/console' # >= Ruby 1.9
2128 | nil until IO.console.getch == 3.chr
2129 | end
2130 | mtx.synchronize do
2131 | running = false
2132 | threads.each { |t| t.raise Interrupt } unless vim7
2133 | end
2134 | threads.each { |t| t.join rescue nil }
2135 | main.kill
2136 | }
2137 | refresh = Thread.new {
2138 | while true
2139 | mtx.synchronize do
2140 | break unless running
2141 | VIM::command('noautocmd normal! a')
2142 | end
2143 | sleep 0.2
2144 | end
2145 | } if VIM::evaluate('s:mac_gui') == 1
2146 |
2147 | clone_opt = VIM::evaluate('s:clone_opt').join(' ')
2148 | progress = VIM::evaluate('s:progress_opt(1)')
2149 | nthr.times do
2150 | mtx.synchronize do
2151 | threads << Thread.new {
2152 | while pair = take1.call
2153 | name = pair.first
2154 | dir, uri, tag = pair.last.values_at *%w[dir uri tag]
2155 | exists = File.directory? dir
2156 | ok, result =
2157 | if exists
2158 | chdir = "#{cd} #{iswin ? dir : esc(dir)}"
2159 | ret, data = bt.call "#{chdir} && git rev-parse --abbrev-ref HEAD 2>&1 && git config -f .git/config remote.origin.url", nil, nil, nil
2160 | current_uri = data.lines.to_a.last
2161 | if !ret
2162 | if data =~ /^Interrupted|^Timeout/
2163 | [false, data]
2164 | else
2165 | [false, [data.chomp, "PlugClean required."].join($/)]
2166 | end
2167 | elsif !compare_git_uri(current_uri, uri)
2168 | [false, ["Invalid URI: #{current_uri}",
2169 | "Expected: #{uri}",
2170 | "PlugClean required."].join($/)]
2171 | else
2172 | if pull
2173 | log.call name, 'Updating ...', :update
2174 | fetch_opt = (tag && File.exist?(File.join(dir, '.git/shallow'))) ? '--depth 99999999' : ''
2175 | bt.call "#{chdir} && git fetch #{fetch_opt} #{progress} 2>&1", name, :update, nil
2176 | else
2177 | [true, skip]
2178 | end
2179 | end
2180 | else
2181 | d = esc dir.sub(%r{[\\/]+$}, '')
2182 | log.call name, 'Installing ...', :install
2183 | bt.call "git clone #{clone_opt unless tag} #{progress} #{uri} #{d} 2>&1", name, :install, proc {
2184 | FileUtils.rm_rf dir
2185 | }
2186 | end
2187 | mtx.synchronize { VIM::command("let s:update.new['#{name}'] = 1") } if !exists && ok
2188 | log.call name, result, ok
2189 | end
2190 | } if running
2191 | end
2192 | end
2193 | threads.each { |t| t.join rescue nil }
2194 | logh.call
2195 | refresh.kill if refresh
2196 | watcher.kill
2197 | EOF
2198 | endfunction
2199 |
2200 | function! s:shellesc_cmd(arg, script)
2201 | let escaped = substitute('"'.a:arg.'"', '[&|<>()@^!"]', '^&', 'g')
2202 | return substitute(escaped, '%', (a:script ? '%' : '^') . '&', 'g')
2203 | endfunction
2204 |
2205 | function! s:shellesc_ps1(arg)
2206 | return "'".substitute(escape(a:arg, '\"'), "'", "''", 'g')."'"
2207 | endfunction
2208 |
2209 | function! s:shellesc_sh(arg)
2210 | return "'".substitute(a:arg, "'", "'\\\\''", 'g')."'"
2211 | endfunction
2212 |
2213 | " Escape the shell argument based on the shell.
2214 | " Vim and Neovim's shellescape() are insufficient.
2215 | " 1. shellslash determines whether to use single/double quotes.
2216 | " Double-quote escaping is fragile for cmd.exe.
2217 | " 2. It does not work for powershell.
2218 | " 3. It does not work for *sh shells if the command is executed
2219 | " via cmd.exe (ie. cmd.exe /c sh -c command command_args)
2220 | " 4. It does not support batchfile syntax.
2221 | "
2222 | " Accepts an optional dictionary with the following keys:
2223 | " - shell: same as Vim/Neovim 'shell' option.
2224 | " If unset, fallback to 'cmd.exe' on Windows or 'sh'.
2225 | " - script: If truthy and shell is cmd.exe, escape for batchfile syntax.
2226 | function! plug#shellescape(arg, ...)
2227 | if a:arg =~# '^[A-Za-z0-9_/:.-]\+$'
2228 | return a:arg
2229 | endif
2230 | let opts = a:0 > 0 && type(a:1) == s:TYPE.dict ? a:1 : {}
2231 | let shell = get(opts, 'shell', s:is_win ? 'cmd.exe' : 'sh')
2232 | let script = get(opts, 'script', 1)
2233 | if shell =~# 'cmd\(\.exe\)\?$'
2234 | return s:shellesc_cmd(a:arg, script)
2235 | elseif s:is_powershell(shell)
2236 | return s:shellesc_ps1(a:arg)
2237 | endif
2238 | return s:shellesc_sh(a:arg)
2239 | endfunction
2240 |
2241 | function! s:glob_dir(path)
2242 | return map(filter(s:glob(a:path, '**'), 'isdirectory(v:val)'), 's:dirpath(v:val)')
2243 | endfunction
2244 |
2245 | function! s:progress_bar(line, bar, total)
2246 | call setline(a:line, '[' . s:lpad(a:bar, a:total) . ']')
2247 | endfunction
2248 |
2249 | function! s:compare_git_uri(a, b)
2250 | " See `git help clone'
2251 | " https:// [user@] github.com[:port] / junegunn/vim-plug [.git]
2252 | " [git@] github.com[:port] : junegunn/vim-plug [.git]
2253 | " file:// / junegunn/vim-plug [/]
2254 | " / junegunn/vim-plug [/]
2255 | let pat = '^\%(\w\+://\)\='.'\%([^@/]*@\)\='.'\([^:/]*\%(:[0-9]*\)\=\)'.'[:/]'.'\(.\{-}\)'.'\%(\.git\)\=/\?$'
2256 | let ma = matchlist(a:a, pat)
2257 | let mb = matchlist(a:b, pat)
2258 | return ma[1:2] ==# mb[1:2]
2259 | endfunction
2260 |
2261 | function! s:format_message(bullet, name, message)
2262 | if a:bullet != 'x'
2263 | return [printf('%s %s: %s', a:bullet, a:name, s:lastline(a:message))]
2264 | else
2265 | let lines = map(s:lines(a:message), '" ".v:val')
2266 | return extend([printf('x %s:', a:name)], lines)
2267 | endif
2268 | endfunction
2269 |
2270 | function! s:with_cd(cmd, dir, ...)
2271 | let script = a:0 > 0 ? a:1 : 1
2272 | return printf('cd%s %s && %s', s:is_win ? ' /d' : '', plug#shellescape(a:dir, {'script': script}), a:cmd)
2273 | endfunction
2274 |
2275 | function! s:system(cmd, ...)
2276 | let batchfile = ''
2277 | try
2278 | let [sh, shellcmdflag, shrd] = s:chsh(1)
2279 | if type(a:cmd) == s:TYPE.list
2280 | " Neovim's system() supports list argument to bypass the shell
2281 | " but it cannot set the working directory for the command.
2282 | " Assume that the command does not rely on the shell.
2283 | if has('nvim') && a:0 == 0
2284 | return system(a:cmd)
2285 | endif
2286 | let cmd = join(map(copy(a:cmd), 'plug#shellescape(v:val, {"shell": &shell, "script": 0})'))
2287 | if s:is_powershell(&shell)
2288 | let cmd = '& ' . cmd
2289 | endif
2290 | else
2291 | let cmd = a:cmd
2292 | endif
2293 | if a:0 > 0
2294 | let cmd = s:with_cd(cmd, a:1, type(a:cmd) != s:TYPE.list)
2295 | endif
2296 | if s:is_win && type(a:cmd) != s:TYPE.list
2297 | let [batchfile, cmd] = s:batchfile(cmd)
2298 | endif
2299 | return system(cmd)
2300 | finally
2301 | let [&shell, &shellcmdflag, &shellredir] = [sh, shellcmdflag, shrd]
2302 | if s:is_win && filereadable(batchfile)
2303 | call delete(batchfile)
2304 | endif
2305 | endtry
2306 | endfunction
2307 |
2308 | function! s:system_chomp(...)
2309 | let ret = call('s:system', a:000)
2310 | return v:shell_error ? '' : substitute(ret, '\n$', '', '')
2311 | endfunction
2312 |
2313 | function! s:git_validate(spec, check_branch)
2314 | let err = ''
2315 | if isdirectory(a:spec.dir)
2316 | let result = [s:git_local_branch(a:spec.dir), s:git_origin_url(a:spec.dir)]
2317 | let remote = result[-1]
2318 | if empty(remote)
2319 | let err = join([remote, 'PlugClean required.'], "\n")
2320 | elseif !s:compare_git_uri(remote, a:spec.uri)
2321 | let err = join(['Invalid URI: '.remote,
2322 | \ 'Expected: '.a:spec.uri,
2323 | \ 'PlugClean required.'], "\n")
2324 | elseif a:check_branch && has_key(a:spec, 'commit')
2325 | let sha = s:git_revision(a:spec.dir)
2326 | if empty(sha)
2327 | let err = join(add(result, 'PlugClean required.'), "\n")
2328 | elseif !s:hash_match(sha, a:spec.commit)
2329 | let err = join([printf('Invalid HEAD (expected: %s, actual: %s)',
2330 | \ a:spec.commit[:6], sha[:6]),
2331 | \ 'PlugUpdate required.'], "\n")
2332 | endif
2333 | elseif a:check_branch
2334 | let current_branch = result[0]
2335 | " Check tag
2336 | let origin_branch = s:git_origin_branch(a:spec)
2337 | if has_key(a:spec, 'tag')
2338 | let tag = s:system_chomp('git describe --exact-match --tags HEAD 2>&1', a:spec.dir)
2339 | if a:spec.tag !=# tag && a:spec.tag !~ '\*'
2340 | let err = printf('Invalid tag: %s (expected: %s). Try PlugUpdate.',
2341 | \ (empty(tag) ? 'N/A' : tag), a:spec.tag)
2342 | endif
2343 | " Check branch
2344 | elseif origin_branch !=# current_branch
2345 | let err = printf('Invalid branch: %s (expected: %s). Try PlugUpdate.',
2346 | \ current_branch, origin_branch)
2347 | endif
2348 | if empty(err)
2349 | let [ahead, behind] = split(s:lastline(s:system([
2350 | \ 'git', 'rev-list', '--count', '--left-right',
2351 | \ printf('HEAD...origin/%s', origin_branch)
2352 | \ ], a:spec.dir)), '\t')
2353 | if !v:shell_error && ahead
2354 | if behind
2355 | " Only mention PlugClean if diverged, otherwise it's likely to be
2356 | " pushable (and probably not that messed up).
2357 | let err = printf(
2358 | \ "Diverged from origin/%s (%d commit(s) ahead and %d commit(s) behind!\n"
2359 | \ .'Backup local changes and run PlugClean and PlugUpdate to reinstall it.', origin_branch, ahead, behind)
2360 | else
2361 | let err = printf("Ahead of origin/%s by %d commit(s).\n"
2362 | \ .'Cannot update until local changes are pushed.',
2363 | \ origin_branch, ahead)
2364 | endif
2365 | endif
2366 | endif
2367 | endif
2368 | else
2369 | let err = 'Not found'
2370 | endif
2371 | return [err, err =~# 'PlugClean']
2372 | endfunction
2373 |
2374 | function! s:rm_rf(dir)
2375 | if isdirectory(a:dir)
2376 | return s:system(s:is_win
2377 | \ ? 'rmdir /S /Q '.plug#shellescape(a:dir)
2378 | \ : ['rm', '-rf', a:dir])
2379 | endif
2380 | endfunction
2381 |
2382 | function! s:clean(force)
2383 | call s:prepare()
2384 | call append(0, 'Searching for invalid plugins in '.g:plug_home)
2385 | call append(1, '')
2386 |
2387 | " List of valid directories
2388 | let dirs = []
2389 | let errs = {}
2390 | let [cnt, total] = [0, len(g:plugs)]
2391 | for [name, spec] in items(g:plugs)
2392 | if !s:is_managed(name)
2393 | call add(dirs, spec.dir)
2394 | else
2395 | let [err, clean] = s:git_validate(spec, 1)
2396 | if clean
2397 | let errs[spec.dir] = s:lines(err)[0]
2398 | else
2399 | call add(dirs, spec.dir)
2400 | endif
2401 | endif
2402 | let cnt += 1
2403 | call s:progress_bar(2, repeat('=', cnt), total)
2404 | normal! 2G
2405 | redraw
2406 | endfor
2407 |
2408 | let allowed = {}
2409 | for dir in dirs
2410 | let allowed[s:dirpath(s:plug_fnamemodify(dir, ':h:h'))] = 1
2411 | let allowed[dir] = 1
2412 | for child in s:glob_dir(dir)
2413 | let allowed[child] = 1
2414 | endfor
2415 | endfor
2416 |
2417 | let todo = []
2418 | let found = sort(s:glob_dir(g:plug_home))
2419 | while !empty(found)
2420 | let f = remove(found, 0)
2421 | if !has_key(allowed, f) && isdirectory(f)
2422 | call add(todo, f)
2423 | call append(line('$'), '- ' . f)
2424 | if has_key(errs, f)
2425 | call append(line('$'), ' ' . errs[f])
2426 | endif
2427 | let found = filter(found, 'stridx(v:val, f) != 0')
2428 | end
2429 | endwhile
2430 |
2431 | 4
2432 | redraw
2433 | if empty(todo)
2434 | call append(line('$'), 'Already clean.')
2435 | else
2436 | let s:clean_count = 0
2437 | call append(3, ['Directories to delete:', ''])
2438 | redraw!
2439 | if a:force || s:ask_no_interrupt('Delete all directories?')
2440 | call s:delete([6, line('$')], 1)
2441 | else
2442 | call setline(4, 'Cancelled.')
2443 | nnoremap d :set opfunc=delete_opg@
2444 | nmap dd d_
2445 | xnoremap d :call delete_op(visualmode(), 1)
2446 | echo 'Delete the lines (d{motion}) to delete the corresponding directories'
2447 | endif
2448 | endif
2449 | 4
2450 | setlocal nomodifiable
2451 | endfunction
2452 |
2453 | function! s:delete_op(type, ...)
2454 | call s:delete(a:0 ? [line("'<"), line("'>")] : [line("'["), line("']")], 0)
2455 | endfunction
2456 |
2457 | function! s:delete(range, force)
2458 | let [l1, l2] = a:range
2459 | let force = a:force
2460 | let err_count = 0
2461 | while l1 <= l2
2462 | let line = getline(l1)
2463 | if line =~ '^- ' && isdirectory(line[2:])
2464 | execute l1
2465 | redraw!
2466 | let answer = force ? 1 : s:ask('Delete '.line[2:].'?', 1)
2467 | let force = force || answer > 1
2468 | if answer
2469 | let err = s:rm_rf(line[2:])
2470 | setlocal modifiable
2471 | if empty(err)
2472 | call setline(l1, '~'.line[1:])
2473 | let s:clean_count += 1
2474 | else
2475 | delete _
2476 | call append(l1 - 1, s:format_message('x', line[1:], err))
2477 | let l2 += len(s:lines(err))
2478 | let err_count += 1
2479 | endif
2480 | let msg = printf('Removed %d directories.', s:clean_count)
2481 | if err_count > 0
2482 | let msg .= printf(' Failed to remove %d directories.', err_count)
2483 | endif
2484 | call setline(4, msg)
2485 | setlocal nomodifiable
2486 | endif
2487 | endif
2488 | let l1 += 1
2489 | endwhile
2490 | endfunction
2491 |
2492 | function! s:upgrade()
2493 | echo 'Downloading the latest version of vim-plug'
2494 | redraw
2495 | let tmp = s:plug_tempname()
2496 | let new = tmp . '/plug.vim'
2497 |
2498 | try
2499 | let out = s:system(['git', 'clone', '--depth', '1', s:plug_src, tmp])
2500 | if v:shell_error
2501 | return s:err('Error upgrading vim-plug: '. out)
2502 | endif
2503 |
2504 | if readfile(s:me) ==# readfile(new)
2505 | echo 'vim-plug is already up-to-date'
2506 | return 0
2507 | else
2508 | call rename(s:me, s:me . '.old')
2509 | call rename(new, s:me)
2510 | unlet g:loaded_plug
2511 | echo 'vim-plug has been upgraded'
2512 | return 1
2513 | endif
2514 | finally
2515 | silent! call s:rm_rf(tmp)
2516 | endtry
2517 | endfunction
2518 |
2519 | function! s:upgrade_specs()
2520 | for spec in values(g:plugs)
2521 | let spec.frozen = get(spec, 'frozen', 0)
2522 | endfor
2523 | endfunction
2524 |
2525 | function! s:status()
2526 | call s:prepare()
2527 | call append(0, 'Checking plugins')
2528 | call append(1, '')
2529 |
2530 | let ecnt = 0
2531 | let unloaded = 0
2532 | let [cnt, total] = [0, len(g:plugs)]
2533 | for [name, spec] in items(g:plugs)
2534 | let is_dir = isdirectory(spec.dir)
2535 | if has_key(spec, 'uri')
2536 | if is_dir
2537 | let [err, _] = s:git_validate(spec, 1)
2538 | let [valid, msg] = [empty(err), empty(err) ? 'OK' : err]
2539 | else
2540 | let [valid, msg] = [0, 'Not found. Try PlugInstall.']
2541 | endif
2542 | else
2543 | if is_dir
2544 | let [valid, msg] = [1, 'OK']
2545 | else
2546 | let [valid, msg] = [0, 'Not found.']
2547 | endif
2548 | endif
2549 | let cnt += 1
2550 | let ecnt += !valid
2551 | " `s:loaded` entry can be missing if PlugUpgraded
2552 | if is_dir && get(s:loaded, name, -1) == 0
2553 | let unloaded = 1
2554 | let msg .= ' (not loaded)'
2555 | endif
2556 | call s:progress_bar(2, repeat('=', cnt), total)
2557 | call append(3, s:format_message(valid ? '-' : 'x', name, msg))
2558 | normal! 2G
2559 | redraw
2560 | endfor
2561 | call setline(1, 'Finished. '.ecnt.' error(s).')
2562 | normal! gg
2563 | setlocal nomodifiable
2564 | if unloaded
2565 | echo "Press 'L' on each line to load plugin, or 'U' to update"
2566 | nnoremap L :call status_load(line('.'))
2567 | xnoremap L :call status_load(line('.'))
2568 | end
2569 | endfunction
2570 |
2571 | function! s:extract_name(str, prefix, suffix)
2572 | return matchstr(a:str, '^'.a:prefix.' \zs[^:]\+\ze:.*'.a:suffix.'$')
2573 | endfunction
2574 |
2575 | function! s:status_load(lnum)
2576 | let line = getline(a:lnum)
2577 | let name = s:extract_name(line, '-', '(not loaded)')
2578 | if !empty(name)
2579 | call plug#load(name)
2580 | setlocal modifiable
2581 | call setline(a:lnum, substitute(line, ' (not loaded)$', '', ''))
2582 | setlocal nomodifiable
2583 | endif
2584 | endfunction
2585 |
2586 | function! s:status_update() range
2587 | let lines = getline(a:firstline, a:lastline)
2588 | let names = filter(map(lines, 's:extract_name(v:val, "[x-]", "")'), '!empty(v:val)')
2589 | if !empty(names)
2590 | echo
2591 | execute 'PlugUpdate' join(names)
2592 | endif
2593 | endfunction
2594 |
2595 | function! s:is_preview_window_open()
2596 | silent! wincmd P
2597 | if &previewwindow
2598 | wincmd p
2599 | return 1
2600 | endif
2601 | endfunction
2602 |
2603 | function! s:find_name(lnum)
2604 | for lnum in reverse(range(1, a:lnum))
2605 | let line = getline(lnum)
2606 | if empty(line)
2607 | return ''
2608 | endif
2609 | let name = s:extract_name(line, '-', '')
2610 | if !empty(name)
2611 | return name
2612 | endif
2613 | endfor
2614 | return ''
2615 | endfunction
2616 |
2617 | function! s:preview_commit()
2618 | if b:plug_preview < 0
2619 | let b:plug_preview = !s:is_preview_window_open()
2620 | endif
2621 |
2622 | let sha = matchstr(getline('.'), '^ \X*\zs[0-9a-f]\{7,9}')
2623 | if empty(sha)
2624 | let name = matchstr(getline('.'), '^- \zs[^:]*\ze:$')
2625 | if empty(name)
2626 | return
2627 | endif
2628 | let title = 'HEAD@{1}..'
2629 | let command = 'git diff --no-color HEAD@{1}'
2630 | else
2631 | let title = sha
2632 | let command = 'git show --no-color --pretty=medium '.sha
2633 | let name = s:find_name(line('.'))
2634 | endif
2635 |
2636 | if empty(name) || !has_key(g:plugs, name) || !isdirectory(g:plugs[name].dir)
2637 | return
2638 | endif
2639 |
2640 | if exists('g:plug_pwindow') && !s:is_preview_window_open()
2641 | execute g:plug_pwindow
2642 | execute 'e' title
2643 | else
2644 | execute 'pedit' title
2645 | wincmd P
2646 | endif
2647 | setlocal previewwindow filetype=git buftype=nofile bufhidden=wipe nobuflisted modifiable
2648 | let batchfile = ''
2649 | try
2650 | let [sh, shellcmdflag, shrd] = s:chsh(1)
2651 | let cmd = 'cd '.plug#shellescape(g:plugs[name].dir).' && '.command
2652 | if s:is_win
2653 | let [batchfile, cmd] = s:batchfile(cmd)
2654 | endif
2655 | execute 'silent %!' cmd
2656 | finally
2657 | let [&shell, &shellcmdflag, &shellredir] = [sh, shellcmdflag, shrd]
2658 | if s:is_win && filereadable(batchfile)
2659 | call delete(batchfile)
2660 | endif
2661 | endtry
2662 | setlocal nomodifiable
2663 | nnoremap q :q
2664 | wincmd p
2665 | endfunction
2666 |
2667 | function! s:section(flags)
2668 | call search('\(^[x-] \)\@<=[^:]\+:', a:flags)
2669 | endfunction
2670 |
2671 | function! s:format_git_log(line)
2672 | let indent = ' '
2673 | let tokens = split(a:line, nr2char(1))
2674 | if len(tokens) != 5
2675 | return indent.substitute(a:line, '\s*$', '', '')
2676 | endif
2677 | let [graph, sha, refs, subject, date] = tokens
2678 | let tag = matchstr(refs, 'tag: [^,)]\+')
2679 | let tag = empty(tag) ? ' ' : ' ('.tag.') '
2680 | return printf('%s%s%s%s%s (%s)', indent, graph, sha, tag, subject, date)
2681 | endfunction
2682 |
2683 | function! s:append_ul(lnum, text)
2684 | call append(a:lnum, ['', a:text, repeat('-', len(a:text))])
2685 | endfunction
2686 |
2687 | function! s:diff()
2688 | call s:prepare()
2689 | call append(0, ['Collecting changes ...', ''])
2690 | let cnts = [0, 0]
2691 | let bar = ''
2692 | let total = filter(copy(g:plugs), 's:is_managed(v:key) && isdirectory(v:val.dir)')
2693 | call s:progress_bar(2, bar, len(total))
2694 | for origin in [1, 0]
2695 | let plugs = reverse(sort(items(filter(copy(total), (origin ? '' : '!').'(has_key(v:val, "commit") || has_key(v:val, "tag"))'))))
2696 | if empty(plugs)
2697 | continue
2698 | endif
2699 | call s:append_ul(2, origin ? 'Pending updates:' : 'Last update:')
2700 | for [k, v] in plugs
2701 | let branch = s:git_origin_branch(v)
2702 | if len(branch)
2703 | let range = origin ? '..origin/'.branch : 'HEAD@{1}..'
2704 | let cmd = ['git', 'log', '--graph', '--color=never']
2705 | if s:git_version_requirement(2, 10, 0)
2706 | call add(cmd, '--no-show-signature')
2707 | endif
2708 | call extend(cmd, ['--pretty=format:%x01%h%x01%d%x01%s%x01%cr', range])
2709 | if has_key(v, 'rtp')
2710 | call extend(cmd, ['--', v.rtp])
2711 | endif
2712 | let diff = s:system_chomp(cmd, v.dir)
2713 | if !empty(diff)
2714 | let ref = has_key(v, 'tag') ? (' (tag: '.v.tag.')') : has_key(v, 'commit') ? (' '.v.commit) : ''
2715 | call append(5, extend(['', '- '.k.':'.ref], map(s:lines(diff), 's:format_git_log(v:val)')))
2716 | let cnts[origin] += 1
2717 | endif
2718 | endif
2719 | let bar .= '='
2720 | call s:progress_bar(2, bar, len(total))
2721 | normal! 2G
2722 | redraw
2723 | endfor
2724 | if !cnts[origin]
2725 | call append(5, ['', 'N/A'])
2726 | endif
2727 | endfor
2728 | call setline(1, printf('%d plugin(s) updated.', cnts[0])
2729 | \ . (cnts[1] ? printf(' %d plugin(s) have pending updates.', cnts[1]) : ''))
2730 |
2731 | if cnts[0] || cnts[1]
2732 | nnoremap (plug-preview) :silent! call preview_commit()
2733 | if empty(maparg("\", 'n'))
2734 | nmap (plug-preview)
2735 | endif
2736 | if empty(maparg('o', 'n'))
2737 | nmap o (plug-preview)
2738 | endif
2739 | endif
2740 | if cnts[0]
2741 | nnoremap X :call revert()
2742 | echo "Press 'X' on each block to revert the update"
2743 | endif
2744 | normal! gg
2745 | setlocal nomodifiable
2746 | endfunction
2747 |
2748 | function! s:revert()
2749 | if search('^Pending updates', 'bnW')
2750 | return
2751 | endif
2752 |
2753 | let name = s:find_name(line('.'))
2754 | if empty(name) || !has_key(g:plugs, name) ||
2755 | \ input(printf('Revert the update of %s? (y/N) ', name)) !~? '^y'
2756 | return
2757 | endif
2758 |
2759 | call s:system('git reset --hard HEAD@{1} && git checkout '.plug#shellescape(g:plugs[name].branch).' --', g:plugs[name].dir)
2760 | setlocal modifiable
2761 | normal! "_dap
2762 | setlocal nomodifiable
2763 | echo 'Reverted'
2764 | endfunction
2765 |
2766 | function! s:snapshot(force, ...) abort
2767 | call s:prepare()
2768 | setf vim
2769 | call append(0, ['" Generated by vim-plug',
2770 | \ '" '.strftime("%c"),
2771 | \ '" :source this file in vim to restore the snapshot',
2772 | \ '" or execute: vim -S snapshot.vim',
2773 | \ '', '', 'PlugUpdate!'])
2774 | 1
2775 | let anchor = line('$') - 3
2776 | let names = sort(keys(filter(copy(g:plugs),
2777 | \'has_key(v:val, "uri") && isdirectory(v:val.dir)')))
2778 | for name in reverse(names)
2779 | let sha = has_key(g:plugs[name], 'commit') ? g:plugs[name].commit : s:git_revision(g:plugs[name].dir)
2780 | if !empty(sha)
2781 | call append(anchor, printf("silent! let g:plugs['%s'].commit = '%s'", name, sha))
2782 | redraw
2783 | endif
2784 | endfor
2785 |
2786 | if a:0 > 0
2787 | let fn = s:plug_expand(a:1)
2788 | if filereadable(fn) && !(a:force || s:ask(a:1.' already exists. Overwrite?'))
2789 | return
2790 | endif
2791 | call writefile(getline(1, '$'), fn)
2792 | echo 'Saved as '.a:1
2793 | silent execute 'e' s:esc(fn)
2794 | setf vim
2795 | endif
2796 | endfunction
2797 |
2798 | function! s:split_rtp()
2799 | return split(&rtp, '\\\@ :
78 |
79 | let mapleader = " "
80 | let g:mapleader = " "
81 |
82 | nmap b :b
83 | nmap e :edit
84 | nmap f :find
85 | nmap q :q
86 | nmap s :%s/
87 | nmap v :vs
88 | nmap w :w!
89 |
90 | inoremap jk
91 | inoremap kj
92 | inoremap JK
93 | inoremap KJ
94 |
95 | " Markdown folding
96 | let g:markdown_folding = 1
97 | set foldlevelstart=99
98 |
99 | " Ctags
100 | nmap ]
101 | nmap t
102 |
103 | nmap ga (EasyAlign)
104 |
105 | let g:lightline = {
106 | \ 'colorscheme': 'powerline',
107 | \ 'active': {
108 | \ 'left': [ [ 'mode', 'paste' ],
109 | \ [ 'filename', 'modified' ],
110 | \ [ 'gitdiff' ] ],
111 | \ 'right': [ [ 'filetype' ],
112 | \ [ 'gitbranch', 'readonly' ] ]
113 | \ },
114 | \ 'component_function': {
115 | \ 'gitbranch': 'FugitiveHead'
116 | \ },
117 | \ 'component_expand': {
118 | \ 'gitdiff': 'lightline#gitdiff#get',
119 | \ },
120 | \ 'component_type': {
121 | \ 'gitdiff': 'middle',
122 | \ },
123 | \ }
124 |
125 | let g:lightline.mode_map = {
126 | \ 'n' : 'N',
127 | \ 'i' : 'I',
128 | \ 'R' : 'R',
129 | \ 'v' : 'V',
130 | \ 'V' : 'V-LINE',
131 | \ "\": 'V-BLOCK',
132 | \ 'c' : 'C',
133 | \ 's' : 'S',
134 | \ 'S' : 'S-LINE',
135 | \ "\": 'S-BLOCK',
136 | \ 't': 'T',
137 | \ }
138 |
139 | let g:lightline#gitdiff#indicator_added = '+'
140 | let g:lightline#gitdiff#indicator_deleted = '-'
141 | let g:lightline#gitdiff#indicator_modified = 'Δ'
142 | let g:lightline#gitdiff#separator = ' '
143 |
144 | " This prevents opening brackets in compound literals from being
145 | " highlighted as errors
146 | let c_no_curly_error = 1
147 |
148 | " Spellcheck markdown files
149 | autocmd FileType markdown setlocal spell spelllang=en_us
150 |
151 | " Use C++ style comments in C files
152 | autocmd FileType c setlocal commentstring=//\ %s
153 | autocmd FileType cpp setlocal commentstring=//\ %s
154 |
155 | " Use C++ style comments in Riff files
156 | autocmd FileType riff setlocal commentstring=//\ %s
157 |
158 | " (C) Do not indent case labels past the indent of switch statements
159 | set cino=:0
160 |
161 | " Assembly
162 | autocmd FileType asm setlocal shiftwidth=8
163 | autocmd FileType asm setlocal tabstop=8
164 |
165 | autocmd BufNewFile,BufRead *[jJ]enkinsfile set ft=groovy
166 |
--------------------------------------------------------------------------------