Compare commits
19 Commits
zcurses/bu
...
34965bb98d
| Author | SHA1 | Date | |
|---|---|---|---|
| 34965bb98d | |||
| 2740f9bc8d | |||
| 2589b63023 | |||
| 6a4531423e | |||
| 8819cd4d18 | |||
| 585925df38 | |||
| 2ac97afdd1 | |||
| f24253b8c1 | |||
| df819f58a8 | |||
| c636dd078c | |||
| 0992b65d17 | |||
| 9e9c43a0cf | |||
| 0ab04406ec | |||
| e17ff47d5e | |||
| ff8bb3e4ab | |||
| 31d06e0f19 | |||
| 7bb6a459ee | |||
| 9e4c984822 | |||
| 9af452a8e2 |
@@ -6,8 +6,8 @@
|
||||
- brew:
|
||||
- zsh
|
||||
- command:
|
||||
- install: sudo chsh $USER -s `which zsh`
|
||||
remove: sudo chsh $USER -s `which bash`
|
||||
- install: sudo chsh -s `which zsh` $USER
|
||||
remove: sudo chsh -s `which bash` $USER
|
||||
- symlink:
|
||||
- {src: zlogin, dst: ~/.zlogin}
|
||||
- {src: zlogout, dst: ~/.zlogout}
|
||||
|
||||
22
README.md
22
README.md
@@ -51,10 +51,26 @@ display. This results in no noticeable lag when redrawing the prompt.
|
||||
Plugins are sourced manually and their git repositories tracked by
|
||||
[conduit][conduit], no plugin manager is used.
|
||||
|
||||
* [zsh-syntax-highlighting][syntax] Fish shell like syntax highlighting for Zsh.
|
||||
* [zsh-autosuggestions][zsh-autosuggestions] Fish-like autosuggestions for zsh.
|
||||
* [fast-syntax-highlighting][syntax] Optimized and extended
|
||||
zsh-syntax-highlighting - Fish shell like syntax highlighting for Zsh.
|
||||
* [zsh-history-substring-search][search] Zsh port of the Fish shell's history
|
||||
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
|
||||
|
||||
The bulk of, if not all, configuration occurs in [`zshenv`](zshenv) and
|
||||
@@ -135,7 +151,9 @@ Various aliases are defined at the end of [zshrc](zshrc) for convenience.
|
||||
[zsh]: https://www.zsh.org/
|
||||
[git]: https://git-scm.com/
|
||||
[git-prompt]: https://github.com/olivierverdier/zsh-git-prompt
|
||||
[syntax]: https://github.com/zsh-users/zsh-syntax-highlighting
|
||||
[zsh-autosuggestions]: https://github.com/zdharma/fast-syntax-highlighting
|
||||
[zsh-autoenv]: https://github.com/Tarrasch/zsh-autoenv
|
||||
[syntax]: https://github.com/zdharma/fast-syntax-highlighting
|
||||
[search]: https://github.com/zsh-users/zsh-history-substring-search
|
||||
[vim-mode]: https://github.com/sharat87/zsh-vim-mode
|
||||
[tmux]: https://tmux.github.io
|
||||
|
||||
@@ -75,6 +75,9 @@ commands:
|
||||
# Global entered directories array.
|
||||
_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,
|
||||
# ignore, or view the file. Authorized files and their modified times are
|
||||
# stored in the ~/.cache/autoenv/authorized file to make authorization
|
||||
|
||||
@@ -1,46 +0,0 @@
|
||||
#!/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)
|
||||
@@ -37,15 +37,18 @@ optional arguments:
|
||||
EOF
|
||||
return
|
||||
fi
|
||||
error() { echo "\e[31merror:\e[0m $1"; return 1 }
|
||||
error() { echo "\e[31merror:\e[0m $1" }
|
||||
warning() { echo "\e[33mwarning:\e[0m $1" }
|
||||
local build_dir
|
||||
if [[ ${#*} -gt 1 ]]; then
|
||||
echo $usage
|
||||
error "unexpected position arguments: ${*[2,${#*}]}"
|
||||
error "unexpected position arguments: ${*[2,${#*}]}"; return 1
|
||||
elif [[ ${#*} -eq 1 ]]; then
|
||||
build_dir=${*[1]}
|
||||
[[ ! -d $build_dir ]] && \
|
||||
error "directory not found: $build_dir"
|
||||
if [[ ! -d ${*[1]} ]]; then
|
||||
warning "directory not found: ${*[1]}"
|
||||
else
|
||||
build_dir=${*[1]}
|
||||
fi
|
||||
fi
|
||||
|
||||
# If <directory> was not set begin selection
|
||||
@@ -60,7 +63,7 @@ EOF
|
||||
# Interactively select a build directory if more than 1 found
|
||||
integer index=0
|
||||
if [[ ${#build_dirs} -eq 0 ]]; then
|
||||
error "no build directories found"
|
||||
error "no build directories found"; return 1
|
||||
elif [[ ${#build_dirs} -gt 1 ]]; then
|
||||
zmodload zsh/curses && {
|
||||
# Get the size of the terminal
|
||||
@@ -139,7 +142,7 @@ EOF
|
||||
|
||||
# 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"
|
||||
warning "build command detection failed: $build_dir"
|
||||
# Prompt user to enter a build command
|
||||
vared -p 'enter comand: ' build
|
||||
fi
|
||||
@@ -149,7 +152,9 @@ EOF
|
||||
hash -d build=$build_dir
|
||||
|
||||
# If `--build` is specified then evaluate the command.
|
||||
[[ -n $do_build ]] && eval build
|
||||
if [[ -n $do_build ]]; then
|
||||
eval build
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
201
git-prompt.c
Normal file
201
git-prompt.c
Normal file
@@ -0,0 +1,201 @@
|
||||
#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
|
||||
|
||||
#define check(CONDITION) \
|
||||
if (CONDITION) { \
|
||||
fprintf(stderr, "error: %s: %d: %s\n", __FILE__, __LINE__, #CONDITION); \
|
||||
exit(0); \
|
||||
}
|
||||
|
||||
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;
|
||||
int i;
|
||||
va_start(list, count);
|
||||
for (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() {
|
||||
process_t process;
|
||||
// check we are in a git repo
|
||||
process = process_open("git rev-parse --git-dir");
|
||||
check(process_close(process));
|
||||
|
||||
// get the current branch name
|
||||
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%}");
|
||||
}
|
||||
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;
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
#compdef layout
|
||||
|
||||
__get_layouts() {
|
||||
ls -1 ~/.config/tmux/layouts 2>/dev/null | \
|
||||
ls -1 ~/.local/share/tmux/layouts 2>/dev/null | \
|
||||
while read -r layout; do echo $layout; done
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ layout() {
|
||||
if [[ "$1" == "" ]]; then
|
||||
echo "usage: layout <layout> [name]"
|
||||
else
|
||||
tmux source-file ~/.config/tmux/layouts/$1
|
||||
tmux source-file ~/.local/share/tmux/layouts/$1
|
||||
if [[ "$2" != "" ]]; then
|
||||
tmux rename-window $2
|
||||
fi
|
||||
|
||||
@@ -1,17 +1,18 @@
|
||||
prompt_fresh_help() {
|
||||
echo "\
|
||||
options:
|
||||
-a enable almostontop like behaviour"
|
||||
-a enable almostontop like behaviour
|
||||
-r recompile git-prompt executable"
|
||||
}
|
||||
|
||||
prompt_fresh_setup() {
|
||||
fresh_compile_git_prompt
|
||||
|
||||
# Parse options
|
||||
local almostontop=0
|
||||
while getopts 'a' opt; do
|
||||
local recompile=0
|
||||
while getopts 'ar' opt; do
|
||||
case $opt in
|
||||
a) local almostontop=1 ;;
|
||||
r) local recompile=1 ;;
|
||||
*) prompt -h fresh; return 1 ;;
|
||||
esac
|
||||
done
|
||||
@@ -19,8 +20,8 @@ prompt_fresh_setup() {
|
||||
autoload -U add-zsh-hook
|
||||
|
||||
# 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 which can sometimes
|
||||
# cause lines before the prompt to disappear.
|
||||
# actually part of the prompt so does not get redrawn, this is preferable
|
||||
# since sometimes lines before the prompt can disappear.
|
||||
add-zsh-hook precmd fresh_line_one
|
||||
|
||||
if [ $almostontop -eq 1 ]; then
|
||||
@@ -31,28 +32,29 @@ prompt_fresh_setup() {
|
||||
add-zsh-hook -d preexec fresh_almostontop
|
||||
fi
|
||||
|
||||
if [ "$USERNAME" = "root" ]; then
|
||||
local user="%{%F{9}%}%n%{%f%}"
|
||||
[ $recompile -eq 1 ] && prompt_cleanup
|
||||
fresh_compile_git_prompt
|
||||
|
||||
if [ "$USER" = "root" ]; then
|
||||
local user="%{%F{1}%}%n%{%f%}"
|
||||
else
|
||||
local user="%{%F{35}%}%n%{%f%}"
|
||||
fi
|
||||
|
||||
local userhost=$USER
|
||||
if [ "$SSH_CONNECTION" != "" ]; then
|
||||
local user="%{%F{35}%}$user%{%f%}@%{%F{244}%}%M%{%f%}"
|
||||
local user="$user@%{%F{244}%}%M%{%f%}"
|
||||
local userhost="$userhost@`hostname`"
|
||||
fi
|
||||
|
||||
local length=`fresh_visible_length "$user"`
|
||||
|
||||
PS1="«$user» "
|
||||
PS2="${(l:$length + 1:: :)}» "
|
||||
PS2="«${(l:${#userhost}:: :)}» "
|
||||
|
||||
RPS1='$(fresh_rprompt)'
|
||||
|
||||
prompt_opts=(cr percent sp subst)
|
||||
prompt_opts=(percent sp subst)
|
||||
}
|
||||
|
||||
prompt_cleanup() {
|
||||
if [ -f ~/.cache/zsh/git-prompt ]; then rm ~/.cache/zsh/git-prompt; fi
|
||||
[ -f ~/.cache/zsh/git-prompt ] && rm ~/.cache/zsh/git-prompt
|
||||
}
|
||||
|
||||
fresh_line_one() {
|
||||
@@ -61,85 +63,30 @@ fresh_line_one() {
|
||||
|
||||
# Construct the time and directory portions of the prompt
|
||||
local time_stamp="%{%F{244}%}%D{%H:%M:%S}%{%f%}"
|
||||
local directory="%{%F{37}%}%~%{%f%}"
|
||||
[[ -n $SANDBOX_HOME ]] && \
|
||||
local directory="%{%F{3}%}$SANDBOX_NAME${PWD#$SANDBOX_HOME}%{%f%}" || \
|
||||
local directory="%{%F{37}%}%~%{%f%}"
|
||||
|
||||
# Check we are in a git repository
|
||||
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
|
||||
local git=`~/.cache/zsh/git-prompt`
|
||||
|
||||
if [ "$branch" != "" ]; then
|
||||
local branch=${branch#refs/heads/}
|
||||
# Get the number of commits ahead/behind from the remote branch
|
||||
local remote="`git config branch.$branch.remote 2> /dev/null`"
|
||||
if [ "" != "remote" ]; then
|
||||
local branches="refs/remotes/$remote/$branch...HEAD"
|
||||
local nahead=`git rev-list --right-only $branches --count 2> /dev/null`
|
||||
if [ "0" -ne "$nahead" ]; then local ahead="↑$nahead"; fi
|
||||
local nbehind=`git rev-list --left-only $branches --count 2> /dev/null`
|
||||
if [ "0" -ne "$nbehind" ]; then local behind="↓$nbehind"; fi
|
||||
fi
|
||||
|
||||
# Construct the git prompt
|
||||
local git="%{%F{66}%}$branch%{%f%}$ahead$behind "
|
||||
|
||||
if [ -f ~/.cache/zsh/git-prompt ]; then
|
||||
# Get the change counts from git-prompt
|
||||
local counts=(`~/.cache/zsh/git-prompt`)
|
||||
|
||||
# Parse the results from git-prompt
|
||||
if [ 0 -eq ${#counts[@]} ]; then # clean
|
||||
local git="$git%{%B%F{2}%}✓%{%f%b%}";
|
||||
else
|
||||
if [ 0 != $counts[1] ]; then # indexed
|
||||
local git="$git%{%F{2}%}*$counts[1]%{%f%}"
|
||||
fi
|
||||
if [ 0 != $counts[2] ]; then # modified
|
||||
local git="$git%{%F{1}%}+$counts[2]%{%f%}";
|
||||
fi
|
||||
if [ 0 != $counts[3] ]; then # deleted
|
||||
local git="$git%{%F{1}%}-$counts[3]%{%f%}";
|
||||
fi
|
||||
if [ 0 != $counts[4] ]; then # unmerged
|
||||
local git="$git%{%B%F{1}%}×$counts[4]%{%f%b%}";
|
||||
fi
|
||||
if [ 0 != $counts[5] ]; then # untracked
|
||||
local git="$git%{%F{1}%}…%{%f%}";
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
# If the last command failed, display its error code at the right
|
||||
if [[ $exit_code -ne 0 ]]; then
|
||||
local result=" %{%B%F{1}%}$exit_code%{%f%b%}"
|
||||
fi
|
||||
|
||||
# Construct the prompt string
|
||||
local line="$time_stamp $directory $git"
|
||||
# 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
|
||||
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
|
||||
}
|
||||
|
||||
fresh_rprompt() {
|
||||
rprompt=""
|
||||
if [[ ! -z "$DOCKER_MACHINE_NAME" ]]; then
|
||||
rprompt="$rprompt %{%F{3}%}$DOCKER_MACHINE_NAME%{%f%}"
|
||||
fi
|
||||
if [[ ! -z "$VIRTUAL_ENV" ]]; then
|
||||
rprompt="$rprompt %{%F{3}%}$(basename $VIRTUAL_ENV)%{%f%}"
|
||||
fi
|
||||
echo $rprompt
|
||||
print -P "$time_stamp $directory$git$py$docker$result"
|
||||
}
|
||||
|
||||
fresh_almostontop() {
|
||||
@@ -148,70 +95,14 @@ fresh_almostontop() {
|
||||
print -P "$PROMPT"'$1'
|
||||
}
|
||||
|
||||
fresh_visible_length() {
|
||||
echo $(( ${#${(S%%)1//(\%(KF1]|)\{*\}|\%[Bbkf])}} ))
|
||||
}
|
||||
|
||||
fresh_compile_git_prompt() {
|
||||
# Compile a simple C executable which parses the output of `git status
|
||||
# --procelain` to greatly decrease the time taken to render the prompt
|
||||
local cache=~/.cache/zsh
|
||||
if [ ! -d $cache ]; then mkdir -p $cache; fi
|
||||
if [ ! -f $cache/git-prompt ]; then
|
||||
cc -x c -std=gnu99 -O3 -DNDEBUG -o $cache/git-prompt - 2> /dev/null << EOF
|
||||
#include <stdio.h>
|
||||
#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
|
||||
# Compile a simple C program which parses the output of `git status
|
||||
# --procelain` to greatly decrease the time taken to draw the prompt
|
||||
[ ! -d ~/.cache/zsh ] && mkdir -p ~/.cache/zsh
|
||||
if [ ! -f ~/.cache/zsh/git-prompt ]; then
|
||||
cc -std=gnu99 -O3 -DNDEBUG ~/.config/zsh/git-prompt.c -o ~/.cache/zsh/git-prompt
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "git prompt disabled, are the system development headers installed?"
|
||||
echo "git-prompt was not compiled, is a C99 toolchain installed?"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -1,9 +1,3 @@
|
||||
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
|
||||
@@ -33,11 +27,11 @@ sandbox() {
|
||||
begin=$PWD
|
||||
cd $sandbox
|
||||
|
||||
echo "SANDBOX_HOME=\$(dirname -- "\$0:a")" >> $SANDBOX_ENV_IN_FILE
|
||||
echo "SANDBOX_NAME=$2" >> $SANDBOX_ENV_IN_FILE
|
||||
echo "SANDBOX_HOME=\$(dirname -- "\$0:a")" >> .enter
|
||||
echo "SANDBOX_NAME=$2" >> .enter
|
||||
|
||||
echo "unset SANDBOX_NAME" >> $SANDBOX_ENV_OUT_FILE
|
||||
echo "unset SANDBOX_HOME" >> $SANDBOX_ENV_OUT_FILE
|
||||
echo "unset SANDBOX_NAME" >> .exit
|
||||
echo "unset SANDBOX_HOME" >> .exit
|
||||
|
||||
git init &> /dev/null
|
||||
|
||||
@@ -73,7 +67,7 @@ sandbox() {
|
||||
rm -rf $sandbox
|
||||
;;
|
||||
list)
|
||||
/bin/ls -1 $SANDBOX_ROOT
|
||||
/bin/ls -1 $SANDBOX_ROOT | less -F -K -R -X
|
||||
;;
|
||||
enable)
|
||||
if [[ "" == $2 ]]; then
|
||||
|
||||
5
zprofile
5
zprofile
@@ -1,2 +1,7 @@
|
||||
# .zprofile [1] Used for executing user's commands at start, will be sourced
|
||||
# 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
|
||||
|
||||
25
zshenv
25
zshenv
@@ -5,22 +5,35 @@
|
||||
# Enable saving command history to file
|
||||
[ ! -d $HOME/.cache/zsh ] && mkdir -p $HOME/.cache/zsh
|
||||
HISTFILE=$HOME/.cache/zsh/histfile
|
||||
HISTSIZE=5000
|
||||
SAVEHIST=5000
|
||||
HISTSIZE=20000
|
||||
SAVEHIST=20000
|
||||
|
||||
# Remove vi mode switch delay
|
||||
KEYTIMEOUT=1
|
||||
|
||||
# Enable time stats for long lasting commands
|
||||
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
|
||||
fpath+=$HOME/.local/share/zsh/site-functions
|
||||
PATH=$HOME/.local/bin:$PATH
|
||||
MANPATH=$HOME/.local/share/man:$MANPATH
|
||||
INFOPATH=$HOME/.local/share/info:$INFOPATH
|
||||
|
||||
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
|
||||
|
||||
# Remove duplicates from environment variables
|
||||
typeset -U fpath
|
||||
typeset -U PATH; export PATH
|
||||
typeset -U MANPATH; export MANPATH
|
||||
typeset -U INFOPATH; export INFOPATH
|
||||
|
||||
# Use ~/.local for pip installs on macOS
|
||||
[ "`uname`" = "Darwin" ] && export PYTHONUSERBASE=$HOME/.local
|
||||
|
||||
|
||||
37
zshrc
37
zshrc
@@ -32,18 +32,19 @@ source-plugin build
|
||||
source-plugin sandbox
|
||||
|
||||
# Layout tmux window commands
|
||||
source-plugin layout
|
||||
[ "$TMUX" != "" ] && source-plugin layout
|
||||
|
||||
# Note taking commands
|
||||
source-plugin notes
|
||||
|
||||
# Remove duplicates from history
|
||||
setopt hist_ignore_all_dups
|
||||
setopt hist_reduce_blanks
|
||||
setopt hist_save_no_dups
|
||||
setopt histignoredups
|
||||
|
||||
# Enable multi-terminal history
|
||||
setopt inc_append_history
|
||||
setopt share_history
|
||||
|
||||
# Disable error when no glob matches are found
|
||||
setopt nonomatch
|
||||
|
||||
# Enable comments in the prompt
|
||||
setopt interactive_comments
|
||||
@@ -52,10 +53,13 @@ setopt interactive_comments
|
||||
setopt ignore_eof
|
||||
|
||||
# Disable sound
|
||||
unsetopt beep
|
||||
setopt nobeep
|
||||
|
||||
# Disable tty flow control, allows vim to use '<Ctrl>S'
|
||||
unsetopt flow_control && stty -ixon
|
||||
setopt noflowcontrol; stty -ixon
|
||||
|
||||
# Enable completions in the middle of a word
|
||||
setopt completeinword
|
||||
|
||||
# Initialize completions
|
||||
autoload -U compinit
|
||||
@@ -82,6 +86,9 @@ prompt fresh
|
||||
# Enable vi mode line editor keymap
|
||||
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'
|
||||
bindkey -M vicmd 'Y' vi-yank-whole-line
|
||||
|
||||
@@ -158,22 +165,6 @@ fi
|
||||
# Load work related config
|
||||
[ -f ~/.config/work/zshrc ] && source ~/.config/work/zshrc
|
||||
|
||||
# Remove duplicates from environment variables
|
||||
typeset -U PATH
|
||||
typeset -U MANPATH
|
||||
typeset -U INFOPATH
|
||||
|
||||
# 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
|
||||
alias grep='grep --color=always'
|
||||
which cmake &> /dev/null && \
|
||||
|
||||
Reference in New Issue
Block a user