17 Commits

Author SHA1 Message Date
3194afc80d Replace build-dir.py with zcurses build-dir
Update the build-dir shell function to usage zcurses instead of the
Python pick package to interactively select build directories, this
results in a more responsive user experience. Add argument parsing to
handle various use cases. Add prompt when the build command for the
selected build directory could not be detected, allowing the user to
specify the desired build command.

```
usage: build-dir [-h] [--build] [<directory>]

Find and select the current build directory interactively.

positional arguments:
  <directory> the build directory to select

optional arguments:
  -h, --help  show this help message and exit
  --build     invoke a build after selection
```
2018-08-24 11:04:18 +01:00
087a315289 Fix build-run and build-debug functions 2018-08-22 17:17:06 +01:00
9b54ebc366 Add fast-syntax-highlighting theme: fresh 2018-08-22 13:44:57 +01:00
9f9c4a11eb Add GoogleTest environment variables 2018-08-22 10:22:36 +01:00
8cad5acd83 Correct build command todo list 2018-08-20 10:41:34 +01:00
90b3e24789 Load work config if present 2018-08-20 10:23:33 +01:00
ada3cb7d3d Add layout and note plugins 2018-08-20 10:16:45 +01:00
e13e70de6b Actually add sandbox plugin 2018-08-20 10:12:43 +01:00
b61ebc4f7a Enable sandbox plugin 2018-08-19 22:20:09 +01:00
f7d952c628 Use bash for default shell on removal 2018-08-19 21:01:02 +01:00
65b0b7a099 Remove --user from pick pip action 2018-08-19 19:30:33 +01:00
64dcee0d78 Use fast-syntax-highlighting
Replace zsh-syntax-highlighting plugin with the improved
fast-syntax-highlighting, faster and more accurate.
2018-07-19 23:52:47 +01:00
128cc3c57a Remove unused tmux split aliases 2018-07-19 23:14:45 +01:00
8e04758760 Fix debug alias always picking gdb 2018-06-17 23:04:59 +01:00
52f42a7875 Edit the command line with ^F in normal mode 2018-06-09 17:41:07 +01:00
639e1b9cee Fix typo in CMAKE_EXPORT_COMPILE_COMMANDS 2018-06-08 19:57:33 +01:00
b12dcfe243 Add build utility commands
* `build` is an alias which on first use invokes `build-dir --build` to
  select a build directory, reconfigure the `build` alias, and invoke
  the `build` alias on the selected build directory.
* `debug` is an alias to the installed system native debugger.
* `build-dir` is a function to select a build directory by reconfiguring
  the `build` alias, it detects `build.ninja` or `Makefile` in the build
  directory and selects the appropriate `ninja` or `make` command.
  Depends on the `build-dir.py` Python script which uses the `pick`
  package to interactively select the build directory.
* `build-run` is a function which builds the specified target then
  attempts to run it, making the assumption it resides in the `bin`
  subdirectory of the build directory.
* `build-debug` is a function which build the specified tared then
  attempts to debug it using the system native debugger, making the
  assumption it resides in the `bin` subdirectory of the build
  directory.
2018-05-01 23:25:31 +01:00
13 changed files with 468 additions and 63 deletions

View File

@@ -6,20 +6,26 @@
- brew:
- zsh
- command:
- sudo chsh $USER -s `which zsh`
- 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
- 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/zsh-users/zsh-syntax-highlighting.git
- pip:
- --user pick
- https://github.com/zdharma/fast-syntax-highlighting.git
- message: zsh will be the default prompt after next login

6
build/_build-dir Normal file
View File

@@ -0,0 +1,6 @@
#compdef build-dir
_arguments \
'(-h --help)'{-h,--help}'[]' \
'--build[invoke a build after selection]' \
'1:directory:_files'

View File

@@ -16,7 +16,7 @@ from pick import Picker
def main():
"""Main entry point to build_dir command."""
"""Main entry point to build-dir.py script."""
parser = ArgumentParser()
parser.add_argument('output')
parser.add_argument('--default', action='store_true')

View File

@@ -17,56 +17,150 @@ elif [ `uname` = Darwin ]; then
alias debug='lldb --'
fi
# Store the path to `build-dir.py`, using `${0:a:h}` does not work in a
# function because it will result in `pwd` not this scripts directory.
_build_dir_py=${0:a:h}/build-dir.py
# Prompt user to interactively choose a build directory for `build` to build.
# TODO: Support arguments:
# * [x] [-h,--help] - show this help message and exit
# * [x] [--build] - execute the build commend
# * [ ] <dir> - start in another directory, not `pwd`
# Interactively choose a `~build` directory for `build` to build.
build-dir() {
# Get a unique filename to store the chosen build directory in.
[ `uname` = Darwin ] && local file=`mktemp` || local file=`tempfile`
# Prompt user to choose a build directory.
python $_build_dir_py $file;
local error=$?
# If the file exists, read the build directory from it, then delete it.
[ -f $file ] && build_dir=$PWD/`cat $file`; rm $file
# If choosing a build directory failed, return that error.
[[ "$error" = "0" ]] || return $error
# If `build.ninja` exists in alias `ninja`, return.
[ -f $build_dir/build.ninja ] && \
local build="ninja -C $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`
local build="make -j $cpu_count -C $build_dir"
local usage='usage: build-dir [-h] [--build] [<directory>]'
local -a help do_build
zparseopts -D h=help -help=help -build=do_build
if [[ -n $help ]]; then
cat << EOF
$usage
Find and select the current build directory interactively.
positional arguments:
<directory> the build directory to select
optional arguments:
-h, --help show this help message and exit
--build invoke a build after selection
EOF
return
fi
# If the build variable is not defined the command could not be determined.
echo "$build"
if [ -z $build ]; then
# TODO: Prompt user to choose a build command?
echo "could not determine build command"
return 1
error() { echo "\e[31merror:\e[0m $1"; return 1 }
local build_dir
if [[ ${#*} -gt 1 ]]; then
echo $usage
error "unexpected position arguments: ${*[2,${#*}]}"
elif [[ ${#*} -eq 1 ]]; then
build_dir=${*[1]}
[[ ! -d $build_dir ]] && \
error "directory not found: $build_dir"
fi
# If <directory> was not set begin selection
if [[ -z $build_dir ]]; then
# Find build directories
local -a build_dirs
for entry in `ls -A`; do
[ -d $entry ] && [[ $entry =~ build* ]] && \
build_dirs+=${entry/\//}
done
# Interactively select a build directory if more than 1 found
integer index=0
if [[ ${#build_dirs} -eq 0 ]]; then
error "no build directories found"
elif [[ ${#build_dirs} -gt 1 ]]; then
zmodload zsh/curses && {
# Get the size of the terminal
local size=`stty size`
integer height=${size% *}
integer width=${size#* }
# Create the window and hide the cursor
zcurses init
zcurses addwin build-dir $height $width 0 0
# Hide the cursor for zcurses, trap SIGINT to ensure cleanup in
# always-list occurs below
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
# On success setup the build directory for use
if [[ $? -eq 0 ]]; then
# Set the build directory from selection if empty
[[ -z $build_dir ]] && \
build_dir=${build_dirs[$index+1]}
# If `build.ninja` exists in alias `ninja`, return.
local build
[ -f $build_dir/build.ninja ] && \
build="ninja -C $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
# Define the new alias.
alias build="$build"
# If `--build` is specified then evaluate the command.
[[ "$1" = "--build" ]] && eval $build
}
# Build then run a target residing in `$build_dir/bin`.
# Build then run a target residing in `~build/bin`.
build-run() {
local target=$1; shift 1
build $target && $build_dir/bin/$target $*
eval build $target && ~build/bin/$target $*
}
# Build then debug a target residing in `$build_dir/bin`.
# Build then debug a target residing in `~build/bin`.
build-debug() {
local target=$1; shift 1
build $target && debug $build_dir/bin/$target $*
eval build $target && debug ~build/bin/$target $*
}

76
fresh.ini Normal file
View File

@@ -0,0 +1,76 @@
; fresh fast-syntax-highlighting theme
[base]
default = none
unknown-token = red,bold
commandseparator = none
redirection = none
here-string-tri = yellow
here-string-word = bg:blue
exec-descriptor = yellow,bold
comment = black,bold
correct-subtle = none
incorrect-subtle = red
subtle-bg = bg:blue
secondary =
[command-point]
reserved-word = yellow
alias = green
suffix-alias = green
global-alias = bg:blue
builtin = green
function = green
command = green
precommand = green
hashed-command = green
[paths]
path = none
pathseparator = none
path-to-dir = none
globbing = blue,bold
[brackets]
paired-bracket = bg:blue
bracket-level-1 = green,bold
bracket-level-2 = yellow,bold
bracket-level-3 = cyan,bold
[arguments]
single-hyphen-option = cyan
double-hyphen-option = cyan
back-quoted-argument = none
single-quoted-argument = yellow
double-quoted-argument = yellow
dollar-quoted-argument = yellow
[in-string]
; backslash in $'...'
back-dollar-quoted-argument = cyan
; backslash or $... in "..."
back-or-dollar-double-quoted-argument = cyan
[other]
variable = 113
assign = none
assign-array-bracket = green
history-expansion = blue,bold
[math]
mathvar = blue,bold
mathnum = magenta
matherr = red
[for-loop]
forvar = none
fornum = magenta
; operator
foroper = yellow
; separator
forsep = yellow,bold
[case]
case-input = green
case-parentheses = yellow
case-condition = bg:blue

14
layout/_layout Normal file
View File

@@ -0,0 +1,14 @@
#compdef layout
__get_layouts() {
ls -1 ~/.config/tmux/layouts 2>/dev/null | \
while read -r layout; do echo $layout; done
}
__layouts() {
local -a layouts
layouts=(${(fo)"$(__get_layouts)"})
_describe 'layout' layouts
}
_arguments ':layout:__layouts'

10
layout/layout.plugin.zsh Normal file
View File

@@ -0,0 +1,10 @@
layout() {
if [[ "$1" == "" ]]; then
echo "usage: layout <layout> [name]"
else
tmux source-file ~/.config/tmux/layouts/$1
if [[ "$2" != "" ]]; then
tmux rename-window $2
fi
fi
}

13
notes/_note Normal file
View File

@@ -0,0 +1,13 @@
#compdef note
__get_notes() {
ls -1 ~/Sync/Notes 2>/dev/null | while read -r note; do echo $note; done
}
__notes() {
local -a notes
notes=(${(fo)"$(__get_notes)"})
_describe 'notes' notes
}
_arguments ':notes:__notes'

8
notes/notes.plugin.zsh Normal file
View File

@@ -0,0 +1,8 @@
# TODO: Support opening multiple notes in buffers or tabs
note() {
if [[ "$1" == "" ]]; then
echo "usage: note \"<title>\""
else
vim -c "Note $1"
fi
}

49
sandbox/_sandbox Normal file
View File

@@ -0,0 +1,49 @@
#compdef sandbox
__get_sandboxes() {
/bin/ls $SANDBOX_ROOT 2> /dev/null
}
__sandboxes() {
local -a sandboxes
sandboxes=(${(fo)"$(__get_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() {
local context curcontext="$curcontext" state line
typeset -A opt_args
_arguments -C \
'1: :_sandbox_cmds' \
'*::arg:->args'
case $state in
(args)
curcontext="${curcontext%:*:*}:sandbox-cmd-$words[1]:"
case $line[1] in
(create|list|disable)
;;
(enable|destroy)
_arguments -C '1:: :__sandboxes'
;;
(rename)
_arguments -C '1:: :__sandboxes'
;;
esac
esac
}
_sandbox "$@"

103
sandbox/sandbox.plugin.zsh Normal file
View File

@@ -0,0 +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
export SANDBOX_ROOT=$HOME/Sandbox
fi
sandbox() {
local usage="usage: sandbox {create,destroy,enable,disable} [name]"
if [[ "" == $1 ]]; then
echo $usage
return 1
fi
case $1 in
create)
if [[ "" == $2 ]]; then
echo $usage
return 1
fi
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)
if [[ "" == $2 || "" == $3 ]]; then
echo $usage
return 1
fi
mv $SANDBOX_ROOT/$2 $SANDBOX_ROOT/$3
sed -i "" "s/$2/$3/g" $SANDBOX_ROOT/$3/.env
;;
destroy)
if [[ "" == $2 ]]; then
echo $usage
return 1
fi
local sandbox=$SANDBOX_ROOT/$2
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
;;
list)
/bin/ls -1 $SANDBOX_ROOT
;;
enable)
if [[ "" == $2 ]]; then
echo $usage
return 1
fi
local sandbox=$SANDBOX_ROOT/$2
if [[ ! -d $sandbox ]]; then
echo "Sandbox '$2' does not exist"
return 2
fi
export SANDBOX_RETURN=$PWD
cd $sandbox
;;
disable)
if [[ -z $SANDBOX_RETURN ]]; then
echo "Sandbox is not currently active"
return 2
fi
cd $SANDBOX_RETURN
unset $SANDBOX_RETURN
;;
esac
}

5
zshenv
View File

@@ -33,5 +33,10 @@ export LESS_TERMCAP_se=`printf "\e[0m"`
export LESS_TERMCAP_us=`printf "\e[0;34m"`
export LESS_TERMCAP_ue=`printf "\e[0m"`
# Force GoogleTest to output colors
export GTEST_COLOR=yes
# Allow completions for GoogleTest break on failure
export GTEST_BREAK_ON_FAILURE=0
# Disable virtualenv prompt
VIRTUAL_ENV_DISABLE_PROMPT=1

51
zshrc
View File

@@ -9,15 +9,34 @@ source-plugin() {
echo "zsh plugin not found: $1"
fi
}
source-plugin zsh-autosuggestions
source-plugin zsh-history-substring-search
source-plugin zsh-syntax-highlighting
source-plugin autoenv
source-plugin build
# Fish like automatic suggestions from command history
source-plugin zsh-autosuggestions
# Disable non end-of-line autosuggest accept widgets
ZSH_AUTOSUGGEST_ACCEPT_WIDGETS=(end-of-line vi-end-of-line)
# Search history with a command substring
source-plugin zsh-history-substring-search
# Command syntax highlighting
source-plugin fast-syntax-highlighting
fast-theme -q ~/.config/zsh/fresh.ini
# Automatically source .enter and .exit scripts on cd
source-plugin autoenv
# Build system helper commands
source-plugin build
# Project sandboxing commands
source-plugin sandbox
# Layout tmux window commands
source-plugin layout
# Note taking commands
source-plugin notes
# Remove duplicates from history
setopt hist_ignore_all_dups
setopt hist_reduce_blanks
@@ -66,6 +85,9 @@ bindkey -v
# Enable yank, change, and delete whole line with 'Y', 'cc', and 'dd'
bindkey -M vicmd 'Y' vi-yank-whole-line
# Edit the command line in vim
bindkey -M vicmd '^F' edit-command-line
# Enable undo with 'u' and redo with 'U'
bindkey -M vicmd 'u' undo
bindkey -M vicmd 'U' redo
@@ -133,6 +155,9 @@ if [[ ! -z "$cursor_block" && ! -z "$cursor_line" ]]; then
zle -N zle-line-finish
fi
# Load work related config
[ -f ~/.config/work/zshrc ] && source ~/.config/work/zshrc
# Remove duplicates from environment variables
typeset -U PATH
typeset -U MANPATH
@@ -152,7 +177,7 @@ fi
# Aliases
alias grep='grep --color=always'
which cmake &> /dev/null && \
alias cninja='cmake -GNinja -DCMAKE_EXPORT_COMPILE_COMMNADS=ON'
alias cninja='cmake -GNinja -DCMAKE_EXPORT_COMPILE_COMMANDS=ON'
which ssh &> /dev/null && \
alias ssh='TERM=xterm-256color ssh'
@@ -162,10 +187,11 @@ case `uname` in
alias cls="printf '\ec'" || \
alias cls="clear && printf '\e[3J'"
alias ls='ls -F --color=auto'
which cgdb &> /dev/null && \
alias debug='cgdb --args' || \
which gdb &> /dev/null && \
alias debug='gdb --args'
if which cgdb &> /dev/null; then
alias debug='cgdb --args'
elif which gdb &> /dev/null; then
alias debug='gdb --args'
fi
;;
Darwin)
alias cls="clear && printf '\e[3J'"
@@ -174,8 +200,3 @@ case `uname` in
alias debug='lldb --'
;;
esac
if [ "$TMUX" != "" ]; then
alias sp='tmux split-window'
alias vs='tmux split-window -h'
fi