Compare commits
No commits in common. "main" and "zcurses/build-dir" have entirely different histories.
main
...
zcurses/bu
6
$
6
$
@ -1,6 +0,0 @@
|
|||||||
#!/usr/bin/env zsh
|
|
||||||
read -p "Are you sure? [y/N]: " -n 1 -r
|
|
||||||
echo
|
|
||||||
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
|
||||||
exec "$@"
|
|
||||||
fi
|
|
31
.conduit.yaml
Normal file
31
.conduit.yaml
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
---
|
||||||
|
- location: ~/.config/zsh
|
||||||
|
- apt:
|
||||||
|
- zsh
|
||||||
|
- zsh-doc
|
||||||
|
- brew:
|
||||||
|
- zsh
|
||||||
|
- command:
|
||||||
|
- install: sudo chsh $USER -s `which zsh`
|
||||||
|
remove: sudo chsh $USER -s `which bash`
|
||||||
|
- symlink:
|
||||||
|
- {src: zlogin, dst: ~/.zlogin}
|
||||||
|
- {src: zlogout, dst: ~/.zlogout}
|
||||||
|
- {src: zprofile, dst: ~/.zprofile}
|
||||||
|
- {src: zshenv, dst: ~/.zshenv}
|
||||||
|
- {src: zshrc, dst: ~/.zshrc}
|
||||||
|
- src: prompt_fresh_setup
|
||||||
|
dst: ~/.local/share/zsh/site-functions/prompt_fresh_setup
|
||||||
|
- src: build/_build-dir
|
||||||
|
dst: ~/.local/share/zsh/site-functions/_build-dir
|
||||||
|
- src: sandbox/_sandbox
|
||||||
|
dst: ~/.local/share/zsh/site-functions/_sandbox
|
||||||
|
- src: layout/_layout
|
||||||
|
dst: ~/.local/share/zsh/site-functions/_layout
|
||||||
|
- src: notes/_note
|
||||||
|
dst: ~/.local/share/zsh/site-functions/_note
|
||||||
|
- repo:
|
||||||
|
- https://github.com/zsh-users/zsh-autosuggestions.git
|
||||||
|
- https://github.com/zsh-users/zsh-history-substring-search.git
|
||||||
|
- https://github.com/zdharma/fast-syntax-highlighting.git
|
||||||
|
- message: zsh will be the default prompt after next login
|
4
.gitignore
vendored
4
.gitignore
vendored
@ -1,4 +1,2 @@
|
|||||||
# Ignore all plugin files in subdirectories
|
# Ignore all plugin files in subdirectories
|
||||||
zsh-*/
|
*/*
|
||||||
local
|
|
||||||
zsh*.local
|
|
||||||
|
29
README.md
29
README.md
@ -2,13 +2,15 @@
|
|||||||
|
|
||||||
<!-- TODO: GIF -->
|
<!-- TODO: GIF -->
|
||||||
|
|
||||||
## Ansible
|
## [conduit][conduit]
|
||||||
|
|
||||||
To install this Zsh configuration:
|
Simple, local, configuration manager.
|
||||||
|
|
||||||
```console
|
Installation of the configuration files in this repository is orchestrated by
|
||||||
$ ansible-playbook main.yaml --ask-become-pass
|
[conduit][conduit] as defined in the [`.conduit.yaml`](.conduit.yaml) file. This
|
||||||
```
|
includes [Zsh][zsh] package installs, setting [Zsh][zsh] as the users default
|
||||||
|
shell, and symbolic linking file such as [`zshrc`](zshrc) to `~/.zshrc`, and
|
||||||
|
cloning plugin repositories. The repository is cloned to `~/.config/zsh`.
|
||||||
|
|
||||||
## Prompt
|
## Prompt
|
||||||
|
|
||||||
@ -49,25 +51,10 @@ display. This results in no noticeable lag when redrawing the prompt.
|
|||||||
Plugins are sourced manually and their git repositories tracked by
|
Plugins are sourced manually and their git repositories tracked by
|
||||||
[conduit][conduit], no plugin manager is used.
|
[conduit][conduit], no plugin manager is used.
|
||||||
|
|
||||||
* [zsh-autosuggestions][zsh-autosuggestions] Fish-like autosuggestions for zsh.
|
|
||||||
* [zsh-syntax-highlighting][syntax] Fish shell like syntax highlighting for Zsh.
|
* [zsh-syntax-highlighting][syntax] Fish shell like syntax highlighting for Zsh.
|
||||||
* [zsh-history-substring-search][search] Zsh port of the Fish shell's history
|
* [zsh-history-substring-search][search] Zsh port of the Fish shell's history
|
||||||
search.
|
search.
|
||||||
|
|
||||||
In addition to third party plugins the following are custom plugins residing in
|
|
||||||
this repository.
|
|
||||||
|
|
||||||
* [autoenv](autoenv/autoenv.zsh) is a inspired by [zsh-autoenv][zsh-autoenv] but
|
|
||||||
simplified by removing customization points and using a less intrusive UI.
|
|
||||||
* [build](build/build.plugin.zsh) is a collection of commands to make it easier
|
|
||||||
to build projects focuses on C/C++ development.
|
|
||||||
* [sandbox](sandbox/sandbox.plugin.zsh) is a command which sets up a throw away
|
|
||||||
directory for quickly testing ideas.
|
|
||||||
* [layout](layout/layout.plugin.zsh) is a command which setups up `tmux` panes
|
|
||||||
in a window with scripts.
|
|
||||||
* [notes](notes/notes.plugin.zsh) is a command to quickly edit markdown note
|
|
||||||
files.
|
|
||||||
|
|
||||||
## Environment & Settings
|
## Environment & Settings
|
||||||
|
|
||||||
The bulk of, if not all, configuration occurs in [`zshenv`](zshenv) and
|
The bulk of, if not all, configuration occurs in [`zshenv`](zshenv) and
|
||||||
@ -148,8 +135,6 @@ Various aliases are defined at the end of [zshrc](zshrc) for convenience.
|
|||||||
[zsh]: https://www.zsh.org/
|
[zsh]: https://www.zsh.org/
|
||||||
[git]: https://git-scm.com/
|
[git]: https://git-scm.com/
|
||||||
[git-prompt]: https://github.com/olivierverdier/zsh-git-prompt
|
[git-prompt]: https://github.com/olivierverdier/zsh-git-prompt
|
||||||
[zsh-autosuggestions]: https://github.com/zdharma/fast-syntax-highlighting
|
|
||||||
[zsh-autoenv]: https://github.com/Tarrasch/zsh-autoenv
|
|
||||||
[syntax]: https://github.com/zsh-users/zsh-syntax-highlighting
|
[syntax]: https://github.com/zsh-users/zsh-syntax-highlighting
|
||||||
[search]: https://github.com/zsh-users/zsh-history-substring-search
|
[search]: https://github.com/zsh-users/zsh-history-substring-search
|
||||||
[vim-mode]: https://github.com/sharat87/zsh-vim-mode
|
[vim-mode]: https://github.com/sharat87/zsh-vim-mode
|
||||||
|
@ -16,9 +16,6 @@ _autoenv() {
|
|||||||
init:'add .enter and .exit scripts in current directory'
|
init:'add .enter and .exit scripts in current directory'
|
||||||
edit:'edit .enter and .exit scripts in current directory'
|
edit:'edit .enter and .exit scripts in current directory'
|
||||||
deinit:'remove .enter and .exit scripts in current directory'
|
deinit:'remove .enter and .exit scripts in current directory'
|
||||||
reload:'reload the current environment'
|
|
||||||
add=local:'add .local/bin to PATH'
|
|
||||||
add=py:'add Python virtualenv to the autoenv'
|
|
||||||
)
|
)
|
||||||
_describe -t commands command commands && ret=0 ;;
|
_describe -t commands command commands && ret=0 ;;
|
||||||
esac
|
esac
|
||||||
|
@ -12,7 +12,7 @@ autoenv() {
|
|||||||
case "$cmd" in
|
case "$cmd" in
|
||||||
-h|--help) # Display help.
|
-h|--help) # Display help.
|
||||||
echo "\
|
echo "\
|
||||||
usage: autoenv [-h] {init,edit,deinit,reload,add=py}
|
usage: autoenv [-h] {init,edit,deinit}
|
||||||
|
|
||||||
options:
|
options:
|
||||||
-h, --help show this help message and exit
|
-h, --help show this help message and exit
|
||||||
@ -20,139 +20,73 @@ options:
|
|||||||
commands:
|
commands:
|
||||||
init add .enter and .exit scripts in current directory
|
init add .enter and .exit scripts in current directory
|
||||||
edit edit .enter and .exit scripts in current directory
|
edit edit .enter and .exit scripts in current directory
|
||||||
deinit remove .enter and .exit scripts in current directory
|
deinit remove .enter and .exit scripts in current directory"
|
||||||
reload reload the current environment
|
|
||||||
add=local add .local/bin to PATH
|
|
||||||
add=py add Python virtualenv to the autoenv"
|
|
||||||
;;
|
;;
|
||||||
|
|
||||||
init) # Create .enter and .exit scripts in current directory.
|
init) # Create enter and exit scripts in current directory.
|
||||||
if [ -f $PWD/.enter ] || [ -f $PWD/.exit ]; then
|
if [ -f $PWD/.enter ] || [ -f $PWD/.exit ]; then
|
||||||
echo '.enter or .exit already exists'; return 1
|
echo '.enter or .exit already exists'; return 1
|
||||||
fi
|
fi
|
||||||
# Create the .enter and .exit scripts.
|
# Create then edit enter and exit scripts.
|
||||||
touch .enter .exit
|
touch .enter .exit && autoenv edit
|
||||||
# If enter script exists, authorize it.
|
# If enter script exists, authorize it.
|
||||||
[ -f $PWD/.enter ] && _autoenv_authorized $PWD/.enter yes
|
[ -f $PWD/.enter ] && _autoenv_authorized $PWD/.enter yes
|
||||||
# If exit script exists, authorize it.
|
# If exit script exists, authorize it.
|
||||||
[ -f $PWD/.exit ] && _autoenv_authorized $PWD/.exit yes
|
[ -f $PWD/.exit ] && _autoenv_authorized $PWD/.exit yes
|
||||||
# Enter the autoenv.
|
# Enter the new autoenv.
|
||||||
_autoenv_enter $PWD
|
_autoenv_enter $PWD ;;
|
||||||
;;
|
|
||||||
|
|
||||||
edit) # Edit .enter and .exit scripts in current directory.
|
edit) # Edit enter and exit scripts in current directory.
|
||||||
if ! [ -f $PWD/.enter ] || ! [ -f $PWD/.exit ]; then
|
if ! [ -f $PWD/.enter ] || ! [ -f $PWD/.exit ]; then
|
||||||
echo '.enter or .exit not found'; return 1
|
echo '.enter or .exit not found'; return 1
|
||||||
fi
|
fi
|
||||||
# Exit the autoenv before editing.
|
# If vim exists, edit enter and exit scripts.
|
||||||
_autoenv_exit $PWD
|
if which vim &> /dev/null; then
|
||||||
if $EDITOR -p $PWD/.enter $PWD/.exit; then
|
vim -p $PWD/.enter $PWD/.exit
|
||||||
# If enter script exists, authorize it.
|
else
|
||||||
[ -f $PWD/.enter ] && _autoenv_authorized $PWD/.enter yes
|
echo 'vim not found'; return 1
|
||||||
# If exit script exists, authorize it.
|
fi ;;
|
||||||
[ -f $PWD/.exit ] && _autoenv_authorized $PWD/.exit yes
|
|
||||||
fi
|
|
||||||
# Enter the autoenv.
|
|
||||||
_autoenv_enter $PWD
|
|
||||||
;;
|
|
||||||
|
|
||||||
deinit) # Remove .enter and .exit scripts in current directory.
|
deinit) # Remove enter and exit scripts in current directory.
|
||||||
if ! [ -f $PWD/.enter ] || ! [ -f $PWD/.exit ]; then
|
if [ -f $PWD/.enter ] || [ -f $PWD/.exit ]; then
|
||||||
echo '.enter or .exit not found'; return 1
|
# Prompt user to confirm removal of enter and exit scripts.
|
||||||
fi
|
while true; do
|
||||||
# Prompt user to confirm removal of enter and exit scripts.
|
read "answer?Are you sure [y/N]? "
|
||||||
while true; do
|
case "$answer" in
|
||||||
read "answer?Are you sure [y/N]? "
|
y|Y|yes)
|
||||||
case "$answer" in
|
# Remove enter and exit scripts if they exist.
|
||||||
y|Y|yes)
|
[ -f $PWD/.enter ] && rm $PWD/.enter
|
||||||
# Exit the autoenv.
|
[ -f $PWD/.exit ] && rm $PWD/.exit
|
||||||
_autoenv_exit $PWD
|
break ;;
|
||||||
# Remove enter and exit scripts if they exist.
|
*) break ;;
|
||||||
[ -f $PWD/.enter ] && rm $PWD/.enter
|
esac
|
||||||
[ -f $PWD/.exit ] && rm $PWD/.exit
|
done
|
||||||
break ;;
|
else
|
||||||
*) break ;;
|
echo '.enter and .exit not found'; return 1
|
||||||
esac
|
fi ;;
|
||||||
done
|
|
||||||
;;
|
|
||||||
|
|
||||||
reload) # Reload the current environment
|
|
||||||
if ! [ -f $PWD/.enter ] || ! [ -f $PWD/.exit ]; then
|
|
||||||
echo '.enter or .exit not found'; return 1
|
|
||||||
fi
|
|
||||||
# Exit the autoenv before editing.
|
|
||||||
_autoenv_exit $PWD
|
|
||||||
# Enter the autoenv.
|
|
||||||
_autoenv_enter $PWD
|
|
||||||
;;
|
|
||||||
|
|
||||||
add=local) # Add .local/bin to PATH
|
|
||||||
if ! [ -f $PWD/.enter ] || ! [ -f $PWD/.exit ]; then
|
|
||||||
echo '.enter or .exit not found'; return 1
|
|
||||||
fi
|
|
||||||
_autoenv_exit $PWD
|
|
||||||
# Create .local/bin if not present
|
|
||||||
if ! [ -d $PWD/.local/bin ]; then
|
|
||||||
mkdir -p $PWD/.local/bin
|
|
||||||
fi
|
|
||||||
# On enter: store PATH and insert .local/bin
|
|
||||||
echo 'OLDPATH=$PATH' >> .enter
|
|
||||||
echo 'PATH=$PWD/.local/bin:$PATH' >> .enter
|
|
||||||
# On exit: reset PATH
|
|
||||||
echo 'PATH=$OLDPATH' >> .exit
|
|
||||||
echo 'unset OLDPATH' >> .exit
|
|
||||||
# Authorize modified autoenv
|
|
||||||
_autoenv_authorized $PWD/.enter yes
|
|
||||||
_autoenv_authorized $PWD/.exit yes
|
|
||||||
_autoenv_enter $PWD
|
|
||||||
;;
|
|
||||||
|
|
||||||
add=py) # Add Python virtualenv to the sandbox
|
|
||||||
if ! [ -f $PWD/.enter ] || ! [ -f $PWD/.exit ]; then
|
|
||||||
echo '.enter or .exit not found'; return 1
|
|
||||||
fi
|
|
||||||
_autoenv_exit $PWD
|
|
||||||
virtualenv -p `command -v python` .local
|
|
||||||
echo 'source ${0:a:h}/.local/bin/activate' >> .enter
|
|
||||||
echo 'deactivate' >> .exit
|
|
||||||
_autoenv_authorized $PWD/.enter yes
|
|
||||||
_autoenv_authorized $PWD/.exit yes
|
|
||||||
_autoenv_enter $PWD
|
|
||||||
pip install pynvim
|
|
||||||
;;
|
|
||||||
|
|
||||||
*) # Invalid arguments, show help then error.
|
*) # Invalid arguments, show help then error.
|
||||||
echo "invalid arguments: $@"
|
echo "invalid arguments: $@"
|
||||||
autoenv --help
|
autoenv --help
|
||||||
return 1
|
return 1 ;;
|
||||||
;;
|
|
||||||
esac
|
esac
|
||||||
}
|
}
|
||||||
|
|
||||||
# Global entered directories array.
|
# Global entered directories array.
|
||||||
_autoenv_entered=()
|
_autoenv_entered=()
|
||||||
|
|
||||||
# Load zstat from stat module for inspecting modified time.
|
|
||||||
zmodload -F zsh/stat b:zstat
|
|
||||||
|
|
||||||
# Check if the given file is authorized, if not prompt the user to authorize,
|
# Check if the given file is authorized, if not prompt the user to authorize,
|
||||||
# ignore, or view the file. Authorized files and their modified times are
|
# ignore, or view the file. Authorized files and their modified times are
|
||||||
# stored in the $XDG_STATE_HOME/autoenv/authorized file to make authorization
|
# stored in the ~/.cache/autoenv/authorized file to make authorization
|
||||||
# persistent.
|
# persistent.
|
||||||
_autoenv_authorized() {
|
_autoenv_authorized() {
|
||||||
local file=$1 yes=$2
|
local file=$1 yes=$2
|
||||||
# If autoenv state directory does not exist, create it.
|
# If autoenv cache directory does not exist, create it.
|
||||||
! [ -d ${XDG_STATE_HOME:-$HOME/.local/state}/autoenv ] && \
|
! [ -d ~/.cache/autoenv ] && mkdir -p ~/.cache/autoenv
|
||||||
mkdir -p ${XDG_STATE_HOME:-$HOME/.local/state}/autoenv
|
|
||||||
# Migrate from cache to state directory
|
|
||||||
[ -f $HOME/.cache/autoenv/authorized ] && \
|
|
||||||
mv $HOME/.cache/autoenv/authorized \
|
|
||||||
${XDG_STATE_HOME:-$HOME/.local/state}/autoenv/authorized
|
|
||||||
# If the authorized file does not exist, create it.
|
# If the authorized file does not exist, create it.
|
||||||
! [ -f ${XDG_STATE_HOME:-$HOME/.local/state}/autoenv/authorized ] && \
|
! [ -f ~/.cache/autoenv/authorized ] && touch ~/.cache/autoenv/authorized
|
||||||
touch ${XDG_STATE_HOME:-$HOME/.local/state}/autoenv/authorized
|
|
||||||
# Load the authorized file into a map of authorized key value pairs.
|
# Load the authorized file into a map of authorized key value pairs.
|
||||||
typeset -A authorized=(`cat ${XDG_STATE_HOME:-$HOME/.local/state}/autoenv/authorized`)
|
typeset -A authorized=(`cat ~/.cache/autoenv/authorized`)
|
||||||
# If the file has been removed, return.
|
# If the file has been removed, return.
|
||||||
! [ -f $file ] && return 1
|
! [ -f $file ] && return 1
|
||||||
# If the given file has been authorized, i.e. the modified time matches that
|
# If the given file has been authorized, i.e. the modified time matches that
|
||||||
@ -174,7 +108,7 @@ _autoenv_authorized() {
|
|||||||
# Add file to the authorized map.
|
# Add file to the authorized map.
|
||||||
authorized[$file]=$modified_time
|
authorized[$file]=$modified_time
|
||||||
# Store authorized map in authorized file.
|
# Store authorized map in authorized file.
|
||||||
echo ${(kv)authorized} > ${XDG_STATE_HOME:-$HOME/.local/state}/autoenv/authorized
|
echo ${(kv)authorized} > ~/.cache/autoenv/authorized
|
||||||
}
|
}
|
||||||
|
|
||||||
# Source an enter script and add its directory to the global entered
|
# Source an enter script and add its directory to the global entered
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
#compdef build-dir
|
#compdef build-dir
|
||||||
|
|
||||||
_arguments \
|
_arguments \
|
||||||
'(-h --help)'{-h,--help}'[show this help message and exit]' \
|
'(-h --help)'{-h,--help}'[]' \
|
||||||
'(-s --show)'{-s,--show}'[show the current build directory]' \
|
|
||||||
'--build[invoke a build after selection]' \
|
'--build[invoke a build after selection]' \
|
||||||
'1:directory:_files'
|
'1:directory:_files'
|
||||||
|
46
build/build-dir.py
Executable file
46
build/build-dir.py
Executable file
@ -0,0 +1,46 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
"""The pick_build_dir command selects a build directory
|
||||||
|
|
||||||
|
The pick_build_dir command scans the current directory for directories starting
|
||||||
|
with ``build`` and prompts the user to select one from the list.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from __future__ import print_function
|
||||||
|
|
||||||
|
from argparse import ArgumentParser
|
||||||
|
from os import listdir
|
||||||
|
from os.path import curdir, isdir
|
||||||
|
from sys import stderr
|
||||||
|
|
||||||
|
from pick import Picker
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
"""Main entry point to build-dir.py script."""
|
||||||
|
parser = ArgumentParser()
|
||||||
|
parser.add_argument('output')
|
||||||
|
parser.add_argument('--default', action='store_true')
|
||||||
|
args = parser.parse_args()
|
||||||
|
directories = []
|
||||||
|
for directory in listdir(curdir):
|
||||||
|
if isdir(directory) and directory.startswith('build'):
|
||||||
|
directories.append(directory)
|
||||||
|
if len(directories) == 0:
|
||||||
|
print('no build directories found', file=stderr)
|
||||||
|
exit(1)
|
||||||
|
build_dirs = sorted(directories)
|
||||||
|
if args.default:
|
||||||
|
build_dir = build_dirs[0]
|
||||||
|
else:
|
||||||
|
picker = Picker(build_dirs, 'Select a build directory:')
|
||||||
|
picker.register_custom_handler(ord(''), lambda _: exit(1))
|
||||||
|
build_dir, _ = picker.start()
|
||||||
|
with open(args.output, 'w') as output:
|
||||||
|
output.write(build_dir)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
try:
|
||||||
|
main()
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
exit(130)
|
@ -7,31 +7,21 @@ alias build="build-dir --build"
|
|||||||
# Detect installed debugger and set the `debug` alias to debug a program with
|
# Detect installed debugger and set the `debug` alias to debug a program with
|
||||||
# command line arguments.
|
# command line arguments.
|
||||||
if [ `uname` = Linux ]; then
|
if [ `uname` = Linux ]; then
|
||||||
autoload -U regexp-replace
|
if which cgdb &> /dev/null; then
|
||||||
function vimdebug() {
|
alias debug='cgdb --args'
|
||||||
# For each item in $* replace * and \* and then replace \ with \\
|
elif which gdb &> /dev/null; then
|
||||||
local args=()
|
|
||||||
for arg in "$@"; do
|
|
||||||
regexp-replace arg '\*' '\\*'
|
|
||||||
args+=($arg)
|
|
||||||
done
|
|
||||||
nvim "+packadd termdebug" "+TermdebugCommand $args"
|
|
||||||
}
|
|
||||||
if command -v nvim &> /dev/null; then
|
|
||||||
alias debug=vimdebug
|
|
||||||
elif command -v gdb &> /dev/null; then
|
|
||||||
alias debug='gdb --args'
|
alias debug='gdb --args'
|
||||||
fi
|
fi
|
||||||
elif [ `uname` = Darwin ]; then
|
elif [ `uname` = Darwin ]; then
|
||||||
command -v lldb &> /dev/null && \
|
which lldb &> /dev/null && \
|
||||||
alias debug='lldb --'
|
alias debug='lldb --'
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Interactively choose a `~build` directory for `build` to build.
|
# Interactively choose a `~build` directory for `build` to build.
|
||||||
build-dir() {
|
build-dir() {
|
||||||
local usage='usage: build-dir [-h] [-s] [--build] [<directory>]'
|
local usage='usage: build-dir [-h] [--build] [<directory>]'
|
||||||
local -a help show do_build
|
local -a help do_build
|
||||||
zparseopts -D h=help -help=help s=show -show=show -build=do_build
|
zparseopts -D h=help -help=help -build=do_build
|
||||||
if [[ -n $help ]]; then
|
if [[ -n $help ]]; then
|
||||||
cat << EOF
|
cat << EOF
|
||||||
$usage
|
$usage
|
||||||
@ -43,128 +33,134 @@ positional arguments:
|
|||||||
|
|
||||||
optional arguments:
|
optional arguments:
|
||||||
-h, --help show this help message and exit
|
-h, --help show this help message and exit
|
||||||
-s, --show show the current build directory
|
|
||||||
--build invoke a build after selection
|
--build invoke a build after selection
|
||||||
EOF
|
EOF
|
||||||
return
|
return
|
||||||
fi
|
fi
|
||||||
error() { echo "\e[31merror:\e[0m $1" }
|
error() { echo "\e[31merror:\e[0m $1"; return 1 }
|
||||||
warning() { echo "\e[33mwarning:\e[0m $1" }
|
local build_dir
|
||||||
if [[ -n $show ]]; then
|
|
||||||
if [[ ! -n $build_dir ]]; then
|
|
||||||
error "build directory not set"
|
|
||||||
return 1
|
|
||||||
else
|
|
||||||
echo "$build_dir"
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
local local_build_dir
|
|
||||||
if [[ ${#*} -gt 1 ]]; then
|
if [[ ${#*} -gt 1 ]]; then
|
||||||
echo $usage
|
echo $usage
|
||||||
error "unexpected positional arguments: ${*[2,${#*}]}"; return 1
|
error "unexpected position arguments: ${*[2,${#*}]}"
|
||||||
elif [[ ${#*} -eq 1 ]]; then
|
elif [[ ${#*} -eq 1 ]]; then
|
||||||
if [[ ! -d ${*[1]} ]]; then
|
build_dir=${*[1]}
|
||||||
warning "directory not found: ${*[1]}"
|
[[ ! -d $build_dir ]] && \
|
||||||
else
|
error "directory not found: $build_dir"
|
||||||
local_build_dir=${*[1]}
|
|
||||||
fi
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# If <directory> was not set begin selection
|
# If <directory> was not set begin selection
|
||||||
if [[ -z $local_build_dir ]]; then
|
if [[ -z $build_dir ]]; then
|
||||||
# Find build directories
|
# Find build directories
|
||||||
local -a local_build_dirs
|
local -a build_dirs
|
||||||
for entry in `ls -A`; do
|
for entry in `ls -A`; do
|
||||||
[ -d $entry ] && [[ $entry =~ build* ]] && \
|
[ -d $entry ] && [[ $entry =~ build* ]] && \
|
||||||
local_build_dirs+=${entry/\//}
|
build_dirs+=${entry/\//}
|
||||||
done
|
done
|
||||||
|
|
||||||
# Interactively select a build directory if more than 1 found
|
# Interactively select a build directory if more than 1 found
|
||||||
integer index=0
|
integer index=0
|
||||||
if [[ ${#local_build_dirs} -eq 0 ]]; then
|
if [[ ${#build_dirs} -eq 0 ]]; then
|
||||||
error "no build directories found"; return 1
|
error "no build directories found"
|
||||||
elif [[ ${#local_build_dirs} -eq 1 ]]; then
|
elif [[ ${#build_dirs} -gt 1 ]]; then
|
||||||
local_build_dir=${local_build_dirs[1]}
|
zmodload zsh/curses && {
|
||||||
elif [[ ${#local_build_dirs} -gt 1 ]]; then
|
# Get the size of the terminal
|
||||||
# Use fzf to select a build directory
|
local size=`stty size`
|
||||||
local max=$(( $( tput lines ) / 2 ))
|
integer height=${size% *}
|
||||||
local best=$(( ${#local_build_dirs} + 4 ))
|
integer width=${size#* }
|
||||||
local_build_dir=$(
|
|
||||||
printf '%s\n' "${local_build_dirs[@]}" |
|
# Create the window and hide the cursor
|
||||||
fzf --layout=reverse --tac --info=hidden --border=rounded \
|
zcurses init
|
||||||
--cycle --height=$(( $best < $max ? $best : $max ))
|
zcurses addwin build-dir $height $width 0 0
|
||||||
)
|
|
||||||
if [[ $? -ne 0 ]]; then
|
# Hide the cursor for zcurses, trap SIGINT to ensure cleanup in
|
||||||
return 1
|
# always-list occurs below
|
||||||
fi
|
tput civis; trap 'return 130' INT
|
||||||
|
|
||||||
|
# Enter display loop
|
||||||
|
local key keypad
|
||||||
|
while (( 1 )); do
|
||||||
|
zcurses clear build-dir
|
||||||
|
|
||||||
|
# Add the prompt text
|
||||||
|
zcurses move build-dir 1 1
|
||||||
|
zcurses string build-dir 'Select a build directory:'
|
||||||
|
|
||||||
|
# Add the selections text
|
||||||
|
for (( i = 0; i < ${#build_dirs}; i++ )); do
|
||||||
|
integer line=$i+3
|
||||||
|
zcurses move build-dir $line 1
|
||||||
|
[[ $index -eq $i ]] &&
|
||||||
|
zcurses string build-dir "* " ||
|
||||||
|
zcurses string build-dir " "
|
||||||
|
zcurses string build-dir ${build_dirs[$i+1]}
|
||||||
|
done
|
||||||
|
|
||||||
|
# Display the text the and wait for input
|
||||||
|
zcurses refresh build-dir
|
||||||
|
zcurses input build-dir key keypad
|
||||||
|
|
||||||
|
# Handle user input
|
||||||
|
case $key in
|
||||||
|
(UP|k|$'\C-P')
|
||||||
|
[[ $index -gt 0 ]] && index=$index-1 ;;
|
||||||
|
(DOWN|j|$'\C-N')
|
||||||
|
[[ $index -lt ${#build_dirs}-1 ]] && index=$index+1 ;;
|
||||||
|
(ENTER|$'\n')
|
||||||
|
break ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
} always {
|
||||||
|
# Restore the cursor and cleanup zcurses
|
||||||
|
tput cvvis; tput cnorm
|
||||||
|
zcurses delwin build-dir
|
||||||
|
zcurses end
|
||||||
|
}
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# If `build.ninja` exists in alias `ninja`, return.
|
# On success setup the build directory for use
|
||||||
local build
|
if [[ $? -eq 0 ]]; then
|
||||||
[ -f $local_build_dir/build.ninja ] && \
|
# Set the build directory from selection if empty
|
||||||
build="ninja -C $local_build_dir"
|
[[ -z $build_dir ]] && \
|
||||||
|
build_dir=${build_dirs[$index+1]}
|
||||||
|
|
||||||
# If `Makefile` exists in alias `make`, return.
|
# If `build.ninja` exists in alias `ninja`, return.
|
||||||
if [ -f $local_build_dir/Makefile ]; then
|
local build
|
||||||
[ `uname` = Darwin ] && \
|
[ -f $build_dir/build.ninja ] && \
|
||||||
local cpu_count=`sysctl -n hw.ncpu` ||
|
build="ninja -C $build_dir"
|
||||||
local cpu_count=`grep -c '^processor' /proc/cpuinfo`
|
|
||||||
build="make -j $cpu_count -C $local_build_dir"
|
# If `Makefile` exists in alias `make`, return.
|
||||||
|
if [ -f $build_dir/Makefile ]; then
|
||||||
|
[ `uname` = Darwin ] && \
|
||||||
|
local cpu_count=`sysctl -n hw.ncpu` ||
|
||||||
|
local cpu_count=`grep -c '^processor' /proc/cpuinfo`
|
||||||
|
build="make -j $cpu_count -C $build_dir"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# If the build variable is not defined the command could not be determined
|
||||||
|
if [ -z $build ]; then
|
||||||
|
echo "\e[33mwarning:\e[0m build command detection failed: $build_dir"
|
||||||
|
# Prompt user to enter a build command
|
||||||
|
vared -p 'enter comand: ' build
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Redefine the `build` alias and update the `~build` hash directory
|
||||||
|
alias build="$build"
|
||||||
|
hash -d build=$build_dir
|
||||||
|
|
||||||
|
# If `--build` is specified then evaluate the command.
|
||||||
|
[[ -n $do_build ]] && eval build
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# If the build variable is not defined the command could not be determined
|
|
||||||
if [ -z $build ]; then
|
|
||||||
warning "build command detection failed: $local_build_dir"
|
|
||||||
# Prompt user to enter a build command
|
|
||||||
vared -p 'enter comand: ' build
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Redefine the `build` alias and update the `~build` hash directory
|
|
||||||
alias build="$build"
|
|
||||||
hash -d build=$local_build_dir
|
|
||||||
export build_dir=$local_build_dir
|
|
||||||
export BUILD_DIR=$PWD/$local_build_dir
|
|
||||||
echo "$build_dir"
|
|
||||||
|
|
||||||
# If `--build` is specified then evaluate the command.
|
|
||||||
if [[ -n $do_build ]]; then
|
|
||||||
eval build
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Bind C-B to fuzzy find & complete cmake variables.
|
|
||||||
zle -N .build-var
|
|
||||||
bindkey '^B' .build-var
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# Build then run a target residing in `~build/bin`.
|
# Build then run a target residing in `~build/bin`.
|
||||||
build-run() {
|
build-run() {
|
||||||
local target=$1; shift 1
|
local target=$1; shift 1
|
||||||
eval build $target && ~build/bin/$target "$@"
|
eval build $target && ~build/bin/$target $*
|
||||||
}
|
}
|
||||||
|
|
||||||
# Build then debug a target residing in `~build/bin`.
|
# Build then debug a target residing in `~build/bin`.
|
||||||
build-debug() {
|
build-debug() {
|
||||||
local target=$1; shift 1
|
local target=$1; shift 1
|
||||||
eval build $target && debug ~build/bin/$target "$@"
|
eval build $target && debug ~build/bin/$target $*
|
||||||
}
|
|
||||||
|
|
||||||
# Fuzzy find CMake variables, select one to set the variable via a command.
|
|
||||||
.build-var() {
|
|
||||||
local var=$(
|
|
||||||
cat $build_dir/CMakeCache.txt |
|
|
||||||
grep --color=never -Ex '^\w+:\w+=.*$' |
|
|
||||||
fzf --layout=reverse --info=hidden --border=rounded \
|
|
||||||
--cycle --height=50%
|
|
||||||
)
|
|
||||||
if [[ -n "$var" ]]; then
|
|
||||||
if [[ "$BUFFER" = "cmake"* ]]; then
|
|
||||||
BUFFER="$BUFFER-D$var"
|
|
||||||
else
|
|
||||||
BUFFER="cmake -B\$build_dir -D$var"
|
|
||||||
fi
|
|
||||||
zle end-of-line
|
|
||||||
fi
|
|
||||||
zle reset-prompt
|
|
||||||
}
|
}
|
||||||
|
105
cmake-uninstall
105
cmake-uninstall
@ -1,105 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
"""Uninstall a previously installed CMake installation.
|
|
||||||
|
|
||||||
Read the ``install_manifest.txt`` file from a CMake build directory
|
|
||||||
which has been installed then delete the files, and optionally the empty
|
|
||||||
subdirectories of the install prefix, specified within.
|
|
||||||
"""
|
|
||||||
|
|
||||||
from argparse import ArgumentParser, RawDescriptionHelpFormatter
|
|
||||||
from os import listdir, path, remove, rmdir
|
|
||||||
from sys import stderr
|
|
||||||
|
|
||||||
|
|
||||||
def uninstall(build_dir, recursive=False):
|
|
||||||
"""Uninstall a previoulsy installed CMake installation.
|
|
||||||
|
|
||||||
Arguments:
|
|
||||||
:build_dir: Path to the build directory containing the
|
|
||||||
``install_manifest.txt`` of files to uninstall.
|
|
||||||
:recursive: Boolean flag to enable recursively uninstall empty
|
|
||||||
directories up to the install prefix specified in ``CMakeCache.txt``.
|
|
||||||
"""
|
|
||||||
# Get the list of installed files from the install_manifest.txt
|
|
||||||
install_manifest_path = path.join(build_dir, 'install_manifest.txt')
|
|
||||||
with open(install_manifest_path, 'r') as install_manifest_file:
|
|
||||||
install_manifest = sorted(install_manifest_file.read().splitlines())
|
|
||||||
# Delete files from the filesystem
|
|
||||||
removed = []
|
|
||||||
directories = []
|
|
||||||
for entry in install_manifest:
|
|
||||||
directories.append(path.dirname(entry))
|
|
||||||
if path.isfile(entry):
|
|
||||||
remove(entry)
|
|
||||||
removed.append(entry)
|
|
||||||
if recursive:
|
|
||||||
# Get the install prefix from CMakeCache.txt
|
|
||||||
cmakecache_path = path.join(build_dir, 'CMakeCache.txt')
|
|
||||||
with open(cmakecache_path, 'r') as cmakecache_file:
|
|
||||||
for line in cmakecache_file.read().splitlines():
|
|
||||||
if line.startswith('CMAKE_INSTALL_PREFIX'):
|
|
||||||
prefix = path.normpath(line.split('=')[1])
|
|
||||||
break
|
|
||||||
while True:
|
|
||||||
# Remove duplicates from list
|
|
||||||
directories = list(dict.fromkeys(directories))
|
|
||||||
# Find directories in list which are not empty
|
|
||||||
not_empty = []
|
|
||||||
for index, entry in enumerate(directories):
|
|
||||||
if listdir(entry):
|
|
||||||
not_empty.append(index)
|
|
||||||
# Remove directories which are not empty from list
|
|
||||||
for index in reversed(not_empty):
|
|
||||||
del directories[index]
|
|
||||||
# Delete directories from the filesystem
|
|
||||||
to_del = []
|
|
||||||
to_append = []
|
|
||||||
for index, entry in enumerate(directories):
|
|
||||||
rmdir(entry)
|
|
||||||
removed.append(entry)
|
|
||||||
to_del.append(index)
|
|
||||||
parent = path.dirname(entry)
|
|
||||||
# Add parent directory to the list when not the install prefix
|
|
||||||
if path.normpath(parent) != prefix:
|
|
||||||
to_append.append(parent)
|
|
||||||
# Remove deleted directories from list
|
|
||||||
for index in reversed(to_del):
|
|
||||||
del directories[index]
|
|
||||||
directories += to_append
|
|
||||||
# Exit loop when no more directories in list
|
|
||||||
if not directories:
|
|
||||||
break
|
|
||||||
return removed
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
|
||||||
"""Command line entry point."""
|
|
||||||
cli = ArgumentParser(description=__doc__,
|
|
||||||
formatter_class=RawDescriptionHelpFormatter)
|
|
||||||
cli.add_argument('--version', action='version', version='%(prog)s 0.1.0')
|
|
||||||
cli.add_argument('-q',
|
|
||||||
'--quiet',
|
|
||||||
action='store_true',
|
|
||||||
help="don't print removed entries to stdout")
|
|
||||||
cli.add_argument('-r',
|
|
||||||
'--recursive',
|
|
||||||
action='store_true',
|
|
||||||
help='recursively remove empty directories')
|
|
||||||
cli.add_argument('build_dir',
|
|
||||||
help='path to the installed CMake build directory')
|
|
||||||
args = cli.parse_args()
|
|
||||||
try:
|
|
||||||
removed = uninstall(args.build_dir, recursive=args.recursive)
|
|
||||||
if not args.quiet:
|
|
||||||
for entry in removed:
|
|
||||||
print(f'-- Uninstalling: {entry}')
|
|
||||||
except FileNotFoundError as error:
|
|
||||||
print(f'error: file not found: {error.filename}', file=stderr)
|
|
||||||
exit(1)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
try:
|
|
||||||
main()
|
|
||||||
except KeyboardInterrupt:
|
|
||||||
exit(130)
|
|
204
git-prompt.c
204
git-prompt.c
@ -1,204 +0,0 @@
|
|||||||
#include <ctype.h>
|
|
||||||
#include <stdarg.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#if __linux__
|
|
||||||
#include <sys/wait.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
#define check(CONDITION) \
|
|
||||||
if (CONDITION) { \
|
|
||||||
fprintf(stderr, "error: %s: %d: %s\n", __FILE__, __LINE__, #CONDITION); \
|
|
||||||
exit(0); \
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
#define check(CONDITION) \
|
|
||||||
if (CONDITION) { \
|
|
||||||
exit(0); \
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef struct process {
|
|
||||||
pid_t pid;
|
|
||||||
FILE *out;
|
|
||||||
} process_t;
|
|
||||||
|
|
||||||
process_t process_open(char *command) {
|
|
||||||
int fds[2];
|
|
||||||
check(pipe(fds));
|
|
||||||
int pid = fork();
|
|
||||||
check(pid == -1);
|
|
||||||
if (pid == 0) { // child process
|
|
||||||
close(fds[0]);
|
|
||||||
dup2(fds[1], STDOUT_FILENO);
|
|
||||||
dup2(STDOUT_FILENO, STDERR_FILENO);
|
|
||||||
char *argv[] = {"sh", "-c", command, NULL};
|
|
||||||
exit(execvp(argv[0], argv));
|
|
||||||
} else { // parent process
|
|
||||||
close(fds[1]);
|
|
||||||
process_t process = {pid, fdopen(fds[0], "rb")};
|
|
||||||
return process;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int process_close(process_t process) {
|
|
||||||
fclose(process.out);
|
|
||||||
int status;
|
|
||||||
check(process.pid != waitpid(process.pid, &status, 0));
|
|
||||||
if (WIFEXITED(status)) {
|
|
||||||
return WEXITSTATUS(status);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
char *trim(char *str) {
|
|
||||||
char *end;
|
|
||||||
while (isspace((unsigned char)*str)) {
|
|
||||||
str++;
|
|
||||||
}
|
|
||||||
if (*str == 0) {
|
|
||||||
return str;
|
|
||||||
}
|
|
||||||
end = str + strlen(str) - 1;
|
|
||||||
while (end > str && isspace((unsigned char)*end)) {
|
|
||||||
end--;
|
|
||||||
}
|
|
||||||
end[1] = '\0';
|
|
||||||
return str;
|
|
||||||
}
|
|
||||||
|
|
||||||
char *append(char *buffer, int count, ...) {
|
|
||||||
va_list list;
|
|
||||||
va_start(list, count);
|
|
||||||
for (int i = 0; i < count; i++) {
|
|
||||||
strcat(buffer, va_arg(list, char *));
|
|
||||||
}
|
|
||||||
va_end(list);
|
|
||||||
return buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
char *inttostr(char *buffer, int value) {
|
|
||||||
sprintf(buffer, "%d", value);
|
|
||||||
return buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
int main() {
|
|
||||||
// get the current branch name
|
|
||||||
process_t process = process_open("git symbolic-ref --short HEAD");
|
|
||||||
char branch_buf[256] = {};
|
|
||||||
fread(branch_buf, 1, sizeof(branch_buf), process.out);
|
|
||||||
if (process_close(process)) {
|
|
||||||
// current HEAD is not a symbolic ref
|
|
||||||
process = process_open("git rev-parse --abbrev-ref HEAD");
|
|
||||||
memset(branch_buf, 0, sizeof(branch_buf));
|
|
||||||
fread(branch_buf, 1, sizeof(branch_buf), process.out);
|
|
||||||
check(process_close(process));
|
|
||||||
if (strcmp("HEAD", trim(branch_buf)) == 0) {
|
|
||||||
// get the commit hash
|
|
||||||
process = process_open("git rev-parse --short HEAD");
|
|
||||||
memset(branch_buf, 0, sizeof(branch_buf));
|
|
||||||
fread(branch_buf, 1, sizeof(branch_buf), process.out);
|
|
||||||
check(process_close(process));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
char *branch = trim(branch_buf);
|
|
||||||
char prompt[1024] = {};
|
|
||||||
append(prompt, 3, " %{%F{66}%}", branch, "%{%f%}");
|
|
||||||
|
|
||||||
// get the upstream remote if one exists
|
|
||||||
char command[1024] = {};
|
|
||||||
append(command, 3, "git config branch.", branch, ".remote");
|
|
||||||
process = process_open(command);
|
|
||||||
char remote_buf[256] = {};
|
|
||||||
fread(remote_buf, 1, sizeof(remote_buf), process.out);
|
|
||||||
if (process_close(process) == 0) {
|
|
||||||
char *remote = trim(remote_buf);
|
|
||||||
// get the number of commits ahead of the remote
|
|
||||||
memset(command, 0, sizeof(command));
|
|
||||||
process = process_open(append(command, 5,
|
|
||||||
"git rev-list --right-only refs/remotes/",
|
|
||||||
remote, "/", branch, "...HEAD --count"));
|
|
||||||
char count[32] = {};
|
|
||||||
fread(count, 1, sizeof(count), process.out);
|
|
||||||
if (process_close(process) == 0 && strcmp("0", trim(count))) {
|
|
||||||
append(prompt, 2, "↑", trim(count));
|
|
||||||
}
|
|
||||||
|
|
||||||
// get the number of commits behind the remote
|
|
||||||
memset(command, 0, sizeof(command));
|
|
||||||
process = process_open(append(command, 5,
|
|
||||||
"git rev-list --left-only refs/remotes/",
|
|
||||||
remote, "/", branch, "...HEAD --count"));
|
|
||||||
memset(count, 0, sizeof(count));
|
|
||||||
fread(count, 1, sizeof(count), process.out);
|
|
||||||
if (process_close(process) == 0 && strcmp("0", trim(count))) {
|
|
||||||
append(prompt, 2, "↓", trim(count));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
append(prompt, 1, " ");
|
|
||||||
|
|
||||||
// get the status and parse it
|
|
||||||
process = process_open("git status --porcelain");
|
|
||||||
char status[2048];
|
|
||||||
int indexed = 0, modified = 0, deleted = 0, untracked = 0, unmerged = 0;
|
|
||||||
while (NULL != fgets(status, sizeof(status) - 1, process.out)) {
|
|
||||||
char X = status[0];
|
|
||||||
char Y = status[1];
|
|
||||||
|
|
||||||
if (X == '?' && Y == '?') {
|
|
||||||
++untracked;
|
|
||||||
} else if ((X == 'A' && (Y == 'A' || Y == 'U')) ||
|
|
||||||
(X == 'D' && (Y == 'D' || Y == 'U')) ||
|
|
||||||
(X == 'U' && (Y == 'A' || Y == 'D' || Y == 'D' || Y == 'U'))) {
|
|
||||||
++unmerged;
|
|
||||||
} else {
|
|
||||||
switch (X) {
|
|
||||||
case ' ':
|
|
||||||
switch (Y) {
|
|
||||||
case 'M': ++modified; break;
|
|
||||||
case 'D': ++deleted; break;
|
|
||||||
} break;
|
|
||||||
case 'D': ++indexed;
|
|
||||||
switch (Y) {
|
|
||||||
case ' ': break;
|
|
||||||
case 'M': ++modified; break;
|
|
||||||
} break;
|
|
||||||
case 'M': case 'A': case 'R': case 'C': ++indexed;
|
|
||||||
switch (Y) {
|
|
||||||
case ' ': break;
|
|
||||||
case 'M': ++modified; break;
|
|
||||||
case 'D': ++deleted; break;
|
|
||||||
} break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
check(process_close(process));
|
|
||||||
|
|
||||||
if (indexed || modified || deleted || unmerged || untracked) { // modified
|
|
||||||
char int_buf[32];
|
|
||||||
if (indexed) {
|
|
||||||
append(prompt, 3, "%{%F{2}%}*", inttostr(int_buf, indexed), "%{%f%}");
|
|
||||||
}
|
|
||||||
if (modified) {
|
|
||||||
append(prompt, 3, "%{%F{1}%}+", inttostr(int_buf, modified), "%{%f%}");
|
|
||||||
}
|
|
||||||
if (deleted) {
|
|
||||||
append(prompt, 3, "%{%F{1}%}-", inttostr(int_buf, deleted), "%{%f%}");
|
|
||||||
}
|
|
||||||
if (unmerged) {
|
|
||||||
append(prompt, 3, "%{%B%F{1}%}×", inttostr(int_buf, unmerged), "%{%f%b%}");
|
|
||||||
}
|
|
||||||
if (untracked) {
|
|
||||||
append(prompt, 1, "%{%F{1}%}…%{%f%}");
|
|
||||||
}
|
|
||||||
} else { // clean
|
|
||||||
append(prompt, 1, "%{%B%F{2}%}✓%{%f%b%}");
|
|
||||||
}
|
|
||||||
|
|
||||||
// print the prompt
|
|
||||||
puts(prompt);
|
|
||||||
return 0;
|
|
||||||
}
|
|
92
install.zsh
92
install.zsh
@ -1,92 +0,0 @@
|
|||||||
#!/usr/bin/env zsh
|
|
||||||
|
|
||||||
error() {
|
|
||||||
echo "error: $*"
|
|
||||||
exit 1
|
|
||||||
}
|
|
||||||
|
|
||||||
directories=(
|
|
||||||
~/.cache/zsh
|
|
||||||
~/.local/bin
|
|
||||||
~/.local/share/zsh/plugins
|
|
||||||
~/.local/share/zsh/site-functions
|
|
||||||
)
|
|
||||||
|
|
||||||
for directory in $directories; do
|
|
||||||
mkdir -p $directory
|
|
||||||
done
|
|
||||||
|
|
||||||
plugins=(
|
|
||||||
zsh-users/zsh-autosuggestions
|
|
||||||
zsh-users/zsh-history-substring-search
|
|
||||||
zsh-users/zsh-syntax-highlighting
|
|
||||||
zsh-users/zsh-completions
|
|
||||||
)
|
|
||||||
|
|
||||||
for plugin in $plugins; do
|
|
||||||
plugin_name=${plugin/*\//}
|
|
||||||
plugin_directory=~/.local/share/zsh/plugins/$plugin_name
|
|
||||||
if [ -d $plugin_directory ]; then
|
|
||||||
if ! git -C $plugin_directory diff-index --quiet HEAD --; then
|
|
||||||
error $plugin_directory contains unstaged changes
|
|
||||||
fi
|
|
||||||
pull=`git -C $plugin_directory pull`
|
|
||||||
if [ "$pull" != "Already up to date." ] && \
|
|
||||||
[ "$pull" != "Already up-to-date." ]; then
|
|
||||||
echo changed pulled $plugin_directory
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
git clone https://github.com/$plugin.git $plugin_directory > /dev/null
|
|
||||||
echo changed cloned $plugin_directory
|
|
||||||
fi
|
|
||||||
old_plugin_directory=~/.config/zsh/$plugin_name
|
|
||||||
if [ -d $old_plugin_directory ]; then
|
|
||||||
rm -rf $old_plugin_directory
|
|
||||||
echo changed removed $old_plugin_directory
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
declare -A symlinks
|
|
||||||
symlinks=(
|
|
||||||
~/.config/zsh/zlogin ~/.zlogin
|
|
||||||
~/.config/zsh/zlogout ~/.zlogout
|
|
||||||
~/.config/zsh/zprofile ~/.zprofile
|
|
||||||
~/.config/zsh/zshenv ~/.zshenv
|
|
||||||
~/.config/zsh/zshrc ~/.zshrc
|
|
||||||
~/.config/zsh/prompt_fresh_setup
|
|
||||||
~/.local/share/zsh/site-functions/prompt_fresh_setup
|
|
||||||
~/.config/zsh/cmake-uninstall ~/.local/bin/cmake-uninstall
|
|
||||||
~/.config/zsh/$ ~/.local/bin/$
|
|
||||||
~/.config/zsh/url/url ~/.local/bin/url
|
|
||||||
)
|
|
||||||
|
|
||||||
for completion in ~/.config/zsh/**/_*; do
|
|
||||||
filename=`basename $completion`
|
|
||||||
symlinks[$completion]=~/.local/share/zsh/site-functions/$filename
|
|
||||||
done
|
|
||||||
|
|
||||||
completions=( ~/.local/share/zsh/plugins/zsh-completions/src/* )
|
|
||||||
for completion in $completions; do
|
|
||||||
filename=`basename $completion`
|
|
||||||
name=${filename:1}
|
|
||||||
if command -v $name > /dev/null; then
|
|
||||||
symlinks[$completion]=~/.local/share/zsh/site-functions/$filename
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
for source in ${(k)symlinks}; do
|
|
||||||
dest=$symlinks[$source]
|
|
||||||
if [ -L $dest ]; then
|
|
||||||
target=`readlink $dest`
|
|
||||||
if [ "$target" != "$source" ]; then
|
|
||||||
rm $dest
|
|
||||||
ln -s $source $dest
|
|
||||||
echo changed replace incorrect symlink $dest
|
|
||||||
fi
|
|
||||||
elif [ -f $dest ]; then
|
|
||||||
error symlink failed $dest exists but is a regular file
|
|
||||||
else
|
|
||||||
ln -s $source $dest
|
|
||||||
echo changed created symlink $dest
|
|
||||||
fi
|
|
||||||
done
|
|
@ -1,7 +1,7 @@
|
|||||||
#compdef layout
|
#compdef layout
|
||||||
|
|
||||||
__get_layouts() {
|
__get_layouts() {
|
||||||
ls -1 ~/.local/share/tmux/layouts 2>/dev/null | \
|
ls -1 ~/.config/tmux/layouts 2>/dev/null | \
|
||||||
while read -r layout; do echo $layout; done
|
while read -r layout; do echo $layout; done
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@ layout() {
|
|||||||
if [[ "$1" == "" ]]; then
|
if [[ "$1" == "" ]]; then
|
||||||
echo "usage: layout <layout> [name]"
|
echo "usage: layout <layout> [name]"
|
||||||
else
|
else
|
||||||
~/.local/share/tmux/layouts/$1
|
tmux source-file ~/.config/tmux/layouts/$1
|
||||||
if [[ "$2" != "" ]]; then
|
if [[ "$2" != "" ]]; then
|
||||||
tmux rename-window $2
|
tmux rename-window $2
|
||||||
fi
|
fi
|
||||||
|
@ -1,22 +0,0 @@
|
|||||||
#!/usr/bin/env zsh
|
|
||||||
|
|
||||||
# Loop over available completions and add existing commands to array.
|
|
||||||
local -a completions
|
|
||||||
completions=(~/.config/zsh/zsh-completions/src/*)
|
|
||||||
local -a command_list
|
|
||||||
for completion in $completions; do
|
|
||||||
local filename=$(basename $completion)
|
|
||||||
local name=${filename:1}
|
|
||||||
if command -v $name &> /dev/null; then
|
|
||||||
command_list+=($name)
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
# Print JSON array of commands Ansible can consume.
|
|
||||||
echo '['
|
|
||||||
local length=${#command_list[@]}
|
|
||||||
for (( i = 1; i < $length; i++ )); do
|
|
||||||
echo " \"${command_list[$i]}\","
|
|
||||||
done
|
|
||||||
echo " \"${command_list[-1]}\""
|
|
||||||
echo ']'
|
|
@ -1,6 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
for d in /sys/kernel/iommu_groups/*/devices/*; do
|
|
||||||
n=${d#*/iommu_groups/*}; n=${n%%/*}
|
|
||||||
printf '%s ' "$n"
|
|
||||||
lspci -nns "${d##*/}"
|
|
||||||
done
|
|
@ -1,18 +1,17 @@
|
|||||||
prompt_fresh_help() {
|
prompt_fresh_help() {
|
||||||
echo "\
|
echo "\
|
||||||
options:
|
options:
|
||||||
-a enable almostontop like behaviour
|
-a enable almostontop like behaviour"
|
||||||
-r recompile git-prompt executable"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
prompt_fresh_setup() {
|
prompt_fresh_setup() {
|
||||||
|
fresh_compile_git_prompt
|
||||||
|
|
||||||
# Parse options
|
# Parse options
|
||||||
local almostontop=0
|
local almostontop=0
|
||||||
local recompile=0
|
while getopts 'a' opt; do
|
||||||
while getopts 'ar' opt; do
|
|
||||||
case $opt in
|
case $opt in
|
||||||
a) local almostontop=1 ;;
|
a) local almostontop=1 ;;
|
||||||
r) local recompile=1 ;;
|
|
||||||
*) prompt -h fresh; return 1 ;;
|
*) prompt -h fresh; return 1 ;;
|
||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
@ -20,173 +19,199 @@ prompt_fresh_setup() {
|
|||||||
autoload -U add-zsh-hook
|
autoload -U add-zsh-hook
|
||||||
|
|
||||||
# Hook to print the first line of the "two line" prompt, this line is not
|
# Hook to print the first line of the "two line" prompt, this line is not
|
||||||
# actually part of the prompt so does not get redrawn, this is preferable
|
# actually part of the prompt so does not get redrawn which can sometimes
|
||||||
# since sometimes lines before the prompt can disappear.
|
# cause lines before the prompt to disappear.
|
||||||
add-zsh-hook precmd fresh_line_one
|
add-zsh-hook precmd fresh_line_one
|
||||||
|
|
||||||
if [ $almostontop -eq 1 ]; then
|
if [ $almostontop -eq 1 ]; then
|
||||||
# Hook to clear the screen then prints the prompt with previous command at
|
# Hook to clear the screen then prints the prompt with previous command at
|
||||||
# the top of the screen.
|
# the top of the screen.
|
||||||
add-zsh-hook precmd fresh_almostontop_precmd
|
add-zsh-hook preexec fresh_almostontop
|
||||||
add-zsh-hook preexec fresh_almostontop_preexec
|
|
||||||
else
|
else
|
||||||
add-zsh-hook -d preexec fresh_almostontop_preexec
|
add-zsh-hook -d preexec fresh_almostontop
|
||||||
add-zsh-hook -d precmd fresh_almostontop_precmd
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
[ $recompile -eq 1 ] && prompt_cleanup
|
if [ "$USERNAME" = "root" ]; then
|
||||||
fresh_compile_git_prompt
|
local user="%{%F{9}%}%n%{%f%}"
|
||||||
|
|
||||||
if [ "$USER" = "root" ]; then
|
|
||||||
local user="%{%F{1}%}%n%{%f%}"
|
|
||||||
else
|
else
|
||||||
local user="%{%F{35}%}%n%{%f%}"
|
local user="%{%F{35}%}%n%{%f%}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
local userhost=$USER
|
if [ "$SSH_CONNECTION" != "" ]; then
|
||||||
if [ "$SSH_CONNECTION" != "" ] || [ "$container" != "" ]; then
|
local user="%{%F{35}%}$user%{%f%}@%{%F{244}%}%M%{%f%}"
|
||||||
local user="$user@%{%F{244}%}%M%{%f%}"
|
|
||||||
local userhost="$userhost@`hostname`"
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
PS1="$user "
|
local length=`fresh_visible_length "$user"`
|
||||||
PS2="${(l:${#userhost}:: :)} "
|
|
||||||
|
|
||||||
prompt_opts=(percent sp subst)
|
PS1="«$user» "
|
||||||
|
PS2="${(l:$length + 1:: :)}» "
|
||||||
|
|
||||||
|
RPS1='$(fresh_rprompt)'
|
||||||
|
|
||||||
|
prompt_opts=(cr percent sp subst)
|
||||||
}
|
}
|
||||||
|
|
||||||
prompt_cleanup() {
|
prompt_cleanup() {
|
||||||
[ -f ${XDG_CACHE_HOME:-$HOME/.cache}/zsh/git-prompt ] && \
|
if [ -f ~/.cache/zsh/git-prompt ]; then rm ~/.cache/zsh/git-prompt; fi
|
||||||
rm ${XDG_CACHE_HOME:-$HOME/.cache}/zsh/git-prompt
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fresh_line_one() {
|
fresh_line_one() {
|
||||||
# First get the last commands exit code before doing anything
|
# First get the last commands exit code before doing anything
|
||||||
local exit_code=$?
|
local exit_code=$?
|
||||||
|
|
||||||
# Clean up if fresh is no longer the current prompt theme
|
|
||||||
if [[ "`prompt -c | tail -1 | xargs`" != "fresh"* ]]; then
|
|
||||||
add-zsh-hook -d precmd fresh_line_one
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Construct the time and directory portions of the prompt
|
# Construct the time and directory portions of the prompt
|
||||||
local time_stamp="%{%F{244}%}%D{%H:%M:%S}%{%f%}"
|
local time_stamp="%{%F{244}%}%D{%H:%M:%S}%{%f%}"
|
||||||
[[ -n $SANDBOX_HOME ]] && \
|
local directory="%{%F{37}%}%~%{%f%}"
|
||||||
local directory="%{%F{220}%}$SANDBOX_NAME${PWD#$SANDBOX_HOME}%{%f%}" || \
|
|
||||||
local directory="%{%F{37}%}%~%{%f%}"
|
|
||||||
|
|
||||||
# Check we are in a git repository
|
# Check we are in a git repository
|
||||||
local git=`${XDG_CACHE_HOME:-$HOME/.cache}/zsh/git-prompt`
|
if `git rev-parse --git-dir > /dev/null 2>&1`; then
|
||||||
|
# Get git branch name & exit early if not found
|
||||||
|
local branch="`git symbolic-ref HEAD 2> /dev/null`"
|
||||||
|
if [ "" = "$branch" ]; then
|
||||||
|
local branch="`git rev-parse --abbrev-ref HEAD`"
|
||||||
|
if [ "HEAD" = "$branch" ]; then
|
||||||
|
local branch="`git rev-parse --short $branch`"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
# If the last command failed, display its error code at the right
|
if [ "$branch" != "" ]; then
|
||||||
if [[ $exit_code -ne 0 ]]; then
|
local branch=${branch#refs/heads/}
|
||||||
case $exit_code in
|
# Get the number of commits ahead/behind from the remote branch
|
||||||
129) exit_code="SIGHUP" ;; # 128 + 1
|
local remote="`git config branch.$branch.remote 2> /dev/null`"
|
||||||
130) exit_code="SIGINT" ;; # 128 + 2
|
if [ "" != "remote" ]; then
|
||||||
131) exit_code="SIGQUIT" ;; # 128 + 3
|
local branches="refs/remotes/$remote/$branch...HEAD"
|
||||||
132) exit_code="SIGILL" ;; # 128 + 4
|
local nahead=`git rev-list --right-only $branches --count 2> /dev/null`
|
||||||
133) exit_code="SIGTRAP" ;; # 128 + 5
|
if [ "0" -ne "$nahead" ]; then local ahead="↑$nahead"; fi
|
||||||
134) exit_code="SIGABRT" ;; # 128 + 6
|
local nbehind=`git rev-list --left-only $branches --count 2> /dev/null`
|
||||||
134) exit_code="SIGIOT" ;; # 128 + 6
|
if [ "0" -ne "$nbehind" ]; then local behind="↓$nbehind"; fi
|
||||||
135) exit_code="SIGBUS" ;; # 128 + 7
|
fi
|
||||||
136) exit_code="SIGFPE" ;; # 128 + 8
|
|
||||||
137) exit_code="SIGKILL" ;; # 128 + 9
|
# Construct the git prompt
|
||||||
138) exit_code="SIGUSR1" ;; # 128 + 10
|
local git="%{%F{66}%}$branch%{%f%}$ahead$behind "
|
||||||
139) exit_code="SIGSEGV" ;; # 128 + 11
|
|
||||||
140) exit_code="SIGUSR2" ;; # 128 + 12
|
if [ -f ~/.cache/zsh/git-prompt ]; then
|
||||||
141) exit_code="SIGPIPE" ;; # 128 + 13
|
# Get the change counts from git-prompt
|
||||||
142) exit_code="SIGALRM" ;; # 128 + 14
|
local counts=(`~/.cache/zsh/git-prompt`)
|
||||||
143) exit_code="SIGTERM" ;; # 128 + 15
|
|
||||||
144) exit_code="SIGSTKFLT" ;; # 128 + 16
|
# Parse the results from git-prompt
|
||||||
145) exit_code="SIGCHLD" ;; # 128 + 17
|
if [ 0 -eq ${#counts[@]} ]; then # clean
|
||||||
146) exit_code="SIGCONT" ;; # 128 + 18
|
local git="$git%{%B%F{2}%}✓%{%f%b%}";
|
||||||
147) exit_code="SIGSTOP" ;; # 128 + 19
|
else
|
||||||
148) exit_code="SIGTSTP" ;; # 128 + 20
|
if [ 0 != $counts[1] ]; then # indexed
|
||||||
149) exit_code="SIGTTIN" ;; # 128 + 21
|
local git="$git%{%F{2}%}*$counts[1]%{%f%}"
|
||||||
150) exit_code="SIGTTOU" ;; # 128 + 22
|
fi
|
||||||
151) exit_code="SIGURG" ;; # 128 + 23
|
if [ 0 != $counts[2] ]; then # modified
|
||||||
152) exit_code="SIGXCPU" ;; # 128 + 24
|
local git="$git%{%F{1}%}+$counts[2]%{%f%}";
|
||||||
153) exit_code="SIGXFSZ" ;; # 128 + 25
|
fi
|
||||||
154) exit_code="SIGVTALRM" ;; # 128 + 26
|
if [ 0 != $counts[3] ]; then # deleted
|
||||||
155) exit_code="SIGPROF" ;; # 128 + 27
|
local git="$git%{%F{1}%}-$counts[3]%{%f%}";
|
||||||
156) exit_code="SIGWINCH" ;; # 128 + 28
|
fi
|
||||||
157) exit_code="SIGIO" ;; # 128 + 29
|
if [ 0 != $counts[4] ]; then # unmerged
|
||||||
158) exit_code="SIGPWR" ;; # 128 + 30
|
local git="$git%{%B%F{1}%}×$counts[4]%{%f%b%}";
|
||||||
159) exit_code="SIGSYS" ;; # 128 + 31
|
fi
|
||||||
esac
|
if [ 0 != $counts[5] ]; then # untracked
|
||||||
local result=" %{%B%F{1}%}$exit_code%{%f%b%}"
|
local git="$git%{%F{1}%}…%{%f%}";
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Unset vim/tmux navigate flag to handle C-z and multiple vim jobs.
|
# Construct the prompt string
|
||||||
[[ ! -z "$TMUX" ]] && \
|
local line="$time_stamp $directory $git"
|
||||||
[[ "`tmux show-window-options`" = *"@vim$TMUX_PANE"* ]] && \
|
|
||||||
tmux set-window-option -u @vim$TMUX_PANE
|
|
||||||
|
|
||||||
# If a virtualenv is enabled, display it's basename
|
|
||||||
if [[ ! -z "$VIRTUAL_ENV" ]]; then
|
|
||||||
local py=" %{%F{4}%}py%{%f%}%{%F{3}%}$(basename $VIRTUAL_ENV)%{%f%}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# If docker-machine env is active, display the machines name
|
|
||||||
if [[ ! -z "$DOCKER_MACHINE_NAME" ]]; then
|
|
||||||
local docker=" %{%F{6}%}$DOCKER_MACHINE_NAME%{%f%}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Print the first line of the prompt
|
# Print the first line of the prompt
|
||||||
print -P "$time_stamp $directory$git$py$docker$result"
|
if [[ $exit_code -eq 0 ]]; then
|
||||||
|
print -P "$line"
|
||||||
|
else
|
||||||
|
# The last command failed, display its error code at the right
|
||||||
|
local result="%{%B%F{1}%}$exit_code%{%f%b%}"
|
||||||
|
local length=`fresh_visible_length "$line$result"`
|
||||||
|
print -P "$line${(l:COLUMNS - $length - 1:: :)}$result"
|
||||||
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
# Executed before each prompt.
|
fresh_rprompt() {
|
||||||
fresh_almostontop_precmd() {
|
rprompt=""
|
||||||
# CSI ESC[6n gets the cursor position in the form ESC[<row>;<column>R
|
if [[ ! -z "$DOCKER_MACHINE_NAME" ]]; then
|
||||||
printf "\033[6n"
|
rprompt="$rprompt %{%F{3}%}$DOCKER_MACHINE_NAME%{%f%}"
|
||||||
# Discard prefix delimited by [
|
fi
|
||||||
read -s -d [
|
if [[ ! -z "$VIRTUAL_ENV" ]]; then
|
||||||
# Store the <row> delimited by ; in row_before
|
rprompt="$rprompt %{%F{3}%}$(basename $VIRTUAL_ENV)%{%f%}"
|
||||||
read -s -d \; row_before
|
fi
|
||||||
# Discard suffix delimted by R otherwise it is output to the tty
|
echo $rprompt
|
||||||
read -s -d R
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# Executed just after a command has been read and is about to be executed.
|
fresh_almostontop() {
|
||||||
fresh_almostontop_preexec() {
|
clear
|
||||||
# CSI ESC[6n gets the cursor position in the form ESC[<row>;<column>R
|
fresh_line_one
|
||||||
printf "\033[6n"
|
print -P "$PROMPT"'$1'
|
||||||
# Discard prefix delimited by [
|
}
|
||||||
read -s -d [
|
|
||||||
# Store the <row> delimited by ; in row
|
fresh_visible_length() {
|
||||||
read -s -d \; row
|
echo $(( ${#${(S%%)1//(\%(KF1]|)\{*\}|\%[Bbkf])}} ))
|
||||||
# Discard suffix delimted by R otherwise it is output to the tty
|
|
||||||
read -s -d R
|
|
||||||
# Move the cursor to the bottom of the terminal
|
|
||||||
# CSI ESC[<num>B moves the cursor down <num> lines
|
|
||||||
let "down = $LINES - $row"
|
|
||||||
printf "\033[${down}B"
|
|
||||||
# Calculate the number of lines in the prompt
|
|
||||||
let "prompt_lines = ($row - $row_before) + 2"
|
|
||||||
# Print new lines to push the old command out of view
|
|
||||||
let "new = $row - $prompt_lines"
|
|
||||||
for (( i = 0; i < $new; i++ )); do
|
|
||||||
printf "\n"
|
|
||||||
done
|
|
||||||
# Move the cursor to the line below the prompt
|
|
||||||
# CSI ESC[<num>A moves the cursor up <num> lines
|
|
||||||
let "up = $LINES - $prompt_lines"
|
|
||||||
printf "\033[${up}A"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fresh_compile_git_prompt() {
|
fresh_compile_git_prompt() {
|
||||||
# Compile a simple C program which parses the output of `git status
|
# Compile a simple C executable which parses the output of `git status
|
||||||
# --procelain` to greatly decrease the time taken to draw the prompt
|
# --procelain` to greatly decrease the time taken to render the prompt
|
||||||
[ ! -d ${XDG_CACHE_HOME:-$HOME/.cache}/zsh ] && \
|
local cache=~/.cache/zsh
|
||||||
mkdir -p ${XDG_CACHE_HOME:-$HOME/.cache}/zsh
|
if [ ! -d $cache ]; then mkdir -p $cache; fi
|
||||||
if [ ! -f ${XDG_CACHE_HOME:-$HOME/.cache}/zsh/git-prompt ]; then
|
if [ ! -f $cache/git-prompt ]; then
|
||||||
cc -std=gnu99 -O3 -DNDEBUG -Wno-unused-result \
|
cc -x c -std=gnu99 -O3 -DNDEBUG -o $cache/git-prompt - 2> /dev/null << EOF
|
||||||
${XDG_CONFIG_HOME:-$HOME/.config}/zsh/git-prompt.c \
|
#include <stdio.h>
|
||||||
-o ${XDG_CACHE_HOME:-$HOME/.cache}/zsh/git-prompt
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
FILE *file = popen("git status --porcelain", "r");
|
||||||
|
if (NULL == file) { return 0; }
|
||||||
|
|
||||||
|
char status[2048];
|
||||||
|
int indexed = 0, modified = 0, deleted = 0, untracked = 0, unmerged = 0;
|
||||||
|
|
||||||
|
while (NULL != fgets(status, sizeof(status) - 1, file)) {
|
||||||
|
char X = status[0];
|
||||||
|
char Y = status[1];
|
||||||
|
|
||||||
|
if (X == '?' && Y == '?') {
|
||||||
|
++untracked;
|
||||||
|
} else if ((X == 'A' && (Y == 'A' || Y == 'U')) ||
|
||||||
|
(X == 'D' && (Y == 'D' || Y == 'U')) ||
|
||||||
|
(X == 'U' && (Y == 'A' || Y == 'D' || Y == 'D' || Y == 'U'))) {
|
||||||
|
++unmerged;
|
||||||
|
} else {
|
||||||
|
switch (X) {
|
||||||
|
case ' ':
|
||||||
|
switch (Y) {
|
||||||
|
case 'M': ++modified; break;
|
||||||
|
case 'D': ++deleted; break;
|
||||||
|
} break;
|
||||||
|
case 'D': ++indexed;
|
||||||
|
switch (Y) {
|
||||||
|
case ' ': break;
|
||||||
|
case 'M': ++modified; break;
|
||||||
|
} break;
|
||||||
|
case 'M': case 'A': case 'R': case 'C': ++indexed;
|
||||||
|
switch (Y) {
|
||||||
|
case ' ': break;
|
||||||
|
case 'M': ++modified; break;
|
||||||
|
case 'D': ++deleted; break;
|
||||||
|
} break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pclose(file);
|
||||||
|
|
||||||
|
if (indexed || modified || deleted || unmerged || untracked) {
|
||||||
|
printf("%d %d %d %d %d", indexed, modified, deleted, unmerged, untracked);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
EOF
|
||||||
if [ $? -ne 0 ]; then
|
if [ $? -ne 0 ]; then
|
||||||
echo "git-prompt was not compiled, is a C99 toolchain installed?"
|
echo "git prompt disabled, are the system development headers installed?"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
@ -1,42 +1,46 @@
|
|||||||
#compdef sandbox
|
#compdef sandbox
|
||||||
|
|
||||||
|
__get_sandboxes() {
|
||||||
|
/bin/ls $SANDBOX_ROOT 2> /dev/null
|
||||||
|
}
|
||||||
|
|
||||||
__sandboxes() {
|
__sandboxes() {
|
||||||
local -a sandboxes
|
local -a sandboxes
|
||||||
sandboxes=(${(fo)"$(ls $SANDBOX_ROOT 2> /dev/null)"})
|
sandboxes=(${(fo)"$(__get_sandboxes)"})
|
||||||
_describe 'in' sandboxes
|
_describe 'in' sandboxes
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_sandbox_cmds() {
|
||||||
|
local commands; commands=(
|
||||||
|
'create:Create a new sandbox'
|
||||||
|
'rename:Rename an existing sandbox'
|
||||||
|
'destroy:Destroy an existing sandbox'
|
||||||
|
'list:Show all existing sandboxes'
|
||||||
|
'enable:Enable an existing sandbox'
|
||||||
|
'disable:Disable the current sandbox'
|
||||||
|
)
|
||||||
|
_describe -t commands 'sandbox command' commands "$@"
|
||||||
|
}
|
||||||
|
|
||||||
_sandbox() {
|
_sandbox() {
|
||||||
local context curcontext="$curcontext" state line
|
local context curcontext="$curcontext" state line
|
||||||
typeset -A opt_args
|
typeset -A opt_args
|
||||||
|
|
||||||
_arguments -C \
|
_arguments -C \
|
||||||
'1: :->cmd' \
|
'1: :_sandbox_cmds' \
|
||||||
'*:: :->args'
|
'*::arg:->args'
|
||||||
|
|
||||||
case $state in
|
case $state in
|
||||||
(cmd)
|
|
||||||
local commands; commands=(
|
|
||||||
'create:Create a new sandbox'
|
|
||||||
'rename:Rename an existing sandbox'
|
|
||||||
'destroy:Destroy an existing sandbox'
|
|
||||||
'list:Show all existing sandboxes'
|
|
||||||
'enable:Enable an existing sandbox'
|
|
||||||
'disable:Disable the current sandbox'
|
|
||||||
)
|
|
||||||
_describe -t commands 'sandbox command' commands "$@"
|
|
||||||
;;
|
|
||||||
|
|
||||||
(args)
|
(args)
|
||||||
curcontext="${curcontext%:*:*}:sandbox-cmd-$words[1]:"
|
curcontext="${curcontext%:*:*}:sandbox-cmd-$words[1]:"
|
||||||
case $line[1] in
|
case $line[1] in
|
||||||
(create)
|
(create|list|disable)
|
||||||
_arguments -C '--git[repository to clone]: :'
|
|
||||||
;;
|
;;
|
||||||
(rename|enable|destroy)
|
(enable|destroy)
|
||||||
_arguments -C '1:: :__sandboxes'
|
_arguments -C '1:: :__sandboxes'
|
||||||
;;
|
;;
|
||||||
(list|disable)
|
(rename)
|
||||||
|
_arguments -C '1:: :__sandboxes'
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
esac
|
esac
|
||||||
|
@ -1,127 +1,103 @@
|
|||||||
|
if [[ "" == $SANDBOX_ENV_IN_FILE ]]; then
|
||||||
|
export SANDBOX_ENV_IN_FILE=$AUTOENV_IN_FILE
|
||||||
|
fi
|
||||||
|
if [[ "" == $SANDBOX_ENV_OUT_FILE ]]; then
|
||||||
|
export SANDBOX_ENV_OUT_FILE=$AUTOENV_OUT_FILE
|
||||||
|
fi
|
||||||
if [[ "" == $SANDBOX_ROOT ]]; then
|
if [[ "" == $SANDBOX_ROOT ]]; then
|
||||||
export SANDBOX_ROOT=$HOME/Sandbox
|
export SANDBOX_ROOT=$HOME/Sandbox
|
||||||
fi
|
fi
|
||||||
|
|
||||||
sandbox() {
|
sandbox() {
|
||||||
local usage="\
|
local usage="usage: sandbox {create,destroy,enable,disable} [name]"
|
||||||
usage: sandbox [-h] {create,rename,destroy,enable,disable,list} ..
|
|
||||||
sandbox create [--git <repo>] <name>
|
|
||||||
sandbox rename <old-name> <new-name>
|
|
||||||
sandbox destroy <name>
|
|
||||||
sandbox enable <name>
|
|
||||||
sandbox disable
|
|
||||||
sandbox list"
|
|
||||||
|
|
||||||
error() { print -P "%F{red}error:%f $1" }
|
if [[ "" == $1 ]]; then
|
||||||
|
echo $usage
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
local cmd=$1
|
case $1 in
|
||||||
[[ -z "$cmd" ]] && \
|
|
||||||
error "missing command\n$usage" && return 1
|
|
||||||
shift 1
|
|
||||||
|
|
||||||
case $cmd in
|
|
||||||
create)
|
create)
|
||||||
# Parse command arguments.
|
if [[ "" == $2 ]]; then
|
||||||
local git=false
|
echo $usage
|
||||||
for arg in $@; do
|
return 1
|
||||||
if [ "${arg[1]}" = - ]; then
|
|
||||||
if [ "$git" = true ]; then
|
|
||||||
error "invalid --git <repo> $arg\n$usage" && return 1
|
|
||||||
elif [ "$arg" = --git ]; then
|
|
||||||
git=true
|
|
||||||
else
|
|
||||||
error "invalid option $arg\n$usage" && return 1
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
if [ "$git" = true ]; then
|
|
||||||
local repo=$arg
|
|
||||||
git=false
|
|
||||||
elif [[ -z "$name" ]]; then
|
|
||||||
error "invalid argument $arg\n$usage" && return 1
|
|
||||||
else
|
|
||||||
local name=$arg
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
unset git
|
|
||||||
[[ -z "$name" ]] && \
|
|
||||||
error "missing argument <name>\n$usage" && return 1
|
|
||||||
local sandbox=$SANDBOX_ROOT/$name
|
|
||||||
[[ -d "$sandbox" ]] && \
|
|
||||||
error "sandbox already exists $name" && return 1
|
|
||||||
if [[ -n "$repo" ]]; then
|
|
||||||
mkdir -p $SANDBOX_ROOT &> /dev/null
|
|
||||||
git clone $repo $sandbox
|
|
||||||
cd $sandbox
|
|
||||||
else
|
|
||||||
mkdir -p $sandbox &> /dev/null
|
|
||||||
cd $sandbox
|
|
||||||
git init &> /dev/null
|
|
||||||
fi
|
fi
|
||||||
echo "SANDBOX_HOME=\$(dirname -- "\$0:a")" >> $sandbox/.enter
|
|
||||||
echo "SANDBOX_NAME=$name" >> $sandbox/.enter
|
|
||||||
_autoenv_authorized $sandbox/.enter yes
|
|
||||||
echo "unset SANDBOX_NAME" >> $sandbox/.exit
|
|
||||||
echo "unset SANDBOX_HOME" >> $sandbox/.exit
|
|
||||||
_autoenv_authorized $sandbox/.exit yes
|
|
||||||
_autoenv_enter $sandbox
|
|
||||||
;;
|
|
||||||
|
|
||||||
|
local sandbox=$SANDBOX_ROOT/$2
|
||||||
|
if [[ -d $sandbox ]]; then
|
||||||
|
echo "Sandbox '$2' already exists"
|
||||||
|
return 2
|
||||||
|
fi
|
||||||
|
|
||||||
|
mkdir -p $sandbox &> /dev/null
|
||||||
|
begin=$PWD
|
||||||
|
cd $sandbox
|
||||||
|
|
||||||
|
echo "SANDBOX_HOME=\$(dirname -- "\$0:a")" >> $SANDBOX_ENV_IN_FILE
|
||||||
|
echo "SANDBOX_NAME=$2" >> $SANDBOX_ENV_IN_FILE
|
||||||
|
|
||||||
|
echo "unset SANDBOX_NAME" >> $SANDBOX_ENV_OUT_FILE
|
||||||
|
echo "unset SANDBOX_HOME" >> $SANDBOX_ENV_OUT_FILE
|
||||||
|
|
||||||
|
git init &> /dev/null
|
||||||
|
|
||||||
|
cd $begin
|
||||||
|
cd $sandbox
|
||||||
|
;;
|
||||||
rename)
|
rename)
|
||||||
local old_name=$1 new_name=$2
|
if [[ "" == $2 || "" == $3 ]]; then
|
||||||
[[ -z "$old_name" ]] && \
|
echo $usage
|
||||||
error "missing argument <old-name>\n$usage" && return 1
|
return 1
|
||||||
[[ -z "$new_name" ]] && \
|
fi
|
||||||
error "missing argument <new-name>\n$usage" && return 1
|
|
||||||
local old=$SANDBOX_ROOT/$old_name new=$SANDBOX_ROOT/$new_name
|
|
||||||
[[ ! -d "$old" ]] && \
|
|
||||||
error "sandbox does not exist $old_name" && return 1
|
|
||||||
[[ -d "$new" ]] && \
|
|
||||||
error "sandbox already exists $new_name" && return 1
|
|
||||||
[[ "$PWD" = "$old"* ]] && _autoenv_exit $PWD
|
|
||||||
mv $old $new
|
|
||||||
sed -i "s/$old_name/$new_name/g" $new/.enter
|
|
||||||
_autoenv_authorized $new/.enter yes
|
|
||||||
_autoenv_authorized $new/.exit yes
|
|
||||||
[[ "$PWD" = "$old"* ]] && cd $new
|
|
||||||
;;
|
|
||||||
|
|
||||||
|
mv $SANDBOX_ROOT/$2 $SANDBOX_ROOT/$3
|
||||||
|
sed -i "" "s/$2/$3/g" $SANDBOX_ROOT/$3/.env
|
||||||
|
;;
|
||||||
destroy)
|
destroy)
|
||||||
local name=$1
|
if [[ "" == $2 ]]; then
|
||||||
[[ -z "$name" ]] && \
|
echo $usage
|
||||||
error "missing argument <name>\n$usage" && return 1
|
return 1
|
||||||
local sandbox=$SANDBOX_ROOT/$name
|
fi
|
||||||
[[ ! -d $sandbox ]] && \
|
|
||||||
error "sandbox does not exist $name" && return 1
|
local sandbox=$SANDBOX_ROOT/$2
|
||||||
[[ "$PWD" = "$sandbox"* ]] && cd ~
|
if [[ ! -d $sandbox ]]; then
|
||||||
|
echo "Sandbox '$2' does not exist"
|
||||||
|
return 2
|
||||||
|
fi
|
||||||
|
|
||||||
|
cd -
|
||||||
|
if [[ "${SANDBOX_ROOT##$PWD}" = "${SANDBOX_ROOT}" ]]; then
|
||||||
|
cd $HOME
|
||||||
|
fi
|
||||||
|
|
||||||
rm -rf $sandbox
|
rm -rf $sandbox
|
||||||
;;
|
;;
|
||||||
|
|
||||||
list)
|
list)
|
||||||
ls -1 $SANDBOX_ROOT | less -F -K -R -X
|
/bin/ls -1 $SANDBOX_ROOT
|
||||||
;;
|
;;
|
||||||
|
|
||||||
enable)
|
enable)
|
||||||
local name=$1
|
if [[ "" == $2 ]]; then
|
||||||
[[ -z "$name" ]] && \
|
echo $usage
|
||||||
error "missing argument <name>\n$usage" && return 1
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
local sandbox=$SANDBOX_ROOT/$2
|
||||||
|
if [[ ! -d $sandbox ]]; then
|
||||||
|
echo "Sandbox '$2' does not exist"
|
||||||
|
return 2
|
||||||
|
fi
|
||||||
|
|
||||||
local sandbox=$SANDBOX_ROOT/$name
|
|
||||||
[[ ! -d $sandbox ]] && \
|
|
||||||
error "sandbox does not exist $name" && return 1
|
|
||||||
export SANDBOX_RETURN=$PWD
|
export SANDBOX_RETURN=$PWD
|
||||||
cd $sandbox
|
cd $sandbox
|
||||||
;;
|
;;
|
||||||
|
|
||||||
disable)
|
disable)
|
||||||
[[ -z "$SANDBOX_RETURN" ]] && \
|
if [[ -z $SANDBOX_RETURN ]]; then
|
||||||
error "sandbox is not currently active" && return 1
|
echo "Sandbox is not currently active"
|
||||||
cd $SANDBOX_RETURN
|
return 2
|
||||||
unset SANDBOX_RETURN
|
fi
|
||||||
;;
|
|
||||||
|
|
||||||
*)
|
cd $SANDBOX_RETURN
|
||||||
error "invalid sandbox command: $cmd" && return 1
|
unset $SANDBOX_RETURN
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
}
|
}
|
||||||
|
@ -1,32 +0,0 @@
|
|||||||
#compdef session
|
|
||||||
|
|
||||||
__session_sessions() {
|
|
||||||
list() {
|
|
||||||
for item in $HOME/.local/share/tmux/layouts/session-*; do
|
|
||||||
item=${item#$HOME/.local/share/tmux/layouts/}
|
|
||||||
echo ${item#session-}
|
|
||||||
done
|
|
||||||
}
|
|
||||||
local -a sessions
|
|
||||||
sessions=(${(fo)"$(list)"})
|
|
||||||
_describe 'session' sessions
|
|
||||||
}
|
|
||||||
|
|
||||||
__session_hosts() {
|
|
||||||
list() {
|
|
||||||
declare -A hosts
|
|
||||||
if [ -f ~/.config/session ]; then
|
|
||||||
source ~/.config/session
|
|
||||||
for key val in "${(@kv)hosts}"; do
|
|
||||||
echo $key
|
|
||||||
done
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
local -a hosts
|
|
||||||
hosts=(${(fo)"$(list)"})
|
|
||||||
_describe 'host' hosts
|
|
||||||
}
|
|
||||||
|
|
||||||
_arguments \
|
|
||||||
':session:__session_sessions' \
|
|
||||||
':host:__session_hosts'
|
|
@ -1,33 +0,0 @@
|
|||||||
session() {
|
|
||||||
if [[ "$1" == "" ]]; then
|
|
||||||
echo "usage: session <name> [<host>]"
|
|
||||||
else
|
|
||||||
local name=$1
|
|
||||||
local host=$2
|
|
||||||
if [[ "$3" != "" ]]; then
|
|
||||||
echo "$fg[red]error:$reset_color invalid argument: $3"
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
declare -A hosts
|
|
||||||
if [ -f ~/.config/session ]; then
|
|
||||||
source ~/.config/session
|
|
||||||
fi
|
|
||||||
local url=$hosts[$host]
|
|
||||||
host=${url:-$host}
|
|
||||||
if [[ "$TMUX" == "" ]]; then
|
|
||||||
local cmd="tmux new-session -As $name"
|
|
||||||
if [[ "$host" != "" ]]; then
|
|
||||||
cmd="ssh $host -t $cmd"
|
|
||||||
fi
|
|
||||||
eval $cmd
|
|
||||||
else
|
|
||||||
if [[ "$host" != "" ]]; then
|
|
||||||
echo "$fg[red]error:$reset_color <host> not allowed inside tmux session"
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
tmux list-sessions | grep "$name:" &> /dev/null || \
|
|
||||||
tmux new-session -Ads $name -c $HOME
|
|
||||||
tmux switch-client -t $name
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
}
|
|
22
url/_url
22
url/_url
@ -1,22 +0,0 @@
|
|||||||
#compdef url
|
|
||||||
|
|
||||||
_url() {
|
|
||||||
local ret=1 context curcontext="$curcontext" state line
|
|
||||||
typeset -A opt_args
|
|
||||||
|
|
||||||
_arguments -C -w -s \
|
|
||||||
'(-h --help)'{-h,--help}'[show this help message and exit]' \
|
|
||||||
'1: :->command'
|
|
||||||
|
|
||||||
case $state in
|
|
||||||
(command)
|
|
||||||
declare -a commands
|
|
||||||
local commands=(
|
|
||||||
encode:'encode unencoded text'
|
|
||||||
decode:'decode encoded text'
|
|
||||||
)
|
|
||||||
_describe -t commands command commands && ret=0 ;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
return ret
|
|
||||||
}
|
|
27
url/url
27
url/url
@ -1,27 +0,0 @@
|
|||||||
#!/usr/bin/env python
|
|
||||||
"""URL encode or decode text."""
|
|
||||||
|
|
||||||
from argparse import ArgumentParser
|
|
||||||
from urllib import parse
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
|
||||||
cli = ArgumentParser(description=__doc__)
|
|
||||||
cli.add_argument('command',
|
|
||||||
choices=['encode', 'decode'],
|
|
||||||
help='type of processing to perform on text')
|
|
||||||
cli.add_argument('text',
|
|
||||||
nargs='?',
|
|
||||||
help='optional text read from stdin when omitted')
|
|
||||||
args = cli.parse_args()
|
|
||||||
print({
|
|
||||||
'encode': parse.quote_plus,
|
|
||||||
'decode': parse.unquote_plus,
|
|
||||||
}[args.command](args.text if args.text else input()))
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
try:
|
|
||||||
main()
|
|
||||||
except KeyboardInterrupt:
|
|
||||||
exit(130)
|
|
@ -1,195 +0,0 @@
|
|||||||
# A collection of various shell utilities.
|
|
||||||
|
|
||||||
autoload colors && colors
|
|
||||||
|
|
||||||
# Abstract different ways to copy to the clipboard.
|
|
||||||
if [ -n "$SSH_CONNECTION" ] ; then
|
|
||||||
# Use OSC-52 to set the clipboard
|
|
||||||
alias copy='base64 | xargs -0 printf "\033]52;c;%s\a"'
|
|
||||||
elif [ "`uname`" = "Darwin" ]; then
|
|
||||||
# Use pbcopy to set the clipboard
|
|
||||||
alias copy='pbcopy'
|
|
||||||
elif which xclip &> /dev/null; then
|
|
||||||
# Use xclip to set the clipboard
|
|
||||||
alias copy='xclip -selection c'
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Abstract different ways to paste from the clipboard.
|
|
||||||
# TODO: Use OSC-52 to get the clipboard, not widely supported though
|
|
||||||
if [ "`uname`" = "Darwin" ]; then
|
|
||||||
# Use pbpaste to get the clipboard
|
|
||||||
alias paste='pbpaste'
|
|
||||||
elif which xclip &> /dev/null; then
|
|
||||||
# Use xclip to get the clipboard
|
|
||||||
alias paste='xclip -selection c -o'
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Passthrough an escape sequences tmux doesn't know about.
|
|
||||||
tmux-dcs-passthrough() {
|
|
||||||
local escape_sequence=$1
|
|
||||||
if [ -n "$TMUX" ]; then
|
|
||||||
# Replace single \x1b or \033 with two, this is required for tmux to
|
|
||||||
# properly pass-through the escape sequence.
|
|
||||||
escape_sequence=${escape_sequence//\\x1b/\\x1b\\x1b}
|
|
||||||
escape_sequence=${escape_sequence//\\033/\\x1b\\x1b}
|
|
||||||
printf '\x1bPtmux;\x1b'"$escape_sequence"'\x1b\\'
|
|
||||||
else
|
|
||||||
printf "$escape_sequence"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# OSC 9 - Post a notification - supported by iTerm2, kitty, WezTerm, others?
|
|
||||||
notify() {
|
|
||||||
tmux-dcs-passthrough '\x1b]9;'"$*"'\x7'
|
|
||||||
}
|
|
||||||
|
|
||||||
# Send a desktop notification when long running commands complete.
|
|
||||||
notify_command_threshold=60
|
|
||||||
notify_ignore_list=(
|
|
||||||
bash
|
|
||||||
bat
|
|
||||||
btop
|
|
||||||
cat
|
|
||||||
cmatrix
|
|
||||||
fg
|
|
||||||
gh
|
|
||||||
git
|
|
||||||
glab
|
|
||||||
htop
|
|
||||||
ipython
|
|
||||||
man
|
|
||||||
nvim
|
|
||||||
ping
|
|
||||||
podman
|
|
||||||
python
|
|
||||||
session
|
|
||||||
slides
|
|
||||||
ssh
|
|
||||||
sudo
|
|
||||||
sudoedit
|
|
||||||
tmux
|
|
||||||
top
|
|
||||||
vi
|
|
||||||
vim
|
|
||||||
watch
|
|
||||||
zsh
|
|
||||||
)
|
|
||||||
|
|
||||||
notify-ignore() {
|
|
||||||
for ignore in $notify_ignore_list; do
|
|
||||||
if [[ "$1" = "$ignore"* ]]; then
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
|
|
||||||
notify-preexec() {
|
|
||||||
if notify-ignore $1; then
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
notify_command_start=`date +%s`
|
|
||||||
notify_command=$1
|
|
||||||
}
|
|
||||||
add-zsh-hook preexec notify-preexec
|
|
||||||
|
|
||||||
notify-precmd() {
|
|
||||||
if ! [[ -z $notify_command_start ]]; then
|
|
||||||
local notify_command_end=`date +%s`
|
|
||||||
local notify_command_time=$(($notify_command_end - $notify_command_start))
|
|
||||||
if [[ $notify_command_time -gt $notify_command_threshold ]]; then
|
|
||||||
notify "completed: $notify_command"
|
|
||||||
fi
|
|
||||||
unset notify_command
|
|
||||||
unset notify_command_start
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
add-zsh-hook precmd notify-precmd
|
|
||||||
|
|
||||||
# Detect the type and extract an archive file.
|
|
||||||
extract() {
|
|
||||||
if [ -f $1 ]; then
|
|
||||||
case $1 in
|
|
||||||
*.tar.bz2) tar xvjf $1 ;;
|
|
||||||
*.tar.gz) tar xvzf $1 ;;
|
|
||||||
*.tar.xz) [ `"uname"` = "Darwin" ] && tar xvJf $1 || tar xf $1 ;;
|
|
||||||
*.bz2) bunzip2 $1 ;;
|
|
||||||
*.rar) unrar x $1 ;;
|
|
||||||
*.gz) gunzip $1 ;;
|
|
||||||
*.tar) tar xvf $1 ;;
|
|
||||||
*.tbz2) tar xvjf $1 ;;
|
|
||||||
*.tgz) tar xvzf $1 ;;
|
|
||||||
*.zip) unzip $1 ;;
|
|
||||||
*.Z) uncompress $1 ;;
|
|
||||||
*.7z) 7zr x $1 ;;
|
|
||||||
*) echo "$fg[red]error:$reset_color unable to extract '$1'" ;;
|
|
||||||
esac
|
|
||||||
else
|
|
||||||
echo "$fg[red]error:$reset_color file not found '$1'"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
if which bat &> /dev/null; then
|
|
||||||
# Wrap bat to specify a theme, always enable color, pipe the output to less.
|
|
||||||
# Both --theme and --color can be specified multiple times and will override
|
|
||||||
# these defaults.
|
|
||||||
bat() {
|
|
||||||
command bat --theme='TwoDark' --color always --paging auto "$@"
|
|
||||||
}
|
|
||||||
elif which batcat &> /dev/null; then
|
|
||||||
bat() {
|
|
||||||
command batcat --theme='TwoDark' --color always --paging auto "$@"
|
|
||||||
}
|
|
||||||
fi
|
|
||||||
|
|
||||||
if which docker-machine &> /dev/null; then
|
|
||||||
# Wrap the docker command to print a message if a docker-machine is not
|
|
||||||
# running, rather than just stating it can not find it's socket.
|
|
||||||
docker() {
|
|
||||||
command docker "$@"
|
|
||||||
if ! docker-machine active &> /dev/null; then
|
|
||||||
echo "$fg[red]error:$reset_color no active host found, run:" \
|
|
||||||
"docker-machine start <machine>"
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# Wrap the docker-machine command to automatically update the environment.
|
|
||||||
# When a machine is started, set the environment variables provided by
|
|
||||||
# docker-machine env <machine>. When a machine is stopped, unset the same
|
|
||||||
# variables.
|
|
||||||
docker-machine() {
|
|
||||||
command docker-machine "$@"
|
|
||||||
if [ "start" = "$1" ]; then
|
|
||||||
eval `docker-machine env $2`
|
|
||||||
elif [ "stop" = "$1" ]; then
|
|
||||||
unset DOCKER_MACHINE_NAME
|
|
||||||
unset DOCKER_CERT_PATH
|
|
||||||
unset DOCKER_HOST
|
|
||||||
unset DOCKER_TLS_VERIFY
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
fi
|
|
||||||
|
|
||||||
ls-iommu() {
|
|
||||||
$HOME/.config/zsh/ls-iommu.sh | sort -n
|
|
||||||
}
|
|
||||||
|
|
||||||
# Fuzzy history search with fzf
|
|
||||||
function .fzf-history-search() {
|
|
||||||
local selected
|
|
||||||
selected=$(
|
|
||||||
cat $HISTFILE | # get entire history
|
|
||||||
sed 's/ *[0-9]* *//' | # remove cruft
|
|
||||||
awk '!seen[$0]++' | # remove duplicates
|
|
||||||
fzf --layout=reverse --tac --cycle --info=hidden \
|
|
||||||
--border=rounded --height=50%
|
|
||||||
)
|
|
||||||
if [[ -n "$selected" ]]; then
|
|
||||||
BUFFER="$selected"
|
|
||||||
zle end-of-line
|
|
||||||
fi
|
|
||||||
zle reset-prompt
|
|
||||||
}
|
|
||||||
zle -N .fzf-history-search
|
|
||||||
bindkey '^R' .fzf-history-search
|
|
5
zprofile
5
zprofile
@ -1,7 +1,2 @@
|
|||||||
# .zprofile [1] Used for executing user's commands at start, will be sourced
|
# .zprofile [1] Used for executing user's commands at start, will be sourced
|
||||||
# when starting as a login shell.
|
# when starting as a login shell.
|
||||||
|
|
||||||
# macOS is obnoxious and overwrites the PATH from a users ~/.zshenv, which is
|
|
||||||
# sourced first, in /etc/zprofile by calling `/usr/libexec/path_helper -s` so
|
|
||||||
# this is required so that PATH is once again set to the desired value.
|
|
||||||
[ `uname` = Darwin ] && source ~/.zshenv
|
|
||||||
|
118
zshenv
118
zshenv
@ -2,89 +2,25 @@
|
|||||||
# contain commands that produce output or assume the shell is attached to a
|
# contain commands that produce output or assume the shell is attached to a
|
||||||
# tty. This file will always be sourced.
|
# tty. This file will always be sourced.
|
||||||
|
|
||||||
[ -f ~/.config/zsh/zshenv.local ] && source ~/.config/zsh/zshenv.local
|
|
||||||
|
|
||||||
# Ensure cache and state directories exist
|
|
||||||
[ ! -d -${XDG_CACHE_HOME:-$HOME/.cache}/zsh ] && \
|
|
||||||
mkdir -p ${XDG_CACHE_HOME:-$HOME/.cache}/zsh
|
|
||||||
[ ! -d -${XDG_STATE_HOME:-$HOME/.local/state}/zsh ] && \
|
|
||||||
mkdir -p ${XDG_STATE_HOME:-$HOME/.local/state}/zsh
|
|
||||||
|
|
||||||
# Enable saving command history to file
|
# Enable saving command history to file
|
||||||
HISTFILE=${XDG_STATE_HOME:-$HOME/.local/state}/zsh/histfile
|
[ ! -d $HOME/.cache/zsh ] && mkdir -p $HOME/.cache/zsh
|
||||||
HISTSIZE=20000
|
HISTFILE=$HOME/.cache/zsh/histfile
|
||||||
SAVEHIST=20000
|
HISTSIZE=5000
|
||||||
|
SAVEHIST=5000
|
||||||
# Migrate histfile from cache to state directory
|
|
||||||
! [ -f $HISTFILE ] && [ -f $HOME/.cache/zsh/histfile ] && \
|
|
||||||
mv $HOME/.cache/zsh/histfile \
|
|
||||||
${XDG_STATE_HOME:-$HOME/.local/state}/zsh/histfile
|
|
||||||
|
|
||||||
# Remove vi mode switch delay
|
|
||||||
KEYTIMEOUT=1
|
|
||||||
|
|
||||||
# Enable time stats for long lasting commands
|
# Enable time stats for long lasting commands
|
||||||
REPORTTIME=5
|
REPORTTIME=5
|
||||||
|
|
||||||
|
# Add Homebrew python to PATH on macOS if present
|
||||||
|
[ "`uname`" = "Darwin" ] && [ -d /usr/local/opt/python/libexec/bin ] &&
|
||||||
|
PATH=/usr/local/opt/python/libexec/bin:$PATH
|
||||||
|
|
||||||
# Add ~/.local to the environment
|
# Add ~/.local to the environment
|
||||||
fpath+=$HOME/.local/share/zsh/site-functions
|
fpath+=$HOME/.local/share/zsh/site-functions
|
||||||
PATH=$HOME/.local/bin:$PATH
|
PATH=$HOME/.local/bin:$PATH
|
||||||
MANPATH=$HOME/.local/share/man:$MANPATH
|
MANPATH=$HOME/.local/share/man:$MANPATH
|
||||||
INFOPATH=$HOME/.local/share/info:$INFOPATH
|
INFOPATH=$HOME/.local/share/info:$INFOPATH
|
||||||
|
|
||||||
# Add ccache compiler aliases to PATH and use XDG base dir paths
|
|
||||||
if [ `uname` = Darwin ]; then
|
|
||||||
if [ `uname -m` = arm64 ]; then
|
|
||||||
homebrew_root=/opt/homebrew
|
|
||||||
[ -d /opt/homebrew/bin ] && \
|
|
||||||
PATH=$homebrew_root/bin:$PATH
|
|
||||||
else
|
|
||||||
homebrew_root=/usr/local
|
|
||||||
fi
|
|
||||||
[ -d $homebrew_root/opt/python/libexec/bin ] && \
|
|
||||||
PATH=$homebrew_root/opt/python/libexec/bin:$PATH
|
|
||||||
[ -f $homebrew_root/bin/ccache ] && \
|
|
||||||
PATH=$homebrew_root/opt/ccache/libexec:$PATH
|
|
||||||
elif [ -f /usr/bin/ccache ]; then
|
|
||||||
if [ -d /usr/lib/ccache/bin ]; then
|
|
||||||
PATH=/usr/lib/ccache/bin:$PATH
|
|
||||||
elif [ -d /usr/lib/ccache ]; then
|
|
||||||
PATH=/usr/lib/ccache:$PATH
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
export CCACHE_CONFIGPATH=${XDG_CONFIG_HOME:-$HOME/.config}/ccache
|
|
||||||
export CCACHE_DIR=${XDG_CACHE_HOME:-$HOME/.cache}/ccache
|
|
||||||
|
|
||||||
# Add default CMake options
|
|
||||||
command -v ninja &> /dev/null && \
|
|
||||||
export CMAKE_GENERATOR=Ninja
|
|
||||||
export CMAKE_EXPORT_COMPILE_COMMANDS=ON
|
|
||||||
export CMAKE_COLOR_DIAGNOSTICS=ON
|
|
||||||
|
|
||||||
# Remove duplicates from environment variables
|
|
||||||
typeset -U fpath
|
|
||||||
typeset -U PATH; export PATH
|
|
||||||
typeset -U MANPATH; export MANPATH
|
|
||||||
typeset -U INFOPATH; export INFOPATH
|
|
||||||
|
|
||||||
# Set default editor.
|
|
||||||
if command -v nvim &> /dev/null; then
|
|
||||||
export EDITOR=`command -v nvim`
|
|
||||||
# Also use nvim for man pages
|
|
||||||
export MANPAGER='nvim +Man!'
|
|
||||||
elif command -v vim &> /dev/null; then
|
|
||||||
export EDITOR=`command -v vim`
|
|
||||||
fi
|
|
||||||
export GIT_EDITOR=$EDITOR
|
|
||||||
|
|
||||||
if command -v fzf &> /dev/null; then
|
|
||||||
export FZF_DEFAULT_OPTS='--no-bold
|
|
||||||
--color=fg:#c5c9c5,fg+:#c5c9c5,bg:#000000,bg+:#393836
|
|
||||||
--color=hl:#8ea4a2,hl+:#8ea4a2,info:#afaf87,marker:#C8C093
|
|
||||||
--color=prompt:#C8C093,spinner:#8992a7,pointer:#FF9E3B,header:#87afaf
|
|
||||||
--color=gutter:#000000,border:#54546D,label:#aeaeae,query:#c5c9c5'
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Use ~/.local for pip installs on macOS
|
# Use ~/.local for pip installs on macOS
|
||||||
[ "`uname`" = "Darwin" ] && export PYTHONUSERBASE=$HOME/.local
|
[ "`uname`" = "Darwin" ] && export PYTHONUSERBASE=$HOME/.local
|
||||||
|
|
||||||
@ -96,47 +32,11 @@ export LESS_TERMCAP_so=`printf "\e[1;40;32m"`
|
|||||||
export LESS_TERMCAP_se=`printf "\e[0m"`
|
export LESS_TERMCAP_se=`printf "\e[0m"`
|
||||||
export LESS_TERMCAP_us=`printf "\e[0;34m"`
|
export LESS_TERMCAP_us=`printf "\e[0;34m"`
|
||||||
export LESS_TERMCAP_ue=`printf "\e[0m"`
|
export LESS_TERMCAP_ue=`printf "\e[0m"`
|
||||||
# Disable storing less history
|
|
||||||
export LESSHISTFILE=/dev/null
|
|
||||||
|
|
||||||
# Force GoogleTest to output colors
|
# Force GoogleTest to output colors
|
||||||
export GTEST_COLOR=yes
|
export GTEST_COLOR=yes
|
||||||
# Allow completions for GoogleTest break on failure
|
# Allow completions for GoogleTest break on failure
|
||||||
export GTEST_BREAK_ON_FAILURE=0
|
export GTEST_BREAK_ON_FAILURE=0
|
||||||
# Force CTest to verbose output
|
|
||||||
export CTEST_OUTPUT_ON_FAILURE=1
|
|
||||||
|
|
||||||
# User ~/.local/share for persistent pylint data
|
|
||||||
export PYLINTHOME=~/.local/share/pylint
|
|
||||||
# Disable virtualenv prompt
|
# Disable virtualenv prompt
|
||||||
export VIRTUAL_ENV_DISABLE_PROMPT=1
|
VIRTUAL_ENV_DISABLE_PROMPT=1
|
||||||
|
|
||||||
# If pinentry-curses exists, use it for lastpass-cli
|
|
||||||
command -v pinentry-curses &> /dev/null && \
|
|
||||||
export LPASS_PINENTRY=pinentry-curses
|
|
||||||
|
|
||||||
# Teach these some XDG Base Directory Spec manners
|
|
||||||
export IPYTHONDIR=${XDG_CONFIG_HOME:-$HOME/.config}/ipython
|
|
||||||
command -v cargo &> /dev/null && \
|
|
||||||
export CARGO_HOME=$HOME/.local/share/cargo
|
|
||||||
if command -v ccache &> /dev/null; then
|
|
||||||
export CCACHE_CONFIGPATH=${XDG_CONFIG_HOME:-$HOME/.config}/ccache.conf
|
|
||||||
export CCACHE_DIR=${XDG_CACHE_HOME:-$HOME/.cache}/ccache
|
|
||||||
fi
|
|
||||||
command -v conan &> /dev/null && \
|
|
||||||
export CONAN_USER_HOME=$HOME/.local/share/conan
|
|
||||||
command -v docker &> /dev/null && \
|
|
||||||
export DOCKER_CONFIG=$HOME/.local/share/docker
|
|
||||||
export GTK_RC_FILES=${XDG_CONFIG_HOME:-$HOME/.config}/gtk/gtkrc
|
|
||||||
export GTK2_RC_FILES=${XDG_CONFIG_HOME:-$HOME/.config}/gtk-2.0/gtkrc
|
|
||||||
export PYLINTHOME=${XDG_CACHE_HOME:-$HOME/.cache}/pylint
|
|
||||||
command -v rustup &> /dev/null && \
|
|
||||||
export RUSTUP_HOME=$HOME/.local/share/rustup
|
|
||||||
[ -f ${XDG_CONFIG_HOME:-$HOME/.config}/wget/rc ] && \
|
|
||||||
export WGETRC=${XDG_CONFIG_HOME:-$HOME/.config}/wget/rc
|
|
||||||
# TODO: terminfo
|
|
||||||
export GOBIN=$HOME/.local/bin
|
|
||||||
export GOPATH=$HOME/.local/share/go
|
|
||||||
export GOCACHE=${XDG_CACHE_HOME:-$HOME/.cache}/go/build
|
|
||||||
export GOMODCACHE=${XDG_CACHE_HOME:-$HOME/.cache}/go/pkg/mod
|
|
||||||
export GOTMPDIR=${XDG_CACHE_HOME:-$HOME/.cache}/go/tmp
|
|
||||||
|
144
zshrc
144
zshrc
@ -3,12 +3,8 @@
|
|||||||
|
|
||||||
# Load plugin scripts
|
# Load plugin scripts
|
||||||
source-plugin() {
|
source-plugin() {
|
||||||
local shared_plugin=${XDG_DATA_HOME:-$HOME/.local/share}/zsh/plugins/$1/$1.plugin.zsh
|
if [ -d ~/.config/zsh/$1 ]; then
|
||||||
local local_plugin=${XDG_CONFIG_HOME:-$HOME/.config}/zsh/$1/$1.plugin.zsh
|
source ~/.config/zsh/$1/$1.plugin.zsh
|
||||||
if [ -f $shared_plugin ]; then
|
|
||||||
source $shared_plugin
|
|
||||||
elif [ -f $local_plugin ]; then
|
|
||||||
source $local_plugin
|
|
||||||
else
|
else
|
||||||
echo "zsh plugin not found: $1"
|
echo "zsh plugin not found: $1"
|
||||||
fi
|
fi
|
||||||
@ -21,13 +17,13 @@ ZSH_AUTOSUGGEST_ACCEPT_WIDGETS=(end-of-line vi-end-of-line)
|
|||||||
|
|
||||||
# Search history with a command substring
|
# Search history with a command substring
|
||||||
source-plugin zsh-history-substring-search
|
source-plugin zsh-history-substring-search
|
||||||
HISTORY_SUBSTRING_SEARCH_HIGHLIGHT_FOUND=
|
|
||||||
HISTORY_SUBSTRING_SEARCH_HIGHLIGHT_NOT_FOUND=
|
|
||||||
|
|
||||||
# Command syntax highlighting
|
# Command syntax highlighting
|
||||||
source-plugin zsh-syntax-highlighting
|
source-plugin fast-syntax-highlighting
|
||||||
(( ${+ZSH_HIGHLIGHT_STYLES} )) || typeset -A ZSH_HIGHLIGHT_STYLES
|
fast-theme -q ~/.config/zsh/fresh.ini
|
||||||
ZSH_HIGHLIGHT_STYLES[precommand]=fg=green
|
|
||||||
|
# Automatically source .enter and .exit scripts on cd
|
||||||
|
source-plugin autoenv
|
||||||
|
|
||||||
# Build system helper commands
|
# Build system helper commands
|
||||||
source-plugin build
|
source-plugin build
|
||||||
@ -35,29 +31,19 @@ source-plugin build
|
|||||||
# Project sandboxing commands
|
# Project sandboxing commands
|
||||||
source-plugin sandbox
|
source-plugin sandbox
|
||||||
|
|
||||||
# Various shell utilities
|
|
||||||
source-plugin utilities
|
|
||||||
|
|
||||||
# Automatically source .enter and .exit scripts on cd
|
|
||||||
source-plugin autoenv
|
|
||||||
|
|
||||||
# Session manager
|
|
||||||
source-plugin session
|
|
||||||
|
|
||||||
# Layout tmux window commands
|
# Layout tmux window commands
|
||||||
[ "$TMUX" != "" ] && source-plugin layout
|
source-plugin layout
|
||||||
|
|
||||||
# Note taking commands
|
# Note taking commands
|
||||||
source-plugin notes
|
source-plugin notes
|
||||||
|
|
||||||
# Remove duplicates from history
|
# Remove duplicates from history
|
||||||
setopt histignoredups
|
setopt hist_ignore_all_dups
|
||||||
|
setopt hist_reduce_blanks
|
||||||
|
setopt hist_save_no_dups
|
||||||
|
|
||||||
# Enable multi-terminal history
|
# Enable multi-terminal history
|
||||||
setopt share_history
|
setopt inc_append_history
|
||||||
|
|
||||||
# Disable error when no glob matches are found
|
|
||||||
setopt nonomatch
|
|
||||||
|
|
||||||
# Enable comments in the prompt
|
# Enable comments in the prompt
|
||||||
setopt interactive_comments
|
setopt interactive_comments
|
||||||
@ -66,20 +52,17 @@ setopt interactive_comments
|
|||||||
setopt ignore_eof
|
setopt ignore_eof
|
||||||
|
|
||||||
# Disable sound
|
# Disable sound
|
||||||
setopt nobeep
|
unsetopt beep
|
||||||
|
|
||||||
# Disable tty flow control, allows vim to use '<Ctrl>S'
|
# Disable tty flow control, allows vim to use '<Ctrl>S'
|
||||||
setopt noflowcontrol; stty -ixon
|
unsetopt flow_control && stty -ixon
|
||||||
|
|
||||||
# Enable completions in the middle of a word
|
|
||||||
setopt completeinword
|
|
||||||
|
|
||||||
# Initialize completions
|
# Initialize completions
|
||||||
autoload -U compinit
|
autoload -U compinit
|
||||||
compinit -d ${XDG_CACHE_HOME:-$HOME/.cache}/zsh/compdump
|
compinit
|
||||||
|
|
||||||
# Add pip to the old completion engine if present
|
# Add pip to the old completion engine if present
|
||||||
if command -v pip &> /dev/null; then
|
if which pip &> /dev/null; then
|
||||||
function _pip_completion {
|
function _pip_completion {
|
||||||
local words cword
|
local words cword
|
||||||
read -Ac words
|
read -Ac words
|
||||||
@ -99,9 +82,6 @@ prompt fresh
|
|||||||
# Enable vi mode line editor keymap
|
# Enable vi mode line editor keymap
|
||||||
bindkey -v
|
bindkey -v
|
||||||
|
|
||||||
# Enable backspace after returning to viins from vicmd mode
|
|
||||||
bindkey '^?' backward-delete-char
|
|
||||||
|
|
||||||
# Enable yank, change, and delete whole line with 'Y', 'cc', and 'dd'
|
# Enable yank, change, and delete whole line with 'Y', 'cc', and 'dd'
|
||||||
bindkey -M vicmd 'Y' vi-yank-whole-line
|
bindkey -M vicmd 'Y' vi-yank-whole-line
|
||||||
|
|
||||||
@ -129,6 +109,9 @@ bindkey -M vicmd 'j' history-substring-search-down
|
|||||||
bindkey -r '^[h'
|
bindkey -r '^[h'
|
||||||
bindkey -M vicmd 'K' run-help
|
bindkey -M vicmd 'K' run-help
|
||||||
|
|
||||||
|
# Disable Ex mode with ':'
|
||||||
|
bindkey -rM vicmd ':'
|
||||||
|
|
||||||
# Enable '<Shirt><Tab>' reverse order completions
|
# Enable '<Shirt><Tab>' reverse order completions
|
||||||
bindkey '^[[Z' reverse-menu-complete
|
bindkey '^[[Z' reverse-menu-complete
|
||||||
|
|
||||||
@ -137,22 +120,17 @@ autoload -U edit-command-line
|
|||||||
zle -N edit-command-line
|
zle -N edit-command-line
|
||||||
bindkey -M vicmd '^V' edit-command-line
|
bindkey -M vicmd '^V' edit-command-line
|
||||||
|
|
||||||
# Enable HOME and END keys
|
# Get the shells parent process name.
|
||||||
if [[ `uname` = Linux ]]; then
|
ppid_name() { echo $(ps -p $(ps -p $(echo $$) -o ppid=) -o comm=) }
|
||||||
# If Home and End are not working as expected setup zkbd mappings.
|
|
||||||
[ -f ~/.zkbd/$TERM-${${DISPLAY:t}:-$VENDOR-$OSTYPE} ] && \
|
|
||||||
source ~/.zkbd/$TERM-${${DISPLAY:t}:-$VENDOR-$OSTYPE}
|
|
||||||
[[ -n ${key[Home]} ]] && bindkey "${key[Home]}" beginning-of-line
|
|
||||||
[[ -n ${key[End]} ]] && bindkey "${key[End]}" end-of-line
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Enable changing cursor shape based on vi mode
|
# Enable changing cursor shape based on vi mode
|
||||||
if [ "$ITERM_PROFILE" != "" ] && [ "$TMUX" = "" ]; then
|
if [ "$ITERM_PROFILE" != "" ] && [ "$TMUX" = "" ]; then
|
||||||
# iTerm2 cursor shape escape sequences outside tmux
|
# iTerm2 cursor shape escape sequences outside tmux
|
||||||
cursor_block="\e]50;CursorShape=0\C-G"
|
cursor_block="\e]50;CursorShape=0\C-G"
|
||||||
cursor_line="\e]50;CursorShape=1\C-G"
|
cursor_line="\e]50;CursorShape=1\C-G"
|
||||||
else
|
elif [ "$(ppid_name)" != "python2" ]; then
|
||||||
# iTerm2 inside tmux or VTE compatible cursor shape escape sequences.
|
# iTerm2 inside tmux or VTE compatible cursor shape escape sequences,
|
||||||
|
# exclude Guake even though it's VTE based it doesn't like these
|
||||||
cursor_block="\e[2 q"
|
cursor_block="\e[2 q"
|
||||||
cursor_line="\e[6 q"
|
cursor_line="\e[6 q"
|
||||||
fi
|
fi
|
||||||
@ -177,70 +155,48 @@ if [[ ! -z "$cursor_block" && ! -z "$cursor_line" ]]; then
|
|||||||
zle -N zle-line-finish
|
zle -N zle-line-finish
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Frequntly used directories
|
|
||||||
function frequent-directory() {
|
|
||||||
if [ -d "$2" ]; then
|
|
||||||
# Replace - with _ in environment variable name.
|
|
||||||
local name=${1//-/_}
|
|
||||||
local value=$2
|
|
||||||
export $name=$value
|
|
||||||
hash -d $1
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
frequent-directory Desktop "$HOME/Desktop"
|
|
||||||
frequent-directory Documents "$HOME/Documents"
|
|
||||||
frequent-directory Downloads "$HOME/Downloads"
|
|
||||||
frequent-directory Projects "$HOME/Projects"
|
|
||||||
frequent-directory Sandbox "$HOME/Sandbox"
|
|
||||||
frequent-directory cache "${XDG_CACHE_HOME:-$HOME/.cache}"
|
|
||||||
frequent-directory config "${XDG_CONFIG_HOME:-$HOME/.config}"
|
|
||||||
frequent-directory local "$HOME/.local"
|
|
||||||
|
|
||||||
# Load work related config
|
# Load work related config
|
||||||
[ -f ${XDG_CONFIG_HOME:-$HOME/.config}/work/zshrc ] && \
|
[ -f ~/.config/work/zshrc ] && source ~/.config/work/zshrc
|
||||||
source ${XDG_CONFIG_HOME:-$HOME/.config}/work/zshrc
|
|
||||||
[ -f ${XDG_CONFIG_HOME:-$HOME/.config}/private/zshrc ] && \
|
# Remove duplicates from environment variables
|
||||||
source ${XDG_CONFIG_HOME:-$HOME/.config}/private/zshrc
|
typeset -U PATH
|
||||||
[ -f ${XDG_CONFIG_HOME:-$HOME/.config}/zsh/local ] && \
|
typeset -U MANPATH
|
||||||
source ${XDG_CONFIG_HOME:-$HOME/.config}/zsh/local
|
typeset -U INFOPATH
|
||||||
[ -f ${XDG_CONFIG_HOME:-$HOME/.config}/zsh/zshrc.local ] && \
|
|
||||||
source ${XDG_CONFIG_HOME:-$HOME/.config}/zsh/zshrc.local
|
# Add ccache symlink directory to start of PATH, this must be after
|
||||||
|
# `typeset -U PATH` because on macOS this reorders the list so ccache's
|
||||||
|
# symlinks will no longer be at the start of PATH rendering it unusable.
|
||||||
|
if [ `uname` = Darwin ]; then
|
||||||
|
[ -f /usr/local/bin/ccache ] && \
|
||||||
|
PATH=/usr/local/opt/ccache/libexec:$PATH
|
||||||
|
else
|
||||||
|
[ -f /usr/bin/ccache ] && \
|
||||||
|
PATH=/usr/lib/ccache:$PATH
|
||||||
|
fi
|
||||||
|
|
||||||
# Aliases
|
# Aliases
|
||||||
alias grep='grep --color=always'
|
alias grep='grep --color=always'
|
||||||
command -v cmake &> /dev/null && \
|
which cmake &> /dev/null && \
|
||||||
alias cninja='cmake -GNinja -DCMAKE_EXPORT_COMPILE_COMMANDS=ON'
|
alias cninja='cmake -GNinja -DCMAKE_EXPORT_COMPILE_COMMANDS=ON'
|
||||||
command -v ssh &> /dev/null && \
|
which ssh &> /dev/null && \
|
||||||
alias ssh='TERM=xterm-256color ssh'
|
alias ssh='TERM=xterm-256color ssh'
|
||||||
alias weather="curl wttr.in"
|
|
||||||
alias cls="clear && printf '\e[3J'"
|
|
||||||
|
|
||||||
case `uname` in
|
case `uname` in
|
||||||
Linux)
|
Linux)
|
||||||
|
[ "$TMUX" = "" ] && \
|
||||||
|
alias cls="printf '\ec'" || \
|
||||||
|
alias cls="clear && printf '\e[3J'"
|
||||||
alias ls='ls -F --color=auto'
|
alias ls='ls -F --color=auto'
|
||||||
if command -v cgdb &> /dev/null; then
|
if which cgdb &> /dev/null; then
|
||||||
alias debug='cgdb --args'
|
alias debug='cgdb --args'
|
||||||
elif command -v gdb &> /dev/null; then
|
elif which gdb &> /dev/null; then
|
||||||
alias debug='gdb --args'
|
alias debug='gdb --args'
|
||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
Darwin)
|
Darwin)
|
||||||
|
alias cls="clear && printf '\e[3J'"
|
||||||
alias ls='ls -GFh'
|
alias ls='ls -GFh'
|
||||||
command -v lldb &> /dev/null && \
|
which lldb &> /dev/null && \
|
||||||
alias debug='lldb --'
|
alias debug='lldb --'
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
command -v wol > /dev/null && \
|
|
||||||
alias wakeonlan='wol'
|
|
||||||
|
|
||||||
# Append any aliases to notify_ignore_list if they contain any ignore commands
|
|
||||||
# NOTE: Keep this at the end of ~/.zshrc so all aliases are processed
|
|
||||||
for name in ${(k)aliases}; do
|
|
||||||
cmd=${${${$(alias $name)#${name}=}#\'}#\"}
|
|
||||||
for ignore in $notify_ignore_list; do
|
|
||||||
if [[ "$cmd" = "$ignore"* ]]; then
|
|
||||||
notify_ignore_list+=( $name )
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
done
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user