From 8ae9c465242c5e379877a15832043113021d714e Mon Sep 17 00:00:00 2001 From: Adam Hovorka Date: Mon, 4 Sep 2017 13:42:23 -0600 Subject: Switch from stowsh to dotbot --- .gitignore | 1 + .gitmodules | 3 + base.yaml | 19 + base/.capsesc | 4 - base/.hushlogin | 0 base/.vim/colors/base16-default-dark.vim | 330 ---------- base/.vim/doc/matchit.txt | 406 ------------ base/.vim/doc/tags | 50 -- base/.vim/ftdetect/json.vim | 3 - base/.vim/ftplugin/json.vim | 40 -- base/.vim/ftplugin/php.vim | 272 -------- base/.vim/indent/json.vim | 177 ----- base/.vim/indent/php.vim | 272 -------- base/.vim/syntax/json.vim | 137 ---- base/.vimrc | 239 ------- base/.zsh/aliases.zsh | 31 - base/.zsh/async | 493 -------------- base/.zsh/colors.zsh | 3 - base/.zsh/completion.zsh | 81 --- base/.zsh/correction.zsh | 7 - base/.zsh/fancy-man.zsh | 32 - base/.zsh/fasd.zsh | 3 - base/.zsh/fast-syntax-highlighting/fast-highlight | 715 --------------------- .../fast-syntax-highlighting.plugin.zsh | 272 -------- base/.zsh/functions.zsh | 18 - base/.zsh/history.zsh | 15 - base/.zsh/k.zsh | 540 ---------------- base/.zsh/prompt.zsh | 6 - base/.zsh/prompt_pure_setup | 385 ----------- base/.zsh/stack.zsh | 3 - base/.zsh/tipz.zsh | 84 --- base/.zshrc | 17 - base/capsesc | 4 + base/dot | 5 + base/vim/colors/base16-default-dark.vim | 330 ++++++++++ base/vim/doc/matchit.txt | 406 ++++++++++++ base/vim/doc/tags | 50 ++ base/vim/ftdetect/json.vim | 3 + base/vim/ftplugin/json.vim | 40 ++ base/vim/ftplugin/php.vim | 272 ++++++++ base/vim/indent/json.vim | 177 +++++ base/vim/indent/php.vim | 272 ++++++++ base/vim/syntax/json.vim | 137 ++++ .../%home%adam%dotfiles%dotfiles%base.yaml | Bin 0 -> 561 bytes base/vimrc | 239 +++++++ base/zsh/aliases.zsh | 31 + base/zsh/async | 493 ++++++++++++++ base/zsh/colors.zsh | 3 + base/zsh/completion.zsh | 81 +++ base/zsh/correction.zsh | 7 + base/zsh/fancy-man.zsh | 32 + base/zsh/fasd.zsh | 3 + base/zsh/fast-syntax-highlighting/fast-highlight | 715 +++++++++++++++++++++ .../fast-syntax-highlighting.plugin.zsh | 272 ++++++++ base/zsh/functions.zsh | 18 + base/zsh/history.zsh | 15 + base/zsh/k.zsh | 540 ++++++++++++++++ base/zsh/prompt.zsh | 6 + base/zsh/prompt_pure_setup | 385 +++++++++++ base/zsh/stack.zsh | 3 + base/zsh/tipz.zsh | 84 +++ base/zshrc | 17 + dotbot | 1 + install | 19 + stowsh | 182 ------ 65 files changed, 4683 insertions(+), 4817 deletions(-) create mode 100644 .gitignore create mode 100644 .gitmodules create mode 100644 base.yaml delete mode 100644 base/.capsesc delete mode 100644 base/.hushlogin delete mode 100644 base/.vim/colors/base16-default-dark.vim delete mode 100644 base/.vim/doc/matchit.txt delete mode 100644 base/.vim/doc/tags delete mode 100644 base/.vim/ftdetect/json.vim delete mode 100644 base/.vim/ftplugin/json.vim delete mode 100644 base/.vim/ftplugin/php.vim delete mode 100644 base/.vim/indent/json.vim delete mode 100644 base/.vim/indent/php.vim delete mode 100644 base/.vim/syntax/json.vim delete mode 100644 base/.vimrc delete mode 100644 base/.zsh/aliases.zsh delete mode 100644 base/.zsh/async delete mode 100644 base/.zsh/colors.zsh delete mode 100644 base/.zsh/completion.zsh delete mode 100644 base/.zsh/correction.zsh delete mode 100644 base/.zsh/fancy-man.zsh delete mode 100644 base/.zsh/fasd.zsh delete mode 100644 base/.zsh/fast-syntax-highlighting/fast-highlight delete mode 100644 base/.zsh/fast-syntax-highlighting/fast-syntax-highlighting.plugin.zsh delete mode 100644 base/.zsh/functions.zsh delete mode 100644 base/.zsh/history.zsh delete mode 100644 base/.zsh/k.zsh delete mode 100644 base/.zsh/prompt.zsh delete mode 100644 base/.zsh/prompt_pure_setup delete mode 100644 base/.zsh/stack.zsh delete mode 100644 base/.zsh/tipz.zsh delete mode 100644 base/.zshrc create mode 100644 base/capsesc create mode 100755 base/dot create mode 100644 base/vim/colors/base16-default-dark.vim create mode 100644 base/vim/doc/matchit.txt create mode 100644 base/vim/doc/tags create mode 100644 base/vim/ftdetect/json.vim create mode 100644 base/vim/ftplugin/json.vim create mode 100644 base/vim/ftplugin/php.vim create mode 100644 base/vim/indent/json.vim create mode 100644 base/vim/indent/php.vim create mode 100644 base/vim/syntax/json.vim create mode 100644 base/vim/undo-dir/%home%adam%dotfiles%dotfiles%base.yaml create mode 100644 base/vimrc create mode 100644 base/zsh/aliases.zsh create mode 100644 base/zsh/async create mode 100644 base/zsh/colors.zsh create mode 100644 base/zsh/completion.zsh create mode 100644 base/zsh/correction.zsh create mode 100644 base/zsh/fancy-man.zsh create mode 100644 base/zsh/fasd.zsh create mode 100644 base/zsh/fast-syntax-highlighting/fast-highlight create mode 100644 base/zsh/fast-syntax-highlighting/fast-syntax-highlighting.plugin.zsh create mode 100644 base/zsh/functions.zsh create mode 100644 base/zsh/history.zsh create mode 100644 base/zsh/k.zsh create mode 100644 base/zsh/prompt.zsh create mode 100644 base/zsh/prompt_pure_setup create mode 100644 base/zsh/stack.zsh create mode 100644 base/zsh/tipz.zsh create mode 100644 base/zshrc create mode 160000 dotbot create mode 100755 install delete mode 100755 stowsh diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..81e0b3d --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.dot.args diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..1ce5c11 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "dotbot"] + path = dotbot + url = https://github.com/anishathalye/dotbot diff --git a/base.yaml b/base.yaml new file mode 100644 index 0000000..fe8240c --- /dev/null +++ b/base.yaml @@ -0,0 +1,19 @@ +- defaults: + link: + create: true + relink: true + force: true + relative: true + +- clean: ['~'] + +- link: + ~/.bin/dot: base/dot + ~/.capsesc: base/capsesc + ~/.vim: base/vim + ~/.vimrc: base/vimrc + ~/.zsh: base/zsh + ~/.zshrc: base/zshrc + +- shell: + - touch ~/.hushlogin diff --git a/base/.capsesc b/base/.capsesc deleted file mode 100644 index 53fe642..0000000 --- a/base/.capsesc +++ /dev/null @@ -1,4 +0,0 @@ -remove Lock = Caps_Lock -keysym Escape = Caps_Lock -keysym Caps_Lock = Escape -add Lock = Caps_Lock diff --git a/base/.hushlogin b/base/.hushlogin deleted file mode 100644 index e69de29..0000000 diff --git a/base/.vim/colors/base16-default-dark.vim b/base/.vim/colors/base16-default-dark.vim deleted file mode 100644 index ea529ec..0000000 --- a/base/.vim/colors/base16-default-dark.vim +++ /dev/null @@ -1,330 +0,0 @@ -" vi:syntax=vim - -" base16-vim (https://github.com/chriskempson/base16-vim) -" by Chris Kempson (http://chriskempson.com) -" Default Dark scheme by Chris Kempson (http://chriskempson.com) - -" This enables the coresponding base16-shell script to run so that -" :colorscheme works in terminals supported by base16-shell scripts -" User must set this variable in .vimrc -" let g:base16_shell_path=base16-builder/output/shell/ -if !has('gui_running') - if exists("g:base16_shell_path") - execute "silent !/bin/sh ".g:base16_shell_path."/base16-default-dark.sh" - endif -endif - -" GUI color definitions -let s:gui00 = "181818" -let s:gui01 = "282828" -let s:gui02 = "383838" -let s:gui03 = "585858" -let s:gui04 = "b8b8b8" -let s:gui05 = "d8d8d8" -let s:gui06 = "e8e8e8" -let s:gui07 = "f8f8f8" -let s:gui08 = "ab4642" -let s:gui09 = "dc9656" -let s:gui0A = "f7ca88" -let s:gui0B = "a1b56c" -let s:gui0C = "86c1b9" -let s:gui0D = "7cafc2" -let s:gui0E = "ba8baf" -let s:gui0F = "a16946" - -" Terminal color definitions -let s:cterm00 = "00" -let s:cterm03 = "08" -let s:cterm05 = "07" -let s:cterm07 = "15" -let s:cterm08 = "01" -let s:cterm0A = "03" -let s:cterm0B = "02" -let s:cterm0C = "06" -let s:cterm0D = "04" -let s:cterm0E = "05" -if exists('base16colorspace') && base16colorspace == "256" - let s:cterm01 = "18" - let s:cterm02 = "19" - let s:cterm04 = "20" - let s:cterm06 = "21" - let s:cterm09 = "16" - let s:cterm0F = "17" -else - let s:cterm01 = "10" - let s:cterm02 = "11" - let s:cterm04 = "12" - let s:cterm06 = "13" - let s:cterm09 = "09" - let s:cterm0F = "14" -endif - -" Neovim terminal colours -if has("nvim") - let g:terminal_color_0 = "#181818" - let g:terminal_color_1 = "#ab4642" - let g:terminal_color_2 = "#a1b56c" - let g:terminal_color_3 = "#f7ca88" - let g:terminal_color_4 = "#7cafc2" - let g:terminal_color_5 = "#ba8baf" - let g:terminal_color_6 = "#86c1b9" - let g:terminal_color_7 = "#d8d8d8" - let g:terminal_color_8 = "#585858" - let g:terminal_color_9 = "#dc9656" - let g:terminal_color_10 = "#282828" - let g:terminal_color_11 = "#383838" - let g:terminal_color_12 = "#b8b8b8" - let g:terminal_color_13 = "#e8e8e8" - let g:terminal_color_14 = "#a16946" - let g:terminal_color_15 = "#f8f8f8" - let g:terminal_color_background = g:terminal_color_0 - let g:terminal_color_foreground = g:terminal_color_7 - if &background == "light" - let g:terminal_color_background = g:terminal_color_7 - let g:terminal_color_foreground = g:terminal_color_2 - endif -endif - -" Theme setup -hi clear -syntax reset -let g:colors_name = "base16-default-dark" - -" Highlighting function -fun hi(group, guifg, guibg, ctermfg, ctermbg, attr, guisp) - if a:guifg != "" - exec "hi " . a:group . " guifg=#" . a:guifg - endif - if a:guibg != "" - exec "hi " . a:group . " guibg=#" . a:guibg - endif - if a:ctermfg != "" - exec "hi " . a:group . " ctermfg=" . a:ctermfg - endif - if a:ctermbg != "" - exec "hi " . a:group . " ctermbg=" . a:ctermbg - endif - if a:attr != "" - exec "hi " . a:group . " gui=" . a:attr . " cterm=" . a:attr - endif - if a:guisp != "" - exec "hi " . a:group . " guisp=#" . a:guisp - endif -endfun - -" Vim editor colors -call hi("Normal", s:gui05, s:gui00, s:cterm05, s:cterm00, "", "") -call hi("Bold", "", "", "", "", "bold", "") -call hi("Debug", s:gui08, "", s:cterm08, "", "", "") -call hi("Directory", s:gui0D, "", s:cterm0D, "", "", "") -call hi("Error", s:gui00, s:gui08, s:cterm00, s:cterm08, "", "") -call hi("ErrorMsg", s:gui08, s:gui00, s:cterm08, s:cterm00, "", "") -call hi("Exception", s:gui08, "", s:cterm08, "", "", "") -call hi("FoldColumn", s:gui0C, s:gui01, s:cterm0C, s:cterm01, "", "") -call hi("Folded", s:gui03, s:gui01, s:cterm03, s:cterm01, "", "") -call hi("IncSearch", s:gui01, s:gui09, s:cterm01, s:cterm09, "none", "") -call hi("Italic", "", "", "", "", "none", "") -call hi("Macro", s:gui08, "", s:cterm08, "", "", "") -call hi("MatchParen", "", s:gui03, "", s:cterm03, "", "") -call hi("ModeMsg", s:gui0B, "", s:cterm0B, "", "", "") -call hi("MoreMsg", s:gui0B, "", s:cterm0B, "", "", "") -call hi("Question", s:gui0D, "", s:cterm0D, "", "", "") -call hi("Search", s:gui03, s:gui0A, s:cterm03, s:cterm0A, "", "") -call hi("SpecialKey", s:gui03, "", s:cterm03, "", "", "") -call hi("TooLong", s:gui08, "", s:cterm08, "", "", "") -call hi("Underlined", s:gui08, "", s:cterm08, "", "", "") -call hi("Visual", "", s:gui02, "", s:cterm02, "", "") -call hi("VisualNOS", s:gui08, "", s:cterm08, "", "", "") -call hi("WarningMsg", s:gui08, "", s:cterm08, "", "", "") -call hi("WildMenu", s:gui08, s:gui0A, s:cterm08, "", "", "") -call hi("Title", s:gui0D, "", s:cterm0D, "", "none", "") -call hi("Conceal", s:gui0D, s:gui00, s:cterm0D, s:cterm00, "", "") -call hi("Cursor", s:gui00, s:gui05, s:cterm00, s:cterm05, "", "") -call hi("NonText", s:gui03, "", s:cterm03, "", "", "") -call hi("LineNr", s:gui03, s:gui01, s:cterm03, s:cterm01, "", "") -call hi("SignColumn", s:gui03, s:gui01, s:cterm03, s:cterm01, "", "") -call hi("StatusLine", s:gui04, s:gui02, s:cterm04, s:cterm02, "none", "") -call hi("StatusLineNC", s:gui03, s:gui01, s:cterm03, s:cterm01, "none", "") -call hi("VertSplit", s:gui02, s:gui02, s:cterm02, s:cterm02, "none", "") -call hi("ColorColumn", "", s:gui01, "", s:cterm01, "none", "") -call hi("CursorColumn", "", s:gui01, "", s:cterm01, "none", "") -call hi("CursorLine", "", s:gui01, "", s:cterm01, "none", "") -call hi("CursorLineNr", s:gui04, s:gui01, s:cterm04, s:cterm01, "", "") -call hi("QuickFixLine", "", s:gui01, "", s:cterm01, "none", "") -call hi("PMenu", s:gui05, s:gui01, s:cterm05, s:cterm01, "none", "") -call hi("PMenuSel", s:gui01, s:gui05, s:cterm01, s:cterm05, "", "") -call hi("TabLine", s:gui03, s:gui01, s:cterm03, s:cterm01, "none", "") -call hi("TabLineFill", s:gui03, s:gui01, s:cterm03, s:cterm01, "none", "") -call hi("TabLineSel", s:gui0B, s:gui01, s:cterm0B, s:cterm01, "none", "") - -" Standard syntax highlighting -call hi("Boolean", s:gui09, "", s:cterm09, "", "", "") -call hi("Character", s:gui08, "", s:cterm08, "", "", "") -call hi("Comment", s:gui03, "", s:cterm03, "", "", "") -call hi("Conditional", s:gui0E, "", s:cterm0E, "", "", "") -call hi("Constant", s:gui09, "", s:cterm09, "", "", "") -call hi("Define", s:gui0E, "", s:cterm0E, "", "none", "") -call hi("Delimiter", s:gui0F, "", s:cterm0F, "", "", "") -call hi("Float", s:gui09, "", s:cterm09, "", "", "") -call hi("Function", s:gui0D, "", s:cterm0D, "", "", "") -call hi("Identifier", s:gui08, "", s:cterm08, "", "none", "") -call hi("Include", s:gui0D, "", s:cterm0D, "", "", "") -call hi("Keyword", s:gui0E, "", s:cterm0E, "", "", "") -call hi("Label", s:gui0A, "", s:cterm0A, "", "", "") -call hi("Number", s:gui09, "", s:cterm09, "", "", "") -call hi("Operator", s:gui05, "", s:cterm05, "", "none", "") -call hi("PreProc", s:gui0A, "", s:cterm0A, "", "", "") -call hi("Repeat", s:gui0A, "", s:cterm0A, "", "", "") -call hi("Special", s:gui0C, "", s:cterm0C, "", "", "") -call hi("SpecialChar", s:gui0F, "", s:cterm0F, "", "", "") -call hi("Statement", s:gui08, "", s:cterm08, "", "", "") -call hi("StorageClass", s:gui0A, "", s:cterm0A, "", "", "") -call hi("String", s:gui0B, "", s:cterm0B, "", "", "") -call hi("Structure", s:gui0E, "", s:cterm0E, "", "", "") -call hi("Tag", s:gui0A, "", s:cterm0A, "", "", "") -call hi("Todo", s:gui0A, s:gui01, s:cterm0A, s:cterm01, "", "") -call hi("Type", s:gui0A, "", s:cterm0A, "", "none", "") -call hi("Typedef", s:gui0A, "", s:cterm0A, "", "", "") - -" C highlighting -call hi("cOperator", s:gui0C, "", s:cterm0C, "", "", "") -call hi("cPreCondit", s:gui0E, "", s:cterm0E, "", "", "") - -" C# highlighting -call hi("csClass", s:gui0A, "", s:cterm0A, "", "", "") -call hi("csAttribute", s:gui0A, "", s:cterm0A, "", "", "") -call hi("csModifier", s:gui0E, "", s:cterm0E, "", "", "") -call hi("csType", s:gui08, "", s:cterm08, "", "", "") -call hi("csUnspecifiedStatement", s:gui0D, "", s:cterm0D, "", "", "") -call hi("csContextualStatement", s:gui0E, "", s:cterm0E, "", "", "") -call hi("csNewDecleration", s:gui08, "", s:cterm08, "", "", "") - -" CSS highlighting -call hi("cssBraces", s:gui05, "", s:cterm05, "", "", "") -call hi("cssClassName", s:gui0E, "", s:cterm0E, "", "", "") -call hi("cssColor", s:gui0C, "", s:cterm0C, "", "", "") - -" Diff highlighting -call hi("DiffAdd", s:gui0B, s:gui01, s:cterm0B, s:cterm01, "", "") -call hi("DiffChange", s:gui03, s:gui01, s:cterm03, s:cterm01, "", "") -call hi("DiffDelete", s:gui08, s:gui01, s:cterm08, s:cterm01, "", "") -call hi("DiffText", s:gui0D, s:gui01, s:cterm0D, s:cterm01, "", "") -call hi("DiffAdded", s:gui0B, s:gui00, s:cterm0B, s:cterm00, "", "") -call hi("DiffFile", s:gui08, s:gui00, s:cterm08, s:cterm00, "", "") -call hi("DiffNewFile", s:gui0B, s:gui00, s:cterm0B, s:cterm00, "", "") -call hi("DiffLine", s:gui0D, s:gui00, s:cterm0D, s:cterm00, "", "") -call hi("DiffRemoved", s:gui08, s:gui00, s:cterm08, s:cterm00, "", "") - -" Git highlighting -call hi("gitcommitOverflow", s:gui08, "", s:cterm08, "", "", "") -call hi("gitcommitSummary", s:gui0B, "", s:cterm0B, "", "", "") -call hi("gitcommitComment", s:gui03, "", s:cterm03, "", "", "") -call hi("gitcommitUntracked", s:gui03, "", s:cterm03, "", "", "") -call hi("gitcommitDiscarded", s:gui03, "", s:cterm03, "", "", "") -call hi("gitcommitSelected", s:gui03, "", s:cterm03, "", "", "") -call hi("gitcommitHeader", s:gui0E, "", s:cterm0E, "", "", "") -call hi("gitcommitSelectedType", s:gui0D, "", s:cterm0D, "", "", "") -call hi("gitcommitUnmergedType", s:gui0D, "", s:cterm0D, "", "", "") -call hi("gitcommitDiscardedType", s:gui0D, "", s:cterm0D, "", "", "") -call hi("gitcommitBranch", s:gui09, "", s:cterm09, "", "bold", "") -call hi("gitcommitUntrackedFile", s:gui0A, "", s:cterm0A, "", "", "") -call hi("gitcommitUnmergedFile", s:gui08, "", s:cterm08, "", "bold", "") -call hi("gitcommitDiscardedFile", s:gui08, "", s:cterm08, "", "bold", "") -call hi("gitcommitSelectedFile", s:gui0B, "", s:cterm0B, "", "bold", "") - -" GitGutter highlighting -call hi("GitGutterAdd", s:gui0B, s:gui01, s:cterm0B, s:cterm01, "", "") -call hi("GitGutterChange", s:gui0D, s:gui01, s:cterm0D, s:cterm01, "", "") -call hi("GitGutterDelete", s:gui08, s:gui01, s:cterm08, s:cterm01, "", "") -call hi("GitGutterChangeDelete", s:gui0E, s:gui01, s:cterm0E, s:cterm01, "", "") - -" HTML highlighting -call hi("htmlBold", s:gui0A, "", s:cterm0A, "", "", "") -call hi("htmlItalic", s:gui0E, "", s:cterm0E, "", "", "") -call hi("htmlEndTag", s:gui05, "", s:cterm05, "", "", "") -call hi("htmlTag", s:gui05, "", s:cterm05, "", "", "") - -" JavaScript highlighting -call hi("javaScript", s:gui05, "", s:cterm05, "", "", "") -call hi("javaScriptBraces", s:gui05, "", s:cterm05, "", "", "") -call hi("javaScriptNumber", s:gui09, "", s:cterm09, "", "", "") -" pangloss/vim-javascript highlighting -call hi("jsOperator", s:gui0D, "", s:cterm0D, "", "", "") -call hi("jsStatement", s:gui0E, "", s:cterm0E, "", "", "") -call hi("jsReturn", s:gui0E, "", s:cterm0E, "", "", "") -call hi("jsThis", s:gui08, "", s:cterm08, "", "", "") -call hi("jsClassDefinition", s:gui0A, "", s:cterm0A, "", "", "") -call hi("jsFunction", s:gui0E, "", s:cterm0E, "", "", "") -call hi("jsFuncName", s:gui0D, "", s:cterm0D, "", "", "") -call hi("jsFuncCall", s:gui0D, "", s:cterm0D, "", "", "") -call hi("jsClassFuncName", s:gui0D, "", s:cterm0D, "", "", "") -call hi("jsClassMethodType", s:gui0E, "", s:cterm0E, "", "", "") -call hi("jsRegexpString", s:gui0C, "", s:cterm0C, "", "", "") -call hi("jsGlobalObjects", s:gui0A, "", s:cterm0A, "", "", "") -call hi("jsGlobalNodeObjects", s:gui0A, "", s:cterm0A, "", "", "") -call hi("jsExceptions", s:gui0A, "", s:cterm0A, "", "", "") -call hi("jsBuiltins", s:gui0A, "", s:cterm0A, "", "", "") - -" Mail highlighting -call hi("mailQuoted1", s:gui0A, "", s:cterm0A, "", "", "") -call hi("mailQuoted2", s:gui0B, "", s:cterm0B, "", "", "") -call hi("mailQuoted3", s:gui0E, "", s:cterm0E, "", "", "") -call hi("mailQuoted4", s:gui0C, "", s:cterm0C, "", "", "") -call hi("mailQuoted5", s:gui0D, "", s:cterm0D, "", "", "") -call hi("mailQuoted6", s:gui0A, "", s:cterm0A, "", "", "") -call hi("mailURL", s:gui0D, "", s:cterm0D, "", "", "") -call hi("mailEmail", s:gui0D, "", s:cterm0D, "", "", "") - -" Markdown highlighting -call hi("markdownCode", s:gui0B, "", s:cterm0B, "", "", "") -call hi("markdownError", s:gui05, s:gui00, s:cterm05, s:cterm00, "", "") -call hi("markdownCodeBlock", s:gui0B, "", s:cterm0B, "", "", "") -call hi("markdownHeadingDelimiter", s:gui0D, "", s:cterm0D, "", "", "") - -" NERDTree highlighting -call hi("NERDTreeDirSlash", s:gui0D, "", s:cterm0D, "", "", "") -call hi("NERDTreeExecFile", s:gui05, "", s:cterm05, "", "", "") - -" PHP highlighting -call hi("phpMemberSelector", s:gui05, "", s:cterm05, "", "", "") -call hi("phpComparison", s:gui05, "", s:cterm05, "", "", "") -call hi("phpParent", s:gui05, "", s:cterm05, "", "", "") - -" Python highlighting -call hi("pythonOperator", s:gui0E, "", s:cterm0E, "", "", "") -call hi("pythonRepeat", s:gui0E, "", s:cterm0E, "", "", "") -call hi("pythonInclude", s:gui0E, "", s:cterm0E, "", "", "") -call hi("pythonStatement", s:gui0E, "", s:cterm0E, "", "", "") - -" Ruby highlighting -call hi("rubyAttribute", s:gui0D, "", s:cterm0D, "", "", "") -call hi("rubyConstant", s:gui0A, "", s:cterm0A, "", "", "") -call hi("rubyInterpolationDelimiter", s:gui0F, "", s:cterm0F, "", "", "") -call hi("rubyRegexp", s:gui0C, "", s:cterm0C, "", "", "") -call hi("rubySymbol", s:gui0B, "", s:cterm0B, "", "", "") -call hi("rubyStringDelimiter", s:gui0B, "", s:cterm0B, "", "", "") - -" SASS highlighting -call hi("sassidChar", s:gui08, "", s:cterm08, "", "", "") -call hi("sassClassChar", s:gui09, "", s:cterm09, "", "", "") -call hi("sassInclude", s:gui0E, "", s:cterm0E, "", "", "") -call hi("sassMixing", s:gui0E, "", s:cterm0E, "", "", "") -call hi("sassMixinName", s:gui0D, "", s:cterm0D, "", "", "") - -" Signify highlighting -call hi("SignifySignAdd", s:gui0B, s:gui01, s:cterm0B, s:cterm01, "", "") -call hi("SignifySignChange", s:gui0D, s:gui01, s:cterm0D, s:cterm01, "", "") -call hi("SignifySignDelete", s:gui08, s:gui01, s:cterm08, s:cterm01, "", "") - -" Spelling highlighting -call hi("SpellBad", "", s:gui00, "", s:cterm00, "undercurl", s:gui08) -call hi("SpellLocal", "", s:gui00, "", s:cterm00, "undercurl", s:gui0C) -call hi("SpellCap", "", s:gui00, "", s:cterm00, "undercurl", s:gui0D) -call hi("SpellRare", "", s:gui00, "", s:cterm00, "undercurl", s:gui0E) - -" Remove functions -delf hi - -" Remove color variables -unlet s:gui00 s:gui01 s:gui02 s:gui03 s:gui04 s:gui05 s:gui06 s:gui07 s:gui08 s:gui09 s:gui0A s:gui0B s:gui0C s:gui0D s:gui0E s:gui0F -unlet s:cterm00 s:cterm01 s:cterm02 s:cterm03 s:cterm04 s:cterm05 s:cterm06 s:cterm07 s:cterm08 s:cterm09 s:cterm0A s:cterm0B s:cterm0C s:cterm0D s:cterm0E s:cterm0F diff --git a/base/.vim/doc/matchit.txt b/base/.vim/doc/matchit.txt deleted file mode 100644 index 8a3a96e..0000000 --- a/base/.vim/doc/matchit.txt +++ /dev/null @@ -1,406 +0,0 @@ -*matchit.txt* Extended "%" matching - -For instructions on installing this file, type - :help matchit-install -inside Vim. - -For Vim version 6.3. Last change: 2007 Aug 29 - - - VIM REFERENCE MANUAL by Benji Fisher - -*matchit* *matchit.vim* - -1. Extended matching with "%" |matchit-intro| -2. Activation |matchit-activate| -3. Configuration |matchit-configure| -4. Supporting a New Language |matchit-newlang| -5. Known Bugs and Limitations |matchit-bugs| - -The functionality mentioned here is a plugin, see |add-plugin|. -This plugin is only available if 'compatible' is not set. -You can avoid loading this plugin by setting the "loaded_matchit" variable -in your |vimrc| file: > - :let loaded_matchit = 1 - -{Vi does not have any of this} - -============================================================================== -1. Extended matching with "%" *matchit-intro* - - *matchit-%* -% Cycle forward through matching groups, such as "if", "else", "endif", - as specified by |b:match_words|. - - *g%* *v_g%* *o_g%* -g% Cycle backwards through matching groups, as specified by - |b:match_words|. For example, go from "if" to "endif" to "else". - - *[%* *v_[%* *o_[%* -[% Go to [count] previous unmatched group, as specified by - |b:match_words|. Similar to |[{|. - - *]%* *v_]%* *o_]%* -]% Go to [count] next unmatched group, as specified by - |b:match_words|. Similar to |]}|. - - *v_a%* -a% In Visual mode, select the matching group, as specified by - |b:match_words|, containing the cursor. Similar to |v_a[|. - A [count] is ignored, and only the first character of the closing - pattern is selected. - -In Vim, as in plain vi, the percent key, |%|, jumps the cursor from a brace, -bracket, or paren to its match. This can be configured with the 'matchpairs' -option. The matchit plugin extends this in several ways: - - You can match whole words, such as "if" and "endif", not just - single characters. You can also specify a |regular-expression|. - You can define groups with more than two words, such as "if", - "else", "endif". Banging on the "%" key will cycle from the "if" to - the first "else", the next "else", ..., the closing "endif", and back - to the opening "if". Nested structures are skipped. Using |g%| goes - in the reverse direction. - By default, words inside comments and strings are ignored, unless - the cursor is inside a comment or string when you type "%". If the - only thing you want to do is modify the behavior of "%" so that it - behaves this way, you do not have to define |b:match_words|, since the - script uses the 'matchpairs' option as well as this variable. - -See |matchit-details| for details on what the script does, and |b:match_words| -for how to specify matching patterns. - -MODES: *matchit-modes* *matchit-v_%* *matchit-o_%* - -Mostly, % and related motions (|g%| and |[%| and |]%|) work just like built-in -|motion| commands in |Operator-pending| and |Visual| modes. However, you -cannot make these motions |linewise| or |characterwise|, since the |:omap|s -that define them start with "v" in order to make the default behavior -inclusive. (See |o_v|.) In other words, "dV%" will not work. The -work-around is to go through Visual mode: "V%d" will work. - -LANGUAGES: *matchit-languages* - -Currently, the following languages are supported: Ada, ASP with VBS, Csh, -DTD, Entity, Essbase, Fortran, HTML, JSP (same as HTML), LaTeX, Lua, Pascal, -SGML, Shell, Tcsh, Vim, XML. Other languages may already have support via -the default |filetype-plugin|s in the standard vim distribution. - -To support a new language, see |matchit-newlang| below. - -DETAILS: *matchit-details* *matchit-parse* - -Here is an outline of what matchit.vim does each time you hit the "%" key. If -there are |backref|s in |b:match_words| then the first step is to produce a -version in which these back references have been eliminated; if there are no -|backref|s then this step is skipped. This step is called parsing. For -example, "\(foo\|bar\):end\1" is parsed to yield -"\(foo\|bar\):end\(foo\|bar\)". This can get tricky, especially if there are -nested groups. If debugging is turned on, the parsed version is saved as -|b:match_pat|. - - *matchit-choose* -Next, the script looks for a word on the current line that matches the pattern -just constructed. It includes the patterns from the 'matchpairs' option. -The goal is to do what you expect, which turns out to be a little complicated. -The script follows these rules: - - Insist on a match that ends on or after the cursor. - Prefer a match that includes the cursor position (that is, one that - starts on or before the cursor). - Prefer a match that starts as close to the cursor as possible. - If more than one pattern in |b:match_words| matches, choose the one - that is listed first. - -Examples: - - Suppose you > - :let b:match_words = '<:>,:' -< and hit "%" with the cursor on or before the "<" in "a is born". - The pattern '<' comes first, so it is preferred over '', which - also matches. If the cursor is on the "t", however, then '' is - preferred, because this matches a bit of text containing the cursor. - If the two groups of patterns were reversed then '<' would never be - preferred. - - Suppose you > - :let b:match_words = 'if:end if' -< (Note the space!) and hit "%" with the cursor at the end of "end if". - Then "if" matches, which is probably not what you want, but if the - cursor starts on the "end " then "end if" is chosen. (You can avoid - this problem by using a more complicated pattern.) - -If there is no match, the cursor does not move. (Before version 1.13 of the -script, it would fall back on the usual behavior of |%|). If debugging is -turned on, the matched bit of text is saved as |b:match_match| and the cursor -column of the start of the match is saved as |b:match_col|. - -Next, the script looks through |b:match_words| (original and parsed versions) -for the group and pattern that match. If debugging is turned on, the group is -saved as |b:match_ini| (the first pattern) and |b:match_tail| (the rest). If -there are |backref|s then, in addition, the matching pattern is saved as -|b:match_word| and a table of translations is saved as |b:match_table|. If -there are |backref|s, these are determined from the matching pattern and -|b:match_match| and substituted into each pattern in the matching group. - -The script decides whether to search forwards or backwards and chooses -arguments for the |searchpair()| function. Then, the cursor is moved to the -start of the match, and |searchpair()| is called. By default, matching -structures inside strings and comments are ignored. This can be changed by -setting |b:match_skip|. - -============================================================================== -2. Activation *matchit-activate* - -You can use this script as a plugin, by copying it to your plugin directory. -See |add-global-plugin| for instructions. You can also add a line to your -|vimrc| file, such as > - :source $VIMRUNTIME/macros/matchit.vim -or > - :runtime macros/matchit.vim -Either way, the script should start working the next time you start up Vim. - -(Earlier versions of the script did nothing unless a |buffer-variable| named -|b:match_words| was defined. Even earlier versions contained autocommands -that set this variable for various file types. Now, |b:match_words| is -defined in many of the default |filetype-plugin|s instead.) - -For a new language, you can add autocommands to the script or to your vimrc -file, but the recommended method is to add a line such as > - let b:match_words = '\:\' -to the |filetype-plugin| for your language. See |b:match_words| below for how -this variable is interpreted. - -TROUBLESHOOTING *matchit-troubleshoot* - -The script should work in most installations of Vim. It may not work if Vim -was compiled with a minimal feature set, for example if the |+syntax| option -was not enabled. If your Vim has support for syntax compiled in, but you do -not have |syntax| highlighting turned on, matchit.vim should work, but it may -fail to skip matching groups in comments and strings. If the |filetype| -mechanism is turned off, the |b:match_words| variable will probably not be -defined automatically. - -============================================================================== -3. Configuration *matchit-configure* - -There are several variables that govern the behavior of matchit.vim. Note -that these are variables local to the buffer, not options, so use |:let| to -define them, not |:set|. Some of these variables have values that matter; for -others, it only matters whether the variable has been defined. All of these -can be defined in the |filetype-plugin| or autocommand that defines -|b:match_words| or "on the fly." - -The main variable is |b:match_words|. It is described in the section below on -supporting a new language. - - *MatchError* *matchit-hl* *matchit-highlight* -MatchError is the highlight group for error messages from the script. By -default, it is linked to WarningMsg. If you do not want to be bothered by -error messages, you can define this to be something invisible. For example, -if you use the GUI version of Vim and your command line is normally white, you -can do > - :hi MatchError guifg=white guibg=white -< - *b:match_ignorecase* -If you > - :let b:match_ignorecase = 1 -then matchit.vim acts as if 'ignorecase' is set: for example, "end" and "END" -are equivalent. If you > - :let b:match_ignorecase = 0 -then matchit.vim treats "end" and "END" differently. (There will be no -b:match_infercase option unless someone requests it.) - - *b:match_debug* -Define b:match_debug if you want debugging information to be saved. See -|matchit-debug|, below. - - *b:match_skip* -If b:match_skip is defined, it is passed as the skip argument to -|searchpair()|. This controls when matching structures are skipped, or -ignored. By default, they are ignored inside comments and strings, as -determined by the |syntax| mechanism. (If syntax highlighting is turned off, -nothing is skipped.) You can set b:match_skip to a string, which evaluates to -a non-zero, numerical value if the match is to be skipped or zero if the match -should not be skipped. In addition, the following special values are -supported by matchit.vim: - s:foo becomes (current syntax item) =~ foo - S:foo becomes (current syntax item) !~ foo - r:foo becomes (line before cursor) =~ foo - R:foo becomes (line before cursor) !~ foo -(The "s" is meant to suggest "syntax", and the "r" is meant to suggest -"regular expression".) - -Examples: - - You can get the default behavior with > - :let b:match_skip = 's:comment\|string' -< - If you want to skip matching structures unless they are at the start - of the line (ignoring whitespace) then you can > - :let b:match_skip = 'R:^\s*' -< Do not do this if strings or comments can span several lines, since - the normal syntax checking will not be done if you set b:match_skip. - - In LaTeX, since "%" is used as the comment character, you can > - :let b:match_skip = 'r:%' -< Unfortunately, this will skip anything after "\%", an escaped "%". To - allow for this, and also "\\%" (an excaped backslash followed by the - comment character) you can > - :let b:match_skip = 'r:\(^\|[^\\]\)\(\\\\\)*%' -< - See the $VIMRUNTIME/ftplugin/vim.vim for an example that uses both - syntax and a regular expression. - -============================================================================== -4. Supporting a New Language *matchit-newlang* - *b:match_words* -In order for matchit.vim to support a new language, you must define a suitable -pattern for |b:match_words|. You may also want to set some of the -|matchit-configure| variables, as described above. If your language has a -complicated syntax, or many keywords, you will need to know something about -Vim's |regular-expression|s. - -The format for |b:match_words| is similar to that of the 'matchpairs' option: -it is a comma (,)-separated list of groups; each group is a colon(:)-separated -list of patterns (regular expressions). Commas and backslashes that are part -of a pattern should be escaped with backslashes ('\:' and '\,'). It is OK to -have only one group; the effect is undefined if a group has only one pattern. -A simple example is > - :let b:match_words = '\:\,' - \ . '\:\:\:\' -(In Vim regular expressions, |\<| and |\>| denote word boundaries. Thus "if" -matches the end of "endif" but "\" does not.) Then banging on the "%" -key will bounce the cursor between "if" and the matching "endif"; and from -"while" to any matching "continue" or "break", then to the matching "endwhile" -and back to the "while". It is almost always easier to use |literal-string|s -(single quotes) as above: '\' rather than "\\" and so on. - -Exception: If the ":" character does not appear in b:match_words, then it is -treated as an expression to be evaluated. For example, > - :let b:match_words = 'GetMatchWords()' -allows you to define a function. This can return a different string depending -on the current syntax, for example. - -Once you have defined the appropriate value of |b:match_words|, you will -probably want to have this set automatically each time you edit the -appropriate file type. The recommended way to do this is by adding the -definition to a |filetype-plugin| file. - -Tips: Be careful that your initial pattern does not match your final pattern. -See the example above for the use of word-boundary expressions. It is usually -better to use ".\{-}" (as many as necessary) instead of ".*" (as many as -possible). See |\{-|. For example, in the string "label", "<.*>" -matches the whole string whereas "<.\{-}>" and "<[^>]*>" match "" and -"". - - *matchit-spaces* *matchit-s:notend* -If "if" is to be paired with "end if" (Note the space!) then word boundaries -are not enough. Instead, define a regular expression s:notend that will match -anything but "end" and use it as follows: > - :let s:notend = '\%(\:\' -< *matchit-s:sol* -This is a simplified version of what is done for Ada. The s:notend is a -|script-variable|. Similarly, you may want to define a start-of-line regular -expression > - :let s:sol = '\%(^\|;\)\s*' -if keywords are only recognized after the start of a line or after a -semicolon (;), with optional white space. - - *matchit-backref* *matchit-\1* -In any group, the expressions |\1|, |\2|, ..., |\9| refer to parts of the -INITIAL pattern enclosed in |\(|escaped parentheses|\)|. These are referred -to as back references, or backrefs. For example, > - :let b:match_words = '\:\(h\)\1\>' -means that "bo" pairs with "ho" and "boo" pairs with "hoo" and so on. Note -that "\1" does not refer to the "\(h\)" in this example. If you have -"\(nested \(parentheses\)\) then "\d" refers to the d-th "\(" and everything -up to and including the matching "\)": in "\(nested\(parentheses\)\)", "\1" -refers to everything and "\2" refers to "\(parentheses\)". If you use a -variable such as |s:notend| or |s:sol| in the previous paragraph then remember -to count any "\(" patterns in this variable. You do not have to count groups -defined by |\%(\)|. - -It should be possible to resolve back references from any pattern in the -group. For example, > - :let b:match_words = '\(foo\)\(bar\):more\1:and\2:end\1\2' -would not work because "\2" cannot be determined from "morefoo" and "\1" -cannot be determined from "andbar". On the other hand, > - :let b:match_words = '\(\(foo\)\(bar\)\):\3\2:end\1' -should work (and have the same effect as "foobar:barfoo:endfoobar"), although -this has not been thoroughly tested. - -You can use |zero-width| patterns such as |\@<=| and |\zs|. (The latter has -not been thouroughly tested in matchit.vim.) For example, if the keyword "if" -must occur at the start of the line, with optional white space, you might use -the pattern "\(^\s*\)\@<=if" so that the cursor will end on the "i" instead of -at the start of the line. For another example, if HTML had only one tag then -one could > - :let b:match_words = '<:>,<\@<=tag>:<\@<=/tag>' -so that "%" can bounce between matching "<" and ">" pairs or (starting on -"tag" or "/tag") between matching tags. Without the |\@<=|, the script would -bounce from "tag" to the "<" in "", and another "%" would not take you -back to where you started. - -DEBUGGING *matchit-debug* *:MatchDebug* - -If you are having trouble figuring out the appropriate definition of -|b:match_words| then you can take advantage of the same information I use when -debugging the script. This is especially true if you are not sure whether -your patterns or my script are at fault! To make this more convenient, I have -made the command :MatchDebug, which defines the variable |b:match_debug| and -creates a Matchit menu. This menu makes it convenient to check the values of -the variables described below. You will probably also want to read -|matchit-details| above. - -Defining the variable |b:match_debug| causes the script to set the following -variables, each time you hit the "%" key. Several of these are only defined -if |b:match_words| includes |backref|s. - - *b:match_pat* -The b:match_pat variable is set to |b:match_words| with |backref|s parsed. - *b:match_match* -The b:match_match variable is set to the bit of text that is recognized as a -match. - *b:match_col* -The b:match_col variable is set to the cursor column of the start of the -matching text. - *b:match_wholeBR* -The b:match_wholeBR variable is set to the comma-separated group of patterns -that matches, with |backref|s unparsed. - *b:match_iniBR* -The b:match_iniBR variable is set to the first pattern in |b:match_wholeBR|. - *b:match_ini* -The b:match_ini variable is set to the first pattern in |b:match_wholeBR|, -with |backref|s resolved from |b:match_match|. - *b:match_tail* -The b:match_tail variable is set to the remaining patterns in -|b:match_wholeBR|, with |backref|s resolved from |b:match_match|. - *b:match_word* -The b:match_word variable is set to the pattern from |b:match_wholeBR| that -matches |b:match_match|. - *b:match_table* -The back reference '\'.d refers to the same thing as '\'.b:match_table[d] in -|b:match_word|. - -============================================================================== -5. Known Bugs and Limitations *matchit-bugs* - -Just because I know about a bug does not mean that it is on my todo list. I -try to respond to reports of bugs that cause real problems. If it does not -cause serious problems, or if there is a work-around, a bug may sit there for -a while. Moral: if a bug (known or not) bothers you, let me know. - -The various |:vmap|s defined in the script (%, |g%|, |[%|, |]%|, |a%|) may -have undesired effects in Select mode |Select-mode-mapping|. At least, if you -want to replace the selection with any character in "ag%[]" there will be a -pause of |'updatetime'| first. - -It would be nice if "\0" were recognized as the entire pattern. That is, it -would be nice if "foo:\end\0" had the same effect as "\(foo\):\end\1". I may -try to implement this in a future version. (This is not so easy to arrange as -you might think!) - -============================================================================== -vim:tw=78:fo=tcq2: diff --git a/base/.vim/doc/tags b/base/.vim/doc/tags deleted file mode 100644 index 4ccdc87..0000000 --- a/base/.vim/doc/tags +++ /dev/null @@ -1,50 +0,0 @@ -:MatchDebug matchit.txt /*:MatchDebug* -MatchError matchit.txt /*MatchError* -[% matchit.txt /*[%* -]% matchit.txt /*]%* -b:match_col matchit.txt /*b:match_col* -b:match_debug matchit.txt /*b:match_debug* -b:match_ignorecase matchit.txt /*b:match_ignorecase* -b:match_ini matchit.txt /*b:match_ini* -b:match_iniBR matchit.txt /*b:match_iniBR* -b:match_match matchit.txt /*b:match_match* -b:match_pat matchit.txt /*b:match_pat* -b:match_skip matchit.txt /*b:match_skip* -b:match_table matchit.txt /*b:match_table* -b:match_tail matchit.txt /*b:match_tail* -b:match_wholeBR matchit.txt /*b:match_wholeBR* -b:match_word matchit.txt /*b:match_word* -b:match_words matchit.txt /*b:match_words* -g% matchit.txt /*g%* -matchit matchit.txt /*matchit* -matchit-% matchit.txt /*matchit-%* -matchit-\1 matchit.txt /*matchit-\\1* -matchit-activate matchit.txt /*matchit-activate* -matchit-backref matchit.txt /*matchit-backref* -matchit-bugs matchit.txt /*matchit-bugs* -matchit-choose matchit.txt /*matchit-choose* -matchit-configure matchit.txt /*matchit-configure* -matchit-debug matchit.txt /*matchit-debug* -matchit-details matchit.txt /*matchit-details* -matchit-highlight matchit.txt /*matchit-highlight* -matchit-hl matchit.txt /*matchit-hl* -matchit-intro matchit.txt /*matchit-intro* -matchit-languages matchit.txt /*matchit-languages* -matchit-modes matchit.txt /*matchit-modes* -matchit-newlang matchit.txt /*matchit-newlang* -matchit-o_% matchit.txt /*matchit-o_%* -matchit-parse matchit.txt /*matchit-parse* -matchit-s:notend matchit.txt /*matchit-s:notend* -matchit-s:sol matchit.txt /*matchit-s:sol* -matchit-spaces matchit.txt /*matchit-spaces* -matchit-troubleshoot matchit.txt /*matchit-troubleshoot* -matchit-v_% matchit.txt /*matchit-v_%* -matchit.txt matchit.txt /*matchit.txt* -matchit.vim matchit.txt /*matchit.vim* -o_[% matchit.txt /*o_[%* -o_]% matchit.txt /*o_]%* -o_g% matchit.txt /*o_g%* -v_[% matchit.txt /*v_[%* -v_]% matchit.txt /*v_]%* -v_a% matchit.txt /*v_a%* -v_g% matchit.txt /*v_g%* diff --git a/base/.vim/ftdetect/json.vim b/base/.vim/ftdetect/json.vim deleted file mode 100644 index b4a5cd7..0000000 --- a/base/.vim/ftdetect/json.vim +++ /dev/null @@ -1,3 +0,0 @@ -autocmd BufNewFile,BufRead *.json setlocal filetype=json -autocmd BufNewFile,BufRead *.jsonp setlocal filetype=json -autocmd BufNewFile,BufRead *.geojson setlocal filetype=json diff --git a/base/.vim/ftplugin/json.vim b/base/.vim/ftplugin/json.vim deleted file mode 100644 index 3ee1062..0000000 --- a/base/.vim/ftplugin/json.vim +++ /dev/null @@ -1,40 +0,0 @@ -" Vim syntax file -" Language: JSON -" Maintainer: Eli Parra https://github.com/elzr/vim-json -" Last Change: 2014-05-20 added warning toggle - -"uncomment to enable folding of `{...}` and `[...]` blocks -"setlocal foldmethod=syntax - -"conceal by default -if !exists("g:vim_json_syntax_conceal") - let g:vim_json_syntax_conceal = 1 -end - -"have warnings by default -if !exists("g:vim_json_warnings") - let g:vim_json_warnings = 1 -end - -"set concealcursor blank by default -"this should turn off the concealing in the current line (where the cursor is at), -"on all modes (normal, visual, insert) -if !exists("g:vim_json_syntax_concealcursor") - let g:vim_json_syntax_concealcursor = "" -end - -if has('conceal') - if (g:vim_json_syntax_conceal == 1) - "level 2 means concealed text gets completely hidden unless a - "replacement is defined (none is defined by us) - setlocal conceallevel=2 - let &l:concealcursor = g:vim_json_syntax_concealcursor - else - "level 0 means text is shown normally = no concealing - setlocal conceallevel=0 - endif - "maybe g:vim_json_syntax_conceal could be settable to 0,1,2 to map - "directly to vim's conceallevels? unsure if anyone cares -endif - -setlocal foldmethod=syntax diff --git a/base/.vim/ftplugin/php.vim b/base/.vim/ftplugin/php.vim deleted file mode 100644 index 3c498a7..0000000 --- a/base/.vim/ftplugin/php.vim +++ /dev/null @@ -1,272 +0,0 @@ -" Vim indent file -" Language: Php -" Authors: Miles Lott , Johannes Zellner , Pim Snel -" URL: http://lingewoud.nl/downloads.php -" Last Change: 23 feb 2004 -" Version: 0.3 -" Notes: This is a combination of the PHP indent file of Miles Lott with -" the HTML indent file of Johannes Zellner. Usefull for editing -" php-files with html parts in it. -" -" Changelog: -" 0.3 - 25 mar 2004 -" - fixed wrong indention when a php-tag is opened and closed on -" one single line. -" 0.2 - 23 feb 2004 -" - applied patch from Holger Dzeik -" - added changelog -" - added default indention of 3 spaces after the ,<>>,,{,} - -" Only define the function once. -if exists("*GetPhpIndent") - finish -endif - -" Handle option(s) -if exists("php_noindent_switch") - let b:php_noindent_switch=1 -endif - -if exists('g:html_indent_tags') - unlet g:html_indent_tags -endif - -function GetPhpIndent() - " Find a non-empty line above the current line. - let lnum = prevnonblank(v:lnum - 1) - - " Hit the start of the file, use zero indent. - if lnum == 0 - return 0 - endif - - let line = getline(lnum) " last line - let cline = getline(v:lnum) " current line - let pline = getline(lnum - 1) " previous to last line - let ind = indent(lnum) - - let restore_ic=&ic - let &ic=1 " ignore case - - let ind = HtmlIndentSum(lnum, -1) - let ind = ind + HtmlIndentSum(v:lnum, 0) - - let &ic=restore_ic - - let ind = indent(lnum) + (&sw * ind) - - " Indent after php open tags - if line =~ '' - let ind = ind + &sw - endif - if cline =~ '^\s*[?>]' " // Fix from Holger Dzeik Thanks! - let ind = ind - &sw - endif - - - if exists("b:php_noindent_switch") " version 1 behavior, diy switch/case,etc - " Indent blocks enclosed by {} or () - if line =~ '[{(]\s*\(#[^)}]*\)\=$' - let ind = ind + &sw - endif - if cline =~ '^\s*[)}]' - let ind = ind - &sw - endif - return ind - else " Try to indent switch/case statements as well - " Indent blocks enclosed by {} or () or case statements, with some anal requirements - if line =~ 'case.*:\|[{(]\s*\(#[^)}]*\)\=$' - let ind = ind + &sw - " return if the current line is not another case statement of the previous line is a bracket open - if cline !~ '.*case.*:\|default:' || line =~ '[{(]\s*\(#[^)}]*\)\=$' - return ind - endif - endif - if cline =~ '^\s*case.*:\|^\s*default:\|^\s*[)}]' - let ind = ind - &sw - " if the last line is a break or return, or the current line is a close bracket, - " or if the previous line is a default statement, subtract another - if line =~ '^\s*break;\|^\s*return\|' && cline =~ '^\s*[)}]' && pline =~ 'default:' - let ind = ind - &sw - endif - endif - - if line =~ 'default:' - let ind = ind + &sw - endif - return ind - endif -endfunction - - -" [-- local settings (must come before aborting the script) --] -"setlocal indentexpr=HtmlIndentGet(v:lnum) -"setlocal indentkeys=o,O,*,<>>,,{,} - - - -" [-- helper function to assemble tag list --] -fun! HtmlIndentPush(tag) - if exists('g:html_indent_tags') - let g:html_indent_tags = g:html_indent_tags.'\|'.a:tag - else - let g:html_indent_tags = a:tag - endif -endfun - - -" [-- --] -call HtmlIndentPush('a') -call HtmlIndentPush('abbr') -call HtmlIndentPush('acronym') -call HtmlIndentPush('address') -call HtmlIndentPush('b') -call HtmlIndentPush('bdo') -call HtmlIndentPush('big') -call HtmlIndentPush('blockquote') -call HtmlIndentPush('button') -call HtmlIndentPush('caption') -call HtmlIndentPush('center') -call HtmlIndentPush('cite') -call HtmlIndentPush('code') -call HtmlIndentPush('colgroup') -call HtmlIndentPush('del') -call HtmlIndentPush('dfn') -call HtmlIndentPush('dir') -call HtmlIndentPush('div') -call HtmlIndentPush('dl') -call HtmlIndentPush('em') -call HtmlIndentPush('fieldset') -call HtmlIndentPush('font') -call HtmlIndentPush('form') -call HtmlIndentPush('frameset') -call HtmlIndentPush('h1') -call HtmlIndentPush('h2') -call HtmlIndentPush('h3') -call HtmlIndentPush('h4') -call HtmlIndentPush('h5') -call HtmlIndentPush('h6') -call HtmlIndentPush('i') -call HtmlIndentPush('iframe') -call HtmlIndentPush('ins') -call HtmlIndentPush('kbd') -call HtmlIndentPush('label') -call HtmlIndentPush('legend') -call HtmlIndentPush('map') -call HtmlIndentPush('menu') -call HtmlIndentPush('noframes') -call HtmlIndentPush('noscript') -call HtmlIndentPush('object') -call HtmlIndentPush('ol') -call HtmlIndentPush('optgroup') -call HtmlIndentPush('pre') -call HtmlIndentPush('q') -call HtmlIndentPush('s') -call HtmlIndentPush('samp') -call HtmlIndentPush('script') -call HtmlIndentPush('select') -call HtmlIndentPush('small') -call HtmlIndentPush('span') -call HtmlIndentPush('strong') -call HtmlIndentPush('style') -call HtmlIndentPush('sub') -call HtmlIndentPush('sup') -call HtmlIndentPush('table') -call HtmlIndentPush('textarea') -call HtmlIndentPush('title') -call HtmlIndentPush('tt') -call HtmlIndentPush('u') -call HtmlIndentPush('ul') -call HtmlIndentPush('var') - - -" [-- --] -if !exists('g:html_indent_strict') - call HtmlIndentPush('body') - call HtmlIndentPush('head') - call HtmlIndentPush('html') - call HtmlIndentPush('tbody') -endif - - -" [-- --] -if !exists('g:html_indent_strict_table') - call HtmlIndentPush('th') - call HtmlIndentPush('td') - call HtmlIndentPush('tr') - call HtmlIndentPush('tfoot') - call HtmlIndentPush('thead') -endif - -delfun HtmlIndentPush - -set cpo-=C - -" [-- count indent-increasing tags of line a:lnum --] -fun! HtmlIndentOpen(lnum) - let s = substitute('x'.getline(a:lnum), - \ '.\{-}\(\(<\)\('.g:html_indent_tags.'\)\>\)', "\1", 'g') - let s = substitute(s, "[^\1].*$", '', '') - return strlen(s) -endfun - -" [-- count indent-decreasing tags of line a:lnum --] -fun! HtmlIndentClose(lnum) - let s = substitute('x'.getline(a:lnum), - \ '.\{-}\(\(<\)/\('.g:html_indent_tags.'\)\>>\)', "\1", 'g') - let s = substitute(s, "[^\1].*$", '', '') - return strlen(s) -endfun - -" [-- count indent-increasing '{' of (java|css) line a:lnum --] -fun! HtmlIndentOpenAlt(lnum) - return strlen(substitute(getline(a:lnum), '[^{]\+', '', 'g')) -endfun - -" [-- count indent-decreasing '}' of (java|css) line a:lnum --] -fun! HtmlIndentCloseAlt(lnum) - return strlen(substitute(getline(a:lnum), '[^}]\+', '', 'g')) -endfun - -" [-- return the sum of indents respecting the syntax of a:lnum --] -fun! HtmlIndentSum(lnum, style) - if a:style == match(getline(a:lnum), '^\s*') - let open = HtmlIndentOpen(a:lnum) - let close = HtmlIndentClose(a:lnum) - if 0 != open || 0 != close - return open - close - endif - endif - endif - if '' != &syntax && - \ synIDattr(synID(a:lnum, 1, 1), 'name') =~ '\(css\|java\).*' && - \ synIDattr(synID(a:lnum, strlen(getline(a:lnum)) - 1, 1), 'name') - \ =~ '\(css\|java\).*' - if a:style == match(getline(a:lnum), '^\s*}') - return HtmlIndentOpenAlt(a:lnum) - HtmlIndentCloseAlt(a:lnum) - endif - endif - return 0 -endfun - -" vim: set ts=3 sw=3: diff --git a/base/.vim/indent/json.vim b/base/.vim/indent/json.vim deleted file mode 100644 index 7873d65..0000000 --- a/base/.vim/indent/json.vim +++ /dev/null @@ -1,177 +0,0 @@ -" Vim indent file -" Language: JSON -" Mantainer: Eli Parra https://github.com/elzr/vim-json -" Last Change: 2014-05-13: merged Fix for square bracket matching by Jakar -" https://github.com/jakar/vim-json/commit/20b650e22aa750c4ab6a66aa646bdd95d7cd548a#diff-e81fc111b2052e306d126bd9989f7b7c -" Original Author: Rogerz Zhang http://github.com/rogerz/vim-json -" Acknowledgement: Based off of vim-javascript maintained by Darrick Wiebe -" http://www.vim.org/scripts/script.php?script_id=2765 - -" 0. Initialization {{{1 -" ================= - -" Only load this indent file when no other was loaded. -if exists("b:did_indent") - finish -endif -let b:did_indent = 1 - -setlocal nosmartindent - -" Now, set up our indentation expression and keys that trigger it. -setlocal indentexpr=GetJSONIndent() -setlocal indentkeys=0{,0},0),0[,0],!^F,o,O,e - -" Only define the function once. -if exists("*GetJSONIndent") - finish -endif - -let s:cpo_save = &cpo -set cpo&vim - -" 1. Variables {{{1 -" ============ - -let s:line_term = '\s*\%(\%(\/\/\).*\)\=$' -" Regex that defines blocks. -let s:block_regex = '\%({\)\s*\%(|\%([*@]\=\h\w*,\=\s*\)\%(,\s*[*@]\=\h\w*\)*|\)\=' . s:line_term - -" 2. Auxiliary Functions {{{1 -" ====================== - -" Check if the character at lnum:col is inside a string. -function s:IsInString(lnum, col) - return synIDattr(synID(a:lnum, a:col, 1), 'name') == "jsonString" -endfunction - -" Find line above 'lnum' that isn't empty, or in a string. -function s:PrevNonBlankNonString(lnum) - let lnum = prevnonblank(a:lnum) - while lnum > 0 - " If the line isn't empty or in a string, end search. - let line = getline(lnum) - if !(s:IsInString(lnum, 1) && s:IsInString(lnum, strlen(line))) - break - endif - let lnum = prevnonblank(lnum - 1) - endwhile - return lnum -endfunction - -" Check if line 'lnum' has more opening brackets than closing ones. -function s:LineHasOpeningBrackets(lnum) - let open_0 = 0 - let open_2 = 0 - let open_4 = 0 - let line = getline(a:lnum) - let pos = match(line, '[][(){}]', 0) - while pos != -1 - let idx = stridx('(){}[]', line[pos]) - if idx % 2 == 0 - let open_{idx} = open_{idx} + 1 - else - let open_{idx - 1} = open_{idx - 1} - 1 - endif - let pos = match(line, '[][(){}]', pos + 1) - endwhile - return (open_0 > 0) . (open_2 > 0) . (open_4 > 0) -endfunction - -function s:Match(lnum, regex) - let col = match(getline(a:lnum), a:regex) + 1 - return col > 0 && !s:IsInString(a:lnum, col) ? col : 0 -endfunction - -" 3. GetJSONIndent Function {{{1 -" ========================= - -function GetJSONIndent() - " 3.1. Setup {{{2 - " ---------- - - " Set up variables for restoring position in file. Could use v:lnum here. - let vcol = col('.') - - " 3.2. Work on the current line {{{2 - " ----------------------------- - - " Get the current line. - let line = getline(v:lnum) - let ind = -1 - - " If we got a closing bracket on an empty line, find its match and indent - " according to it. - let col = matchend(line, '^\s*[]}]') - - if col > 0 && !s:IsInString(v:lnum, col) - call cursor(v:lnum, col) - let bs = strpart('{}[]', stridx('}]', line[col - 1]) * 2, 2) - - let pairstart = escape(bs[0], '[') - let pairend = escape(bs[1], ']') - let pairline = searchpair(pairstart, '', pairend, 'bW') - - if pairline > 0 - let ind = indent(pairline) - else - let ind = virtcol('.') - 1 - endif - - return ind - endif - - " If we are in a multi-line string, don't do anything to it. - if s:IsInString(v:lnum, matchend(line, '^\s*') + 1) - return indent('.') - endif - - " 3.3. Work on the previous line. {{{2 - " ------------------------------- - - let lnum = prevnonblank(v:lnum - 1) - - if lnum == 0 - return 0 - endif - - " Set up variables for current line. - let line = getline(lnum) - let ind = indent(lnum) - - " If the previous line ended with a block opening, add a level of indent. - " if s:Match(lnum, s:block_regex) - " if exists('*shiftwidth') - " return indent(lnum) + shiftwidth() - " else - " return indent(lnum) + &sw - " endif - " endif - - " If the previous line contained an opening bracket, and we are still in it, - " add indent depending on the bracket type. - if line =~ '[[({]' - let counts = s:LineHasOpeningBrackets(lnum) - if counts[0] == '1' || counts[1] == '1' || counts[2] == '1' - if exists('*shiftwidth') - return ind + shiftwidth() - else - return ind + &sw - endif - else - call cursor(v:lnum, vcol) - end - endif - - " }}}2 - - return ind -endfunction - -" }}}1 - -let &cpo = s:cpo_save -unlet s:cpo_save - -" vim:set sw=2 sts=2 ts=8 noet: - diff --git a/base/.vim/indent/php.vim b/base/.vim/indent/php.vim deleted file mode 100644 index 3c498a7..0000000 --- a/base/.vim/indent/php.vim +++ /dev/null @@ -1,272 +0,0 @@ -" Vim indent file -" Language: Php -" Authors: Miles Lott , Johannes Zellner , Pim Snel -" URL: http://lingewoud.nl/downloads.php -" Last Change: 23 feb 2004 -" Version: 0.3 -" Notes: This is a combination of the PHP indent file of Miles Lott with -" the HTML indent file of Johannes Zellner. Usefull for editing -" php-files with html parts in it. -" -" Changelog: -" 0.3 - 25 mar 2004 -" - fixed wrong indention when a php-tag is opened and closed on -" one single line. -" 0.2 - 23 feb 2004 -" - applied patch from Holger Dzeik -" - added changelog -" - added default indention of 3 spaces after the ,<>>,,{,} - -" Only define the function once. -if exists("*GetPhpIndent") - finish -endif - -" Handle option(s) -if exists("php_noindent_switch") - let b:php_noindent_switch=1 -endif - -if exists('g:html_indent_tags') - unlet g:html_indent_tags -endif - -function GetPhpIndent() - " Find a non-empty line above the current line. - let lnum = prevnonblank(v:lnum - 1) - - " Hit the start of the file, use zero indent. - if lnum == 0 - return 0 - endif - - let line = getline(lnum) " last line - let cline = getline(v:lnum) " current line - let pline = getline(lnum - 1) " previous to last line - let ind = indent(lnum) - - let restore_ic=&ic - let &ic=1 " ignore case - - let ind = HtmlIndentSum(lnum, -1) - let ind = ind + HtmlIndentSum(v:lnum, 0) - - let &ic=restore_ic - - let ind = indent(lnum) + (&sw * ind) - - " Indent after php open tags - if line =~ '' - let ind = ind + &sw - endif - if cline =~ '^\s*[?>]' " // Fix from Holger Dzeik Thanks! - let ind = ind - &sw - endif - - - if exists("b:php_noindent_switch") " version 1 behavior, diy switch/case,etc - " Indent blocks enclosed by {} or () - if line =~ '[{(]\s*\(#[^)}]*\)\=$' - let ind = ind + &sw - endif - if cline =~ '^\s*[)}]' - let ind = ind - &sw - endif - return ind - else " Try to indent switch/case statements as well - " Indent blocks enclosed by {} or () or case statements, with some anal requirements - if line =~ 'case.*:\|[{(]\s*\(#[^)}]*\)\=$' - let ind = ind + &sw - " return if the current line is not another case statement of the previous line is a bracket open - if cline !~ '.*case.*:\|default:' || line =~ '[{(]\s*\(#[^)}]*\)\=$' - return ind - endif - endif - if cline =~ '^\s*case.*:\|^\s*default:\|^\s*[)}]' - let ind = ind - &sw - " if the last line is a break or return, or the current line is a close bracket, - " or if the previous line is a default statement, subtract another - if line =~ '^\s*break;\|^\s*return\|' && cline =~ '^\s*[)}]' && pline =~ 'default:' - let ind = ind - &sw - endif - endif - - if line =~ 'default:' - let ind = ind + &sw - endif - return ind - endif -endfunction - - -" [-- local settings (must come before aborting the script) --] -"setlocal indentexpr=HtmlIndentGet(v:lnum) -"setlocal indentkeys=o,O,*,<>>,,{,} - - - -" [-- helper function to assemble tag list --] -fun! HtmlIndentPush(tag) - if exists('g:html_indent_tags') - let g:html_indent_tags = g:html_indent_tags.'\|'.a:tag - else - let g:html_indent_tags = a:tag - endif -endfun - - -" [-- --] -call HtmlIndentPush('a') -call HtmlIndentPush('abbr') -call HtmlIndentPush('acronym') -call HtmlIndentPush('address') -call HtmlIndentPush('b') -call HtmlIndentPush('bdo') -call HtmlIndentPush('big') -call HtmlIndentPush('blockquote') -call HtmlIndentPush('button') -call HtmlIndentPush('caption') -call HtmlIndentPush('center') -call HtmlIndentPush('cite') -call HtmlIndentPush('code') -call HtmlIndentPush('colgroup') -call HtmlIndentPush('del') -call HtmlIndentPush('dfn') -call HtmlIndentPush('dir') -call HtmlIndentPush('div') -call HtmlIndentPush('dl') -call HtmlIndentPush('em') -call HtmlIndentPush('fieldset') -call HtmlIndentPush('font') -call HtmlIndentPush('form') -call HtmlIndentPush('frameset') -call HtmlIndentPush('h1') -call HtmlIndentPush('h2') -call HtmlIndentPush('h3') -call HtmlIndentPush('h4') -call HtmlIndentPush('h5') -call HtmlIndentPush('h6') -call HtmlIndentPush('i') -call HtmlIndentPush('iframe') -call HtmlIndentPush('ins') -call HtmlIndentPush('kbd') -call HtmlIndentPush('label') -call HtmlIndentPush('legend') -call HtmlIndentPush('map') -call HtmlIndentPush('menu') -call HtmlIndentPush('noframes') -call HtmlIndentPush('noscript') -call HtmlIndentPush('object') -call HtmlIndentPush('ol') -call HtmlIndentPush('optgroup') -call HtmlIndentPush('pre') -call HtmlIndentPush('q') -call HtmlIndentPush('s') -call HtmlIndentPush('samp') -call HtmlIndentPush('script') -call HtmlIndentPush('select') -call HtmlIndentPush('small') -call HtmlIndentPush('span') -call HtmlIndentPush('strong') -call HtmlIndentPush('style') -call HtmlIndentPush('sub') -call HtmlIndentPush('sup') -call HtmlIndentPush('table') -call HtmlIndentPush('textarea') -call HtmlIndentPush('title') -call HtmlIndentPush('tt') -call HtmlIndentPush('u') -call HtmlIndentPush('ul') -call HtmlIndentPush('var') - - -" [-- --] -if !exists('g:html_indent_strict') - call HtmlIndentPush('body') - call HtmlIndentPush('head') - call HtmlIndentPush('html') - call HtmlIndentPush('tbody') -endif - - -" [-- --] -if !exists('g:html_indent_strict_table') - call HtmlIndentPush('th') - call HtmlIndentPush('td') - call HtmlIndentPush('tr') - call HtmlIndentPush('tfoot') - call HtmlIndentPush('thead') -endif - -delfun HtmlIndentPush - -set cpo-=C - -" [-- count indent-increasing tags of line a:lnum --] -fun! HtmlIndentOpen(lnum) - let s = substitute('x'.getline(a:lnum), - \ '.\{-}\(\(<\)\('.g:html_indent_tags.'\)\>\)', "\1", 'g') - let s = substitute(s, "[^\1].*$", '', '') - return strlen(s) -endfun - -" [-- count indent-decreasing tags of line a:lnum --] -fun! HtmlIndentClose(lnum) - let s = substitute('x'.getline(a:lnum), - \ '.\{-}\(\(<\)/\('.g:html_indent_tags.'\)\>>\)', "\1", 'g') - let s = substitute(s, "[^\1].*$", '', '') - return strlen(s) -endfun - -" [-- count indent-increasing '{' of (java|css) line a:lnum --] -fun! HtmlIndentOpenAlt(lnum) - return strlen(substitute(getline(a:lnum), '[^{]\+', '', 'g')) -endfun - -" [-- count indent-decreasing '}' of (java|css) line a:lnum --] -fun! HtmlIndentCloseAlt(lnum) - return strlen(substitute(getline(a:lnum), '[^}]\+', '', 'g')) -endfun - -" [-- return the sum of indents respecting the syntax of a:lnum --] -fun! HtmlIndentSum(lnum, style) - if a:style == match(getline(a:lnum), '^\s*') - let open = HtmlIndentOpen(a:lnum) - let close = HtmlIndentClose(a:lnum) - if 0 != open || 0 != close - return open - close - endif - endif - endif - if '' != &syntax && - \ synIDattr(synID(a:lnum, 1, 1), 'name') =~ '\(css\|java\).*' && - \ synIDattr(synID(a:lnum, strlen(getline(a:lnum)) - 1, 1), 'name') - \ =~ '\(css\|java\).*' - if a:style == match(getline(a:lnum), '^\s*}') - return HtmlIndentOpenAlt(a:lnum) - HtmlIndentCloseAlt(a:lnum) - endif - endif - return 0 -endfun - -" vim: set ts=3 sw=3: diff --git a/base/.vim/syntax/json.vim b/base/.vim/syntax/json.vim deleted file mode 100644 index 3423eba..0000000 --- a/base/.vim/syntax/json.vim +++ /dev/null @@ -1,137 +0,0 @@ -" Vim syntax file -" Language: JSON -" Maintainer: Eli Parra https://github.com/elzr/vim-json -" Last Change: 2014-12-20 Load ftplugin/json.vim - -" Reload the definition of g:vim_json_syntax_conceal -" see https://github.com/elzr/vim-json/issues/42 -runtime! ftplugin/json.vim - -if !exists("main_syntax") - if version < 600 - syntax clear - elseif exists("b:current_syntax") - finish - endif - let main_syntax = 'json' -endif - -syntax match jsonNoise /\%(:\|,\)/ - -" NOTE that for the concealing to work your conceallevel should be set to 2 - -" Syntax: Strings -" Separated into a match and region because a region by itself is always greedy -syn match jsonStringMatch /"\([^"]\|\\\"\)\+"\ze[[:blank:]\r\n]*[,}\]]/ contains=jsonString -if has('conceal') && g:vim_json_syntax_conceal == 1 - syn region jsonString oneline matchgroup=jsonQuote start=/"/ skip=/\\\\\|\\"/ end=/"/ concealends contains=jsonEscape contained -else - syn region jsonString oneline matchgroup=jsonQuote start=/"/ skip=/\\\\\|\\"/ end=/"/ contains=jsonEscape contained -endif - -" Syntax: JSON does not allow strings with single quotes, unlike JavaScript. -syn region jsonStringSQError oneline start=+'+ skip=+\\\\\|\\"+ end=+'+ - -" Syntax: JSON Keywords -" Separated into a match and region because a region by itself is always greedy -syn match jsonKeywordMatch /"\([^"]\|\\\"\)\+"[[:blank:]\r\n]*\:/ contains=jsonKeyword -if has('conceal') && g:vim_json_syntax_conceal == 1 - syn region jsonKeyword matchgroup=jsonQuote start=/"/ end=/"\ze[[:blank:]\r\n]*\:/ concealends contains=jsonEscape contained -else - syn region jsonKeyword matchgroup=jsonQuote start=/"/ end=/"\ze[[:blank:]\r\n]*\:/ contains=jsonEscape contained -endif - -" Syntax: Escape sequences -syn match jsonEscape "\\["\\/bfnrt]" contained -syn match jsonEscape "\\u\x\{4}" contained - -" Syntax: Numbers -syn match jsonNumber "-\=\<\%(0\|[1-9]\d*\)\%(\.\d\+\)\=\%([eE][-+]\=\d\+\)\=\>\ze[[:blank:]\r\n]*[,}\]]" - -" ERROR WARNINGS ********************************************** -if (!exists("g:vim_json_warnings") || g:vim_json_warnings==1) - " Syntax: Strings should always be enclosed with quotes. - syn match jsonNoQuotesError "\<[[:alpha:]][[:alnum:]]*\>" - syn match jsonTripleQuotesError /"""/ - - " Syntax: An integer part of 0 followed by other digits is not allowed. - syn match jsonNumError "-\=\<0\d\.\d*\>" - - " Syntax: Decimals smaller than one should begin with 0 (so .1 should be 0.1). - syn match jsonNumError "\:\@<=[[:blank:]\r\n]*\zs\.\d\+" - - " Syntax: No comments in JSON, see http://stackoverflow.com/questions/244777/can-i-comment-a-json-file - syn match jsonCommentError "//.*" - syn match jsonCommentError "\(/\*\)\|\(\*/\)" - - " Syntax: No semicolons in JSON - syn match jsonSemicolonError ";" - - " Syntax: No trailing comma after the last element of arrays or objects - syn match jsonTrailingCommaError ",\_s*[}\]]" - - " Syntax: Watch out for missing commas between elements - syn match jsonMissingCommaError /\("\|\]\|\d\)\zs\_s\+\ze"/ - syn match jsonMissingCommaError /\(\]\|\}\)\_s\+\ze"/ "arrays/objects as values - syn match jsonMissingCommaError /}\_s\+\ze{/ "objects as elements in an array - syn match jsonMissingCommaError /\(true\|false\)\_s\+\ze"/ "true/false as value -endif - -" ********************************************** END OF ERROR WARNINGS -" Allowances for JSONP: function call at the beginning of the file, -" parenthesis and semicolon at the end. -" Function name validation based on -" http://stackoverflow.com/questions/2008279/validate-a-javascript-function-name/2008444#2008444 -syn match jsonPadding "\%^[[:blank:]\r\n]*[_$[:alpha:]][_$[:alnum:]]*[[:blank:]\r\n]*(" -syn match jsonPadding ");[[:blank:]\r\n]*\%$" - -" Syntax: Boolean -syn match jsonBoolean /\(true\|false\)\(\_s\+\ze"\)\@!/ - -" Syntax: Null -syn keyword jsonNull null - -" Syntax: Braces -syn region jsonFold matchgroup=jsonBraces start="{" end=/}\(\_s\+\ze\("\|{\)\)\@!/ transparent fold -syn region jsonFold matchgroup=jsonBraces start="\[" end=/]\(\_s\+\ze"\)\@!/ transparent fold - -" Define the default highlighting. -if version >= 508 || !exists("did_json_syn_inits") - hi def link jsonPadding Operator - hi def link jsonString String - hi def link jsonTest Label - hi def link jsonEscape Special - hi def link jsonNumber Delimiter - hi def link jsonBraces Delimiter - hi def link jsonNull Function - hi def link jsonBoolean Delimiter - hi def link jsonKeyword Label - - if (!exists("g:vim_json_warnings") || g:vim_json_warnings==1) - hi def link jsonNumError Error - hi def link jsonCommentError Error - hi def link jsonSemicolonError Error - hi def link jsonTrailingCommaError Error - hi def link jsonMissingCommaError Error - hi def link jsonStringSQError Error - hi def link jsonNoQuotesError Error - hi def link jsonTripleQuotesError Error - endif - hi def link jsonQuote Quote - hi def link jsonNoise Noise -endif - -let b:current_syntax = "json" -if main_syntax == 'json' - unlet main_syntax -endif - -" Vim settings -" vim: ts=8 fdm=marker - -" MIT License -" Copyright (c) 2013, Jeroen Ruigrok van der Werven, Eli Parra -"Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the Software), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: -"The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. -"THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -"See https://twitter.com/elzr/status/294964017926119424 diff --git a/base/.vimrc b/base/.vimrc deleted file mode 100644 index 3a4b16a..0000000 --- a/base/.vimrc +++ /dev/null @@ -1,239 +0,0 @@ -set nocompatible -set encoding=utf-8 - -set modelines=0 " for security - -set mouse="" -set backspace=indent,eol,start - -au FocusLost * :wa - -" Leader ====---- -nnoremap ,, , -let mapleader="," -nnoremap ; ; -nnoremap ; : - -" Highlighting ====---- -syntax on -filetype plugin indent on - -set t_Co=256 " force enable 256-color mode. -if &t_Co >= 256 || has("gui_running") - let base16colorspace=256 - colorscheme base16-default-dark -endif -if &t_Co > 2 || has("gui_running") - syntax on -endif - -" Indentation ====---- -set shiftwidth=2 -set tabstop=2 -set expandtab -set shiftround " use multiple of shiftwidth with '<' and '>' -set autoindent -set copyindent " copy the previous line's indentation - -xnoremap < >gv - -" Search ====---- -set incsearch -set hlsearch -set wrapscan -set ignorecase " ignore case when searching -set smartcase " ignore case if search pattern is all lowercase, - " case-sensitive otherwise - -nnoremap :noh - -" Case insensitive -nmap * /\<=expand('')\> -nmap # ?\<=expand('')\> - -set showmatch -nnoremap % -vnoremap % - -" Screen ====---- -"set nowrap -set wrap -"set textwidth=79 -"set formatoptions=tqrn1 -set colorcolumn=85 -set ruler -set number -set relativenumber -set laststatus=2 -set shortmess=aoOstTWAI -set cursorline -"set showmode -set showcmd -set title " change the terminal's title -set scrolloff=3 - -set visualbell " don't beep -set noerrorbells " don't beep - -set list -set listchars=tab:»\ ,extends:›,precedes:‹,nbsp:·,trail:· -"autocmd filetype html,xml set listchars-=tab:>. - -set wildmenu -set wildmode=longest:full,full -set wildignore=*.swp,*.bak,*.pyc,*.class - -set ttyfast - -hi ColorColumn ctermbg=18 -hi Folded ctermbg=0 ctermfg=12 - -" Stop using arrow keys ====---- -noremap -noremap -noremap -noremap - -" nnoremap j gj -" nnoremap k gk - -" Splits ====---- -nnoremap w vl -nnoremap h -nnoremap j -nnoremap k -nnoremap l - -" History ====---- -set history=1000 " remember more commands and search history -set undolevels=1000 " use many muchos levels of undo - -if !isdirectory($HOME."/.vim") - call mkdir($HOME."/.vim", "", 0770) -endif -if !isdirectory($HOME."/.vim/undo-dir") - call mkdir($HOME."/.vim/undo-dir", "", 0700) -endif -set undodir=~/.vim/undo-dir -set undofile -" !!!! ADD THIS TO CRONTAB -" 43 0 * * 3 find /home/adam/.vim/undo-dir -type f -mtime +90 -delete - -set nobackup -set noswapfile " Note: swap helps large files. - -" Custom mappings ====---- - -" Quickly edit/reload the vimrc file -nnoremap ve :tabe $MYVIMRC -nnoremap vs :so $MYVIMRC - -nnoremap :set invpaste paste? -set pastetoggle= - -nnoremap W :%s/\s\+$//:let @/='' -nnoremap ft Vatzf -nnoremap S ?{jV/^\s*\}?$k:sort:noh -nnoremap q gqip -nnoremap vp V`] -nnoremap h :syntax sync fromstart -nnoremap l :nohlsearch:diffupdate:syntax sync fromstart -nnoremap [ :put! =repeat(nr2char(10), v:count1)'[ -nnoremap ] :put =repeat(nr2char(10), v:count1) - -noremap y "*y -noremap yy "*Y -noremap p :set paste:put *:set nopaste - -noremap + :s/^\s*/&\/\//:noh -noremap - :s/^\(\s*\)\/\//\1/:noh - -vnoremap Q gq -nnoremap Q gqap - -cnoremap w!! w !sudo tee % >/dev/null - -" helper function to toggle hex mode -function! ToggleHex() - " hex mode should be considered a read-only operation - " save values for modified and read-only for restoration later, - " and clear the read-only flag for now - let l:modified=&mod - let l:oldreadonly=&readonly - let &readonly=0 - let l:oldmodifiable=&modifiable - let &modifiable=1 - if !exists("b:editHex") || !b:editHex - " save old options - let b:oldft=&ft - let b:oldbin=&bin - " set new options - setlocal binary " make sure it overrides any textwidth, etc. - let &ft="xxd" - " set status - let b:editHex=1 - " switch to hex editor - %!xxd - else - " restore old options - let &ft=b:oldft - if !b:oldbin - setlocal nobinary - endif - " set status - let b:editHex=0 - " return to normal editing - %!xxd -r - endif - " restore values for modified and read only state - let &mod=l:modified - let &readonly=l:oldreadonly - let &modifiable=l:oldmodifiable -endfunction - -command! -bar Hexmode call ToggleHex() -nnoremap H :Hexmode - -function! NumberToggle() - if(&relativenumber == 1) - set norelativenumber - else - set relativenumber - endif -endfunc - -nnoremap N :call NumberToggle() -"autocmd InsertEnter * :set norelativenumber -"autocmd InsertLeave * :set relativenumber - -" Custom functions ====---- - -if filereadable(expand("~/.vimrc.local")) - source ~/.vimrc.local -endif - -function! SetLocalOptions(fname) - let dirname = fnamemodify(a:fname, ":p:h") - while "/" != dirname - let lvimrc = dirname . "/.vimrc.local" - if filereadable(lvimrc) - execute "source " . lvimrc - break - endif - let dirname = fnamemodify(dirname, ":p:h:h") - endwhile -endfunction - -au BufNewFile,BufRead * call SetLocalOptions(bufname("%")) - - -" To move elsewhere ====---- -au BufNewFile,BufRead *.less set filetype=less -autocmd! BufWritePost $MYVIMRC source $MYVIMRC -packadd! matchit -cnoremap -cnoremap -autocmd! BufRead,BufNewFile *.md set filetype=markdown -autocmd! BufRead,BufNewFile *.md set spell -vnoremap p "_dP diff --git a/base/.zsh/aliases.zsh b/base/.zsh/aliases.zsh deleted file mode 100644 index 21544af..0000000 --- a/base/.zsh/aliases.zsh +++ /dev/null @@ -1,31 +0,0 @@ -# UTILITY - -alias ls="ls --color=auto" -alias less='less -R' -alias grep='grep --color=auto' -alias ..='cd ../' - -alias sudoe="sudo -E" -alias svim="sudo -E vim" -alias svimdiff="sudo -E vimdiff" - -# SAFETY - -alias cp="cp -i" -alias mv="mv -i" - -# GIT - -alias gd='git diff' -alias gco='git checkout' -alias gs='git status --short' -alias gl='git pull' -alias gp='git push' -alias gpp='git pull; git push' -alias gwc='git whatchanged -p --abbrev-commit --pretty=medium' - -# POWER - -alias reboot="systemctl reboot" -alias shutdown="systemctl poweroff" -alias poweroff="systemctl poweroff" diff --git a/base/.zsh/async b/base/.zsh/async deleted file mode 100644 index d11a99a..0000000 --- a/base/.zsh/async +++ /dev/null @@ -1,493 +0,0 @@ -#!/usr/bin/env zsh - -# -# zsh-async -# -# version: 1.5.0 -# author: Mathias Fredriksson -# url: https://github.com/mafredri/zsh-async -# - -# Produce debug output from zsh-async when set to 1. -ASYNC_DEBUG=${ASYNC_DEBUG:-0} - -# Wrapper for jobs executed by the async worker, gives output in parseable format with execution time -_async_job() { - # Disable xtrace as it would mangle the output. - setopt localoptions noxtrace - - # Store start time as double precision (+E disables scientific notation) - float -F duration=$EPOCHREALTIME - - # Run the command and capture both stdout (`eval`) and stderr (`cat`) in - # separate subshells. When the command is complete, we grab write lock - # (mutex token) and output everything except stderr inside the command - # block, after the command block has completed, the stdin for `cat` is - # closed, causing stderr to be appended with a $'\0' at the end to mark the - # end of output from this job. - local stdout stderr ret tok - { - stdout=$(eval "$@") - ret=$? - duration=$(( EPOCHREALTIME - duration )) # Calculate duration. - - # Grab mutex lock, stalls until token is available. - read -r -k 1 -p tok || exit 1 - - # Return output ( ). - print -r -n - ${(q)1} $ret ${(q)stdout} $duration - } 2> >(stderr=$(cat) && print -r -n - " "${(q)stderr}$'\0') - - # Unlock mutex by inserting a token. - print -n -p $tok -} - -# The background worker manages all tasks and runs them without interfering with other processes -_async_worker() { - # Reset all options to defaults inside async worker. - emulate -R zsh - - # Make sure monitor is unset to avoid printing the - # pids of child processes. - unsetopt monitor - - # Redirect stderr to `/dev/null` in case unforseen errors produced by the - # worker. For example: `fork failed: resource temporarily unavailable`. - # Some older versions of zsh might also print malloc errors (know to happen - # on at least zsh 5.0.2 and 5.0.8) likely due to kill signals. - exec 2>/dev/null - - # When a zpty is deleted (using -d) all the zpty instances created before - # the one being deleted receive a SIGHUP, unless we catch it, the async - # worker would simply exit (stop working) even though visible in the list - # of zpty's (zpty -L). - TRAPHUP() { - return 0 # Return 0, indicating signal was handled. - } - - local -A storage - local unique=0 - local notify_parent=0 - local parent_pid=0 - local coproc_pid=0 - local processing=0 - - local -a zsh_hooks zsh_hook_functions - zsh_hooks=(chpwd periodic precmd preexec zshexit zshaddhistory) - zsh_hook_functions=(${^zsh_hooks}_functions) - unfunction $zsh_hooks &>/dev/null # Deactivate all zsh hooks inside the worker. - unset $zsh_hook_functions # And hooks with registered functions. - unset zsh_hooks zsh_hook_functions # Cleanup. - - child_exit() { - local -a pids - pids=(${${(v)jobstates##*:*:}%\=*}) - - # If coproc (cat) is the only child running, we close it to avoid - # leaving it running indefinitely and cluttering the process tree. - if (( ! processing )) && [[ $#pids = 1 ]] && [[ $coproc_pid = $pids[1] ]]; then - coproc : - coproc_pid=0 - fi - - # On older version of zsh (pre 5.2) we notify the parent through a - # SIGWINCH signal because `zpty` did not return a file descriptor (fd) - # prior to that. - if (( notify_parent )); then - # We use SIGWINCH for compatibility with older versions of zsh - # (pre 5.1.1) where other signals (INFO, ALRM, USR1, etc.) could - # cause a deadlock in the shell under certain circumstances. - kill -WINCH $parent_pid - fi - } - - # Register a SIGCHLD trap to handle the completion of child processes. - trap child_exit CHLD - - # Process option parameters passed to worker - while getopts "np:u" opt; do - case $opt in - n) notify_parent=1;; - p) parent_pid=$OPTARG;; - u) unique=1;; - esac - done - - killjobs() { - local tok - local -a pids - pids=(${${(v)jobstates##*:*:}%\=*}) - - # No need to send SIGHUP if no jobs are running. - (( $#pids == 0 )) && continue - (( $#pids == 1 )) && [[ $coproc_pid = $pids[1] ]] && continue - - # Grab lock to prevent half-written output in case a child - # process is in the middle of writing to stdin during kill. - (( coproc_pid )) && read -r -k 1 -p tok - - kill -HUP -$$ # Send to entire process group. - coproc : # Quit coproc. - coproc_pid=0 # Reset pid. - } - - local request - local -a cmd - while :; do - # Wait for jobs sent by async_job. - read -r -d $'\0' request || { - # Since we handle SIGHUP above (and thus do not know when `zpty -d`) - # occurs, a failure to read probably indicates that stdin has - # closed. This is why we propagate the signal to all children and - # exit manually. - kill -HUP -$$ # Send SIGHUP to all jobs. - exit 0 - } - - # Check for non-job commands sent to worker - case $request in - _unset_trap) notify_parent=0; continue;; - _killjobs) killjobs; continue;; - esac - - # Parse the request using shell parsing (z) to allow commands - # to be parsed from single strings and multi-args alike. - cmd=("${(z)request}") - - # Name of the job (first argument). - local job=$cmd[1] - - # If worker should perform unique jobs - if (( unique )); then - # Check if a previous job is still running, if yes, let it finnish - for pid in ${${(v)jobstates##*:*:}%\=*}; do - if [[ ${storage[$job]} == $pid ]]; then - continue 2 - fi - done - fi - - # Guard against closing coproc from trap before command has started. - processing=1 - - # Because we close the coproc after the last job has completed, we must - # recreate it when there are no other jobs running. - if (( ! coproc_pid )); then - # Use coproc as a mutex for synchronized output between children. - coproc cat - coproc_pid="$!" - # Insert token into coproc - print -n -p "t" - fi - - # Run job in background, completed jobs are printed to stdout. - _async_job $cmd & - # Store pid because zsh job manager is extremely unflexible (show jobname as non-unique '$job')... - storage[$job]="$!" - - processing=0 # Disable guard. - done -} - -# -# Get results from finnished jobs and pass it to the to callback function. This is the only way to reliably return the -# job name, return code, output and execution time and with minimal effort. -# -# usage: -# async_process_results -# -# callback_function is called with the following parameters: -# $1 = job name, e.g. the function passed to async_job -# $2 = return code -# $3 = resulting stdout from execution -# $4 = execution time, floating point e.g. 2.05 seconds -# $5 = resulting stderr from execution -# -async_process_results() { - setopt localoptions noshwordsplit - - local worker=$1 - local callback=$2 - local caller=$3 - local -a items - local null=$'\0' data - integer -l len pos num_processed - - typeset -gA ASYNC_PROCESS_BUFFER - - # Read output from zpty and parse it if available. - while zpty -r -t $worker data 2>/dev/null; do - ASYNC_PROCESS_BUFFER[$worker]+=$data - len=${#ASYNC_PROCESS_BUFFER[$worker]} - pos=${ASYNC_PROCESS_BUFFER[$worker][(i)$null]} # Get index of NULL-character (delimiter). - - # Keep going until we find a NULL-character. - if (( ! len )) || (( pos > len )); then - continue - fi - - while (( pos <= len )); do - # Take the content from the beginning, until the NULL-character and - # perform shell parsing (z) and unquoting (Q) as an array (@). - items=("${(@Q)${(z)ASYNC_PROCESS_BUFFER[$worker][1,$pos-1]}}") - - # Remove the extracted items from the buffer. - ASYNC_PROCESS_BUFFER[$worker]=${ASYNC_PROCESS_BUFFER[$worker][$pos+1,$len]} - - if (( $#items == 5 )); then - $callback "${(@)items}" # Send all parsed items to the callback. - else - # In case of corrupt data, invoke callback with *async* as job - # name, non-zero exit status and an error message on stderr. - $callback "async" 1 "" 0 "$0:$LINENO: error: bad format, got ${#items} items (${(@q)items})" - fi - - (( num_processed++ )) - - len=${#ASYNC_PROCESS_BUFFER[$worker]} - if (( len > 1 )); then - pos=${ASYNC_PROCESS_BUFFER[$worker][(i)$null]} # Get index of NULL-character (delimiter). - fi - done - done - - (( num_processed )) && return 0 - - # Avoid printing exit value when `setopt printexitvalue` is active.` - [[ $caller = trap || $caller = watcher ]] && return 0 - - # No results were processed - return 1 -} - -# Watch worker for output -_async_zle_watcher() { - setopt localoptions noshwordsplit - typeset -gA ASYNC_PTYS ASYNC_CALLBACKS - local worker=$ASYNC_PTYS[$1] - local callback=$ASYNC_CALLBACKS[$worker] - - if [[ -n $callback ]]; then - async_process_results $worker $callback watcher - fi -} - -# -# Start a new asynchronous job on specified worker, assumes the worker is running. -# -# usage: -# async_job [] -# -async_job() { - setopt localoptions noshwordsplit - - local worker=$1; shift - - local -a cmd - cmd=("$@") - if (( $#cmd > 1 )); then - cmd=(${(q)cmd}) # Quote special characters in multi argument commands. - fi - - zpty -w $worker $cmd$'\0' -} - -# This function traps notification signals and calls all registered callbacks -_async_notify_trap() { - setopt localoptions noshwordsplit - - for k in ${(k)ASYNC_CALLBACKS}; do - async_process_results $k ${ASYNC_CALLBACKS[$k]} trap - done -} - -# -# Register a callback for completed jobs. As soon as a job is finnished, async_process_results will be called with the -# specified callback function. This requires that a worker is initialized with the -n (notify) option. -# -# usage: -# async_register_callback -# -async_register_callback() { - setopt localoptions noshwordsplit nolocaltraps - - typeset -gA ASYNC_CALLBACKS - local worker=$1; shift - - ASYNC_CALLBACKS[$worker]="$*" - - # Enable trap when the ZLE watcher is unavailable, allows - # workers to notify (via -n) when a job is done. - if [[ ! -o interactive ]] || [[ ! -o zle ]]; then - trap '_async_notify_trap' WINCH - fi -} - -# -# Unregister the callback for a specific worker. -# -# usage: -# async_unregister_callback -# -async_unregister_callback() { - typeset -gA ASYNC_CALLBACKS - - unset "ASYNC_CALLBACKS[$1]" -} - -# -# Flush all current jobs running on a worker. This will terminate any and all running processes under the worker, use -# with caution. -# -# usage: -# async_flush_jobs -# -async_flush_jobs() { - setopt localoptions noshwordsplit - - local worker=$1; shift - - # Check if the worker exists - zpty -t $worker &>/dev/null || return 1 - - # Send kill command to worker - async_job $worker "_killjobs" - - # Clear the zpty buffer. - local junk - if zpty -r -t $worker junk '*'; then - (( ASYNC_DEBUG )) && print -n "async_flush_jobs $worker: ${(V)junk}" - while zpty -r -t $worker junk '*'; do - (( ASYNC_DEBUG )) && print -n "${(V)junk}" - done - (( ASYNC_DEBUG )) && print - fi - - # Finally, clear the process buffer in case of partially parsed responses. - typeset -gA ASYNC_PROCESS_BUFFER - unset "ASYNC_PROCESS_BUFFER[$worker]" -} - -# -# Start a new async worker with optional parameters, a worker can be told to only run unique tasks and to notify a -# process when tasks are complete. -# -# usage: -# async_start_worker [-u] [-n] [-p ] -# -# opts: -# -u unique (only unique job names can run) -# -n notify through SIGWINCH signal -# -p pid to notify (defaults to current pid) -# -async_start_worker() { - setopt localoptions noshwordsplit - - local worker=$1; shift - zpty -t $worker &>/dev/null && return - - typeset -gA ASYNC_PTYS - typeset -h REPLY - typeset has_xtrace=0 - - # Make sure async worker is started without xtrace - # (the trace output interferes with the worker). - [[ -o xtrace ]] && { - has_xtrace=1 - unsetopt xtrace - } - - if (( ! ASYNC_ZPTY_RETURNS_FD )) && [[ -o interactive ]] && [[ -o zle ]]; then - # When zpty doesn't return a file descriptor (on older versions of zsh) - # we try to guess it anyway. - integer -l zptyfd - exec {zptyfd}>&1 # Open a new file descriptor (above 10). - exec {zptyfd}>&- # Close it so it's free to be used by zpty. - fi - - zpty -b $worker _async_worker -p $$ $@ || { - async_stop_worker $worker - return 1 - } - - # Re-enable it if it was enabled, for debugging. - (( has_xtrace )) && setopt xtrace - - if [[ $ZSH_VERSION < 5.0.8 ]]; then - # For ZSH versions older than 5.0.8 we delay a bit to give - # time for the worker to start before issuing commands, - # otherwise it will not be ready to receive them. - sleep 0.001 - fi - - if [[ -o interactive ]] && [[ -o zle ]]; then - if (( ! ASYNC_ZPTY_RETURNS_FD )); then - REPLY=$zptyfd # Use the guessed value for the file desciptor. - fi - - ASYNC_PTYS[$REPLY]=$worker # Map the file desciptor to the worker. - zle -F $REPLY _async_zle_watcher # Register the ZLE handler. - - # Disable trap in favor of ZLE handler when notify is enabled (-n). - async_job $worker _unset_trap - fi -} - -# -# Stop one or multiple workers that are running, all unfetched and incomplete work will be lost. -# -# usage: -# async_stop_worker [] -# -async_stop_worker() { - setopt localoptions noshwordsplit - - local ret=0 - for worker in $@; do - # Find and unregister the zle handler for the worker - for k v in ${(@kv)ASYNC_PTYS}; do - if [[ $v == $worker ]]; then - zle -F $k - unset "ASYNC_PTYS[$k]" - fi - done - async_unregister_callback $worker - zpty -d $worker 2>/dev/null || ret=$? - - # Clear any partial buffers. - typeset -gA ASYNC_PROCESS_BUFFER - unset "ASYNC_PROCESS_BUFFER[$worker]" - done - - return $ret -} - -# -# Initialize the required modules for zsh-async. To be called before using the zsh-async library. -# -# usage: -# async_init -# -async_init() { - (( ASYNC_INIT_DONE )) && return - ASYNC_INIT_DONE=1 - - zmodload zsh/zpty - zmodload zsh/datetime - - # Check if zsh/zpty returns a file descriptor or not, - # shell must also be interactive with zle enabled. - ASYNC_ZPTY_RETURNS_FD=0 - [[ -o interactive ]] && [[ -o zle ]] && { - typeset -h REPLY - zpty _async_test : - (( REPLY )) && ASYNC_ZPTY_RETURNS_FD=1 - zpty -d _async_test - } -} - -async() { - async_init -} - -async "$@" diff --git a/base/.zsh/colors.zsh b/base/.zsh/colors.zsh deleted file mode 100644 index 9c8e32b..0000000 --- a/base/.zsh/colors.zsh +++ /dev/null @@ -1,3 +0,0 @@ -export CLICOLOR=1 - -source `dirname $0`/fast-syntax-highlighting/fast-syntax-highlighting.plugin.zsh diff --git a/base/.zsh/completion.zsh b/base/.zsh/completion.zsh deleted file mode 100644 index f9e452d..0000000 --- a/base/.zsh/completion.zsh +++ /dev/null @@ -1,81 +0,0 @@ -autoload -U compinit -compinit - -setopt extendedglob -setopt NO_NOMATCH - -unsetopt menu_complete # do not autoselect the first completion entry -unsetopt flowcontrol -setopt auto_menu # show completion menu on succesive tab press -setopt complete_in_word -setopt always_to_end - -WORDCHARS='' - -zmodload -i zsh/complist - -## case-insensitive (all),partial-word and then substring completion -if [ "x$CASE_SENSITIVE" = "xtrue" ]; then - zstyle ':completion:*' matcher-list 'r:|[._-]=* r:|=*' 'l:|=* r:|=*' - unset CASE_SENSITIVE -else - zstyle ':completion:*' matcher-list 'm:{a-zA-Z}={A-Za-z}' 'r:|[._-]=* r:|=*' 'l:|=* r:|=*' -fi - -zstyle ':completion:*' list-colors '' - -# should this be in keybindings? -bindkey -M menuselect '^o' accept-and-infer-next-history - -zstyle ':completion:*:*:*:*:*' menu select -zstyle ':completion:*:*:kill:*:processes' list-colors '=(#b) #([0-9]#) ([0-9a-z-]#)*=01;34=0=01' -zstyle ':completion:*:*:*:*:processes' command "ps -u `whoami` -o pid,user,comm -w -w" - -# disable named-directories autocompletion -zstyle ':completion:*:cd:*' tag-order local-directories directory-stack path-directories -cdpath=(.) - -# use /etc/hosts and known_hosts for hostname completion -[ -r /etc/ssh/ssh_known_hosts ] && _global_ssh_hosts=(${${${${(f)"$( "$HOME/.bin/nroff" </dev/null 2>&1; then - eval "$(fasd --init zsh-hook zsh-ccomp zsh-ccomp-install zsh-wcomp zsh-wcomp-install posix-alias)" -fi diff --git a/base/.zsh/fast-syntax-highlighting/fast-highlight b/base/.zsh/fast-syntax-highlighting/fast-highlight deleted file mode 100644 index 70c8867..0000000 --- a/base/.zsh/fast-syntax-highlighting/fast-highlight +++ /dev/null @@ -1,715 +0,0 @@ -# ------------------------------------------------------------------------------------------------- -# Copyright (c) 2010-2016 zsh-syntax-highlighting contributors -# Copyright (c) 2016-2017 Sebastian Gniazdowski (modifications) -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without modification, are permitted -# provided that the following conditions are met: -# -# * Redistributions of source code must retain the above copyright notice, this list of conditions -# and the following disclaimer. -# * Redistributions in binary form must reproduce the above copyright notice, this list of -# conditions and the following disclaimer in the documentation and/or other materials provided -# with the distribution. -# * Neither the name of the zsh-syntax-highlighting contributors nor the names of its contributors -# may be used to endorse or promote products derived from this software without specific prior -# written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR -# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -# FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER -# IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT -# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# ------------------------------------------------------------------------------------------------- - -typeset -gA __fast_highlight_main__command_type_cache - -# Define default styles. You can set this after loading the plugin in -# Zshrc and use 256 via numbers, like: fg=150 -typeset -gA FAST_HIGHLIGHT_STYLES -: ${FAST_HIGHLIGHT_STYLES[default]:=none} -: ${FAST_HIGHLIGHT_STYLES[unknown-token]:=fg=red,bold} -: ${FAST_HIGHLIGHT_STYLES[reserved-word]:=fg=yellow} -: ${FAST_HIGHLIGHT_STYLES[alias]:=fg=green} -: ${FAST_HIGHLIGHT_STYLES[suffix-alias]:=fg=green} -: ${FAST_HIGHLIGHT_STYLES[builtin]:=fg=green} -: ${FAST_HIGHLIGHT_STYLES[function]:=fg=green} -: ${FAST_HIGHLIGHT_STYLES[command]:=fg=green} -: ${FAST_HIGHLIGHT_STYLES[precommand]:=fg=green} -: ${FAST_HIGHLIGHT_STYLES[commandseparator]:=none} -: ${FAST_HIGHLIGHT_STYLES[hashed-command]:=fg=green} -: ${FAST_HIGHLIGHT_STYLES[path]:=fg=magenta} -: ${FAST_HIGHLIGHT_STYLES[path_pathseparator]:=} -: ${FAST_HIGHLIGHT_STYLES[globbing]:=fg=blue,bold} -: ${FAST_HIGHLIGHT_STYLES[history-expansion]:=fg=blue,bold} -: ${FAST_HIGHLIGHT_STYLES[single-hyphen-option]:=fg=cyan} -: ${FAST_HIGHLIGHT_STYLES[double-hyphen-option]:=fg=cyan} -: ${FAST_HIGHLIGHT_STYLES[back-quoted-argument]:=none} -: ${FAST_HIGHLIGHT_STYLES[single-quoted-argument]:=fg=yellow} -: ${FAST_HIGHLIGHT_STYLES[double-quoted-argument]:=fg=yellow} -: ${FAST_HIGHLIGHT_STYLES[dollar-quoted-argument]:=fg=yellow} -: ${FAST_HIGHLIGHT_STYLES[back-or-dollar-double-quoted-argument]:=fg=cyan} -: ${FAST_HIGHLIGHT_STYLES[back-dollar-quoted-argument]:=fg=cyan} -: ${FAST_HIGHLIGHT_STYLES[assign]:=none} -: ${FAST_HIGHLIGHT_STYLES[redirection]:=none} -: ${FAST_HIGHLIGHT_STYLES[comment]:=fg=black,bold} -: ${FAST_HIGHLIGHT_STYLES[variable]:=none} - - -typeset -gA __FAST_HIGHLIGHT_TOKEN_TYPES - -__FAST_HIGHLIGHT_TOKEN_TYPES=( - - # Precommand - - 'builtin' 1 - 'command' 1 - 'exec' 1 - 'nocorrect' 1 - 'noglob' 1 - 'pkexec' 1 # immune to #121 because it's usually not passed --option flags - - # Control flow - # Tokens that, at (naively-determined) "command position", are followed by - # a de jure command position. All of these are reserved words. - - $'\x7b' 2 # block - $'\x28' 2 # subshell - '()' 2 # anonymous function - 'while' 2 - 'until' 2 - 'if' 2 - 'then' 2 - 'elif' 2 - 'else' 2 - 'do' 2 - 'time' 2 - 'coproc' 2 - '!' 2 # reserved word; unrelated to $histchars[1] - - # Command separators - - '|' 3 - '||' 3 - ';' 3 - '&' 3 - '&&' 3 - '|&' 3 - '&!' 3 - '&|' 3 - # ### 'case' syntax, but followed by a pattern, not by a command - # ';;' ';&' ';|' -) - -# A hash instead of multiple globals -typeset -gA FAST_HIGHLIGHT - -# Get the type of a command. -# -# Uses the zsh/parameter module if available to avoid forks, and a -# wrapper around 'type -w' as fallback. -# -# Takes a single argument. -# -# The result will be stored in REPLY. --fast-highlight-main-type() { - REPLY=$__fast_highlight_main__command_type_cache[(e)$1] - [[ -z "$REPLY" ]] && { - - if zmodload -e zsh/parameter; then - if (( $+aliases[(e)$1] )); then - REPLY=alias - elif (( $+functions[(e)$1] )); then - REPLY=function - elif (( $+builtins[(e)$1] )); then - REPLY=builtin - elif (( $+commands[(e)$1] )); then - REPLY=command - elif (( $+saliases[(e)${1##*.}] )); then - REPLY='suffix alias' - elif (( $reswords[(Ie)$1] )); then - REPLY=reserved - # zsh 5.2 and older have a bug whereby running 'type -w ./sudo' implicitly - # runs 'hash ./sudo=/usr/local/bin/./sudo' (assuming /usr/local/bin/sudo - # exists and is in $PATH). Avoid triggering the bug, at the expense of - # falling through to the $() below, incurring a fork. (Issue #354.) - # - # The second disjunct mimics the isrelative() C call from the zsh bug. - elif [[ $1 != */* || "${+ZSH_ARGZERO}" = "1" ]] && ! builtin type -w -- $1 >/dev/null 2>&1; then - REPLY=none - fi - fi - - [[ -z "$REPLY" ]] && REPLY="${$(LC_ALL=C builtin type -w -- $1 2>/dev/null)##*: }" - - [[ "$REPLY" = "none" ]] && { - [[ -d "$1" ]] && REPLY="dirpath" || { - for cdpath_dir in $cdpath; do - [[ -d "$cdpath_dir/$1" ]] && { REPLY="dirpath"; break; } - done - } - } - - __fast_highlight_main__command_type_cache[(e)$1]=$REPLY - - } -} - -# Below are variables that must be defined in outer -# scope so that they are reachable in *-process() --fast-highlight-fill-option-variables() { - if [[ -o ignore_braces ]] || eval '[[ -o ignore_close_braces ]] 2>/dev/null'; then - FAST_HIGHLIGHT[right_brace_is_recognised_everywhere]=0 - else - FAST_HIGHLIGHT[right_brace_is_recognised_everywhere]=1 - fi - - if [[ -o path_dirs ]]; then - FAST_HIGHLIGHT[path_dirs_was_set]=1 - else - FAST_HIGHLIGHT[path_dirs_was_set]=0 - fi - - if [[ -o multi_func_def ]]; then - FAST_HIGHLIGHT[multi_func_def]=1 - else - FAST_HIGHLIGHT[multi_func_def]=0 - fi - - if [[ -o interactive_comments ]]; then - FAST_HIGHLIGHT[ointeractive_comments]=1 - else - FAST_HIGHLIGHT[ointeractive_comments]=0 - fi -} - -# Main syntax highlighting function. --fast-highlight-process() -{ - emulate -L zsh - setopt extendedglob bareglobqual nonomatch noksharrays - - [[ $CONTEXT == "select" ]] && return 1 - [[ ${#BUFFER} -gt 10000 ]] && return 1 # Limit based on n-history length - - (( FAST_HIGHLIGHT[path_dirs_was_set] )) && setopt PATH_DIRS - (( FAST_HIGHLIGHT[ointeractive_comments] )) && local interactive_comments= # _set_ to empty - - # Variable declarations and initializations - # in_array_assignment true between 'a=(' and the matching ')' - # braces_stack: "R" for round, "Q" for square, "Y" for curly - # mybuf, cdpath_dir are used in sub-functions - local start_pos=0 end_pos start end highlight_glob=1 arg style in_array_assignment=0 MATCH expanded_path braces_stack buf="$PREBUFFER$BUFFER" mybuf cdpath_dir cur_cmd alias_target - # arg_type can be 0, 1, 2 or 3, i.e. precommand, control flow, command separator - # idx and end_idx are used in sub-functions - # for this_word and next_word look below at commented integers and at state machine description - integer arg_type=0 MBEGIN MEND in_redirection len=${#buf} already_added offset idx end_idx this_word=1 next_word=0 insane_alias pos - local -a match mbegin mend - - # integer BIT_start=1 BIT_regular=2 BIT_sudo_opt=4 BIT_sudo_arg=8 BIT_always=16 - - # State machine - # - # The states are: - # - :start: Command word - # - :sudo_opt: A leading-dash option to sudo (such as "-u" or "-i") - # - :sudo_arg: The argument to a sudo leading-dash option that takes one, - # when given as a separate word; i.e., "foo" in "-u foo" (two - # words) but not in "-ufoo" (one word). - # - :regular: "Not a command word", and command delimiters are permitted. - # Mainly used to detect premature termination of commands. - # - :always: The word 'always' in the «{ foo } always { bar }» syntax. - # - # When the kind of a word is not yet known, $this_word / $next_word may contain - # multiple states. For example, after "sudo -i", the next word may be either - # another --flag or a command name, hence the state would include both :start: - # and :sudo_opt:. - # - # The tokens are always added with both leading and trailing colons to serve as - # word delimiters (an improvised array); [[ $x == *:foo:* ]] and x=${x//:foo:/} - # will DTRT regardless of how many elements or repetitions $x has.. - # - # Handling of redirections: upon seeing a redirection token, we must stall - # the current state --- that is, the value of $this_word --- for two iterations - # (one for the redirection operator, one for the word following it representing - # the redirection target). Therefore, we set $in_redirection to 2 upon seeing a - # redirection operator, decrement it each iteration, and stall the current state - # when it is non-zero. Thus, upon reaching the next word (the one that follows - # the redirection operator and target), $this_word will still contain values - # appropriate for the word immediately following the word that preceded the - # redirection operator. - # - # The "the previous word was a redirection operator" state is not communicated - # to the next iteration via $next_word/$this_word as usual, but via - # $in_redirection. The value of $next_word from the iteration that processed - # the operator is discarded. - # - - # Processing buffer - local proc_buf="$buf" needle - for arg in ${interactive_comments-${(z)buf}} \ - ${interactive_comments+${(zZ+c+)buf}}; do - # Initialize $next_word to its default value? - (( in_redirection )) && (( --in_redirection )) - (( in_redirection == 0 )) && next_word=2 # else Stall $next_word. - - # Initialize per-"simple command" [zshmisc(1)] variables: - # - # $already_added (see next paragraph) - # $style how to highlight $arg - # $in_array_assignment boolean flag for "between '(' and ')' of array assignment" - # $highlight_glob boolean flag for "'noglob' is in effect" - # - # $already_added is set to 1 to disable adding an entry to region_highlight - # for this iteration. Currently, that is done for "" and $'' strings, - # which add the entry early so escape sequences within the string override - # the string's color. - already_added=0 - style=unknown-token - if (( this_word & 1 )); then - in_array_assignment=0 - [[ $arg == 'noglob' ]] && highlight_glob=0 - fi - - # Compute the new $start_pos and $end_pos, skipping over whitespace in $buf. - if [[ $arg == ';' ]] ; then - # We're looking for either a semicolon or a newline, whichever comes - # first. Both of these are rendered as a ";" (SEPER) by the ${(z)..} - # flag. - # - # We can't use the (Z+n+) flag because that elides the end-of-command - # token altogether, so 'echo foo\necho bar' (two commands) becomes - # indistinguishable from 'echo foo echo bar' (one command with three - # words for arguments). - needle=$'[;\n]' - offset=$(( ${proc_buf[(i)$needle]} - 1 )) - (( start_pos += offset )) - (( end_pos = start_pos + $#arg )) - - # Do not run default code for case when there is a new line - # It shouldn't be treated as ';', i.e. shouldn't be highlighted - # as unknown-token when appears after command-starting arg like "{" - if [[ "${proc_buf[offset+1]}" = $'\n' ]]; then - (( in_array_assignment )) && (( this_word = 2 )) || { (( this_word = 1 )); highlight_glob=1; } - in_redirection=0 - proc_buf="${proc_buf[offset + $#arg + 1,len]}" - start_pos=$end_pos - continue - else - # One more short path – for ';' command separator - (( in_array_assignment )) && (( this_word = 2 )) || { (( this_word = 1 )); highlight_glob=1; } - in_redirection=0 - [[ "${FAST_HIGHLIGHT_STYLES[commandseparator]}" != "none" ]] && (( start=start_pos-${#PREBUFFER}, end=end_pos-${#PREBUFFER}, start >= 0 )) && reply+=("$start $end ${FAST_HIGHLIGHT_STYLES[commandseparator]}") - proc_buf="${proc_buf[offset + $#arg + 1,len]}" - start_pos=$end_pos - continue - fi - - arg_type=3 - else - offset=0 - if [[ "$proc_buf" = (#b)(#s)(([[:space:]]|\\[[:space:]])##)* ]]; then - # The first, outer parenthesis - offset="${mend[1]}" - fi - ((start_pos+=offset)) - ((end_pos=start_pos+${#arg})) - - # No-hit will result in value 0 - arg_type=${__FAST_HIGHLIGHT_TOKEN_TYPES[$arg]} - fi - - proc_buf="${proc_buf[offset + $#arg + 1,len]}" - - # Handle the INTERACTIVE_COMMENTS option. - # - # We use the (Z+c+) flag so the entire comment is presented as one token in $arg. - if [[ -n ${interactive_comments+'set'} && $arg[1] == $histchars[3] ]]; then - if (( this_word & 3 )); then - style=comment - else - style=unknown-token # prematurely terminated - fi - # ADD - (( start=start_pos-${#PREBUFFER}, end=end_pos-${#PREBUFFER}, start >= 0 )) && reply+=("$start $end ${FAST_HIGHLIGHT_STYLES[$style]}") - start_pos=$end_pos - continue - fi - - # Analyse the current word. - if [[ $arg == (<0-9>|)(\<|\>)* ]] && [[ $arg != (\<|\>)$'\x28'* ]]; then - # A '<' or '>', possibly followed by a digit - in_redirection=2 - fi - - # Special-case the first word after 'sudo'. - if (( ! in_redirection )); then - if (( this_word & 4 )) && [[ $arg != -* ]]; then - (( this_word = this_word ^ 4 )) - fi - - # Parse the sudo command line - if (( this_word & 4 )); then - case "$arg" in - # Flag that requires an argument - '-'[Cgprtu]) - (( this_word & 1 )) && (( this_word = this_word ^ 1 )) - (( next_word = 8 )) - ;; - # This prevents misbehavior with sudo -u -otherargument - '-'*) - (( this_word & 1 )) && (( this_word = this_word ^ 1 )) - (( next_word = next_word | 1 )) - (( next_word = next_word | 4 )) - ;; - *) ;; - esac - elif (( this_word & 8 )); then - (( next_word = next_word | 4 )) - (( next_word = next_word | 1 )) - fi - fi - - expanded_path="" - - # The Great Fork: is this a command word? Is this a non-command word? - if (( this_word & 16 )) && [[ $arg == 'always' ]]; then - # try-always construct - style=reserved-word # de facto a reserved word, although not de jure - (( next_word = 1 )) - elif (( this_word & 1 )) && (( in_redirection == 0 )); then # $arg is the command word - cur_cmd="$arg" - if (( arg_type == 1 )); then - style=precommand - elif [[ "$arg" = "sudo" ]]; then - style=precommand - (( next_word & 2 )) && (( next_word = next_word ^ 2 )) - (( next_word = next_word | 4 )) - (( next_word = next_word | 1 )) - else - # Special-case: command word is '$foo', like that, without braces or anything. - # - # That's not entirely correct --- if the parameter's value happens to be a reserved - # word, the parameter expansion will be highlighted as a reserved word --- but that - # incorrectness is outweighed by the usability improvement of permitting the use of - # parameters that refer to commands, functions, and builtins. - if [[ ${arg[1]} == \$ ]] && (( ${+parameters} )) && [[ ${arg:1} = (#m)([a-zA-Z_][a-zA-Z0-9_]#|[0-9]##) ]] && (( ${+parameters[${MATCH}]} )); then - -fast-highlight-main-type ${(P)MATCH} - else - : ${expanded_path::=${(Q)~arg}} - -fast-highlight-main-type $expanded_path - fi - - case $REPLY in - reserved) # reserved word - style=reserved-word - if [[ $arg == $'\x7b' ]]; then - braces_stack='Y'"$braces_stack" - elif [[ $arg == $'\x7d' && $braces_stack[1] == "Y" ]]; then - # We're at command word, so no need to check right_brace_is_recognised_everywhere - braces_stack[1]="" - style=reserved-word - (( next_word = next_word | 16 )) - elif [[ $arg == "[[" ]]; then - braces_stack='A'"$braces_stack" - fi - ;; - 'suffix alias') style=suffix-alias;; - alias) - insane_alias=0 - case $arg in - # Issue #263: aliases with '=' on their LHS. - # - # There are three cases: - # - # - Unsupported, breaks 'alias -L' output, but invokable: - ('='*) :;; - # - Unsupported, not invokable: - (*'='*) insane_alias=1;; - # - The common case: - (*) :;; - esac - if (( insane_alias )); then - style=unknown-token - else - style=alias - zmodload -e zsh/parameter && alias_target=${aliases[$arg]} || alias_target="${"$(alias -- $arg)"#*=}" - [[ ${__FAST_HIGHLIGHT_TOKEN_TYPES[$alias_target]} = "1" && "$arg_type" != "1" ]] && __FAST_HIGHLIGHT_TOKEN_TYPES[$arg]="1" - fi - ;; - builtin) style=builtin;; - function) style=function;; - command) style=command;; - hashed) style=hashed-command;; - dirpath) style=path;; - none) # Assign? - if [[ $arg == [[:alpha:]_][[:alnum:]_]#(|\[[^\]]#\])(|[+])=* ]] || [[ $arg == [0-9]##(|[+])=* ]]; then - style=assign - # Assignment to a scalar parameter or to array - # (For array assignments, the command doesn't start until the ")" token.) - [[ $arg[-1] == '(' ]] && in_array_assignment=1 || (( next_word = next_word | 1 )) - elif [[ $arg[1] = $histchars[1] && -n "${arg[2]}" ]]; then - style=history-expansion - elif [[ $arg[1] == $histchars[2] ]]; then - style=history-expansion - elif (( arg_type == 3 )); then - # This highlights empty commands (semicolon follows nothing) as an error. - # Zsh accepts them, though. - (( this_word & 2 )) && style=commandseparator - elif [[ $arg[1,2] == '((' ]]; then - # Arithmetic evaluation. - # - # Note: prior to zsh-5.1.1-52-g4bed2cf (workers/36669), the ${(z)...} - # splitter would only output the '((' token if the matching '))' had - # been typed. Therefore, under those versions of zsh, BUFFER="(( 42" - # would be highlighted as an error until the matching "))" are typed. - # - # We highlight just the opening parentheses, as a reserved word; this - # is how [[ ... ]] is highlighted, too. - - # ADD - (( start=start_pos-${#PREBUFFER}, end=end_pos-${#PREBUFFER}, start >= 0 )) && reply+=("$start $(( start + 2 )) ${FAST_HIGHLIGHT_STYLES[reserved-word]}") - already_added=1 - # ADD - [[ $arg[-2,-1] == '))' ]] && (( start=start_pos-${#PREBUFFER}, end=end_pos-${#PREBUFFER}, start >= 0 )) && reply+=("$(( end - 2 )) $end ${FAST_HIGHLIGHT_STYLES[reserved-word]}") - elif [[ $arg == '()' ]]; then - # anonymous function - style=reserved-word - elif [[ $arg == $'\x28' ]]; then - # subshell - style=reserved-word - braces_stack='R'"$braces_stack" - elif [[ $arg == $'\x29' ]]; then - [[ $braces_stack[1] == "R" ]] && { braces_stack[1]=""; style=reserved-word; } - elif (( this_word & 14 )); then - style=default - fi - ;; - *) - # ADD - # (( start=start_pos-${#PREBUFFER}, end=end_pos-${#PREBUFFER}, start >= 0 )) && reply+=("$start $end commandtypefromthefuture-$REPLY") - already_added=1 - ;; - esac - fi - # in_redirection || BIT_regular || BIT_sudo_opt || BIT_sudo_arg - elif (( in_redirection + this_word & 14 )) - then # $arg is a non-command word - case $arg in - ']]') - style=reserved-word - [[ $braces_stack[1] == "A" ]] && braces_stack[1]="" - ;; - ']') - style=builtin - ;; - $'\x28') - # '(' inside [[ - style=reserved-word - braces_stack='R'"$braces_stack" - ;; - $'\x29') # subshell or end of array assignment - if (( in_array_assignment )); then - style=assign - in_array_assignment=0 - (( next_word = next_word | 1 )) - elif [[ $braces_stack[1] == "R" ]]; then - braces_stack[1]="" - style=reserved-word - fi;; - $'\x28\x29') # possibly a function definition - # || false # TODO: or if the previous word was a command word - (( FAST_HIGHLIGHT[multi_func_def] )) && (( next_word = next_word | 1 )) - style=reserved-word - # Remove possible annoying unknown-token style, or misleading function style - reply[-1]=() - ;; - '--'*) style=double-hyphen-option;; - '-'*) style=single-hyphen-option;; - "'"*) style=single-quoted-argument;; - '"'*) - # ADD - (( start=start_pos-${#PREBUFFER}, end=end_pos-${#PREBUFFER}, start >= 0 )) && reply+=("$start $end ${FAST_HIGHLIGHT_STYLES[double-quoted-argument]}") - -fast-highlight-string - already_added=1 - ;; - \$\'*) - # ADD - (( start=start_pos-${#PREBUFFER}, end=end_pos-${#PREBUFFER}, start >= 0 )) && reply+=("$start $end ${FAST_HIGHLIGHT_STYLES[dollar-quoted-argument]}") - -fast-highlight-dollar-string - already_added=1 - ;; - \$[^\(]*) - style=variable - ;; - '`'*) style=back-quoted-argument;; - [*?]*|*[^\\][*?]*) - (( highlight_glob )) && style=globbing || style=default;; - *) if [[ $arg = $'\x7d' && $braces_stack[1] == "Y" && "$FAST_HIGHLIGHT[right_brace_is_recognised_everywhere]" = "1" ]]; then - # right brace - # Parsing rule: # { - # - # Additionally, `tt(})' is recognized in any position if neither the - # tt(IGNORE_BRACES) option nor the tt(IGNORE_CLOSE_BRACES) option is set.""" - braces_stack[1]="" - style=reserved-word - (( next_word = next_word | 16 )) - elif [[ $arg[1] = $histchars[1] && -n "${arg[2]}" ]]; then - style=history-expansion - elif (( arg_type == 3 )); then - style=commandseparator - elif (( in_redirection == 2 )); then - style=redirection - else - if [[ -z "${FAST_HIGHLIGHT[no_check_paths]}" ]] && -fast-highlight-check-path; then - # ADD - (( start=start_pos-${#PREBUFFER}, end=end_pos-${#PREBUFFER}, start >= 0 )) && reply+=("$start $end ${FAST_HIGHLIGHT_STYLES[path]}") - already_added=1 - - [[ -n "$FAST_HIGHLIGHT_STYLES[path_pathseparator]" && "$FAST_HIGHLIGHT_STYLES[path]" != "$FAST_HIGHLIGHT_STYLES[path_pathseparator]" ]] && { - for (( pos = start_pos; pos <= end_pos; pos++ )) ; do - # ADD - [[ ${buf[pos]} == "/" ]] && (( start=pos-${#PREBUFFER}, start >= 0 )) && reply+=("$(( start - 1 )) $start ${FAST_HIGHLIGHT_STYLES[path_pathseparator]}") - done - } - else - style=default - fi - fi - ;; - esac - fi - - # ADD - (( already_added == 0 )) && [[ "${FAST_HIGHLIGHT_STYLES[$style]}" != "none" ]] && (( start=start_pos-${#PREBUFFER}, end=end_pos-${#PREBUFFER}, start >= 0 )) && reply+=("$start $end ${FAST_HIGHLIGHT_STYLES[$style]}") - - if (( arg_type == 3 )); then - if [[ $arg == ';' ]] && (( in_array_assignment )); then - # literal newline inside an array assignment - (( next_word = 2 )) - elif [[ -n "${braces_stack[(r)A]}" ]]; then - (( next_word = 2 )) - else - (( next_word = 1 )) - highlight_glob=1 - fi - elif (( arg_type == 1 || arg_type == 2 )) && (( this_word & 1 )); then - (( next_word = 1 )) - elif [[ $arg == "repeat" ]] && (( this_word & 1 )); then - # skip the repeat-count word - in_redirection=2 - # The redirection mechanism assumes $this_word describes the word - # following the redirection. Make it so. - # - # That word can be a command word with shortloops (`repeat 2 ls`) - # or a command separator (`repeat 2; ls` or `repeat 2; do ls; done`). - # - # The repeat-count word will be handled like a redirection target. - (( this_word = 3 )) - fi - start_pos=$end_pos - # This is the default/common codepath. - (( in_redirection == 0 )) && (( this_word = next_word )) #else # Stall $this_word. - done - - return 0 -} - -# Check if $arg is a path. -# If yes, return 0 and in $REPLY the style to use. -# Else, return non-zero (and the contents of $REPLY is undefined). --fast-highlight-check-path() -{ - : ${expanded_path:=${(Q)~arg}} - - [[ -z $expanded_path ]] && return 1 - [[ -e $expanded_path ]] && return 0 - - # Search the path in CDPATH, only for CD command - [[ "$cur_cmd" = "cd" ]] && for cdpath_dir in $cdpath ; do - [[ -e "$cdpath_dir/$expanded_path" ]] && return 0 - done - - # It's not a path. - return 1 -} - -# Highlight special chars inside double-quoted strings --fast-highlight-string() -{ - mybuf="$arg" - idx=start_pos - - while [[ "$mybuf" = (#b)[^\$\\]#((\$(#B)([a-zA-Z_:][a-zA-Z0-9_:]#|[0-9]##)(#b)(\[[^\]]#\])(#c0,1))|(\$[{](\([a-zA-Z0@%#]##\))(#c0,1)[a-zA-Z0-9_:#]##(\[[^\]]#\])(#c0,1)[}])|[\\][\'\"\$]|[\\](*))(*) ]]; do - [[ -n "${match[7]}" ]] && { - # Skip following char – it is quoted. Choice is - # made to not highlight such quoting - idx+=${mbegin[1]}+1 - mybuf="${match[7]:1}" - } || { - idx+=${mbegin[1]}-1 - end_idx=idx+${mend[1]}-${mbegin[1]}+1 - mybuf="${match[8]}" - - # ADD - (( start=idx-${#PREBUFFER}, end=end_idx-${#PREBUFFER}, start >= 0 )) && reply+=("$start $end ${FAST_HIGHLIGHT_STYLES[back-or-dollar-double-quoted-argument]}") - - idx=end_idx - } - done -} - -# Highlight special chars inside dollar-quoted strings --fast-highlight-dollar-string() -{ - local i j k style - local AA - integer c - # Starting dollar-quote is at 1:2, so start parsing at offset 3 in the string. - for (( i = 3 ; i < end_pos - start_pos ; i += 1 )) ; do - (( j = i + start_pos - 1 )) - (( k = j + 1 )) - case "$arg[$i]" in - "\\") style=back-dollar-quoted-argument - for (( c = i + 1 ; c <= end_pos - start_pos ; c += 1 )); do - [[ "$arg[$c]" != ([0-9xXuUa-fA-F]) ]] && break - done - AA=$arg[$i+1,$c-1] - # Matching for HEX and OCT values like \0xA6, \xA6 or \012 - if [[ "$AA" =~ "^(x|X)[0-9a-fA-F]{1,2}" - || "$AA" =~ "^[0-7]{1,3}" - || "$AA" =~ "^u[0-9a-fA-F]{1,4}" - || "$AA" =~ "^U[0-9a-fA-F]{1,8}" - ]]; then - (( k += $#MATCH )) - (( i += $#MATCH )) - else - if (( $#arg > $i+1 )) && [[ $arg[$i+1] == [xXuU] ]]; then - # \x not followed by hex digits is probably an error - style=unknown-token - fi - (( k += 1 )) # Color following char too. - (( i += 1 )) # Skip parsing the escaped char. - fi - ;; - *) continue ;; - - esac - # ADD - (( start=j-${#PREBUFFER}, end=k-${#PREBUFFER}, start >= 0 )) && reply+=("$start $end ${FAST_HIGHLIGHT_STYLES[$style]}") - done -} - -# ------------------------------------------------------------------------------------------------- -# Main highlighter initialization -# ------------------------------------------------------------------------------------------------- - --fast-highlight-init() { - __fast_highlight_main__command_type_cache=() -} - -# vim:ft=zsh:sw=2:sts=2 -# -*- mode: zsh; sh-indentation: 2; indent-tabs-mode: nil; sh-basic-offset: 2; -*- diff --git a/base/.zsh/fast-syntax-highlighting/fast-syntax-highlighting.plugin.zsh b/base/.zsh/fast-syntax-highlighting/fast-syntax-highlighting.plugin.zsh deleted file mode 100644 index 235d425..0000000 --- a/base/.zsh/fast-syntax-highlighting/fast-syntax-highlighting.plugin.zsh +++ /dev/null @@ -1,272 +0,0 @@ -# ------------------------------------------------------------------------------------------------- -# Copyright (c) 2010-2016 zsh-syntax-highlighting contributors -# Copyright (c) 2017 Sebastian Gniazdowski (modifications) -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without modification, are permitted -# provided that the following conditions are met: -# -# * Redistributions of source code must retain the above copyright notice, this list of conditions -# and the following disclaimer. -# * Redistributions in binary form must reproduce the above copyright notice, this list of -# conditions and the following disclaimer in the documentation and/or other materials provided -# with the distribution. -# * Neither the name of the zsh-syntax-highlighting contributors nor the names of its contributors -# may be used to endorse or promote products derived from this software without specific prior -# written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR -# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -# FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER -# IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT -# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# ------------------------------------------------------------------------------------------------- -# -*- mode: zsh; sh-indentation: 2; indent-tabs-mode: nil; sh-basic-offset: 2; -*- -# vim: ft=zsh sw=2 ts=2 et -# ------------------------------------------------------------------------------------------------- - - -# Set $ZERO to the expected value, regardless of functionargzero. -typeset -g ZERO=${(%):-%N} - -# Invokes each highlighter that needs updating. -# This function is supposed to be called whenever the ZLE state changes. -_zsh_highlight() -{ - # Store the previous command return code to restore it whatever happens. - local ret=$? - - # Remove all highlighting in isearch, so that only the underlining done by zsh itself remains. - # For details see FAQ entry 'Why does syntax highlighting not work while searching history?'. - if [[ $WIDGET == zle-isearch-update ]] && ! (( $+ISEARCHMATCH_ACTIVE )); then - region_highlight=() - return $ret - fi - - setopt localoptions warncreateglobal noksharrays - local REPLY # don't leak $REPLY into global scope - local -a reply - - # Do not highlight if there are more than 300 chars in the buffer. It's most - # likely a pasted command or a huge list of files in that case.. - [[ -n ${ZSH_HIGHLIGHT_MAXLENGTH:-} ]] && [[ $#BUFFER -gt $ZSH_HIGHLIGHT_MAXLENGTH ]] && return $ret - - # Do not highlight if there are pending inputs (copy/paste). - [[ $PENDING -gt 0 ]] && return $ret - - # Reset region highlight to build it from scratch - # may need to remove path_prefix highlighting when the line ends - if [[ $WIDGET == zle-line-finish ]] || _zsh_highlight_buffer_modified; then - -fast-highlight-init - -fast-highlight-process && region_highlight=( $reply ) || region_highlight=() - fi - - { - local cache_place - local -a region_highlight_copy - - # Re-apply zle_highlight settings - - # region - if (( REGION_ACTIVE == 1 )); then - _zsh_highlight_apply_zle_highlight region standout "$MARK" "$CURSOR" - elif (( REGION_ACTIVE == 2 )); then - () { - local needle=$'\n' - integer min max - if (( MARK > CURSOR )) ; then - min=$CURSOR max=$MARK - else - min=$MARK max=$CURSOR - fi - (( min = ${${BUFFER[1,$min]}[(I)$needle]} )) - (( max += ${${BUFFER:($max-1)}[(i)$needle]} - 1 )) - _zsh_highlight_apply_zle_highlight region standout "$min" "$max" - } - fi - - # yank / paste (zsh-5.1.1 and newer) - (( $+YANK_ACTIVE )) && (( YANK_ACTIVE )) && _zsh_highlight_apply_zle_highlight paste standout "$YANK_START" "$YANK_END" - - # isearch - (( $+ISEARCHMATCH_ACTIVE )) && (( ISEARCHMATCH_ACTIVE )) && _zsh_highlight_apply_zle_highlight isearch underline "$ISEARCHMATCH_START" "$ISEARCHMATCH_END" - - # suffix - (( $+SUFFIX_ACTIVE )) && (( SUFFIX_ACTIVE )) && _zsh_highlight_apply_zle_highlight suffix bold "$SUFFIX_START" "$SUFFIX_END" - - return $ret - - } always { - typeset -g _ZSH_HIGHLIGHT_PRIOR_BUFFER="$BUFFER" - typeset -gi _ZSH_HIGHLIGHT_PRIOR_CURSOR=$CURSOR - } -} - -# Apply highlighting based on entries in the zle_highlight array. -# This function takes four arguments: -# 1. The exact entry (no patterns) in the zle_highlight array: -# region, paste, isearch, or suffix -# 2. The default highlighting that should be applied if the entry is unset -# 3. and 4. Two integer values describing the beginning and end of the -# range. The order does not matter. -_zsh_highlight_apply_zle_highlight() { - local entry="$1" default="$2" - integer first="$3" second="$4" - - # read the relevant entry from zle_highlight - local region="${zle_highlight[(r)${entry}:*]}" - - if [[ -z "$region" ]]; then - # entry not specified at all, use default value - region=$default - else - # strip prefix - region="${region#${entry}:}" - - # no highlighting when set to the empty string or to 'none' - if [[ -z "$region" ]] || [[ "$region" == none ]]; then - return - fi - fi - - integer start end - if (( first < second )); then - start=$first end=$second - else - start=$second end=$first - fi - region_highlight+=("$start $end $region") -} - - -# ------------------------------------------------------------------------------------------------- -# API/utility functions for highlighters -# ------------------------------------------------------------------------------------------------- - -# Whether the command line buffer has been modified or not. -# -# Returns 0 if the buffer has changed since _zsh_highlight was last called. -_zsh_highlight_buffer_modified() -{ - [[ "${_ZSH_HIGHLIGHT_PRIOR_BUFFER:-}" != "$BUFFER" ]] -} - -# Whether the cursor has moved or not. -# -# Returns 0 if the cursor has moved since _zsh_highlight was last called. -_zsh_highlight_cursor_moved() -{ - [[ -n $CURSOR ]] && [[ -n ${_ZSH_HIGHLIGHT_PRIOR_CURSOR-} ]] && (($_ZSH_HIGHLIGHT_PRIOR_CURSOR != $CURSOR)) -} - -# ------------------------------------------------------------------------------------------------- -# Setup functions -# ------------------------------------------------------------------------------------------------- - -# Helper for _zsh_highlight_bind_widgets -# $1 is name of widget to call -_zsh_highlight_call_widget() -{ - builtin zle "$@" && _zsh_highlight -} - -# Rebind all ZLE widgets to make them invoke _zsh_highlights. -_zsh_highlight_bind_widgets() -{ - setopt localoptions noksharrays - typeset -F SECONDS - local prefix=orig-s$SECONDS-r$RANDOM # unique each time, in case we're sourced more than once - - # Load ZSH module zsh/zleparameter, needed to override user defined widgets. - zmodload zsh/zleparameter 2>/dev/null || { - print -r -- >&2 'zsh-syntax-highlighting: failed loading zsh/zleparameter.' - return 1 - } - - # Override ZLE widgets to make them invoke _zsh_highlight. - local -U widgets_to_bind - widgets_to_bind=(${${(k)widgets}:#(.*|run-help|which-command|beep|set-local-history|yank)}) - - # Always wrap special zle-line-finish widget. This is needed to decide if the - # current line ends and special highlighting logic needs to be applied. - # E.g. remove cursor imprint, don't highlight partial paths, ... - widgets_to_bind+=(zle-line-finish) - - # Always wrap special zle-isearch-update widget to be notified of updates in isearch. - # This is needed because we need to disable highlighting in that case. - widgets_to_bind+=(zle-isearch-update) - - local cur_widget - for cur_widget in $widgets_to_bind; do - case $widgets[$cur_widget] in - - # Already rebound event: do nothing. - user:_zsh_highlight_widget_*);; - - # The "eval"'s are required to make $cur_widget a closure: the value of the parameter at function - # definition time is used. - # - # We can't use ${0/_zsh_highlight_widget_} because these widgets are always invoked with - # NO_function_argzero, regardless of the option's setting here. - - # User defined widget: override and rebind old one with prefix "orig-". - user:*) zle -N $prefix-$cur_widget ${widgets[$cur_widget]#*:} - eval "_zsh_highlight_widget_${(q)prefix}-${(q)cur_widget}() { _zsh_highlight_call_widget ${(q)prefix}-${(q)cur_widget} -- \"\$@\" }" - zle -N $cur_widget _zsh_highlight_widget_$prefix-$cur_widget;; - - # Completion widget: override and rebind old one with prefix "orig-". - completion:*) zle -C $prefix-$cur_widget ${${(s.:.)widgets[$cur_widget]}[2,3]} - eval "_zsh_highlight_widget_${(q)prefix}-${(q)cur_widget}() { _zsh_highlight_call_widget ${(q)prefix}-${(q)cur_widget} -- \"\$@\" }" - zle -N $cur_widget _zsh_highlight_widget_$prefix-$cur_widget;; - - # Builtin widget: override and make it call the builtin ".widget". - builtin) eval "_zsh_highlight_widget_${(q)prefix}-${(q)cur_widget}() { _zsh_highlight_call_widget .${(q)cur_widget} -- \"\$@\" }" - zle -N $cur_widget _zsh_highlight_widget_$prefix-$cur_widget;; - - # Incomplete or nonexistent widget: Bind to z-sy-h directly. - *) - if [[ $cur_widget == zle-* ]] && [[ -z $widgets[$cur_widget] ]]; then - _zsh_highlight_widget_${cur_widget}() { :; _zsh_highlight } - zle -N $cur_widget _zsh_highlight_widget_$cur_widget - else - # Default: unhandled case. - print -r -- >&2 "zsh-syntax-highlighting: unhandled ZLE widget ${(qq)cur_widget}" - fi - esac - done -} - -# ------------------------------------------------------------------------------------------------- -# Setup -# ------------------------------------------------------------------------------------------------- - -# Try binding widgets. -_zsh_highlight_bind_widgets || { - print -r -- >&2 'zsh-syntax-highlighting: failed binding ZLE widgets, exiting.' - return 1 -} - -# Reset scratch variables when commandline is done. -_zsh_highlight_preexec_hook() -{ - typeset -g _ZSH_HIGHLIGHT_PRIOR_BUFFER= - typeset -gi _ZSH_HIGHLIGHT_PRIOR_CURSOR=0 -} - -autoload -U add-zsh-hook -add-zsh-hook preexec _zsh_highlight_preexec_hook 2>/dev/null || { - print -r -- >&2 'zsh-syntax-highlighting: failed loading add-zsh-hook.' -} - -# Load zsh/parameter module if available -zmodload zsh/parameter 2>/dev/null - -autoload -U is-at-least -source "${ZERO:h}/fast-highlight" - -[[ "${+termcap[Co]}" = 1 && "${termcap[Co]}" = "256" ]] && FAST_HIGHLIGHT_STYLES[variable]="fg=112" - --fast-highlight-fill-option-variables diff --git a/base/.zsh/functions.zsh b/base/.zsh/functions.zsh deleted file mode 100644 index d2905ad..0000000 --- a/base/.zsh/functions.zsh +++ /dev/null @@ -1,18 +0,0 @@ -function todo { - a="" - for i; do a="$a,$i"; done - a="{$(echo "$a" | cut -d',' -f2-)}" - echo "grep -R --exclude-dir=$a TODO | sed -e 's/.*TODO //;s/ \*\/$//;s/ -->//' | LC_ALL=C sort -u" | zsh -} - -function which { - (alias; declare -f) | /usr/bin/which --tty-only --read-alias --read-functions --show-tilde --show-dot $@ -} #export -f which - -function trash { - mkdir -p "$HOME/.trash" - for file in "$@"; do - mv "$file" "$HOME/.trash/$(basename $file).$(date +%Y%m%d-%H%M%S)" - done -} # Add this to your crontab: -# 43 0 * * 3 find ~/.trash -mindepth 1 -mtime +90 -delete diff --git a/base/.zsh/history.zsh b/base/.zsh/history.zsh deleted file mode 100644 index f21023d..0000000 --- a/base/.zsh/history.zsh +++ /dev/null @@ -1,15 +0,0 @@ -if [ -z $HISTFILE ]; then - HISTFILE=$HOME/.zsh_history -fi -HISTSIZE=100000 -SAVEHIST=100000 -HISTCONTROL=ignoredups - -setopt append_history -setopt extended_history -setopt hist_expire_dups_first -setopt hist_ignore_dups # ignore duplication command history list -setopt hist_ignore_space -setopt hist_verify -setopt inc_append_history - diff --git a/base/.zsh/k.zsh b/base/.zsh/k.zsh deleted file mode 100644 index e7dc9fb..0000000 --- a/base/.zsh/k.zsh +++ /dev/null @@ -1,540 +0,0 @@ -zmodload zsh/datetime -zmodload -F zsh/stat b:zstat - -k () { - # ---------------------------------------------------------------------------- - # Setup - # ---------------------------------------------------------------------------- - - # Stop stat failing when a directory contains either no files or no hidden files - # Track if we _accidentally_ create a new global variable - setopt local_options null_glob typeset_silent no_auto_pushd - - # Process options and get files/directories - typeset -a o_all o_almost_all o_human o_si o_directory o_no_directory o_no_vcs o_help - zparseopts -E -D \ - a=o_all -all=o_all \ - A=o_almost_all -almost-all=o_almost_all \ - d=o_directory -directory=o_directory \ - h=o_human -human=o_human \ - -si=o_si \ - n=o_no_directory -no-directory=o_no_directory \ - -no-vcs=o_no_vcs \ - -help=o_help - - # Print Help if bad usage, or they asked for it - if [[ $? != 0 || "$o_help" != "" ]] - then - print -u2 "Usage: k [options] DIR" - print -u2 "Options:" - print -u2 "\t-a --all list entries starting with ." - print -u2 "\t-A --almost-all list all except . and .." - print -u2 "\t-d --directory list only directories" - print -u2 "\t-n --no-directory do not list directories" - print -u2 "\t-h --human show filesizes in human-readable format" - print -u2 "\t --si with -h, use powers of 1000 not 1024" - print -u2 "\t --no-vcs do not get VCS status (much faster)" - print -u2 "\t --help show this help" - return 1 - fi - - # Check for conflicts - if [[ "$o_directory" != "" && "$o_no_directory" != "" ]]; then - print -u2 "$o_directory and $o_no_directory cannot be used together" - return 1 - fi - - # Check which numfmt available (if any), warn user if not available - typeset -i numfmt_available=0 - typeset -i gnumfmt_available=0 - if [[ "$o_human" != "" ]]; then - if [[ $+commands[numfmt] == 1 ]]; then - numfmt_available=1 - elif [[ $+commands[gnumfmt] == 1 ]]; then - gnumfmt_available=1 - else - print -u2 "'numfmt' or 'gnumfmt' command not found, human readable output will not work." - print -u2 "\tFalling back to normal file size output" - # Set o_human to off - o_human="" - fi - fi - - # Create numfmt local function - numfmt_local () { - if [[ "$o_si" != "" ]]; then - if (( $numfmt_available )); then - numfmt --to=si $1 - elif (( $gnumfmt_available )); then - gnumfmt --to=si $1 - fi - else - if (( $numfmt_available )); then - numfmt --to=iec $1 - elif (( $gnumfmt_available )); then - gnumfmt --to=iec $1 - fi - fi - } - - # Set if we're in a repo or not - typeset -i INSIDE_WORK_TREE=0 - if [[ $(command git rev-parse --is-inside-work-tree 2>/dev/null) == true ]]; then - INSIDE_WORK_TREE=1 - fi - - # Setup array of directories to print - typeset -a base_dirs - typeset base_dir - - if [[ "$@" == "" ]]; then - base_dirs=. - else - base_dirs=($@) - fi - - - # Colors - # ---------------------------------------------------------------------------- - # default colors - K_COLOR_DI="0;34" # di:directory - K_COLOR_LN="0;35" # ln:symlink - K_COLOR_SO="0;32" # so:socket - K_COLOR_PI="0;33" # pi:pipe - K_COLOR_EX="0;31" # ex:executable - K_COLOR_BD="34;46" # bd:block special - K_COLOR_CD="34;43" # cd:character special - K_COLOR_SU="30;41" # su:executable with setuid bit set - K_COLOR_SG="30;46" # sg:executable with setgid bit set - K_COLOR_TW="30;42" # tw:directory writable to others, with sticky bit - K_COLOR_OW="30;43" # ow:directory writable to others, without sticky bit - - # read colors if osx and $LSCOLORS is defined - if [[ $(uname) == 'Darwin' && -n $LSCOLORS ]]; then - # Translate OSX/BSD's LSCOLORS so we can use the same here - K_COLOR_DI=$(_k_bsd_to_ansi $LSCOLORS[1] $LSCOLORS[2]) - K_COLOR_LN=$(_k_bsd_to_ansi $LSCOLORS[3] $LSCOLORS[4]) - K_COLOR_SO=$(_k_bsd_to_ansi $LSCOLORS[5] $LSCOLORS[6]) - K_COLOR_PI=$(_k_bsd_to_ansi $LSCOLORS[7] $LSCOLORS[8]) - K_COLOR_EX=$(_k_bsd_to_ansi $LSCOLORS[9] $LSCOLORS[10]) - K_COLOR_BD=$(_k_bsd_to_ansi $LSCOLORS[11] $LSCOLORS[12]) - K_COLOR_CD=$(_k_bsd_to_ansi $LSCOLORS[13] $LSCOLORS[14]) - K_COLOR_SU=$(_k_bsd_to_ansi $LSCOLORS[15] $LSCOLORS[16]) - K_COLOR_SG=$(_k_bsd_to_ansi $LSCOLORS[17] $LSCOLORS[18]) - K_COLOR_TW=$(_k_bsd_to_ansi $LSCOLORS[19] $LSCOLORS[20]) - K_COLOR_OW=$(_k_bsd_to_ansi $LSCOLORS[21] $LSCOLORS[22]) - fi - - # read colors if linux and $LS_COLORS is defined - # if [[ $(uname) == 'Linux' && -n $LS_COLORS ]]; then - - # fi - - # ---------------------------------------------------------------------------- - # Loop over passed directories and files to display - # ---------------------------------------------------------------------------- - for base_dir in $base_dirs - do - # ---------------------------------------------------------------------------- - # Display name if multiple paths were passed - # ---------------------------------------------------------------------------- - if [[ "$#base_dirs" > 1 ]]; then - # Only add a newline if its not the first iteration - if [[ "$base_dir" != "${base_dirs[1]}" ]]; then - print - fi - print -r "${base_dir}:" - fi - # ---------------------------------------------------------------------------- - # Vars - # ---------------------------------------------------------------------------- - - typeset -a MAX_LEN A RESULTS STAT_RESULTS - typeset TOTAL_BLOCKS - - # Get now - typeset K_EPOCH="${EPOCHSECONDS:?}" - - typeset -i TOTAL_BLOCKS=0 - - MAX_LEN=(0 0 0 0 0 0) - - # Array to hold results from `stat` call - RESULTS=() - - # only set once per directory so must be out of the main loop - typeset -i IS_GIT_REPO=0 - typeset GIT_TOPLEVEL - - typeset -i LARGE_FILE_COLOR=196 - typeset -a SIZELIMITS_TO_COLOR - SIZELIMITS_TO_COLOR=( - 1024 46 # <= 1kb - 2048 82 # <= 2kb - 3072 118 # <= 3kb - 5120 154 # <= 5kb - 10240 190 # <= 10kb - 20480 226 # <= 20kb - 40960 220 # <= 40kb - 102400 214 # <= 100kb - 262144 208 # <= 0.25mb || 256kb - 524288 202 # <= 0.5mb || 512kb - ) - typeset -i ANCIENT_TIME_COLOR=236 # > more than 2 years old - typeset -a FILEAGES_TO_COLOR - FILEAGES_TO_COLOR=( - 0 196 # < in the future, #spooky - 60 255 # < less than a min old - 3600 252 # < less than an hour old - 86400 250 # < less than 1 day old - 604800 244 # < less than 1 week old - 2419200 244 # < less than 28 days (4 weeks) old - 15724800 242 # < less than 26 weeks (6 months) old - 31449600 240 # < less than 1 year old - 62899200 238 # < less than 2 years old - ) - - # ---------------------------------------------------------------------------- - # Build up list of files/directories to show - # ---------------------------------------------------------------------------- - - typeset -a show_list - show_list=() - - # Check if it even exists - if [[ ! -e $base_dir ]]; then - print -u2 "k: cannot access $base_dir: No such file or directory" - - # If its just a file, skip the directory handling - elif [[ -f $base_dir ]]; then - show_list=($base_dir) - - #Directory, add its contents - else - # Break total blocks of the front of the stat call, then push the rest to results - if [[ "$o_all" != "" && "$o_almost_all" == "" && "$o_no_directory" == "" ]]; then - show_list+=($base_dir/.) - show_list+=($base_dir/..) - fi - - if [[ "$o_all" != "" || "$o_almost_all" != "" ]]; then - if [[ "$o_directory" != "" ]]; then - show_list+=($base_dir/*(D/)) - elif [[ "$o_no_directory" != "" ]]; then - #Use (^/) instead of (.) so sockets and symlinks get displayed - show_list+=($base_dir/*(D^/)) - else - show_list+=($base_dir/*(D)) - fi - else - if [[ "$o_directory" != "" ]]; then - show_list+=($base_dir/*(/)) - elif [[ "$o_no_directory" != "" ]]; then - #Use (^/) instead of (.) so sockets and symlinks get displayed - show_list+=($base_dir/*(^/)) - else - show_list+=($base_dir/*) - fi - fi - fi - - # ---------------------------------------------------------------------------- - # Stat call to get directory listing - # ---------------------------------------------------------------------------- - typeset -i i=1 j=1 k=1 - typeset -a STATS_PARAMS_LIST - typeset fn statvar h - typeset -A sv - - STATS_PARAMS_LIST=() - for fn in $show_list - do - statvar="stats_$i" - typeset -A $statvar - zstat -H $statvar -Lsn -F "%s^%d^%b^%H:%M^%Y" -- "$fn" # use lstat, render mode/uid/gid to strings - STATS_PARAMS_LIST+=($statvar) - i+=1 - done - - - # On each result calculate padding by getting max length on each array member - for statvar in "${STATS_PARAMS_LIST[@]}" - do - sv=("${(@Pkv)statvar}") - if [[ ${#sv[mode]} -gt $MAX_LEN[1] ]]; then MAX_LEN[1]=${#sv[mode]} ; fi - if [[ ${#sv[nlink]} -gt $MAX_LEN[2] ]]; then MAX_LEN[2]=${#sv[nlink]} ; fi - if [[ ${#sv[uid]} -gt $MAX_LEN[3] ]]; then MAX_LEN[3]=${#sv[uid]} ; fi - if [[ ${#sv[gid]} -gt $MAX_LEN[4] ]]; then MAX_LEN[4]=${#sv[gid]} ; fi - - if [[ "$o_human" != "" ]]; then - h=$(numfmt_local ${sv[size]}) - if (( ${#h} > $MAX_LEN[5] )); then MAX_LEN[5]=${#h}; fi - else - if [[ ${#sv[size]} -gt $MAX_LEN[5] ]]; then MAX_LEN[5]=${#sv[size]}; fi - fi - - TOTAL_BLOCKS+=$sv[blocks] - done - - # Print total block before listing - echo "total $TOTAL_BLOCKS" - - # ---------------------------------------------------------------------------- - # Loop through each line of stat, pad where appropriate and do git dirty checking - # ---------------------------------------------------------------------------- - - typeset REPOMARKER - typeset PERMISSIONS HARDLINKCOUNT OWNER GROUP FILESIZE FILESIZE_OUT DATE NAME SYMLINK_TARGET - typeset FILETYPE PER1 PER2 PER3 PERMISSIONS_OUTPUT STATUS - typeset TIME_DIFF TIME_COLOR DATE_OUTPUT - typeset -i IS_DIRECTORY IS_SYMLINK IS_SOCKET IS_PIPE IS_EXECUTABLE IS_BLOCK_SPECIAL IS_CHARACTER_SPECIAL HAS_UID_BIT HAS_GID_BIT HAS_STICKY_BIT IS_WRITABLE_BY_OTHERS - typeset -i COLOR - - k=1 - for statvar in "${STATS_PARAMS_LIST[@]}" - do - sv=("${(@Pkv)statvar}") - - # We check if the result is a git repo later, so set a blank marker indication the result is not a git repo - REPOMARKER=" " - IS_DIRECTORY=0 - IS_SYMLINK=0 - IS_SOCKET=0 - IS_PIPE=0 - IS_EXECUTABLE=0 - IS_BLOCK_SPECIAL=0 - IS_CHARACTER_SPECIAL=0 - HAS_UID_BIT=0 - HAS_GID_BIT=0 - HAS_STICKY_BIT=0 - IS_WRITABLE_BY_OTHERS=0 - - PERMISSIONS="${sv[mode]}" - HARDLINKCOUNT="${sv[nlink]}" - OWNER="${sv[uid]}" - GROUP="${sv[gid]}" - FILESIZE="${sv[size]}" - DATE=(${(s:^:)sv[mtime]}) # Split date on ^ - NAME="${sv[name]}" - SYMLINK_TARGET="${sv[link]}" - - # Check for file types - if [[ -d "$NAME" ]]; then IS_DIRECTORY=1; fi - if [[ -L "$NAME" ]]; then IS_SYMLINK=1; fi - if [[ -S "$NAME" ]]; then IS_SOCKET=1; fi - if [[ -p "$NAME" ]]; then IS_PIPE=1; fi - if [[ -x "$NAME" ]]; then IS_EXECUTABLE=1; fi - if [[ -b "$NAME" ]]; then IS_BLOCK_SPECIAL=1; fi - if [[ -c "$NAME" ]]; then IS_CHARACTER_SPECIAL=1; fi - if [[ -u "$NAME" ]]; then HAS_UID_BIT=1; fi - if [[ -g "$NAME" ]]; then HAS_GID_BIT=1; fi - if [[ -k "$NAME" ]]; then HAS_STICKY_BIT=1; fi - if [[ $PERMISSIONS[9] == 'w' ]]; then IS_WRITABLE_BY_OTHERS=1; fi - - # IS_GIT_REPO is a 1 if $NAME is a file/directory in a git repo, OR if $NAME is a git-repo itself - # GIT_TOPLEVEL is set to the directory containing the .git folder of a git-repo - - # is this a git repo - if [[ "$o_no_vcs" != "" ]]; then - IS_GIT_REPO=0 - GIT_TOPLEVEL='' - else - if (( IS_DIRECTORY )); - then builtin cd -q $NAME 2>/dev/null || builtin cd -q - >/dev/null && IS_GIT_REPO=0 #Say no if we don't have permissions there - else builtin cd -q $NAME:a:h 2>/dev/null || builtin cd -q - >/dev/null && IS_GIT_REPO=0 - fi - if [[ $(command git rev-parse --is-inside-work-tree 2>/dev/null) == true ]]; then - IS_GIT_REPO=1 - GIT_TOPLEVEL=$(command git rev-parse --show-toplevel) - else - IS_GIT_REPO=0 - fi - builtin cd -q - >/dev/null - fi - - # Get human readable output if necessary - if [[ "$o_human" != "" ]]; then - # I hate making this call twice, but its either that, or do a bunch - # of calculations much earlier. - FILESIZE_OUT=$(numfmt_local $FILESIZE) - else - FILESIZE_OUT=$FILESIZE - fi - - # Pad so all the lines align - firstline gets padded the other way - PERMISSIONS="${(r:MAX_LEN[1]:)PERMISSIONS}" - HARDLINKCOUNT="${(l:MAX_LEN[2]:)HARDLINKCOUNT}" - OWNER="${(l:MAX_LEN[3]:)OWNER}" - GROUP="${(l:MAX_LEN[4]:)GROUP}" - FILESIZE_OUT="${(l:MAX_LEN[5]:)FILESIZE_OUT}" - - # -------------------------------------------------------------------------- - # Colour the permissions - TODO - # -------------------------------------------------------------------------- - # Colour the first character based on filetype - FILETYPE="${PERMISSIONS[1]}" - - # Permissions Owner - PER1="${PERMISSIONS[2,4]}" - - # Permissions Group - PER2="${PERMISSIONS[5,7]}" - - # Permissions User - PER3="${PERMISSIONS[8,10]}" - - PERMISSIONS_OUTPUT="$FILETYPE$PER1$PER2$PER3" - - # -------------------------------------------------------------------------- - # Colour the symlinks - # -------------------------------------------------------------------------- - - # -------------------------------------------------------------------------- - # Colour Owner and Group - # -------------------------------------------------------------------------- - OWNER=$'\e[38;5;241m'"$OWNER"$'\e[0m' - GROUP=$'\e[38;5;241m'"$GROUP"$'\e[0m' - - # -------------------------------------------------------------------------- - # Colour file weights - # -------------------------------------------------------------------------- - COLOR=LARGE_FILE_COLOR - for i j in ${SIZELIMITS_TO_COLOR[@]} - do - (( FILESIZE <= i )) || continue - COLOR=$j - break - done - - FILESIZE_OUT=$'\e[38;5;'"${COLOR}m$FILESIZE_OUT"$'\e[0m' - - # -------------------------------------------------------------------------- - # Colour the date and time based on age, then format for output - # -------------------------------------------------------------------------- - # Setup colours based on time difference - TIME_DIFF=$(( K_EPOCH - DATE[1] )) - TIME_COLOR=$ANCIENT_TIME_COLOR - for i j in ${FILEAGES_TO_COLOR[@]} - do - (( TIME_DIFF < i )) || continue - TIME_COLOR=$j - break - done - - # Format date to show year if more than 6 months since last modified - if (( TIME_DIFF < 15724800 )); then - DATE_OUTPUT="${DATE[2]} ${(r:5:: :)${DATE[3][0,5]}} ${DATE[4]}" - else - DATE_OUTPUT="${DATE[2]} ${(r:6:: :)${DATE[3][0,5]}} ${DATE[5]}" # extra space; 4 digit year instead of 5 digit HH:MM - fi; - DATE_OUTPUT[1]="${DATE_OUTPUT[1]//0/ }" # If day of month begins with zero, replace zero with space - - # Apply colour to formated date - DATE_OUTPUT=$'\e[38;5;'"${TIME_COLOR}m${DATE_OUTPUT}"$'\e[0m' - - # -------------------------------------------------------------------------- - # Colour the repomarker - # -------------------------------------------------------------------------- - if [[ "$o_no_vcs" != "" ]]; then - REPOMARKER="" - elif (( IS_GIT_REPO != 0)); then - # If we're not in a repo, still check each directory if it's a repo, and - # then mark appropriately - if (( INSIDE_WORK_TREE == 0 )); then - if (( IS_DIRECTORY )); then - if command git --git-dir="$GIT_TOPLEVEL/.git" --work-tree="${NAME}" diff --stat --quiet --ignore-submodules HEAD &>/dev/null # if dirty - then REPOMARKER=$'\e[38;5;46m|\e[0m' # Show a green vertical bar for clean - else REPOMARKER=$'\e[0;31m+\e[0m' # Show a red vertical bar if dirty - fi - fi - else - if (( IS_DIRECTORY )); then - # If the directory isn't ignored or clean, we'll just say it's dirty - if command git check-ignore --quiet ${NAME} 2>/dev/null; then STATUS='!!' - elif command git diff --stat --quiet --ignore-submodules ${NAME} 2> /dev/null; then STATUS=''; - else STATUS=' M' - fi - else - # File - STATUS=$(command git status --porcelain --ignored --untracked-files=normal $GIT_TOPLEVEL/${${${NAME:a}##$GIT_TOPLEVEL}#*/}) - fi - STATUS=${STATUS[1,2]} - if [[ $STATUS == ' M' ]]; then REPOMARKER=$'\e[0;31m+\e[0m'; # Tracked & Dirty - elif [[ $STATUS == 'M ' ]]; then REPOMARKER=$'\e[38;5;082m+\e[0m'; # Tracked & Dirty & Added - elif [[ $STATUS == '??' ]]; then REPOMARKER=$'\e[38;5;214m+\e[0m'; # Untracked - elif [[ $STATUS == '!!' ]]; then REPOMARKER=$'\e[38;5;238m|\e[0m'; # Ignored - elif [[ $STATUS == 'A ' ]]; then REPOMARKER=$'\e[38;5;082m+\e[0m'; # Added - else REPOMARKER=$'\e[38;5;082m|\e[0m'; # Good - fi - fi - fi - - # -------------------------------------------------------------------------- - # Colour the filename - # -------------------------------------------------------------------------- - # Unfortunately, the choices for quoting which escape ANSI color sequences are q & qqqq; none of q- qq qqq work. - # But we don't want to quote '.'; so instead we escape the escape manually and use q- - NAME="${${NAME##*/}//$'\e'/\\e}" # also propagate changes to SYMLINK_TARGET below - - if [[ $IS_DIRECTORY == 1 ]]; then - if [[ $IS_WRITABLE_BY_OTHERS == 1 ]]; then - if [[ $HAS_STICKY_BIT == 1 ]]; then - NAME=$'\e['"$K_COLOR_TW"'m'"$NAME"$'\e[0m'; - fi - NAME=$'\e['"$K_COLOR_OW"'m'"$NAME"$'\e[0m'; - fi - NAME=$'\e['"$K_COLOR_DI"'m'"$NAME"$'\e[0m'; - elif [[ $IS_SYMLINK == 1 ]]; then NAME=$'\e['"$K_COLOR_LN"'m'"$NAME"$'\e[0m'; - elif [[ $IS_SOCKET == 1 ]]; then NAME=$'\e['"$K_COLOR_SO"'m'"$NAME"$'\e[0m'; - elif [[ $IS_PIPE == 1 ]]; then NAME=$'\e['"$K_COLOR_PI"'m'"$NAME"$'\e[0m'; - elif [[ $HAS_UID_BIT == 1 ]]; then NAME=$'\e['"$K_COLOR_SU"'m'"$NAME"$'\e[0m'; - elif [[ $HAS_GID_BIT == 1 ]]; then NAME=$'\e['"$K_COLOR_SG"'m'"$NAME"$'\e[0m'; - elif [[ $IS_EXECUTABLE == 1 ]]; then NAME=$'\e['"$K_COLOR_EX"'m'"$NAME"$'\e[0m'; - elif [[ $IS_BLOCK_SPECIAL == 1 ]]; then NAME=$'\e['"$K_COLOR_BD"'m'"$NAME"$'\e[0m'; - elif [[ $IS_CHARACTER_SPECIAL == 1 ]]; then NAME=$'\e['"$K_COLOR_CD"'m'"$NAME"$'\e[0m'; - fi - - # -------------------------------------------------------------------------- - # Format symlink target - # -------------------------------------------------------------------------- - if [[ $SYMLINK_TARGET != "" ]]; then SYMLINK_TARGET="-> ${SYMLINK_TARGET//$'\e'/\\e}"; fi - - # -------------------------------------------------------------------------- - # Display final result - # -------------------------------------------------------------------------- - print -r -- "$PERMISSIONS_OUTPUT $HARDLINKCOUNT $OWNER $GROUP $FILESIZE_OUT $DATE_OUTPUT $REPOMARKER $NAME $SYMLINK_TARGET" - - k=$((k+1)) # Bump loop index - done - done -} - -_k_bsd_to_ansi() { - local foreground=$1 background=$2 foreground_ansi background_ansi - case $foreground in - a) foreground_ansi=30;; - b) foreground_ansi=31;; - c) foreground_ansi=32;; - d) foreground_ansi=33;; - e) foreground_ansi=34;; - f) foreground_ansi=35;; - g) foreground_ansi=36;; - h) foreground_ansi=37;; - x) foreground_ansi=0;; - esac - case $background in - a) background_ansi=40;; - b) background_ansi=41;; - c) background_ansi=42;; - d) background_ansi=43;; - e) background_ansi=44;; - f) background_ansi=45;; - g) background_ansi=46;; - h) background_ansi=47;; - x) background_ansi=0;; - esac - printf "%s;%s" $background_ansi $foreground_ansi -} - -# http://upload.wikimedia.org/wikipedia/en/1/15/Xterm_256color_chart.svg -# vim: set ts=2 sw=2 ft=zsh et : diff --git a/base/.zsh/prompt.zsh b/base/.zsh/prompt.zsh deleted file mode 100644 index 2e4dca9..0000000 --- a/base/.zsh/prompt.zsh +++ /dev/null @@ -1,6 +0,0 @@ -if [[ `tty | sed -ne "\_^/dev/tty[0-9]*_p"` ]]; then - PROMPT='%F{0}%B[ %F{6}%b%M %B%1~ %F{0}]%(!.#.$)%f%b ' -else - autoload -U promptinit && promptinit - prompt pure -fi diff --git a/base/.zsh/prompt_pure_setup b/base/.zsh/prompt_pure_setup deleted file mode 100644 index d9b7f2d..0000000 --- a/base/.zsh/prompt_pure_setup +++ /dev/null @@ -1,385 +0,0 @@ -# Quickref -# git: -# %b => current branch -# %a => current action (rebase/merge) -# prompt: -# %F => color dict -# %f => reset color -# %~ => current path -# %* => time -# %n => username -# %m => shortname host -# %(?..) => prompt conditional - %(condition.true.false) -# terminal codes: -# \e7 => save cursor position -# \e[2A => move cursor 2 lines up -# \e[1G => go to position 1 in terminal -# \e8 => restore cursor position -# \e[K => clears everything after the cursor on the current line -# \e[2K => clear everything on the current line - -PURER_PROMPT_COMMAND_COUNT=0 -STATUS_COLOR=6 - -# turns seconds into human readable time -# 165392 => 1d 21h 56m 32s -# https://github.com/sindresorhus/pretty-time-zsh -prompt_pure_human_time_to_var() { - local human=" [" total_seconds=$1 var=$2 - local days=$(( total_seconds / 60 / 60 / 24 )) - local hours=$(( total_seconds / 60 / 60 % 24 )) - local minutes=$(( total_seconds / 60 % 60 )) - local seconds=$(( total_seconds % 60 )) - (( days > 0 )) && human+="${days}d " - (( hours > 0 )) && human+="${hours}h " - (( minutes > 0 )) && human+="${minutes}m " - human+="${seconds}s]" - - # store human readable time in variable as specified by caller - typeset -g "${var}"="${human}" -} - -# stores (into prompt_pure_cmd_exec_time) the exec time of the last command if set threshold was exceeded -prompt_pure_check_cmd_exec_time() { - integer elapsed - (( elapsed = EPOCHSECONDS - ${prompt_pure_cmd_timestamp:-$EPOCHSECONDS} )) - prompt_pure_cmd_exec_time= - (( elapsed > ${PURE_CMD_MAX_EXEC_TIME:=15} )) && { - prompt_pure_human_time_to_var $elapsed "prompt_pure_cmd_exec_time" - } -} - -prompt_pure_clear_screen() { - # enable output to terminal - zle -I - # clear screen and move cursor to (0, 0) - print -n '\e[2J\e[0;0H' - # reset command count to zero so we don't start with a blank line - PURER_PROMPT_COMMAND_COUNT=0 - # print preprompt - prompt_pure_preprompt_render precmd -} - -# set STATUS_COLOR: cyan for "insert", green for "normal" mode. -prompt_purer_vim_mode() { - STATUS_COLOR="${${KEYMAP/vicmd/16}/(main|viins)/6}" - prompt_pure_preprompt_render -} - -prompt_pure_set_title() { - # emacs terminal does not support settings the title - (( ${+EMACS} )) && return - - # tell the terminal we are setting the title - print -n '\e]0;' - # show hostname if connected through ssh - [[ -n $SSH_CONNECTION ]] && print -Pn '(%m) ' - case $1 in - expand-prompt) - print -Pn $2;; - ignore-escape) - print -rn $2;; - esac - # end set title - print -n '\a' -} - -prompt_pure_preexec() { - # attempt to detect and prevent prompt_pure_async_git_fetch from interfering with user initiated git or hub fetch - [[ $2 =~ (git|hub)\ .*(pull|fetch) ]] && async_flush_jobs 'prompt_pure' - - prompt_pure_cmd_timestamp=$EPOCHSECONDS - - # shows the current dir and executed command in the title while a process is active - prompt_pure_set_title 'ignore-escape' "$PWD:t: $2" -} - -# string length ignoring ansi escapes -prompt_pure_string_length_to_var() { - local str=$1 var=$2 length - # perform expansion on str and check length - length=$(( ${#${(S%%)str//(\%([KF1]|)\{*\}|\%[Bbkf])}} )) - - # store string length in variable as specified by caller - typeset -g "${var}"="${length}" -} - -prompt_pure_preprompt_render() { - # store the current prompt_subst setting so that it can be restored later - local prompt_subst_status=$options[prompt_subst] - - # make sure prompt_subst is unset to prevent parameter expansion in preprompt - setopt local_options no_prompt_subst - - # check that no command is currently running, the preprompt will otherwise be rendered in the wrong place - [[ -n ${prompt_pure_cmd_timestamp+x} && "$1" != "precmd" ]] && return - - # set color for git branch/dirty status, change color if dirty checking has been delayed - local git_color=20 - [[ -n ${prompt_pure_git_last_dirty_check_timestamp+x} ]] && git_color=1 - - # construct preprompt - local preprompt="" - - # add a newline between commands - FIRST_COMMAND_THRESHOLD=1 - if [[ "$PURER_PROMPT_COMMAND_COUNT" -gt "$FIRST_COMMAND_THRESHOLD" ]]; then - preprompt+=$'\n' - fi - - # host ID - if [[ "$PROMPT_HOST_COLOR" ]]; then - preprompt+="%b%F{black}%K{$PROMPT_HOST_COLOR} " - [[ "$PROMPT_SHORT_HOSTNAME" ]] && preprompt+="$PROMPT_SHORT_HOSTNAME " - preprompt+="%F{$PROMPT_HOST_COLOR}%K{18}%f" - fi - preprompt+="%K{18} " - # directory, colored by vim status - preprompt+="%B%F{$STATUS_COLOR}%c%f%b" - # git info - preprompt+="%F{$git_color}${vcs_info_msg_0_}${prompt_pure_git_dirty}%f" - # git pull/push arrows - preprompt+="%F{cyan}${prompt_pure_git_arrows}%f" - # username and machine if applicable - #preprompt+=$prompt_pure_username - # execution time - preprompt+="%F{20}${prompt_pure_cmd_exec_time}%f" - # end with symbol, colored by previous command exit code - # local symbol_color="%(?.${PURE_PROMPT_SYMBOL_COLOR:-magenta}.red)" - # preprompt+=" %F{$symbol_color}${PURE_PROMPT_SYMBOL:-❯}%f" - preprompt+=" %F{18}%(?.%k.%K{1}%F{1}%k)%f" - #  - - preprompt+=" " - - # make sure prompt_pure_last_preprompt is a global array - typeset -g -a prompt_pure_last_preprompt - - PROMPT="$preprompt" - - # if executing through precmd, do not perform fancy terminal editing - if [[ "$1" != "precmd" ]]; then - # only redraw if the expanded preprompt has changed - # [[ "${prompt_pure_last_preprompt[2]}" != "${(S%%)preprompt}" ]] || return - - # redraw prompt (also resets cursor position) - zle && zle .reset-prompt - - setopt no_prompt_subst - fi - - # store both unexpanded and expanded preprompt for comparison - prompt_pure_last_preprompt=("$preprompt" "${(S%%)preprompt}") -} - -prompt_pure_precmd() { - # check exec time and store it in a variable - prompt_pure_check_cmd_exec_time - - # by making sure that prompt_pure_cmd_timestamp is defined here the async functions are prevented from interfering - # with the initial preprompt rendering - prompt_pure_cmd_timestamp= - - # shows the full path in the title - prompt_pure_set_title 'expand-prompt' '%~' - - # get vcs info - vcs_info - - # preform async git dirty check and fetch - prompt_pure_async_tasks - - # Increment command counter - PURER_PROMPT_COMMAND_COUNT=$((PURER_PROMPT_COMMAND_COUNT+1)) - - # print the preprompt - prompt_pure_preprompt_render "precmd" - - # remove the prompt_pure_cmd_timestamp, indicating that precmd has completed - unset prompt_pure_cmd_timestamp -} - -# fastest possible way to check if repo is dirty -prompt_pure_async_git_dirty() { - setopt localoptions noshwordsplit - local untracked_dirty=$1 dir=$2 - - # use cd -q to avoid side effects of changing directory, e.g. chpwd hooks - builtin cd -q $dir - - if [[ $untracked_dirty = 0 ]]; then - command git diff --no-ext-diff --quiet --exit-code - else - test -z "$(command git status --porcelain --ignore-submodules -unormal)" - fi - - return $? -} - -prompt_pure_async_git_fetch() { - setopt localoptions noshwordsplit - # use cd -q to avoid side effects of changing directory, e.g. chpwd hooks - builtin cd -q $1 - - # set GIT_TERMINAL_PROMPT=0 to disable auth prompting for git fetch (git 2.3+) - export GIT_TERMINAL_PROMPT=0 - # set ssh BachMode to disable all interactive ssh password prompting - export GIT_SSH_COMMAND=${GIT_SSH_COMMAND:-"ssh -o BatchMode=yes"} - - command git -c gc.auto=0 fetch &>/dev/null || return 1 - - # check arrow status after a successful git fetch - prompt_pure_async_git_arrows $1 -} - -prompt_pure_async_git_arrows() { - setopt localoptions noshwordsplit - builtin cd -q $1 - command git rev-list --left-right --count HEAD...@'{u}' -} - -prompt_pure_async_tasks() { - setopt localoptions noshwordsplit - - # initialize async worker - ((!${prompt_pure_async_init:-0})) && { - async_start_worker "prompt_pure" -u -n - async_register_callback "prompt_pure" prompt_pure_async_callback - prompt_pure_async_init=1 - } - - # store working_tree without the "x" prefix - local working_tree="${vcs_info_msg_1_#x}" - - # check if the working tree changed (prompt_pure_current_working_tree is prefixed by "x") - if [[ ${prompt_pure_current_working_tree#x} != $working_tree ]]; then - # stop any running async jobs - async_flush_jobs "prompt_pure" - - # reset git preprompt variables, switching working tree - unset prompt_pure_git_dirty - unset prompt_pure_git_last_dirty_check_timestamp - prompt_pure_git_arrows= - - # set the new working tree and prefix with "x" to prevent the creation of a named path by AUTO_NAME_DIRS - prompt_pure_current_working_tree="x${working_tree}" - fi - - # only perform tasks inside git working tree - [[ -n $working_tree ]] || return - - async_job "prompt_pure" prompt_pure_async_git_arrows $working_tree - - # do not preform git fetch if it is disabled or working_tree == HOME - if (( ${PURE_GIT_PULL:-1} )) && [[ $working_tree != $HOME ]]; then - # tell worker to do a git fetch - async_job "prompt_pure" prompt_pure_async_git_fetch $working_tree - fi - - # if dirty checking is sufficiently fast, tell worker to check it again, or wait for timeout - integer time_since_last_dirty_check=$(( EPOCHSECONDS - ${prompt_pure_git_last_dirty_check_timestamp:-0} )) - if (( time_since_last_dirty_check > ${PURE_GIT_DELAY_DIRTY_CHECK:-1800} )); then - unset prompt_pure_git_last_dirty_check_timestamp - # check check if there is anything to pull - async_job "prompt_pure" prompt_pure_async_git_dirty ${PURE_GIT_UNTRACKED_DIRTY:-1} $working_tree - fi -} - -prompt_pure_check_git_arrows() { - setopt localoptions noshwordsplit - local arrows left=${1:-0} right=${2:-0} - - (( right > 0 )) && arrows+=${PURE_GIT_DOWN_ARROW:-⇣} - (( left > 0 )) && arrows+=${PURE_GIT_UP_ARROW:-⇡} - - [[ -n $arrows ]] || return - typeset -g REPLY=" $arrows" -} - -prompt_pure_async_callback() { - setopt localoptions noshwordsplit - local job=$1 code=$2 output=$3 exec_time=$4 - - case $job in - prompt_pure_async_git_dirty) - local prev_dirty=$prompt_pure_git_dirty - if (( code == 0 )); then - prompt_pure_git_dirty= - else - prompt_pure_git_dirty="*" - fi - - [[ $prev_dirty != $prompt_pure_git_dirty ]] && prompt_pure_preprompt_render - - # When prompt_pure_git_last_dirty_check_timestamp is set, the git info is displayed in a different color. - # To distinguish between a "fresh" and a "cached" result, the preprompt is rendered before setting this - # variable. Thus, only upon next rendering of the preprompt will the result appear in a different color. - (( $exec_time > 2 )) && prompt_pure_git_last_dirty_check_timestamp=$EPOCHSECONDS - ;; - prompt_pure_async_git_fetch|prompt_pure_async_git_arrows) - # prompt_pure_async_git_fetch executes prompt_pure_async_git_arrows - # after a successful fetch. - if (( code == 0 )); then - local REPLY - prompt_pure_check_git_arrows ${(ps:\t:)output} - if [[ $prompt_pure_git_arrows != $REPLY ]]; then - prompt_pure_git_arrows=$REPLY - prompt_pure_preprompt_render - fi - fi - ;; - esac -} - -prompt_pure_setup() { - # prevent percentage showing up - # if output doesn't end with a newline - export PROMPT_EOL_MARK='' - - # prompt_opts=(subst percent) - - # borrowed from promptinit, sets the prompt options in case pure was not - # initialized via promptinit. - # setopt noprompt{bang,cr,percent,subst} "prompt${^prompt_opts[@]}" - - zmodload zsh/datetime - zmodload zsh/zle - zmodload zsh/parameter - - autoload -Uz add-zsh-hook - autoload -Uz vcs_info - autoload -Uz async && async - - add-zsh-hook precmd prompt_pure_precmd - add-zsh-hook preexec prompt_pure_preexec - - zstyle ':vcs_info:*' enable git - zstyle ':vcs_info:*' use-simple true - # only export two msg variables from vcs_info - zstyle ':vcs_info:*' max-exports 2 - # vcs_info_msg_0_ = ' %b' (for branch) - # vcs_info_msg_1_ = 'x%R' git top level (%R), x-prefix prevents creation of a named path (AUTO_NAME_DIRS) - zstyle ':vcs_info:git*' formats ' %b' 'x%R' - zstyle ':vcs_info:git*' actionformats ' %b|%a' 'x%R' - - # if the user has not registered a custom zle widget for clear-screen, - # override the builtin one so that the preprompt is displayed correctly when - # ^L is issued. - if [[ $widgets[clear-screen] == 'builtin' ]]; then - zle -N clear-screen prompt_pure_clear_screen - fi - - # register custom function for vim-mode - zle -N zle-keymap-select prompt_purer_vim_mode - - # show username@host if logged in through SSH - [[ "$SSH_CONNECTION" != '' ]] && prompt_pure_username=' %F{242}%n@%m%f' - - # show username@host if root, with username in white - [[ $UID -eq 0 ]] && prompt_pure_username=' %F{white}%n%f%F{242}@%m%f' - - # create prompt - prompt_pure_preprompt_render 'precmd' -} - -prompt_pure_setup "$@" diff --git a/base/.zsh/stack.zsh b/base/.zsh/stack.zsh deleted file mode 100644 index 444b88d..0000000 --- a/base/.zsh/stack.zsh +++ /dev/null @@ -1,3 +0,0 @@ -DIRSTACKSIZE=8 -setopt autocd autopushd pushdminus pushdsilent pushdtohome -alias dh='dirs -v' diff --git a/base/.zsh/tipz.zsh b/base/.zsh/tipz.zsh deleted file mode 100644 index bb1e224..0000000 --- a/base/.zsh/tipz.zsh +++ /dev/null @@ -1,84 +0,0 @@ -### -# Search the defined aliases for a match -### -function _tipz_find_match() { - local bits alias command result="" - local -a aliases args; args="$@" - - # Load the current aliases into an array - local oldIFS=$IFS - IFS=$'\n' aliases=($(alias)) - IFS=$oldIFS - - # Loop through each of the aliases - for line in "${aliases[@]}"; do - # Split the line on '=' to separate the command - # and its alias - bits=("${(s/=/)line}") - alias=$bits[1] - command=$bits[2] - - # Create a regex that finds an exact match for - # the current argument string - args="${(@)args[@]}" - local pattern=$'^[\'\"]?'${args//([\{\}\(\)\[\]\*\?\:\\\.\|])/\\\$1}$'[\'\"]?$' - - # Check if the command matches the regex - if [[ "$command" =~ $pattern ]]; then - # Ensure that the longest matching command is stored - if [[ ${#command} > ${#result} ]]; then - result=$alias - fi - fi - done - - # If a result has been found, output it - if [[ -n $result ]]; then - echo $result - return 0 - fi - - return 1 -} - -### -# Search for alias tips for the currently executing command -### -function _tipz_process { - local -a cmd; cmd=($@) - integer i=$(( ${#cmd} + 1 )) - - # Loop for the length of the argument list, knocking - # an argument from the end of the list each time, and - # then using the remaining arguments to search for aliases - while [[ $i > 0 ]]; do - # Check the current string for a match - result=$(_tipz_find_match "${(@)cmd:0:$i}") - - # If the search exited successfully, - # output the tip to the user - if [[ $? -eq 0 ]]; then - print -P "%B%F{8}Alias tip: %b$result ${(@)cmd:$i}%f" - return 0 - fi - - # Decrement the counter - i=$(( i - 1 )) - done - - return 1 -} - -### -# A small function to filter out strange arguments -# sent from the add-zsh-hook preexec hook -### -function _tipz_prexec() { - _tipz_process $(echo $1) -} - -### -# Register the preexec hook -### -autoload -Uz add-zsh-hook -add-zsh-hook preexec _tipz_prexec diff --git a/base/.zshrc b/base/.zshrc deleted file mode 100644 index b2ddd15..0000000 --- a/base/.zshrc +++ /dev/null @@ -1,17 +0,0 @@ -path=( $HOME/.bin $path ) -fpath=( $HOME/.zsh $fpath ) - -export EDITOR=vim -export NCURSES_NO_UTF8_ACS=1 - -if [ -d $HOME/.zsh ]; then - for file in $HOME/.zsh/*.zsh; do - source $file - done -fi - -if [ -f $HOME/.zshrc.local ]; then - source $HOME/.zshrc.local -fi - -#~/.motd diff --git a/base/capsesc b/base/capsesc new file mode 100644 index 0000000..53fe642 --- /dev/null +++ b/base/capsesc @@ -0,0 +1,4 @@ +remove Lock = Caps_Lock +keysym Escape = Caps_Lock +keysym Caps_Lock = Escape +add Lock = Caps_Lock diff --git a/base/dot b/base/dot new file mode 100755 index 0000000..c491cda --- /dev/null +++ b/base/dot @@ -0,0 +1,5 @@ +#!/bin/sh + +cd $HOME/.dotfiles +git pull +./install `cat .dot.args` diff --git a/base/vim/colors/base16-default-dark.vim b/base/vim/colors/base16-default-dark.vim new file mode 100644 index 0000000..ea529ec --- /dev/null +++ b/base/vim/colors/base16-default-dark.vim @@ -0,0 +1,330 @@ +" vi:syntax=vim + +" base16-vim (https://github.com/chriskempson/base16-vim) +" by Chris Kempson (http://chriskempson.com) +" Default Dark scheme by Chris Kempson (http://chriskempson.com) + +" This enables the coresponding base16-shell script to run so that +" :colorscheme works in terminals supported by base16-shell scripts +" User must set this variable in .vimrc +" let g:base16_shell_path=base16-builder/output/shell/ +if !has('gui_running') + if exists("g:base16_shell_path") + execute "silent !/bin/sh ".g:base16_shell_path."/base16-default-dark.sh" + endif +endif + +" GUI color definitions +let s:gui00 = "181818" +let s:gui01 = "282828" +let s:gui02 = "383838" +let s:gui03 = "585858" +let s:gui04 = "b8b8b8" +let s:gui05 = "d8d8d8" +let s:gui06 = "e8e8e8" +let s:gui07 = "f8f8f8" +let s:gui08 = "ab4642" +let s:gui09 = "dc9656" +let s:gui0A = "f7ca88" +let s:gui0B = "a1b56c" +let s:gui0C = "86c1b9" +let s:gui0D = "7cafc2" +let s:gui0E = "ba8baf" +let s:gui0F = "a16946" + +" Terminal color definitions +let s:cterm00 = "00" +let s:cterm03 = "08" +let s:cterm05 = "07" +let s:cterm07 = "15" +let s:cterm08 = "01" +let s:cterm0A = "03" +let s:cterm0B = "02" +let s:cterm0C = "06" +let s:cterm0D = "04" +let s:cterm0E = "05" +if exists('base16colorspace') && base16colorspace == "256" + let s:cterm01 = "18" + let s:cterm02 = "19" + let s:cterm04 = "20" + let s:cterm06 = "21" + let s:cterm09 = "16" + let s:cterm0F = "17" +else + let s:cterm01 = "10" + let s:cterm02 = "11" + let s:cterm04 = "12" + let s:cterm06 = "13" + let s:cterm09 = "09" + let s:cterm0F = "14" +endif + +" Neovim terminal colours +if has("nvim") + let g:terminal_color_0 = "#181818" + let g:terminal_color_1 = "#ab4642" + let g:terminal_color_2 = "#a1b56c" + let g:terminal_color_3 = "#f7ca88" + let g:terminal_color_4 = "#7cafc2" + let g:terminal_color_5 = "#ba8baf" + let g:terminal_color_6 = "#86c1b9" + let g:terminal_color_7 = "#d8d8d8" + let g:terminal_color_8 = "#585858" + let g:terminal_color_9 = "#dc9656" + let g:terminal_color_10 = "#282828" + let g:terminal_color_11 = "#383838" + let g:terminal_color_12 = "#b8b8b8" + let g:terminal_color_13 = "#e8e8e8" + let g:terminal_color_14 = "#a16946" + let g:terminal_color_15 = "#f8f8f8" + let g:terminal_color_background = g:terminal_color_0 + let g:terminal_color_foreground = g:terminal_color_7 + if &background == "light" + let g:terminal_color_background = g:terminal_color_7 + let g:terminal_color_foreground = g:terminal_color_2 + endif +endif + +" Theme setup +hi clear +syntax reset +let g:colors_name = "base16-default-dark" + +" Highlighting function +fun hi(group, guifg, guibg, ctermfg, ctermbg, attr, guisp) + if a:guifg != "" + exec "hi " . a:group . " guifg=#" . a:guifg + endif + if a:guibg != "" + exec "hi " . a:group . " guibg=#" . a:guibg + endif + if a:ctermfg != "" + exec "hi " . a:group . " ctermfg=" . a:ctermfg + endif + if a:ctermbg != "" + exec "hi " . a:group . " ctermbg=" . a:ctermbg + endif + if a:attr != "" + exec "hi " . a:group . " gui=" . a:attr . " cterm=" . a:attr + endif + if a:guisp != "" + exec "hi " . a:group . " guisp=#" . a:guisp + endif +endfun + +" Vim editor colors +call hi("Normal", s:gui05, s:gui00, s:cterm05, s:cterm00, "", "") +call hi("Bold", "", "", "", "", "bold", "") +call hi("Debug", s:gui08, "", s:cterm08, "", "", "") +call hi("Directory", s:gui0D, "", s:cterm0D, "", "", "") +call hi("Error", s:gui00, s:gui08, s:cterm00, s:cterm08, "", "") +call hi("ErrorMsg", s:gui08, s:gui00, s:cterm08, s:cterm00, "", "") +call hi("Exception", s:gui08, "", s:cterm08, "", "", "") +call hi("FoldColumn", s:gui0C, s:gui01, s:cterm0C, s:cterm01, "", "") +call hi("Folded", s:gui03, s:gui01, s:cterm03, s:cterm01, "", "") +call hi("IncSearch", s:gui01, s:gui09, s:cterm01, s:cterm09, "none", "") +call hi("Italic", "", "", "", "", "none", "") +call hi("Macro", s:gui08, "", s:cterm08, "", "", "") +call hi("MatchParen", "", s:gui03, "", s:cterm03, "", "") +call hi("ModeMsg", s:gui0B, "", s:cterm0B, "", "", "") +call hi("MoreMsg", s:gui0B, "", s:cterm0B, "", "", "") +call hi("Question", s:gui0D, "", s:cterm0D, "", "", "") +call hi("Search", s:gui03, s:gui0A, s:cterm03, s:cterm0A, "", "") +call hi("SpecialKey", s:gui03, "", s:cterm03, "", "", "") +call hi("TooLong", s:gui08, "", s:cterm08, "", "", "") +call hi("Underlined", s:gui08, "", s:cterm08, "", "", "") +call hi("Visual", "", s:gui02, "", s:cterm02, "", "") +call hi("VisualNOS", s:gui08, "", s:cterm08, "", "", "") +call hi("WarningMsg", s:gui08, "", s:cterm08, "", "", "") +call hi("WildMenu", s:gui08, s:gui0A, s:cterm08, "", "", "") +call hi("Title", s:gui0D, "", s:cterm0D, "", "none", "") +call hi("Conceal", s:gui0D, s:gui00, s:cterm0D, s:cterm00, "", "") +call hi("Cursor", s:gui00, s:gui05, s:cterm00, s:cterm05, "", "") +call hi("NonText", s:gui03, "", s:cterm03, "", "", "") +call hi("LineNr", s:gui03, s:gui01, s:cterm03, s:cterm01, "", "") +call hi("SignColumn", s:gui03, s:gui01, s:cterm03, s:cterm01, "", "") +call hi("StatusLine", s:gui04, s:gui02, s:cterm04, s:cterm02, "none", "") +call hi("StatusLineNC", s:gui03, s:gui01, s:cterm03, s:cterm01, "none", "") +call hi("VertSplit", s:gui02, s:gui02, s:cterm02, s:cterm02, "none", "") +call hi("ColorColumn", "", s:gui01, "", s:cterm01, "none", "") +call hi("CursorColumn", "", s:gui01, "", s:cterm01, "none", "") +call hi("CursorLine", "", s:gui01, "", s:cterm01, "none", "") +call hi("CursorLineNr", s:gui04, s:gui01, s:cterm04, s:cterm01, "", "") +call hi("QuickFixLine", "", s:gui01, "", s:cterm01, "none", "") +call hi("PMenu", s:gui05, s:gui01, s:cterm05, s:cterm01, "none", "") +call hi("PMenuSel", s:gui01, s:gui05, s:cterm01, s:cterm05, "", "") +call hi("TabLine", s:gui03, s:gui01, s:cterm03, s:cterm01, "none", "") +call hi("TabLineFill", s:gui03, s:gui01, s:cterm03, s:cterm01, "none", "") +call hi("TabLineSel", s:gui0B, s:gui01, s:cterm0B, s:cterm01, "none", "") + +" Standard syntax highlighting +call hi("Boolean", s:gui09, "", s:cterm09, "", "", "") +call hi("Character", s:gui08, "", s:cterm08, "", "", "") +call hi("Comment", s:gui03, "", s:cterm03, "", "", "") +call hi("Conditional", s:gui0E, "", s:cterm0E, "", "", "") +call hi("Constant", s:gui09, "", s:cterm09, "", "", "") +call hi("Define", s:gui0E, "", s:cterm0E, "", "none", "") +call hi("Delimiter", s:gui0F, "", s:cterm0F, "", "", "") +call hi("Float", s:gui09, "", s:cterm09, "", "", "") +call hi("Function", s:gui0D, "", s:cterm0D, "", "", "") +call hi("Identifier", s:gui08, "", s:cterm08, "", "none", "") +call hi("Include", s:gui0D, "", s:cterm0D, "", "", "") +call hi("Keyword", s:gui0E, "", s:cterm0E, "", "", "") +call hi("Label", s:gui0A, "", s:cterm0A, "", "", "") +call hi("Number", s:gui09, "", s:cterm09, "", "", "") +call hi("Operator", s:gui05, "", s:cterm05, "", "none", "") +call hi("PreProc", s:gui0A, "", s:cterm0A, "", "", "") +call hi("Repeat", s:gui0A, "", s:cterm0A, "", "", "") +call hi("Special", s:gui0C, "", s:cterm0C, "", "", "") +call hi("SpecialChar", s:gui0F, "", s:cterm0F, "", "", "") +call hi("Statement", s:gui08, "", s:cterm08, "", "", "") +call hi("StorageClass", s:gui0A, "", s:cterm0A, "", "", "") +call hi("String", s:gui0B, "", s:cterm0B, "", "", "") +call hi("Structure", s:gui0E, "", s:cterm0E, "", "", "") +call hi("Tag", s:gui0A, "", s:cterm0A, "", "", "") +call hi("Todo", s:gui0A, s:gui01, s:cterm0A, s:cterm01, "", "") +call hi("Type", s:gui0A, "", s:cterm0A, "", "none", "") +call hi("Typedef", s:gui0A, "", s:cterm0A, "", "", "") + +" C highlighting +call hi("cOperator", s:gui0C, "", s:cterm0C, "", "", "") +call hi("cPreCondit", s:gui0E, "", s:cterm0E, "", "", "") + +" C# highlighting +call hi("csClass", s:gui0A, "", s:cterm0A, "", "", "") +call hi("csAttribute", s:gui0A, "", s:cterm0A, "", "", "") +call hi("csModifier", s:gui0E, "", s:cterm0E, "", "", "") +call hi("csType", s:gui08, "", s:cterm08, "", "", "") +call hi("csUnspecifiedStatement", s:gui0D, "", s:cterm0D, "", "", "") +call hi("csContextualStatement", s:gui0E, "", s:cterm0E, "", "", "") +call hi("csNewDecleration", s:gui08, "", s:cterm08, "", "", "") + +" CSS highlighting +call hi("cssBraces", s:gui05, "", s:cterm05, "", "", "") +call hi("cssClassName", s:gui0E, "", s:cterm0E, "", "", "") +call hi("cssColor", s:gui0C, "", s:cterm0C, "", "", "") + +" Diff highlighting +call hi("DiffAdd", s:gui0B, s:gui01, s:cterm0B, s:cterm01, "", "") +call hi("DiffChange", s:gui03, s:gui01, s:cterm03, s:cterm01, "", "") +call hi("DiffDelete", s:gui08, s:gui01, s:cterm08, s:cterm01, "", "") +call hi("DiffText", s:gui0D, s:gui01, s:cterm0D, s:cterm01, "", "") +call hi("DiffAdded", s:gui0B, s:gui00, s:cterm0B, s:cterm00, "", "") +call hi("DiffFile", s:gui08, s:gui00, s:cterm08, s:cterm00, "", "") +call hi("DiffNewFile", s:gui0B, s:gui00, s:cterm0B, s:cterm00, "", "") +call hi("DiffLine", s:gui0D, s:gui00, s:cterm0D, s:cterm00, "", "") +call hi("DiffRemoved", s:gui08, s:gui00, s:cterm08, s:cterm00, "", "") + +" Git highlighting +call hi("gitcommitOverflow", s:gui08, "", s:cterm08, "", "", "") +call hi("gitcommitSummary", s:gui0B, "", s:cterm0B, "", "", "") +call hi("gitcommitComment", s:gui03, "", s:cterm03, "", "", "") +call hi("gitcommitUntracked", s:gui03, "", s:cterm03, "", "", "") +call hi("gitcommitDiscarded", s:gui03, "", s:cterm03, "", "", "") +call hi("gitcommitSelected", s:gui03, "", s:cterm03, "", "", "") +call hi("gitcommitHeader", s:gui0E, "", s:cterm0E, "", "", "") +call hi("gitcommitSelectedType", s:gui0D, "", s:cterm0D, "", "", "") +call hi("gitcommitUnmergedType", s:gui0D, "", s:cterm0D, "", "", "") +call hi("gitcommitDiscardedType", s:gui0D, "", s:cterm0D, "", "", "") +call hi("gitcommitBranch", s:gui09, "", s:cterm09, "", "bold", "") +call hi("gitcommitUntrackedFile", s:gui0A, "", s:cterm0A, "", "", "") +call hi("gitcommitUnmergedFile", s:gui08, "", s:cterm08, "", "bold", "") +call hi("gitcommitDiscardedFile", s:gui08, "", s:cterm08, "", "bold", "") +call hi("gitcommitSelectedFile", s:gui0B, "", s:cterm0B, "", "bold", "") + +" GitGutter highlighting +call hi("GitGutterAdd", s:gui0B, s:gui01, s:cterm0B, s:cterm01, "", "") +call hi("GitGutterChange", s:gui0D, s:gui01, s:cterm0D, s:cterm01, "", "") +call hi("GitGutterDelete", s:gui08, s:gui01, s:cterm08, s:cterm01, "", "") +call hi("GitGutterChangeDelete", s:gui0E, s:gui01, s:cterm0E, s:cterm01, "", "") + +" HTML highlighting +call hi("htmlBold", s:gui0A, "", s:cterm0A, "", "", "") +call hi("htmlItalic", s:gui0E, "", s:cterm0E, "", "", "") +call hi("htmlEndTag", s:gui05, "", s:cterm05, "", "", "") +call hi("htmlTag", s:gui05, "", s:cterm05, "", "", "") + +" JavaScript highlighting +call hi("javaScript", s:gui05, "", s:cterm05, "", "", "") +call hi("javaScriptBraces", s:gui05, "", s:cterm05, "", "", "") +call hi("javaScriptNumber", s:gui09, "", s:cterm09, "", "", "") +" pangloss/vim-javascript highlighting +call hi("jsOperator", s:gui0D, "", s:cterm0D, "", "", "") +call hi("jsStatement", s:gui0E, "", s:cterm0E, "", "", "") +call hi("jsReturn", s:gui0E, "", s:cterm0E, "", "", "") +call hi("jsThis", s:gui08, "", s:cterm08, "", "", "") +call hi("jsClassDefinition", s:gui0A, "", s:cterm0A, "", "", "") +call hi("jsFunction", s:gui0E, "", s:cterm0E, "", "", "") +call hi("jsFuncName", s:gui0D, "", s:cterm0D, "", "", "") +call hi("jsFuncCall", s:gui0D, "", s:cterm0D, "", "", "") +call hi("jsClassFuncName", s:gui0D, "", s:cterm0D, "", "", "") +call hi("jsClassMethodType", s:gui0E, "", s:cterm0E, "", "", "") +call hi("jsRegexpString", s:gui0C, "", s:cterm0C, "", "", "") +call hi("jsGlobalObjects", s:gui0A, "", s:cterm0A, "", "", "") +call hi("jsGlobalNodeObjects", s:gui0A, "", s:cterm0A, "", "", "") +call hi("jsExceptions", s:gui0A, "", s:cterm0A, "", "", "") +call hi("jsBuiltins", s:gui0A, "", s:cterm0A, "", "", "") + +" Mail highlighting +call hi("mailQuoted1", s:gui0A, "", s:cterm0A, "", "", "") +call hi("mailQuoted2", s:gui0B, "", s:cterm0B, "", "", "") +call hi("mailQuoted3", s:gui0E, "", s:cterm0E, "", "", "") +call hi("mailQuoted4", s:gui0C, "", s:cterm0C, "", "", "") +call hi("mailQuoted5", s:gui0D, "", s:cterm0D, "", "", "") +call hi("mailQuoted6", s:gui0A, "", s:cterm0A, "", "", "") +call hi("mailURL", s:gui0D, "", s:cterm0D, "", "", "") +call hi("mailEmail", s:gui0D, "", s:cterm0D, "", "", "") + +" Markdown highlighting +call hi("markdownCode", s:gui0B, "", s:cterm0B, "", "", "") +call hi("markdownError", s:gui05, s:gui00, s:cterm05, s:cterm00, "", "") +call hi("markdownCodeBlock", s:gui0B, "", s:cterm0B, "", "", "") +call hi("markdownHeadingDelimiter", s:gui0D, "", s:cterm0D, "", "", "") + +" NERDTree highlighting +call hi("NERDTreeDirSlash", s:gui0D, "", s:cterm0D, "", "", "") +call hi("NERDTreeExecFile", s:gui05, "", s:cterm05, "", "", "") + +" PHP highlighting +call hi("phpMemberSelector", s:gui05, "", s:cterm05, "", "", "") +call hi("phpComparison", s:gui05, "", s:cterm05, "", "", "") +call hi("phpParent", s:gui05, "", s:cterm05, "", "", "") + +" Python highlighting +call hi("pythonOperator", s:gui0E, "", s:cterm0E, "", "", "") +call hi("pythonRepeat", s:gui0E, "", s:cterm0E, "", "", "") +call hi("pythonInclude", s:gui0E, "", s:cterm0E, "", "", "") +call hi("pythonStatement", s:gui0E, "", s:cterm0E, "", "", "") + +" Ruby highlighting +call hi("rubyAttribute", s:gui0D, "", s:cterm0D, "", "", "") +call hi("rubyConstant", s:gui0A, "", s:cterm0A, "", "", "") +call hi("rubyInterpolationDelimiter", s:gui0F, "", s:cterm0F, "", "", "") +call hi("rubyRegexp", s:gui0C, "", s:cterm0C, "", "", "") +call hi("rubySymbol", s:gui0B, "", s:cterm0B, "", "", "") +call hi("rubyStringDelimiter", s:gui0B, "", s:cterm0B, "", "", "") + +" SASS highlighting +call hi("sassidChar", s:gui08, "", s:cterm08, "", "", "") +call hi("sassClassChar", s:gui09, "", s:cterm09, "", "", "") +call hi("sassInclude", s:gui0E, "", s:cterm0E, "", "", "") +call hi("sassMixing", s:gui0E, "", s:cterm0E, "", "", "") +call hi("sassMixinName", s:gui0D, "", s:cterm0D, "", "", "") + +" Signify highlighting +call hi("SignifySignAdd", s:gui0B, s:gui01, s:cterm0B, s:cterm01, "", "") +call hi("SignifySignChange", s:gui0D, s:gui01, s:cterm0D, s:cterm01, "", "") +call hi("SignifySignDelete", s:gui08, s:gui01, s:cterm08, s:cterm01, "", "") + +" Spelling highlighting +call hi("SpellBad", "", s:gui00, "", s:cterm00, "undercurl", s:gui08) +call hi("SpellLocal", "", s:gui00, "", s:cterm00, "undercurl", s:gui0C) +call hi("SpellCap", "", s:gui00, "", s:cterm00, "undercurl", s:gui0D) +call hi("SpellRare", "", s:gui00, "", s:cterm00, "undercurl", s:gui0E) + +" Remove functions +delf hi + +" Remove color variables +unlet s:gui00 s:gui01 s:gui02 s:gui03 s:gui04 s:gui05 s:gui06 s:gui07 s:gui08 s:gui09 s:gui0A s:gui0B s:gui0C s:gui0D s:gui0E s:gui0F +unlet s:cterm00 s:cterm01 s:cterm02 s:cterm03 s:cterm04 s:cterm05 s:cterm06 s:cterm07 s:cterm08 s:cterm09 s:cterm0A s:cterm0B s:cterm0C s:cterm0D s:cterm0E s:cterm0F diff --git a/base/vim/doc/matchit.txt b/base/vim/doc/matchit.txt new file mode 100644 index 0000000..8a3a96e --- /dev/null +++ b/base/vim/doc/matchit.txt @@ -0,0 +1,406 @@ +*matchit.txt* Extended "%" matching + +For instructions on installing this file, type + :help matchit-install +inside Vim. + +For Vim version 6.3. Last change: 2007 Aug 29 + + + VIM REFERENCE MANUAL by Benji Fisher + +*matchit* *matchit.vim* + +1. Extended matching with "%" |matchit-intro| +2. Activation |matchit-activate| +3. Configuration |matchit-configure| +4. Supporting a New Language |matchit-newlang| +5. Known Bugs and Limitations |matchit-bugs| + +The functionality mentioned here is a plugin, see |add-plugin|. +This plugin is only available if 'compatible' is not set. +You can avoid loading this plugin by setting the "loaded_matchit" variable +in your |vimrc| file: > + :let loaded_matchit = 1 + +{Vi does not have any of this} + +============================================================================== +1. Extended matching with "%" *matchit-intro* + + *matchit-%* +% Cycle forward through matching groups, such as "if", "else", "endif", + as specified by |b:match_words|. + + *g%* *v_g%* *o_g%* +g% Cycle backwards through matching groups, as specified by + |b:match_words|. For example, go from "if" to "endif" to "else". + + *[%* *v_[%* *o_[%* +[% Go to [count] previous unmatched group, as specified by + |b:match_words|. Similar to |[{|. + + *]%* *v_]%* *o_]%* +]% Go to [count] next unmatched group, as specified by + |b:match_words|. Similar to |]}|. + + *v_a%* +a% In Visual mode, select the matching group, as specified by + |b:match_words|, containing the cursor. Similar to |v_a[|. + A [count] is ignored, and only the first character of the closing + pattern is selected. + +In Vim, as in plain vi, the percent key, |%|, jumps the cursor from a brace, +bracket, or paren to its match. This can be configured with the 'matchpairs' +option. The matchit plugin extends this in several ways: + + You can match whole words, such as "if" and "endif", not just + single characters. You can also specify a |regular-expression|. + You can define groups with more than two words, such as "if", + "else", "endif". Banging on the "%" key will cycle from the "if" to + the first "else", the next "else", ..., the closing "endif", and back + to the opening "if". Nested structures are skipped. Using |g%| goes + in the reverse direction. + By default, words inside comments and strings are ignored, unless + the cursor is inside a comment or string when you type "%". If the + only thing you want to do is modify the behavior of "%" so that it + behaves this way, you do not have to define |b:match_words|, since the + script uses the 'matchpairs' option as well as this variable. + +See |matchit-details| for details on what the script does, and |b:match_words| +for how to specify matching patterns. + +MODES: *matchit-modes* *matchit-v_%* *matchit-o_%* + +Mostly, % and related motions (|g%| and |[%| and |]%|) work just like built-in +|motion| commands in |Operator-pending| and |Visual| modes. However, you +cannot make these motions |linewise| or |characterwise|, since the |:omap|s +that define them start with "v" in order to make the default behavior +inclusive. (See |o_v|.) In other words, "dV%" will not work. The +work-around is to go through Visual mode: "V%d" will work. + +LANGUAGES: *matchit-languages* + +Currently, the following languages are supported: Ada, ASP with VBS, Csh, +DTD, Entity, Essbase, Fortran, HTML, JSP (same as HTML), LaTeX, Lua, Pascal, +SGML, Shell, Tcsh, Vim, XML. Other languages may already have support via +the default |filetype-plugin|s in the standard vim distribution. + +To support a new language, see |matchit-newlang| below. + +DETAILS: *matchit-details* *matchit-parse* + +Here is an outline of what matchit.vim does each time you hit the "%" key. If +there are |backref|s in |b:match_words| then the first step is to produce a +version in which these back references have been eliminated; if there are no +|backref|s then this step is skipped. This step is called parsing. For +example, "\(foo\|bar\):end\1" is parsed to yield +"\(foo\|bar\):end\(foo\|bar\)". This can get tricky, especially if there are +nested groups. If debugging is turned on, the parsed version is saved as +|b:match_pat|. + + *matchit-choose* +Next, the script looks for a word on the current line that matches the pattern +just constructed. It includes the patterns from the 'matchpairs' option. +The goal is to do what you expect, which turns out to be a little complicated. +The script follows these rules: + + Insist on a match that ends on or after the cursor. + Prefer a match that includes the cursor position (that is, one that + starts on or before the cursor). + Prefer a match that starts as close to the cursor as possible. + If more than one pattern in |b:match_words| matches, choose the one + that is listed first. + +Examples: + + Suppose you > + :let b:match_words = '<:>,:' +< and hit "%" with the cursor on or before the "<" in "a is born". + The pattern '<' comes first, so it is preferred over '', which + also matches. If the cursor is on the "t", however, then '' is + preferred, because this matches a bit of text containing the cursor. + If the two groups of patterns were reversed then '<' would never be + preferred. + + Suppose you > + :let b:match_words = 'if:end if' +< (Note the space!) and hit "%" with the cursor at the end of "end if". + Then "if" matches, which is probably not what you want, but if the + cursor starts on the "end " then "end if" is chosen. (You can avoid + this problem by using a more complicated pattern.) + +If there is no match, the cursor does not move. (Before version 1.13 of the +script, it would fall back on the usual behavior of |%|). If debugging is +turned on, the matched bit of text is saved as |b:match_match| and the cursor +column of the start of the match is saved as |b:match_col|. + +Next, the script looks through |b:match_words| (original and parsed versions) +for the group and pattern that match. If debugging is turned on, the group is +saved as |b:match_ini| (the first pattern) and |b:match_tail| (the rest). If +there are |backref|s then, in addition, the matching pattern is saved as +|b:match_word| and a table of translations is saved as |b:match_table|. If +there are |backref|s, these are determined from the matching pattern and +|b:match_match| and substituted into each pattern in the matching group. + +The script decides whether to search forwards or backwards and chooses +arguments for the |searchpair()| function. Then, the cursor is moved to the +start of the match, and |searchpair()| is called. By default, matching +structures inside strings and comments are ignored. This can be changed by +setting |b:match_skip|. + +============================================================================== +2. Activation *matchit-activate* + +You can use this script as a plugin, by copying it to your plugin directory. +See |add-global-plugin| for instructions. You can also add a line to your +|vimrc| file, such as > + :source $VIMRUNTIME/macros/matchit.vim +or > + :runtime macros/matchit.vim +Either way, the script should start working the next time you start up Vim. + +(Earlier versions of the script did nothing unless a |buffer-variable| named +|b:match_words| was defined. Even earlier versions contained autocommands +that set this variable for various file types. Now, |b:match_words| is +defined in many of the default |filetype-plugin|s instead.) + +For a new language, you can add autocommands to the script or to your vimrc +file, but the recommended method is to add a line such as > + let b:match_words = '\:\' +to the |filetype-plugin| for your language. See |b:match_words| below for how +this variable is interpreted. + +TROUBLESHOOTING *matchit-troubleshoot* + +The script should work in most installations of Vim. It may not work if Vim +was compiled with a minimal feature set, for example if the |+syntax| option +was not enabled. If your Vim has support for syntax compiled in, but you do +not have |syntax| highlighting turned on, matchit.vim should work, but it may +fail to skip matching groups in comments and strings. If the |filetype| +mechanism is turned off, the |b:match_words| variable will probably not be +defined automatically. + +============================================================================== +3. Configuration *matchit-configure* + +There are several variables that govern the behavior of matchit.vim. Note +that these are variables local to the buffer, not options, so use |:let| to +define them, not |:set|. Some of these variables have values that matter; for +others, it only matters whether the variable has been defined. All of these +can be defined in the |filetype-plugin| or autocommand that defines +|b:match_words| or "on the fly." + +The main variable is |b:match_words|. It is described in the section below on +supporting a new language. + + *MatchError* *matchit-hl* *matchit-highlight* +MatchError is the highlight group for error messages from the script. By +default, it is linked to WarningMsg. If you do not want to be bothered by +error messages, you can define this to be something invisible. For example, +if you use the GUI version of Vim and your command line is normally white, you +can do > + :hi MatchError guifg=white guibg=white +< + *b:match_ignorecase* +If you > + :let b:match_ignorecase = 1 +then matchit.vim acts as if 'ignorecase' is set: for example, "end" and "END" +are equivalent. If you > + :let b:match_ignorecase = 0 +then matchit.vim treats "end" and "END" differently. (There will be no +b:match_infercase option unless someone requests it.) + + *b:match_debug* +Define b:match_debug if you want debugging information to be saved. See +|matchit-debug|, below. + + *b:match_skip* +If b:match_skip is defined, it is passed as the skip argument to +|searchpair()|. This controls when matching structures are skipped, or +ignored. By default, they are ignored inside comments and strings, as +determined by the |syntax| mechanism. (If syntax highlighting is turned off, +nothing is skipped.) You can set b:match_skip to a string, which evaluates to +a non-zero, numerical value if the match is to be skipped or zero if the match +should not be skipped. In addition, the following special values are +supported by matchit.vim: + s:foo becomes (current syntax item) =~ foo + S:foo becomes (current syntax item) !~ foo + r:foo becomes (line before cursor) =~ foo + R:foo becomes (line before cursor) !~ foo +(The "s" is meant to suggest "syntax", and the "r" is meant to suggest +"regular expression".) + +Examples: + + You can get the default behavior with > + :let b:match_skip = 's:comment\|string' +< + If you want to skip matching structures unless they are at the start + of the line (ignoring whitespace) then you can > + :let b:match_skip = 'R:^\s*' +< Do not do this if strings or comments can span several lines, since + the normal syntax checking will not be done if you set b:match_skip. + + In LaTeX, since "%" is used as the comment character, you can > + :let b:match_skip = 'r:%' +< Unfortunately, this will skip anything after "\%", an escaped "%". To + allow for this, and also "\\%" (an excaped backslash followed by the + comment character) you can > + :let b:match_skip = 'r:\(^\|[^\\]\)\(\\\\\)*%' +< + See the $VIMRUNTIME/ftplugin/vim.vim for an example that uses both + syntax and a regular expression. + +============================================================================== +4. Supporting a New Language *matchit-newlang* + *b:match_words* +In order for matchit.vim to support a new language, you must define a suitable +pattern for |b:match_words|. You may also want to set some of the +|matchit-configure| variables, as described above. If your language has a +complicated syntax, or many keywords, you will need to know something about +Vim's |regular-expression|s. + +The format for |b:match_words| is similar to that of the 'matchpairs' option: +it is a comma (,)-separated list of groups; each group is a colon(:)-separated +list of patterns (regular expressions). Commas and backslashes that are part +of a pattern should be escaped with backslashes ('\:' and '\,'). It is OK to +have only one group; the effect is undefined if a group has only one pattern. +A simple example is > + :let b:match_words = '\:\,' + \ . '\:\:\:\' +(In Vim regular expressions, |\<| and |\>| denote word boundaries. Thus "if" +matches the end of "endif" but "\" does not.) Then banging on the "%" +key will bounce the cursor between "if" and the matching "endif"; and from +"while" to any matching "continue" or "break", then to the matching "endwhile" +and back to the "while". It is almost always easier to use |literal-string|s +(single quotes) as above: '\' rather than "\\" and so on. + +Exception: If the ":" character does not appear in b:match_words, then it is +treated as an expression to be evaluated. For example, > + :let b:match_words = 'GetMatchWords()' +allows you to define a function. This can return a different string depending +on the current syntax, for example. + +Once you have defined the appropriate value of |b:match_words|, you will +probably want to have this set automatically each time you edit the +appropriate file type. The recommended way to do this is by adding the +definition to a |filetype-plugin| file. + +Tips: Be careful that your initial pattern does not match your final pattern. +See the example above for the use of word-boundary expressions. It is usually +better to use ".\{-}" (as many as necessary) instead of ".*" (as many as +possible). See |\{-|. For example, in the string "label", "<.*>" +matches the whole string whereas "<.\{-}>" and "<[^>]*>" match "" and +"". + + *matchit-spaces* *matchit-s:notend* +If "if" is to be paired with "end if" (Note the space!) then word boundaries +are not enough. Instead, define a regular expression s:notend that will match +anything but "end" and use it as follows: > + :let s:notend = '\%(\:\' +< *matchit-s:sol* +This is a simplified version of what is done for Ada. The s:notend is a +|script-variable|. Similarly, you may want to define a start-of-line regular +expression > + :let s:sol = '\%(^\|;\)\s*' +if keywords are only recognized after the start of a line or after a +semicolon (;), with optional white space. + + *matchit-backref* *matchit-\1* +In any group, the expressions |\1|, |\2|, ..., |\9| refer to parts of the +INITIAL pattern enclosed in |\(|escaped parentheses|\)|. These are referred +to as back references, or backrefs. For example, > + :let b:match_words = '\:\(h\)\1\>' +means that "bo" pairs with "ho" and "boo" pairs with "hoo" and so on. Note +that "\1" does not refer to the "\(h\)" in this example. If you have +"\(nested \(parentheses\)\) then "\d" refers to the d-th "\(" and everything +up to and including the matching "\)": in "\(nested\(parentheses\)\)", "\1" +refers to everything and "\2" refers to "\(parentheses\)". If you use a +variable such as |s:notend| or |s:sol| in the previous paragraph then remember +to count any "\(" patterns in this variable. You do not have to count groups +defined by |\%(\)|. + +It should be possible to resolve back references from any pattern in the +group. For example, > + :let b:match_words = '\(foo\)\(bar\):more\1:and\2:end\1\2' +would not work because "\2" cannot be determined from "morefoo" and "\1" +cannot be determined from "andbar". On the other hand, > + :let b:match_words = '\(\(foo\)\(bar\)\):\3\2:end\1' +should work (and have the same effect as "foobar:barfoo:endfoobar"), although +this has not been thoroughly tested. + +You can use |zero-width| patterns such as |\@<=| and |\zs|. (The latter has +not been thouroughly tested in matchit.vim.) For example, if the keyword "if" +must occur at the start of the line, with optional white space, you might use +the pattern "\(^\s*\)\@<=if" so that the cursor will end on the "i" instead of +at the start of the line. For another example, if HTML had only one tag then +one could > + :let b:match_words = '<:>,<\@<=tag>:<\@<=/tag>' +so that "%" can bounce between matching "<" and ">" pairs or (starting on +"tag" or "/tag") between matching tags. Without the |\@<=|, the script would +bounce from "tag" to the "<" in "", and another "%" would not take you +back to where you started. + +DEBUGGING *matchit-debug* *:MatchDebug* + +If you are having trouble figuring out the appropriate definition of +|b:match_words| then you can take advantage of the same information I use when +debugging the script. This is especially true if you are not sure whether +your patterns or my script are at fault! To make this more convenient, I have +made the command :MatchDebug, which defines the variable |b:match_debug| and +creates a Matchit menu. This menu makes it convenient to check the values of +the variables described below. You will probably also want to read +|matchit-details| above. + +Defining the variable |b:match_debug| causes the script to set the following +variables, each time you hit the "%" key. Several of these are only defined +if |b:match_words| includes |backref|s. + + *b:match_pat* +The b:match_pat variable is set to |b:match_words| with |backref|s parsed. + *b:match_match* +The b:match_match variable is set to the bit of text that is recognized as a +match. + *b:match_col* +The b:match_col variable is set to the cursor column of the start of the +matching text. + *b:match_wholeBR* +The b:match_wholeBR variable is set to the comma-separated group of patterns +that matches, with |backref|s unparsed. + *b:match_iniBR* +The b:match_iniBR variable is set to the first pattern in |b:match_wholeBR|. + *b:match_ini* +The b:match_ini variable is set to the first pattern in |b:match_wholeBR|, +with |backref|s resolved from |b:match_match|. + *b:match_tail* +The b:match_tail variable is set to the remaining patterns in +|b:match_wholeBR|, with |backref|s resolved from |b:match_match|. + *b:match_word* +The b:match_word variable is set to the pattern from |b:match_wholeBR| that +matches |b:match_match|. + *b:match_table* +The back reference '\'.d refers to the same thing as '\'.b:match_table[d] in +|b:match_word|. + +============================================================================== +5. Known Bugs and Limitations *matchit-bugs* + +Just because I know about a bug does not mean that it is on my todo list. I +try to respond to reports of bugs that cause real problems. If it does not +cause serious problems, or if there is a work-around, a bug may sit there for +a while. Moral: if a bug (known or not) bothers you, let me know. + +The various |:vmap|s defined in the script (%, |g%|, |[%|, |]%|, |a%|) may +have undesired effects in Select mode |Select-mode-mapping|. At least, if you +want to replace the selection with any character in "ag%[]" there will be a +pause of |'updatetime'| first. + +It would be nice if "\0" were recognized as the entire pattern. That is, it +would be nice if "foo:\end\0" had the same effect as "\(foo\):\end\1". I may +try to implement this in a future version. (This is not so easy to arrange as +you might think!) + +============================================================================== +vim:tw=78:fo=tcq2: diff --git a/base/vim/doc/tags b/base/vim/doc/tags new file mode 100644 index 0000000..4ccdc87 --- /dev/null +++ b/base/vim/doc/tags @@ -0,0 +1,50 @@ +:MatchDebug matchit.txt /*:MatchDebug* +MatchError matchit.txt /*MatchError* +[% matchit.txt /*[%* +]% matchit.txt /*]%* +b:match_col matchit.txt /*b:match_col* +b:match_debug matchit.txt /*b:match_debug* +b:match_ignorecase matchit.txt /*b:match_ignorecase* +b:match_ini matchit.txt /*b:match_ini* +b:match_iniBR matchit.txt /*b:match_iniBR* +b:match_match matchit.txt /*b:match_match* +b:match_pat matchit.txt /*b:match_pat* +b:match_skip matchit.txt /*b:match_skip* +b:match_table matchit.txt /*b:match_table* +b:match_tail matchit.txt /*b:match_tail* +b:match_wholeBR matchit.txt /*b:match_wholeBR* +b:match_word matchit.txt /*b:match_word* +b:match_words matchit.txt /*b:match_words* +g% matchit.txt /*g%* +matchit matchit.txt /*matchit* +matchit-% matchit.txt /*matchit-%* +matchit-\1 matchit.txt /*matchit-\\1* +matchit-activate matchit.txt /*matchit-activate* +matchit-backref matchit.txt /*matchit-backref* +matchit-bugs matchit.txt /*matchit-bugs* +matchit-choose matchit.txt /*matchit-choose* +matchit-configure matchit.txt /*matchit-configure* +matchit-debug matchit.txt /*matchit-debug* +matchit-details matchit.txt /*matchit-details* +matchit-highlight matchit.txt /*matchit-highlight* +matchit-hl matchit.txt /*matchit-hl* +matchit-intro matchit.txt /*matchit-intro* +matchit-languages matchit.txt /*matchit-languages* +matchit-modes matchit.txt /*matchit-modes* +matchit-newlang matchit.txt /*matchit-newlang* +matchit-o_% matchit.txt /*matchit-o_%* +matchit-parse matchit.txt /*matchit-parse* +matchit-s:notend matchit.txt /*matchit-s:notend* +matchit-s:sol matchit.txt /*matchit-s:sol* +matchit-spaces matchit.txt /*matchit-spaces* +matchit-troubleshoot matchit.txt /*matchit-troubleshoot* +matchit-v_% matchit.txt /*matchit-v_%* +matchit.txt matchit.txt /*matchit.txt* +matchit.vim matchit.txt /*matchit.vim* +o_[% matchit.txt /*o_[%* +o_]% matchit.txt /*o_]%* +o_g% matchit.txt /*o_g%* +v_[% matchit.txt /*v_[%* +v_]% matchit.txt /*v_]%* +v_a% matchit.txt /*v_a%* +v_g% matchit.txt /*v_g%* diff --git a/base/vim/ftdetect/json.vim b/base/vim/ftdetect/json.vim new file mode 100644 index 0000000..b4a5cd7 --- /dev/null +++ b/base/vim/ftdetect/json.vim @@ -0,0 +1,3 @@ +autocmd BufNewFile,BufRead *.json setlocal filetype=json +autocmd BufNewFile,BufRead *.jsonp setlocal filetype=json +autocmd BufNewFile,BufRead *.geojson setlocal filetype=json diff --git a/base/vim/ftplugin/json.vim b/base/vim/ftplugin/json.vim new file mode 100644 index 0000000..3ee1062 --- /dev/null +++ b/base/vim/ftplugin/json.vim @@ -0,0 +1,40 @@ +" Vim syntax file +" Language: JSON +" Maintainer: Eli Parra https://github.com/elzr/vim-json +" Last Change: 2014-05-20 added warning toggle + +"uncomment to enable folding of `{...}` and `[...]` blocks +"setlocal foldmethod=syntax + +"conceal by default +if !exists("g:vim_json_syntax_conceal") + let g:vim_json_syntax_conceal = 1 +end + +"have warnings by default +if !exists("g:vim_json_warnings") + let g:vim_json_warnings = 1 +end + +"set concealcursor blank by default +"this should turn off the concealing in the current line (where the cursor is at), +"on all modes (normal, visual, insert) +if !exists("g:vim_json_syntax_concealcursor") + let g:vim_json_syntax_concealcursor = "" +end + +if has('conceal') + if (g:vim_json_syntax_conceal == 1) + "level 2 means concealed text gets completely hidden unless a + "replacement is defined (none is defined by us) + setlocal conceallevel=2 + let &l:concealcursor = g:vim_json_syntax_concealcursor + else + "level 0 means text is shown normally = no concealing + setlocal conceallevel=0 + endif + "maybe g:vim_json_syntax_conceal could be settable to 0,1,2 to map + "directly to vim's conceallevels? unsure if anyone cares +endif + +setlocal foldmethod=syntax diff --git a/base/vim/ftplugin/php.vim b/base/vim/ftplugin/php.vim new file mode 100644 index 0000000..3c498a7 --- /dev/null +++ b/base/vim/ftplugin/php.vim @@ -0,0 +1,272 @@ +" Vim indent file +" Language: Php +" Authors: Miles Lott , Johannes Zellner , Pim Snel +" URL: http://lingewoud.nl/downloads.php +" Last Change: 23 feb 2004 +" Version: 0.3 +" Notes: This is a combination of the PHP indent file of Miles Lott with +" the HTML indent file of Johannes Zellner. Usefull for editing +" php-files with html parts in it. +" +" Changelog: +" 0.3 - 25 mar 2004 +" - fixed wrong indention when a php-tag is opened and closed on +" one single line. +" 0.2 - 23 feb 2004 +" - applied patch from Holger Dzeik +" - added changelog +" - added default indention of 3 spaces after the ,<>>,,{,} + +" Only define the function once. +if exists("*GetPhpIndent") + finish +endif + +" Handle option(s) +if exists("php_noindent_switch") + let b:php_noindent_switch=1 +endif + +if exists('g:html_indent_tags') + unlet g:html_indent_tags +endif + +function GetPhpIndent() + " Find a non-empty line above the current line. + let lnum = prevnonblank(v:lnum - 1) + + " Hit the start of the file, use zero indent. + if lnum == 0 + return 0 + endif + + let line = getline(lnum) " last line + let cline = getline(v:lnum) " current line + let pline = getline(lnum - 1) " previous to last line + let ind = indent(lnum) + + let restore_ic=&ic + let &ic=1 " ignore case + + let ind = HtmlIndentSum(lnum, -1) + let ind = ind + HtmlIndentSum(v:lnum, 0) + + let &ic=restore_ic + + let ind = indent(lnum) + (&sw * ind) + + " Indent after php open tags + if line =~ '' + let ind = ind + &sw + endif + if cline =~ '^\s*[?>]' " // Fix from Holger Dzeik Thanks! + let ind = ind - &sw + endif + + + if exists("b:php_noindent_switch") " version 1 behavior, diy switch/case,etc + " Indent blocks enclosed by {} or () + if line =~ '[{(]\s*\(#[^)}]*\)\=$' + let ind = ind + &sw + endif + if cline =~ '^\s*[)}]' + let ind = ind - &sw + endif + return ind + else " Try to indent switch/case statements as well + " Indent blocks enclosed by {} or () or case statements, with some anal requirements + if line =~ 'case.*:\|[{(]\s*\(#[^)}]*\)\=$' + let ind = ind + &sw + " return if the current line is not another case statement of the previous line is a bracket open + if cline !~ '.*case.*:\|default:' || line =~ '[{(]\s*\(#[^)}]*\)\=$' + return ind + endif + endif + if cline =~ '^\s*case.*:\|^\s*default:\|^\s*[)}]' + let ind = ind - &sw + " if the last line is a break or return, or the current line is a close bracket, + " or if the previous line is a default statement, subtract another + if line =~ '^\s*break;\|^\s*return\|' && cline =~ '^\s*[)}]' && pline =~ 'default:' + let ind = ind - &sw + endif + endif + + if line =~ 'default:' + let ind = ind + &sw + endif + return ind + endif +endfunction + + +" [-- local settings (must come before aborting the script) --] +"setlocal indentexpr=HtmlIndentGet(v:lnum) +"setlocal indentkeys=o,O,*,<>>,,{,} + + + +" [-- helper function to assemble tag list --] +fun! HtmlIndentPush(tag) + if exists('g:html_indent_tags') + let g:html_indent_tags = g:html_indent_tags.'\|'.a:tag + else + let g:html_indent_tags = a:tag + endif +endfun + + +" [-- --] +call HtmlIndentPush('a') +call HtmlIndentPush('abbr') +call HtmlIndentPush('acronym') +call HtmlIndentPush('address') +call HtmlIndentPush('b') +call HtmlIndentPush('bdo') +call HtmlIndentPush('big') +call HtmlIndentPush('blockquote') +call HtmlIndentPush('button') +call HtmlIndentPush('caption') +call HtmlIndentPush('center') +call HtmlIndentPush('cite') +call HtmlIndentPush('code') +call HtmlIndentPush('colgroup') +call HtmlIndentPush('del') +call HtmlIndentPush('dfn') +call HtmlIndentPush('dir') +call HtmlIndentPush('div') +call HtmlIndentPush('dl') +call HtmlIndentPush('em') +call HtmlIndentPush('fieldset') +call HtmlIndentPush('font') +call HtmlIndentPush('form') +call HtmlIndentPush('frameset') +call HtmlIndentPush('h1') +call HtmlIndentPush('h2') +call HtmlIndentPush('h3') +call HtmlIndentPush('h4') +call HtmlIndentPush('h5') +call HtmlIndentPush('h6') +call HtmlIndentPush('i') +call HtmlIndentPush('iframe') +call HtmlIndentPush('ins') +call HtmlIndentPush('kbd') +call HtmlIndentPush('label') +call HtmlIndentPush('legend') +call HtmlIndentPush('map') +call HtmlIndentPush('menu') +call HtmlIndentPush('noframes') +call HtmlIndentPush('noscript') +call HtmlIndentPush('object') +call HtmlIndentPush('ol') +call HtmlIndentPush('optgroup') +call HtmlIndentPush('pre') +call HtmlIndentPush('q') +call HtmlIndentPush('s') +call HtmlIndentPush('samp') +call HtmlIndentPush('script') +call HtmlIndentPush('select') +call HtmlIndentPush('small') +call HtmlIndentPush('span') +call HtmlIndentPush('strong') +call HtmlIndentPush('style') +call HtmlIndentPush('sub') +call HtmlIndentPush('sup') +call HtmlIndentPush('table') +call HtmlIndentPush('textarea') +call HtmlIndentPush('title') +call HtmlIndentPush('tt') +call HtmlIndentPush('u') +call HtmlIndentPush('ul') +call HtmlIndentPush('var') + + +" [-- --] +if !exists('g:html_indent_strict') + call HtmlIndentPush('body') + call HtmlIndentPush('head') + call HtmlIndentPush('html') + call HtmlIndentPush('tbody') +endif + + +" [-- --] +if !exists('g:html_indent_strict_table') + call HtmlIndentPush('th') + call HtmlIndentPush('td') + call HtmlIndentPush('tr') + call HtmlIndentPush('tfoot') + call HtmlIndentPush('thead') +endif + +delfun HtmlIndentPush + +set cpo-=C + +" [-- count indent-increasing tags of line a:lnum --] +fun! HtmlIndentOpen(lnum) + let s = substitute('x'.getline(a:lnum), + \ '.\{-}\(\(<\)\('.g:html_indent_tags.'\)\>\)', "\1", 'g') + let s = substitute(s, "[^\1].*$", '', '') + return strlen(s) +endfun + +" [-- count indent-decreasing tags of line a:lnum --] +fun! HtmlIndentClose(lnum) + let s = substitute('x'.getline(a:lnum), + \ '.\{-}\(\(<\)/\('.g:html_indent_tags.'\)\>>\)', "\1", 'g') + let s = substitute(s, "[^\1].*$", '', '') + return strlen(s) +endfun + +" [-- count indent-increasing '{' of (java|css) line a:lnum --] +fun! HtmlIndentOpenAlt(lnum) + return strlen(substitute(getline(a:lnum), '[^{]\+', '', 'g')) +endfun + +" [-- count indent-decreasing '}' of (java|css) line a:lnum --] +fun! HtmlIndentCloseAlt(lnum) + return strlen(substitute(getline(a:lnum), '[^}]\+', '', 'g')) +endfun + +" [-- return the sum of indents respecting the syntax of a:lnum --] +fun! HtmlIndentSum(lnum, style) + if a:style == match(getline(a:lnum), '^\s*') + let open = HtmlIndentOpen(a:lnum) + let close = HtmlIndentClose(a:lnum) + if 0 != open || 0 != close + return open - close + endif + endif + endif + if '' != &syntax && + \ synIDattr(synID(a:lnum, 1, 1), 'name') =~ '\(css\|java\).*' && + \ synIDattr(synID(a:lnum, strlen(getline(a:lnum)) - 1, 1), 'name') + \ =~ '\(css\|java\).*' + if a:style == match(getline(a:lnum), '^\s*}') + return HtmlIndentOpenAlt(a:lnum) - HtmlIndentCloseAlt(a:lnum) + endif + endif + return 0 +endfun + +" vim: set ts=3 sw=3: diff --git a/base/vim/indent/json.vim b/base/vim/indent/json.vim new file mode 100644 index 0000000..7873d65 --- /dev/null +++ b/base/vim/indent/json.vim @@ -0,0 +1,177 @@ +" Vim indent file +" Language: JSON +" Mantainer: Eli Parra https://github.com/elzr/vim-json +" Last Change: 2014-05-13: merged Fix for square bracket matching by Jakar +" https://github.com/jakar/vim-json/commit/20b650e22aa750c4ab6a66aa646bdd95d7cd548a#diff-e81fc111b2052e306d126bd9989f7b7c +" Original Author: Rogerz Zhang http://github.com/rogerz/vim-json +" Acknowledgement: Based off of vim-javascript maintained by Darrick Wiebe +" http://www.vim.org/scripts/script.php?script_id=2765 + +" 0. Initialization {{{1 +" ================= + +" Only load this indent file when no other was loaded. +if exists("b:did_indent") + finish +endif +let b:did_indent = 1 + +setlocal nosmartindent + +" Now, set up our indentation expression and keys that trigger it. +setlocal indentexpr=GetJSONIndent() +setlocal indentkeys=0{,0},0),0[,0],!^F,o,O,e + +" Only define the function once. +if exists("*GetJSONIndent") + finish +endif + +let s:cpo_save = &cpo +set cpo&vim + +" 1. Variables {{{1 +" ============ + +let s:line_term = '\s*\%(\%(\/\/\).*\)\=$' +" Regex that defines blocks. +let s:block_regex = '\%({\)\s*\%(|\%([*@]\=\h\w*,\=\s*\)\%(,\s*[*@]\=\h\w*\)*|\)\=' . s:line_term + +" 2. Auxiliary Functions {{{1 +" ====================== + +" Check if the character at lnum:col is inside a string. +function s:IsInString(lnum, col) + return synIDattr(synID(a:lnum, a:col, 1), 'name') == "jsonString" +endfunction + +" Find line above 'lnum' that isn't empty, or in a string. +function s:PrevNonBlankNonString(lnum) + let lnum = prevnonblank(a:lnum) + while lnum > 0 + " If the line isn't empty or in a string, end search. + let line = getline(lnum) + if !(s:IsInString(lnum, 1) && s:IsInString(lnum, strlen(line))) + break + endif + let lnum = prevnonblank(lnum - 1) + endwhile + return lnum +endfunction + +" Check if line 'lnum' has more opening brackets than closing ones. +function s:LineHasOpeningBrackets(lnum) + let open_0 = 0 + let open_2 = 0 + let open_4 = 0 + let line = getline(a:lnum) + let pos = match(line, '[][(){}]', 0) + while pos != -1 + let idx = stridx('(){}[]', line[pos]) + if idx % 2 == 0 + let open_{idx} = open_{idx} + 1 + else + let open_{idx - 1} = open_{idx - 1} - 1 + endif + let pos = match(line, '[][(){}]', pos + 1) + endwhile + return (open_0 > 0) . (open_2 > 0) . (open_4 > 0) +endfunction + +function s:Match(lnum, regex) + let col = match(getline(a:lnum), a:regex) + 1 + return col > 0 && !s:IsInString(a:lnum, col) ? col : 0 +endfunction + +" 3. GetJSONIndent Function {{{1 +" ========================= + +function GetJSONIndent() + " 3.1. Setup {{{2 + " ---------- + + " Set up variables for restoring position in file. Could use v:lnum here. + let vcol = col('.') + + " 3.2. Work on the current line {{{2 + " ----------------------------- + + " Get the current line. + let line = getline(v:lnum) + let ind = -1 + + " If we got a closing bracket on an empty line, find its match and indent + " according to it. + let col = matchend(line, '^\s*[]}]') + + if col > 0 && !s:IsInString(v:lnum, col) + call cursor(v:lnum, col) + let bs = strpart('{}[]', stridx('}]', line[col - 1]) * 2, 2) + + let pairstart = escape(bs[0], '[') + let pairend = escape(bs[1], ']') + let pairline = searchpair(pairstart, '', pairend, 'bW') + + if pairline > 0 + let ind = indent(pairline) + else + let ind = virtcol('.') - 1 + endif + + return ind + endif + + " If we are in a multi-line string, don't do anything to it. + if s:IsInString(v:lnum, matchend(line, '^\s*') + 1) + return indent('.') + endif + + " 3.3. Work on the previous line. {{{2 + " ------------------------------- + + let lnum = prevnonblank(v:lnum - 1) + + if lnum == 0 + return 0 + endif + + " Set up variables for current line. + let line = getline(lnum) + let ind = indent(lnum) + + " If the previous line ended with a block opening, add a level of indent. + " if s:Match(lnum, s:block_regex) + " if exists('*shiftwidth') + " return indent(lnum) + shiftwidth() + " else + " return indent(lnum) + &sw + " endif + " endif + + " If the previous line contained an opening bracket, and we are still in it, + " add indent depending on the bracket type. + if line =~ '[[({]' + let counts = s:LineHasOpeningBrackets(lnum) + if counts[0] == '1' || counts[1] == '1' || counts[2] == '1' + if exists('*shiftwidth') + return ind + shiftwidth() + else + return ind + &sw + endif + else + call cursor(v:lnum, vcol) + end + endif + + " }}}2 + + return ind +endfunction + +" }}}1 + +let &cpo = s:cpo_save +unlet s:cpo_save + +" vim:set sw=2 sts=2 ts=8 noet: + diff --git a/base/vim/indent/php.vim b/base/vim/indent/php.vim new file mode 100644 index 0000000..3c498a7 --- /dev/null +++ b/base/vim/indent/php.vim @@ -0,0 +1,272 @@ +" Vim indent file +" Language: Php +" Authors: Miles Lott , Johannes Zellner , Pim Snel +" URL: http://lingewoud.nl/downloads.php +" Last Change: 23 feb 2004 +" Version: 0.3 +" Notes: This is a combination of the PHP indent file of Miles Lott with +" the HTML indent file of Johannes Zellner. Usefull for editing +" php-files with html parts in it. +" +" Changelog: +" 0.3 - 25 mar 2004 +" - fixed wrong indention when a php-tag is opened and closed on +" one single line. +" 0.2 - 23 feb 2004 +" - applied patch from Holger Dzeik +" - added changelog +" - added default indention of 3 spaces after the ,<>>,,{,} + +" Only define the function once. +if exists("*GetPhpIndent") + finish +endif + +" Handle option(s) +if exists("php_noindent_switch") + let b:php_noindent_switch=1 +endif + +if exists('g:html_indent_tags') + unlet g:html_indent_tags +endif + +function GetPhpIndent() + " Find a non-empty line above the current line. + let lnum = prevnonblank(v:lnum - 1) + + " Hit the start of the file, use zero indent. + if lnum == 0 + return 0 + endif + + let line = getline(lnum) " last line + let cline = getline(v:lnum) " current line + let pline = getline(lnum - 1) " previous to last line + let ind = indent(lnum) + + let restore_ic=&ic + let &ic=1 " ignore case + + let ind = HtmlIndentSum(lnum, -1) + let ind = ind + HtmlIndentSum(v:lnum, 0) + + let &ic=restore_ic + + let ind = indent(lnum) + (&sw * ind) + + " Indent after php open tags + if line =~ '' + let ind = ind + &sw + endif + if cline =~ '^\s*[?>]' " // Fix from Holger Dzeik Thanks! + let ind = ind - &sw + endif + + + if exists("b:php_noindent_switch") " version 1 behavior, diy switch/case,etc + " Indent blocks enclosed by {} or () + if line =~ '[{(]\s*\(#[^)}]*\)\=$' + let ind = ind + &sw + endif + if cline =~ '^\s*[)}]' + let ind = ind - &sw + endif + return ind + else " Try to indent switch/case statements as well + " Indent blocks enclosed by {} or () or case statements, with some anal requirements + if line =~ 'case.*:\|[{(]\s*\(#[^)}]*\)\=$' + let ind = ind + &sw + " return if the current line is not another case statement of the previous line is a bracket open + if cline !~ '.*case.*:\|default:' || line =~ '[{(]\s*\(#[^)}]*\)\=$' + return ind + endif + endif + if cline =~ '^\s*case.*:\|^\s*default:\|^\s*[)}]' + let ind = ind - &sw + " if the last line is a break or return, or the current line is a close bracket, + " or if the previous line is a default statement, subtract another + if line =~ '^\s*break;\|^\s*return\|' && cline =~ '^\s*[)}]' && pline =~ 'default:' + let ind = ind - &sw + endif + endif + + if line =~ 'default:' + let ind = ind + &sw + endif + return ind + endif +endfunction + + +" [-- local settings (must come before aborting the script) --] +"setlocal indentexpr=HtmlIndentGet(v:lnum) +"setlocal indentkeys=o,O,*,<>>,,{,} + + + +" [-- helper function to assemble tag list --] +fun! HtmlIndentPush(tag) + if exists('g:html_indent_tags') + let g:html_indent_tags = g:html_indent_tags.'\|'.a:tag + else + let g:html_indent_tags = a:tag + endif +endfun + + +" [-- --] +call HtmlIndentPush('a') +call HtmlIndentPush('abbr') +call HtmlIndentPush('acronym') +call HtmlIndentPush('address') +call HtmlIndentPush('b') +call HtmlIndentPush('bdo') +call HtmlIndentPush('big') +call HtmlIndentPush('blockquote') +call HtmlIndentPush('button') +call HtmlIndentPush('caption') +call HtmlIndentPush('center') +call HtmlIndentPush('cite') +call HtmlIndentPush('code') +call HtmlIndentPush('colgroup') +call HtmlIndentPush('del') +call HtmlIndentPush('dfn') +call HtmlIndentPush('dir') +call HtmlIndentPush('div') +call HtmlIndentPush('dl') +call HtmlIndentPush('em') +call HtmlIndentPush('fieldset') +call HtmlIndentPush('font') +call HtmlIndentPush('form') +call HtmlIndentPush('frameset') +call HtmlIndentPush('h1') +call HtmlIndentPush('h2') +call HtmlIndentPush('h3') +call HtmlIndentPush('h4') +call HtmlIndentPush('h5') +call HtmlIndentPush('h6') +call HtmlIndentPush('i') +call HtmlIndentPush('iframe') +call HtmlIndentPush('ins') +call HtmlIndentPush('kbd') +call HtmlIndentPush('label') +call HtmlIndentPush('legend') +call HtmlIndentPush('map') +call HtmlIndentPush('menu') +call HtmlIndentPush('noframes') +call HtmlIndentPush('noscript') +call HtmlIndentPush('object') +call HtmlIndentPush('ol') +call HtmlIndentPush('optgroup') +call HtmlIndentPush('pre') +call HtmlIndentPush('q') +call HtmlIndentPush('s') +call HtmlIndentPush('samp') +call HtmlIndentPush('script') +call HtmlIndentPush('select') +call HtmlIndentPush('small') +call HtmlIndentPush('span') +call HtmlIndentPush('strong') +call HtmlIndentPush('style') +call HtmlIndentPush('sub') +call HtmlIndentPush('sup') +call HtmlIndentPush('table') +call HtmlIndentPush('textarea') +call HtmlIndentPush('title') +call HtmlIndentPush('tt') +call HtmlIndentPush('u') +call HtmlIndentPush('ul') +call HtmlIndentPush('var') + + +" [-- --] +if !exists('g:html_indent_strict') + call HtmlIndentPush('body') + call HtmlIndentPush('head') + call HtmlIndentPush('html') + call HtmlIndentPush('tbody') +endif + + +" [-- --] +if !exists('g:html_indent_strict_table') + call HtmlIndentPush('th') + call HtmlIndentPush('td') + call HtmlIndentPush('tr') + call HtmlIndentPush('tfoot') + call HtmlIndentPush('thead') +endif + +delfun HtmlIndentPush + +set cpo-=C + +" [-- count indent-increasing tags of line a:lnum --] +fun! HtmlIndentOpen(lnum) + let s = substitute('x'.getline(a:lnum), + \ '.\{-}\(\(<\)\('.g:html_indent_tags.'\)\>\)', "\1", 'g') + let s = substitute(s, "[^\1].*$", '', '') + return strlen(s) +endfun + +" [-- count indent-decreasing tags of line a:lnum --] +fun! HtmlIndentClose(lnum) + let s = substitute('x'.getline(a:lnum), + \ '.\{-}\(\(<\)/\('.g:html_indent_tags.'\)\>>\)', "\1", 'g') + let s = substitute(s, "[^\1].*$", '', '') + return strlen(s) +endfun + +" [-- count indent-increasing '{' of (java|css) line a:lnum --] +fun! HtmlIndentOpenAlt(lnum) + return strlen(substitute(getline(a:lnum), '[^{]\+', '', 'g')) +endfun + +" [-- count indent-decreasing '}' of (java|css) line a:lnum --] +fun! HtmlIndentCloseAlt(lnum) + return strlen(substitute(getline(a:lnum), '[^}]\+', '', 'g')) +endfun + +" [-- return the sum of indents respecting the syntax of a:lnum --] +fun! HtmlIndentSum(lnum, style) + if a:style == match(getline(a:lnum), '^\s*') + let open = HtmlIndentOpen(a:lnum) + let close = HtmlIndentClose(a:lnum) + if 0 != open || 0 != close + return open - close + endif + endif + endif + if '' != &syntax && + \ synIDattr(synID(a:lnum, 1, 1), 'name') =~ '\(css\|java\).*' && + \ synIDattr(synID(a:lnum, strlen(getline(a:lnum)) - 1, 1), 'name') + \ =~ '\(css\|java\).*' + if a:style == match(getline(a:lnum), '^\s*}') + return HtmlIndentOpenAlt(a:lnum) - HtmlIndentCloseAlt(a:lnum) + endif + endif + return 0 +endfun + +" vim: set ts=3 sw=3: diff --git a/base/vim/syntax/json.vim b/base/vim/syntax/json.vim new file mode 100644 index 0000000..3423eba --- /dev/null +++ b/base/vim/syntax/json.vim @@ -0,0 +1,137 @@ +" Vim syntax file +" Language: JSON +" Maintainer: Eli Parra https://github.com/elzr/vim-json +" Last Change: 2014-12-20 Load ftplugin/json.vim + +" Reload the definition of g:vim_json_syntax_conceal +" see https://github.com/elzr/vim-json/issues/42 +runtime! ftplugin/json.vim + +if !exists("main_syntax") + if version < 600 + syntax clear + elseif exists("b:current_syntax") + finish + endif + let main_syntax = 'json' +endif + +syntax match jsonNoise /\%(:\|,\)/ + +" NOTE that for the concealing to work your conceallevel should be set to 2 + +" Syntax: Strings +" Separated into a match and region because a region by itself is always greedy +syn match jsonStringMatch /"\([^"]\|\\\"\)\+"\ze[[:blank:]\r\n]*[,}\]]/ contains=jsonString +if has('conceal') && g:vim_json_syntax_conceal == 1 + syn region jsonString oneline matchgroup=jsonQuote start=/"/ skip=/\\\\\|\\"/ end=/"/ concealends contains=jsonEscape contained +else + syn region jsonString oneline matchgroup=jsonQuote start=/"/ skip=/\\\\\|\\"/ end=/"/ contains=jsonEscape contained +endif + +" Syntax: JSON does not allow strings with single quotes, unlike JavaScript. +syn region jsonStringSQError oneline start=+'+ skip=+\\\\\|\\"+ end=+'+ + +" Syntax: JSON Keywords +" Separated into a match and region because a region by itself is always greedy +syn match jsonKeywordMatch /"\([^"]\|\\\"\)\+"[[:blank:]\r\n]*\:/ contains=jsonKeyword +if has('conceal') && g:vim_json_syntax_conceal == 1 + syn region jsonKeyword matchgroup=jsonQuote start=/"/ end=/"\ze[[:blank:]\r\n]*\:/ concealends contains=jsonEscape contained +else + syn region jsonKeyword matchgroup=jsonQuote start=/"/ end=/"\ze[[:blank:]\r\n]*\:/ contains=jsonEscape contained +endif + +" Syntax: Escape sequences +syn match jsonEscape "\\["\\/bfnrt]" contained +syn match jsonEscape "\\u\x\{4}" contained + +" Syntax: Numbers +syn match jsonNumber "-\=\<\%(0\|[1-9]\d*\)\%(\.\d\+\)\=\%([eE][-+]\=\d\+\)\=\>\ze[[:blank:]\r\n]*[,}\]]" + +" ERROR WARNINGS ********************************************** +if (!exists("g:vim_json_warnings") || g:vim_json_warnings==1) + " Syntax: Strings should always be enclosed with quotes. + syn match jsonNoQuotesError "\<[[:alpha:]][[:alnum:]]*\>" + syn match jsonTripleQuotesError /"""/ + + " Syntax: An integer part of 0 followed by other digits is not allowed. + syn match jsonNumError "-\=\<0\d\.\d*\>" + + " Syntax: Decimals smaller than one should begin with 0 (so .1 should be 0.1). + syn match jsonNumError "\:\@<=[[:blank:]\r\n]*\zs\.\d\+" + + " Syntax: No comments in JSON, see http://stackoverflow.com/questions/244777/can-i-comment-a-json-file + syn match jsonCommentError "//.*" + syn match jsonCommentError "\(/\*\)\|\(\*/\)" + + " Syntax: No semicolons in JSON + syn match jsonSemicolonError ";" + + " Syntax: No trailing comma after the last element of arrays or objects + syn match jsonTrailingCommaError ",\_s*[}\]]" + + " Syntax: Watch out for missing commas between elements + syn match jsonMissingCommaError /\("\|\]\|\d\)\zs\_s\+\ze"/ + syn match jsonMissingCommaError /\(\]\|\}\)\_s\+\ze"/ "arrays/objects as values + syn match jsonMissingCommaError /}\_s\+\ze{/ "objects as elements in an array + syn match jsonMissingCommaError /\(true\|false\)\_s\+\ze"/ "true/false as value +endif + +" ********************************************** END OF ERROR WARNINGS +" Allowances for JSONP: function call at the beginning of the file, +" parenthesis and semicolon at the end. +" Function name validation based on +" http://stackoverflow.com/questions/2008279/validate-a-javascript-function-name/2008444#2008444 +syn match jsonPadding "\%^[[:blank:]\r\n]*[_$[:alpha:]][_$[:alnum:]]*[[:blank:]\r\n]*(" +syn match jsonPadding ");[[:blank:]\r\n]*\%$" + +" Syntax: Boolean +syn match jsonBoolean /\(true\|false\)\(\_s\+\ze"\)\@!/ + +" Syntax: Null +syn keyword jsonNull null + +" Syntax: Braces +syn region jsonFold matchgroup=jsonBraces start="{" end=/}\(\_s\+\ze\("\|{\)\)\@!/ transparent fold +syn region jsonFold matchgroup=jsonBraces start="\[" end=/]\(\_s\+\ze"\)\@!/ transparent fold + +" Define the default highlighting. +if version >= 508 || !exists("did_json_syn_inits") + hi def link jsonPadding Operator + hi def link jsonString String + hi def link jsonTest Label + hi def link jsonEscape Special + hi def link jsonNumber Delimiter + hi def link jsonBraces Delimiter + hi def link jsonNull Function + hi def link jsonBoolean Delimiter + hi def link jsonKeyword Label + + if (!exists("g:vim_json_warnings") || g:vim_json_warnings==1) + hi def link jsonNumError Error + hi def link jsonCommentError Error + hi def link jsonSemicolonError Error + hi def link jsonTrailingCommaError Error + hi def link jsonMissingCommaError Error + hi def link jsonStringSQError Error + hi def link jsonNoQuotesError Error + hi def link jsonTripleQuotesError Error + endif + hi def link jsonQuote Quote + hi def link jsonNoise Noise +endif + +let b:current_syntax = "json" +if main_syntax == 'json' + unlet main_syntax +endif + +" Vim settings +" vim: ts=8 fdm=marker + +" MIT License +" Copyright (c) 2013, Jeroen Ruigrok van der Werven, Eli Parra +"Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the Software), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: +"The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. +"THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +"See https://twitter.com/elzr/status/294964017926119424 diff --git a/base/vim/undo-dir/%home%adam%dotfiles%dotfiles%base.yaml b/base/vim/undo-dir/%home%adam%dotfiles%dotfiles%base.yaml new file mode 100644 index 0000000..ada8e68 Binary files /dev/null and b/base/vim/undo-dir/%home%adam%dotfiles%dotfiles%base.yaml differ diff --git a/base/vimrc b/base/vimrc new file mode 100644 index 0000000..3a4b16a --- /dev/null +++ b/base/vimrc @@ -0,0 +1,239 @@ +set nocompatible +set encoding=utf-8 + +set modelines=0 " for security + +set mouse="" +set backspace=indent,eol,start + +au FocusLost * :wa + +" Leader ====---- +nnoremap ,, , +let mapleader="," +nnoremap ; ; +nnoremap ; : + +" Highlighting ====---- +syntax on +filetype plugin indent on + +set t_Co=256 " force enable 256-color mode. +if &t_Co >= 256 || has("gui_running") + let base16colorspace=256 + colorscheme base16-default-dark +endif +if &t_Co > 2 || has("gui_running") + syntax on +endif + +" Indentation ====---- +set shiftwidth=2 +set tabstop=2 +set expandtab +set shiftround " use multiple of shiftwidth with '<' and '>' +set autoindent +set copyindent " copy the previous line's indentation + +xnoremap < >gv + +" Search ====---- +set incsearch +set hlsearch +set wrapscan +set ignorecase " ignore case when searching +set smartcase " ignore case if search pattern is all lowercase, + " case-sensitive otherwise + +nnoremap :noh + +" Case insensitive +nmap * /\<=expand('')\> +nmap # ?\<=expand('')\> + +set showmatch +nnoremap % +vnoremap % + +" Screen ====---- +"set nowrap +set wrap +"set textwidth=79 +"set formatoptions=tqrn1 +set colorcolumn=85 +set ruler +set number +set relativenumber +set laststatus=2 +set shortmess=aoOstTWAI +set cursorline +"set showmode +set showcmd +set title " change the terminal's title +set scrolloff=3 + +set visualbell " don't beep +set noerrorbells " don't beep + +set list +set listchars=tab:»\ ,extends:›,precedes:‹,nbsp:·,trail:· +"autocmd filetype html,xml set listchars-=tab:>. + +set wildmenu +set wildmode=longest:full,full +set wildignore=*.swp,*.bak,*.pyc,*.class + +set ttyfast + +hi ColorColumn ctermbg=18 +hi Folded ctermbg=0 ctermfg=12 + +" Stop using arrow keys ====---- +noremap +noremap +noremap +noremap + +" nnoremap j gj +" nnoremap k gk + +" Splits ====---- +nnoremap w vl +nnoremap h +nnoremap j +nnoremap k +nnoremap l + +" History ====---- +set history=1000 " remember more commands and search history +set undolevels=1000 " use many muchos levels of undo + +if !isdirectory($HOME."/.vim") + call mkdir($HOME."/.vim", "", 0770) +endif +if !isdirectory($HOME."/.vim/undo-dir") + call mkdir($HOME."/.vim/undo-dir", "", 0700) +endif +set undodir=~/.vim/undo-dir +set undofile +" !!!! ADD THIS TO CRONTAB +" 43 0 * * 3 find /home/adam/.vim/undo-dir -type f -mtime +90 -delete + +set nobackup +set noswapfile " Note: swap helps large files. + +" Custom mappings ====---- + +" Quickly edit/reload the vimrc file +nnoremap ve :tabe $MYVIMRC +nnoremap vs :so $MYVIMRC + +nnoremap :set invpaste paste? +set pastetoggle= + +nnoremap W :%s/\s\+$//:let @/='' +nnoremap ft Vatzf +nnoremap S ?{jV/^\s*\}?$k:sort:noh +nnoremap q gqip +nnoremap vp V`] +nnoremap h :syntax sync fromstart +nnoremap l :nohlsearch:diffupdate:syntax sync fromstart +nnoremap [ :put! =repeat(nr2char(10), v:count1)'[ +nnoremap ] :put =repeat(nr2char(10), v:count1) + +noremap y "*y +noremap yy "*Y +noremap p :set paste:put *:set nopaste + +noremap + :s/^\s*/&\/\//:noh +noremap - :s/^\(\s*\)\/\//\1/:noh + +vnoremap Q gq +nnoremap Q gqap + +cnoremap w!! w !sudo tee % >/dev/null + +" helper function to toggle hex mode +function! ToggleHex() + " hex mode should be considered a read-only operation + " save values for modified and read-only for restoration later, + " and clear the read-only flag for now + let l:modified=&mod + let l:oldreadonly=&readonly + let &readonly=0 + let l:oldmodifiable=&modifiable + let &modifiable=1 + if !exists("b:editHex") || !b:editHex + " save old options + let b:oldft=&ft + let b:oldbin=&bin + " set new options + setlocal binary " make sure it overrides any textwidth, etc. + let &ft="xxd" + " set status + let b:editHex=1 + " switch to hex editor + %!xxd + else + " restore old options + let &ft=b:oldft + if !b:oldbin + setlocal nobinary + endif + " set status + let b:editHex=0 + " return to normal editing + %!xxd -r + endif + " restore values for modified and read only state + let &mod=l:modified + let &readonly=l:oldreadonly + let &modifiable=l:oldmodifiable +endfunction + +command! -bar Hexmode call ToggleHex() +nnoremap H :Hexmode + +function! NumberToggle() + if(&relativenumber == 1) + set norelativenumber + else + set relativenumber + endif +endfunc + +nnoremap N :call NumberToggle() +"autocmd InsertEnter * :set norelativenumber +"autocmd InsertLeave * :set relativenumber + +" Custom functions ====---- + +if filereadable(expand("~/.vimrc.local")) + source ~/.vimrc.local +endif + +function! SetLocalOptions(fname) + let dirname = fnamemodify(a:fname, ":p:h") + while "/" != dirname + let lvimrc = dirname . "/.vimrc.local" + if filereadable(lvimrc) + execute "source " . lvimrc + break + endif + let dirname = fnamemodify(dirname, ":p:h:h") + endwhile +endfunction + +au BufNewFile,BufRead * call SetLocalOptions(bufname("%")) + + +" To move elsewhere ====---- +au BufNewFile,BufRead *.less set filetype=less +autocmd! BufWritePost $MYVIMRC source $MYVIMRC +packadd! matchit +cnoremap +cnoremap +autocmd! BufRead,BufNewFile *.md set filetype=markdown +autocmd! BufRead,BufNewFile *.md set spell +vnoremap p "_dP diff --git a/base/zsh/aliases.zsh b/base/zsh/aliases.zsh new file mode 100644 index 0000000..21544af --- /dev/null +++ b/base/zsh/aliases.zsh @@ -0,0 +1,31 @@ +# UTILITY + +alias ls="ls --color=auto" +alias less='less -R' +alias grep='grep --color=auto' +alias ..='cd ../' + +alias sudoe="sudo -E" +alias svim="sudo -E vim" +alias svimdiff="sudo -E vimdiff" + +# SAFETY + +alias cp="cp -i" +alias mv="mv -i" + +# GIT + +alias gd='git diff' +alias gco='git checkout' +alias gs='git status --short' +alias gl='git pull' +alias gp='git push' +alias gpp='git pull; git push' +alias gwc='git whatchanged -p --abbrev-commit --pretty=medium' + +# POWER + +alias reboot="systemctl reboot" +alias shutdown="systemctl poweroff" +alias poweroff="systemctl poweroff" diff --git a/base/zsh/async b/base/zsh/async new file mode 100644 index 0000000..d11a99a --- /dev/null +++ b/base/zsh/async @@ -0,0 +1,493 @@ +#!/usr/bin/env zsh + +# +# zsh-async +# +# version: 1.5.0 +# author: Mathias Fredriksson +# url: https://github.com/mafredri/zsh-async +# + +# Produce debug output from zsh-async when set to 1. +ASYNC_DEBUG=${ASYNC_DEBUG:-0} + +# Wrapper for jobs executed by the async worker, gives output in parseable format with execution time +_async_job() { + # Disable xtrace as it would mangle the output. + setopt localoptions noxtrace + + # Store start time as double precision (+E disables scientific notation) + float -F duration=$EPOCHREALTIME + + # Run the command and capture both stdout (`eval`) and stderr (`cat`) in + # separate subshells. When the command is complete, we grab write lock + # (mutex token) and output everything except stderr inside the command + # block, after the command block has completed, the stdin for `cat` is + # closed, causing stderr to be appended with a $'\0' at the end to mark the + # end of output from this job. + local stdout stderr ret tok + { + stdout=$(eval "$@") + ret=$? + duration=$(( EPOCHREALTIME - duration )) # Calculate duration. + + # Grab mutex lock, stalls until token is available. + read -r -k 1 -p tok || exit 1 + + # Return output ( ). + print -r -n - ${(q)1} $ret ${(q)stdout} $duration + } 2> >(stderr=$(cat) && print -r -n - " "${(q)stderr}$'\0') + + # Unlock mutex by inserting a token. + print -n -p $tok +} + +# The background worker manages all tasks and runs them without interfering with other processes +_async_worker() { + # Reset all options to defaults inside async worker. + emulate -R zsh + + # Make sure monitor is unset to avoid printing the + # pids of child processes. + unsetopt monitor + + # Redirect stderr to `/dev/null` in case unforseen errors produced by the + # worker. For example: `fork failed: resource temporarily unavailable`. + # Some older versions of zsh might also print malloc errors (know to happen + # on at least zsh 5.0.2 and 5.0.8) likely due to kill signals. + exec 2>/dev/null + + # When a zpty is deleted (using -d) all the zpty instances created before + # the one being deleted receive a SIGHUP, unless we catch it, the async + # worker would simply exit (stop working) even though visible in the list + # of zpty's (zpty -L). + TRAPHUP() { + return 0 # Return 0, indicating signal was handled. + } + + local -A storage + local unique=0 + local notify_parent=0 + local parent_pid=0 + local coproc_pid=0 + local processing=0 + + local -a zsh_hooks zsh_hook_functions + zsh_hooks=(chpwd periodic precmd preexec zshexit zshaddhistory) + zsh_hook_functions=(${^zsh_hooks}_functions) + unfunction $zsh_hooks &>/dev/null # Deactivate all zsh hooks inside the worker. + unset $zsh_hook_functions # And hooks with registered functions. + unset zsh_hooks zsh_hook_functions # Cleanup. + + child_exit() { + local -a pids + pids=(${${(v)jobstates##*:*:}%\=*}) + + # If coproc (cat) is the only child running, we close it to avoid + # leaving it running indefinitely and cluttering the process tree. + if (( ! processing )) && [[ $#pids = 1 ]] && [[ $coproc_pid = $pids[1] ]]; then + coproc : + coproc_pid=0 + fi + + # On older version of zsh (pre 5.2) we notify the parent through a + # SIGWINCH signal because `zpty` did not return a file descriptor (fd) + # prior to that. + if (( notify_parent )); then + # We use SIGWINCH for compatibility with older versions of zsh + # (pre 5.1.1) where other signals (INFO, ALRM, USR1, etc.) could + # cause a deadlock in the shell under certain circumstances. + kill -WINCH $parent_pid + fi + } + + # Register a SIGCHLD trap to handle the completion of child processes. + trap child_exit CHLD + + # Process option parameters passed to worker + while getopts "np:u" opt; do + case $opt in + n) notify_parent=1;; + p) parent_pid=$OPTARG;; + u) unique=1;; + esac + done + + killjobs() { + local tok + local -a pids + pids=(${${(v)jobstates##*:*:}%\=*}) + + # No need to send SIGHUP if no jobs are running. + (( $#pids == 0 )) && continue + (( $#pids == 1 )) && [[ $coproc_pid = $pids[1] ]] && continue + + # Grab lock to prevent half-written output in case a child + # process is in the middle of writing to stdin during kill. + (( coproc_pid )) && read -r -k 1 -p tok + + kill -HUP -$$ # Send to entire process group. + coproc : # Quit coproc. + coproc_pid=0 # Reset pid. + } + + local request + local -a cmd + while :; do + # Wait for jobs sent by async_job. + read -r -d $'\0' request || { + # Since we handle SIGHUP above (and thus do not know when `zpty -d`) + # occurs, a failure to read probably indicates that stdin has + # closed. This is why we propagate the signal to all children and + # exit manually. + kill -HUP -$$ # Send SIGHUP to all jobs. + exit 0 + } + + # Check for non-job commands sent to worker + case $request in + _unset_trap) notify_parent=0; continue;; + _killjobs) killjobs; continue;; + esac + + # Parse the request using shell parsing (z) to allow commands + # to be parsed from single strings and multi-args alike. + cmd=("${(z)request}") + + # Name of the job (first argument). + local job=$cmd[1] + + # If worker should perform unique jobs + if (( unique )); then + # Check if a previous job is still running, if yes, let it finnish + for pid in ${${(v)jobstates##*:*:}%\=*}; do + if [[ ${storage[$job]} == $pid ]]; then + continue 2 + fi + done + fi + + # Guard against closing coproc from trap before command has started. + processing=1 + + # Because we close the coproc after the last job has completed, we must + # recreate it when there are no other jobs running. + if (( ! coproc_pid )); then + # Use coproc as a mutex for synchronized output between children. + coproc cat + coproc_pid="$!" + # Insert token into coproc + print -n -p "t" + fi + + # Run job in background, completed jobs are printed to stdout. + _async_job $cmd & + # Store pid because zsh job manager is extremely unflexible (show jobname as non-unique '$job')... + storage[$job]="$!" + + processing=0 # Disable guard. + done +} + +# +# Get results from finnished jobs and pass it to the to callback function. This is the only way to reliably return the +# job name, return code, output and execution time and with minimal effort. +# +# usage: +# async_process_results +# +# callback_function is called with the following parameters: +# $1 = job name, e.g. the function passed to async_job +# $2 = return code +# $3 = resulting stdout from execution +# $4 = execution time, floating point e.g. 2.05 seconds +# $5 = resulting stderr from execution +# +async_process_results() { + setopt localoptions noshwordsplit + + local worker=$1 + local callback=$2 + local caller=$3 + local -a items + local null=$'\0' data + integer -l len pos num_processed + + typeset -gA ASYNC_PROCESS_BUFFER + + # Read output from zpty and parse it if available. + while zpty -r -t $worker data 2>/dev/null; do + ASYNC_PROCESS_BUFFER[$worker]+=$data + len=${#ASYNC_PROCESS_BUFFER[$worker]} + pos=${ASYNC_PROCESS_BUFFER[$worker][(i)$null]} # Get index of NULL-character (delimiter). + + # Keep going until we find a NULL-character. + if (( ! len )) || (( pos > len )); then + continue + fi + + while (( pos <= len )); do + # Take the content from the beginning, until the NULL-character and + # perform shell parsing (z) and unquoting (Q) as an array (@). + items=("${(@Q)${(z)ASYNC_PROCESS_BUFFER[$worker][1,$pos-1]}}") + + # Remove the extracted items from the buffer. + ASYNC_PROCESS_BUFFER[$worker]=${ASYNC_PROCESS_BUFFER[$worker][$pos+1,$len]} + + if (( $#items == 5 )); then + $callback "${(@)items}" # Send all parsed items to the callback. + else + # In case of corrupt data, invoke callback with *async* as job + # name, non-zero exit status and an error message on stderr. + $callback "async" 1 "" 0 "$0:$LINENO: error: bad format, got ${#items} items (${(@q)items})" + fi + + (( num_processed++ )) + + len=${#ASYNC_PROCESS_BUFFER[$worker]} + if (( len > 1 )); then + pos=${ASYNC_PROCESS_BUFFER[$worker][(i)$null]} # Get index of NULL-character (delimiter). + fi + done + done + + (( num_processed )) && return 0 + + # Avoid printing exit value when `setopt printexitvalue` is active.` + [[ $caller = trap || $caller = watcher ]] && return 0 + + # No results were processed + return 1 +} + +# Watch worker for output +_async_zle_watcher() { + setopt localoptions noshwordsplit + typeset -gA ASYNC_PTYS ASYNC_CALLBACKS + local worker=$ASYNC_PTYS[$1] + local callback=$ASYNC_CALLBACKS[$worker] + + if [[ -n $callback ]]; then + async_process_results $worker $callback watcher + fi +} + +# +# Start a new asynchronous job on specified worker, assumes the worker is running. +# +# usage: +# async_job [] +# +async_job() { + setopt localoptions noshwordsplit + + local worker=$1; shift + + local -a cmd + cmd=("$@") + if (( $#cmd > 1 )); then + cmd=(${(q)cmd}) # Quote special characters in multi argument commands. + fi + + zpty -w $worker $cmd$'\0' +} + +# This function traps notification signals and calls all registered callbacks +_async_notify_trap() { + setopt localoptions noshwordsplit + + for k in ${(k)ASYNC_CALLBACKS}; do + async_process_results $k ${ASYNC_CALLBACKS[$k]} trap + done +} + +# +# Register a callback for completed jobs. As soon as a job is finnished, async_process_results will be called with the +# specified callback function. This requires that a worker is initialized with the -n (notify) option. +# +# usage: +# async_register_callback +# +async_register_callback() { + setopt localoptions noshwordsplit nolocaltraps + + typeset -gA ASYNC_CALLBACKS + local worker=$1; shift + + ASYNC_CALLBACKS[$worker]="$*" + + # Enable trap when the ZLE watcher is unavailable, allows + # workers to notify (via -n) when a job is done. + if [[ ! -o interactive ]] || [[ ! -o zle ]]; then + trap '_async_notify_trap' WINCH + fi +} + +# +# Unregister the callback for a specific worker. +# +# usage: +# async_unregister_callback +# +async_unregister_callback() { + typeset -gA ASYNC_CALLBACKS + + unset "ASYNC_CALLBACKS[$1]" +} + +# +# Flush all current jobs running on a worker. This will terminate any and all running processes under the worker, use +# with caution. +# +# usage: +# async_flush_jobs +# +async_flush_jobs() { + setopt localoptions noshwordsplit + + local worker=$1; shift + + # Check if the worker exists + zpty -t $worker &>/dev/null || return 1 + + # Send kill command to worker + async_job $worker "_killjobs" + + # Clear the zpty buffer. + local junk + if zpty -r -t $worker junk '*'; then + (( ASYNC_DEBUG )) && print -n "async_flush_jobs $worker: ${(V)junk}" + while zpty -r -t $worker junk '*'; do + (( ASYNC_DEBUG )) && print -n "${(V)junk}" + done + (( ASYNC_DEBUG )) && print + fi + + # Finally, clear the process buffer in case of partially parsed responses. + typeset -gA ASYNC_PROCESS_BUFFER + unset "ASYNC_PROCESS_BUFFER[$worker]" +} + +# +# Start a new async worker with optional parameters, a worker can be told to only run unique tasks and to notify a +# process when tasks are complete. +# +# usage: +# async_start_worker [-u] [-n] [-p ] +# +# opts: +# -u unique (only unique job names can run) +# -n notify through SIGWINCH signal +# -p pid to notify (defaults to current pid) +# +async_start_worker() { + setopt localoptions noshwordsplit + + local worker=$1; shift + zpty -t $worker &>/dev/null && return + + typeset -gA ASYNC_PTYS + typeset -h REPLY + typeset has_xtrace=0 + + # Make sure async worker is started without xtrace + # (the trace output interferes with the worker). + [[ -o xtrace ]] && { + has_xtrace=1 + unsetopt xtrace + } + + if (( ! ASYNC_ZPTY_RETURNS_FD )) && [[ -o interactive ]] && [[ -o zle ]]; then + # When zpty doesn't return a file descriptor (on older versions of zsh) + # we try to guess it anyway. + integer -l zptyfd + exec {zptyfd}>&1 # Open a new file descriptor (above 10). + exec {zptyfd}>&- # Close it so it's free to be used by zpty. + fi + + zpty -b $worker _async_worker -p $$ $@ || { + async_stop_worker $worker + return 1 + } + + # Re-enable it if it was enabled, for debugging. + (( has_xtrace )) && setopt xtrace + + if [[ $ZSH_VERSION < 5.0.8 ]]; then + # For ZSH versions older than 5.0.8 we delay a bit to give + # time for the worker to start before issuing commands, + # otherwise it will not be ready to receive them. + sleep 0.001 + fi + + if [[ -o interactive ]] && [[ -o zle ]]; then + if (( ! ASYNC_ZPTY_RETURNS_FD )); then + REPLY=$zptyfd # Use the guessed value for the file desciptor. + fi + + ASYNC_PTYS[$REPLY]=$worker # Map the file desciptor to the worker. + zle -F $REPLY _async_zle_watcher # Register the ZLE handler. + + # Disable trap in favor of ZLE handler when notify is enabled (-n). + async_job $worker _unset_trap + fi +} + +# +# Stop one or multiple workers that are running, all unfetched and incomplete work will be lost. +# +# usage: +# async_stop_worker [] +# +async_stop_worker() { + setopt localoptions noshwordsplit + + local ret=0 + for worker in $@; do + # Find and unregister the zle handler for the worker + for k v in ${(@kv)ASYNC_PTYS}; do + if [[ $v == $worker ]]; then + zle -F $k + unset "ASYNC_PTYS[$k]" + fi + done + async_unregister_callback $worker + zpty -d $worker 2>/dev/null || ret=$? + + # Clear any partial buffers. + typeset -gA ASYNC_PROCESS_BUFFER + unset "ASYNC_PROCESS_BUFFER[$worker]" + done + + return $ret +} + +# +# Initialize the required modules for zsh-async. To be called before using the zsh-async library. +# +# usage: +# async_init +# +async_init() { + (( ASYNC_INIT_DONE )) && return + ASYNC_INIT_DONE=1 + + zmodload zsh/zpty + zmodload zsh/datetime + + # Check if zsh/zpty returns a file descriptor or not, + # shell must also be interactive with zle enabled. + ASYNC_ZPTY_RETURNS_FD=0 + [[ -o interactive ]] && [[ -o zle ]] && { + typeset -h REPLY + zpty _async_test : + (( REPLY )) && ASYNC_ZPTY_RETURNS_FD=1 + zpty -d _async_test + } +} + +async() { + async_init +} + +async "$@" diff --git a/base/zsh/colors.zsh b/base/zsh/colors.zsh new file mode 100644 index 0000000..9c8e32b --- /dev/null +++ b/base/zsh/colors.zsh @@ -0,0 +1,3 @@ +export CLICOLOR=1 + +source `dirname $0`/fast-syntax-highlighting/fast-syntax-highlighting.plugin.zsh diff --git a/base/zsh/completion.zsh b/base/zsh/completion.zsh new file mode 100644 index 0000000..f9e452d --- /dev/null +++ b/base/zsh/completion.zsh @@ -0,0 +1,81 @@ +autoload -U compinit +compinit + +setopt extendedglob +setopt NO_NOMATCH + +unsetopt menu_complete # do not autoselect the first completion entry +unsetopt flowcontrol +setopt auto_menu # show completion menu on succesive tab press +setopt complete_in_word +setopt always_to_end + +WORDCHARS='' + +zmodload -i zsh/complist + +## case-insensitive (all),partial-word and then substring completion +if [ "x$CASE_SENSITIVE" = "xtrue" ]; then + zstyle ':completion:*' matcher-list 'r:|[._-]=* r:|=*' 'l:|=* r:|=*' + unset CASE_SENSITIVE +else + zstyle ':completion:*' matcher-list 'm:{a-zA-Z}={A-Za-z}' 'r:|[._-]=* r:|=*' 'l:|=* r:|=*' +fi + +zstyle ':completion:*' list-colors '' + +# should this be in keybindings? +bindkey -M menuselect '^o' accept-and-infer-next-history + +zstyle ':completion:*:*:*:*:*' menu select +zstyle ':completion:*:*:kill:*:processes' list-colors '=(#b) #([0-9]#) ([0-9a-z-]#)*=01;34=0=01' +zstyle ':completion:*:*:*:*:processes' command "ps -u `whoami` -o pid,user,comm -w -w" + +# disable named-directories autocompletion +zstyle ':completion:*:cd:*' tag-order local-directories directory-stack path-directories +cdpath=(.) + +# use /etc/hosts and known_hosts for hostname completion +[ -r /etc/ssh/ssh_known_hosts ] && _global_ssh_hosts=(${${${${(f)"$( "$HOME/.bin/nroff" </dev/null 2>&1; then + eval "$(fasd --init zsh-hook zsh-ccomp zsh-ccomp-install zsh-wcomp zsh-wcomp-install posix-alias)" +fi diff --git a/base/zsh/fast-syntax-highlighting/fast-highlight b/base/zsh/fast-syntax-highlighting/fast-highlight new file mode 100644 index 0000000..70c8867 --- /dev/null +++ b/base/zsh/fast-syntax-highlighting/fast-highlight @@ -0,0 +1,715 @@ +# ------------------------------------------------------------------------------------------------- +# Copyright (c) 2010-2016 zsh-syntax-highlighting contributors +# Copyright (c) 2016-2017 Sebastian Gniazdowski (modifications) +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, are permitted +# provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, this list of conditions +# and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright notice, this list of +# conditions and the following disclaimer in the documentation and/or other materials provided +# with the distribution. +# * Neither the name of the zsh-syntax-highlighting contributors nor the names of its contributors +# may be used to endorse or promote products derived from this software without specific prior +# written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR +# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +# FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER +# IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT +# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# ------------------------------------------------------------------------------------------------- + +typeset -gA __fast_highlight_main__command_type_cache + +# Define default styles. You can set this after loading the plugin in +# Zshrc and use 256 via numbers, like: fg=150 +typeset -gA FAST_HIGHLIGHT_STYLES +: ${FAST_HIGHLIGHT_STYLES[default]:=none} +: ${FAST_HIGHLIGHT_STYLES[unknown-token]:=fg=red,bold} +: ${FAST_HIGHLIGHT_STYLES[reserved-word]:=fg=yellow} +: ${FAST_HIGHLIGHT_STYLES[alias]:=fg=green} +: ${FAST_HIGHLIGHT_STYLES[suffix-alias]:=fg=green} +: ${FAST_HIGHLIGHT_STYLES[builtin]:=fg=green} +: ${FAST_HIGHLIGHT_STYLES[function]:=fg=green} +: ${FAST_HIGHLIGHT_STYLES[command]:=fg=green} +: ${FAST_HIGHLIGHT_STYLES[precommand]:=fg=green} +: ${FAST_HIGHLIGHT_STYLES[commandseparator]:=none} +: ${FAST_HIGHLIGHT_STYLES[hashed-command]:=fg=green} +: ${FAST_HIGHLIGHT_STYLES[path]:=fg=magenta} +: ${FAST_HIGHLIGHT_STYLES[path_pathseparator]:=} +: ${FAST_HIGHLIGHT_STYLES[globbing]:=fg=blue,bold} +: ${FAST_HIGHLIGHT_STYLES[history-expansion]:=fg=blue,bold} +: ${FAST_HIGHLIGHT_STYLES[single-hyphen-option]:=fg=cyan} +: ${FAST_HIGHLIGHT_STYLES[double-hyphen-option]:=fg=cyan} +: ${FAST_HIGHLIGHT_STYLES[back-quoted-argument]:=none} +: ${FAST_HIGHLIGHT_STYLES[single-quoted-argument]:=fg=yellow} +: ${FAST_HIGHLIGHT_STYLES[double-quoted-argument]:=fg=yellow} +: ${FAST_HIGHLIGHT_STYLES[dollar-quoted-argument]:=fg=yellow} +: ${FAST_HIGHLIGHT_STYLES[back-or-dollar-double-quoted-argument]:=fg=cyan} +: ${FAST_HIGHLIGHT_STYLES[back-dollar-quoted-argument]:=fg=cyan} +: ${FAST_HIGHLIGHT_STYLES[assign]:=none} +: ${FAST_HIGHLIGHT_STYLES[redirection]:=none} +: ${FAST_HIGHLIGHT_STYLES[comment]:=fg=black,bold} +: ${FAST_HIGHLIGHT_STYLES[variable]:=none} + + +typeset -gA __FAST_HIGHLIGHT_TOKEN_TYPES + +__FAST_HIGHLIGHT_TOKEN_TYPES=( + + # Precommand + + 'builtin' 1 + 'command' 1 + 'exec' 1 + 'nocorrect' 1 + 'noglob' 1 + 'pkexec' 1 # immune to #121 because it's usually not passed --option flags + + # Control flow + # Tokens that, at (naively-determined) "command position", are followed by + # a de jure command position. All of these are reserved words. + + $'\x7b' 2 # block + $'\x28' 2 # subshell + '()' 2 # anonymous function + 'while' 2 + 'until' 2 + 'if' 2 + 'then' 2 + 'elif' 2 + 'else' 2 + 'do' 2 + 'time' 2 + 'coproc' 2 + '!' 2 # reserved word; unrelated to $histchars[1] + + # Command separators + + '|' 3 + '||' 3 + ';' 3 + '&' 3 + '&&' 3 + '|&' 3 + '&!' 3 + '&|' 3 + # ### 'case' syntax, but followed by a pattern, not by a command + # ';;' ';&' ';|' +) + +# A hash instead of multiple globals +typeset -gA FAST_HIGHLIGHT + +# Get the type of a command. +# +# Uses the zsh/parameter module if available to avoid forks, and a +# wrapper around 'type -w' as fallback. +# +# Takes a single argument. +# +# The result will be stored in REPLY. +-fast-highlight-main-type() { + REPLY=$__fast_highlight_main__command_type_cache[(e)$1] + [[ -z "$REPLY" ]] && { + + if zmodload -e zsh/parameter; then + if (( $+aliases[(e)$1] )); then + REPLY=alias + elif (( $+functions[(e)$1] )); then + REPLY=function + elif (( $+builtins[(e)$1] )); then + REPLY=builtin + elif (( $+commands[(e)$1] )); then + REPLY=command + elif (( $+saliases[(e)${1##*.}] )); then + REPLY='suffix alias' + elif (( $reswords[(Ie)$1] )); then + REPLY=reserved + # zsh 5.2 and older have a bug whereby running 'type -w ./sudo' implicitly + # runs 'hash ./sudo=/usr/local/bin/./sudo' (assuming /usr/local/bin/sudo + # exists and is in $PATH). Avoid triggering the bug, at the expense of + # falling through to the $() below, incurring a fork. (Issue #354.) + # + # The second disjunct mimics the isrelative() C call from the zsh bug. + elif [[ $1 != */* || "${+ZSH_ARGZERO}" = "1" ]] && ! builtin type -w -- $1 >/dev/null 2>&1; then + REPLY=none + fi + fi + + [[ -z "$REPLY" ]] && REPLY="${$(LC_ALL=C builtin type -w -- $1 2>/dev/null)##*: }" + + [[ "$REPLY" = "none" ]] && { + [[ -d "$1" ]] && REPLY="dirpath" || { + for cdpath_dir in $cdpath; do + [[ -d "$cdpath_dir/$1" ]] && { REPLY="dirpath"; break; } + done + } + } + + __fast_highlight_main__command_type_cache[(e)$1]=$REPLY + + } +} + +# Below are variables that must be defined in outer +# scope so that they are reachable in *-process() +-fast-highlight-fill-option-variables() { + if [[ -o ignore_braces ]] || eval '[[ -o ignore_close_braces ]] 2>/dev/null'; then + FAST_HIGHLIGHT[right_brace_is_recognised_everywhere]=0 + else + FAST_HIGHLIGHT[right_brace_is_recognised_everywhere]=1 + fi + + if [[ -o path_dirs ]]; then + FAST_HIGHLIGHT[path_dirs_was_set]=1 + else + FAST_HIGHLIGHT[path_dirs_was_set]=0 + fi + + if [[ -o multi_func_def ]]; then + FAST_HIGHLIGHT[multi_func_def]=1 + else + FAST_HIGHLIGHT[multi_func_def]=0 + fi + + if [[ -o interactive_comments ]]; then + FAST_HIGHLIGHT[ointeractive_comments]=1 + else + FAST_HIGHLIGHT[ointeractive_comments]=0 + fi +} + +# Main syntax highlighting function. +-fast-highlight-process() +{ + emulate -L zsh + setopt extendedglob bareglobqual nonomatch noksharrays + + [[ $CONTEXT == "select" ]] && return 1 + [[ ${#BUFFER} -gt 10000 ]] && return 1 # Limit based on n-history length + + (( FAST_HIGHLIGHT[path_dirs_was_set] )) && setopt PATH_DIRS + (( FAST_HIGHLIGHT[ointeractive_comments] )) && local interactive_comments= # _set_ to empty + + # Variable declarations and initializations + # in_array_assignment true between 'a=(' and the matching ')' + # braces_stack: "R" for round, "Q" for square, "Y" for curly + # mybuf, cdpath_dir are used in sub-functions + local start_pos=0 end_pos start end highlight_glob=1 arg style in_array_assignment=0 MATCH expanded_path braces_stack buf="$PREBUFFER$BUFFER" mybuf cdpath_dir cur_cmd alias_target + # arg_type can be 0, 1, 2 or 3, i.e. precommand, control flow, command separator + # idx and end_idx are used in sub-functions + # for this_word and next_word look below at commented integers and at state machine description + integer arg_type=0 MBEGIN MEND in_redirection len=${#buf} already_added offset idx end_idx this_word=1 next_word=0 insane_alias pos + local -a match mbegin mend + + # integer BIT_start=1 BIT_regular=2 BIT_sudo_opt=4 BIT_sudo_arg=8 BIT_always=16 + + # State machine + # + # The states are: + # - :start: Command word + # - :sudo_opt: A leading-dash option to sudo (such as "-u" or "-i") + # - :sudo_arg: The argument to a sudo leading-dash option that takes one, + # when given as a separate word; i.e., "foo" in "-u foo" (two + # words) but not in "-ufoo" (one word). + # - :regular: "Not a command word", and command delimiters are permitted. + # Mainly used to detect premature termination of commands. + # - :always: The word 'always' in the «{ foo } always { bar }» syntax. + # + # When the kind of a word is not yet known, $this_word / $next_word may contain + # multiple states. For example, after "sudo -i", the next word may be either + # another --flag or a command name, hence the state would include both :start: + # and :sudo_opt:. + # + # The tokens are always added with both leading and trailing colons to serve as + # word delimiters (an improvised array); [[ $x == *:foo:* ]] and x=${x//:foo:/} + # will DTRT regardless of how many elements or repetitions $x has.. + # + # Handling of redirections: upon seeing a redirection token, we must stall + # the current state --- that is, the value of $this_word --- for two iterations + # (one for the redirection operator, one for the word following it representing + # the redirection target). Therefore, we set $in_redirection to 2 upon seeing a + # redirection operator, decrement it each iteration, and stall the current state + # when it is non-zero. Thus, upon reaching the next word (the one that follows + # the redirection operator and target), $this_word will still contain values + # appropriate for the word immediately following the word that preceded the + # redirection operator. + # + # The "the previous word was a redirection operator" state is not communicated + # to the next iteration via $next_word/$this_word as usual, but via + # $in_redirection. The value of $next_word from the iteration that processed + # the operator is discarded. + # + + # Processing buffer + local proc_buf="$buf" needle + for arg in ${interactive_comments-${(z)buf}} \ + ${interactive_comments+${(zZ+c+)buf}}; do + # Initialize $next_word to its default value? + (( in_redirection )) && (( --in_redirection )) + (( in_redirection == 0 )) && next_word=2 # else Stall $next_word. + + # Initialize per-"simple command" [zshmisc(1)] variables: + # + # $already_added (see next paragraph) + # $style how to highlight $arg + # $in_array_assignment boolean flag for "between '(' and ')' of array assignment" + # $highlight_glob boolean flag for "'noglob' is in effect" + # + # $already_added is set to 1 to disable adding an entry to region_highlight + # for this iteration. Currently, that is done for "" and $'' strings, + # which add the entry early so escape sequences within the string override + # the string's color. + already_added=0 + style=unknown-token + if (( this_word & 1 )); then + in_array_assignment=0 + [[ $arg == 'noglob' ]] && highlight_glob=0 + fi + + # Compute the new $start_pos and $end_pos, skipping over whitespace in $buf. + if [[ $arg == ';' ]] ; then + # We're looking for either a semicolon or a newline, whichever comes + # first. Both of these are rendered as a ";" (SEPER) by the ${(z)..} + # flag. + # + # We can't use the (Z+n+) flag because that elides the end-of-command + # token altogether, so 'echo foo\necho bar' (two commands) becomes + # indistinguishable from 'echo foo echo bar' (one command with three + # words for arguments). + needle=$'[;\n]' + offset=$(( ${proc_buf[(i)$needle]} - 1 )) + (( start_pos += offset )) + (( end_pos = start_pos + $#arg )) + + # Do not run default code for case when there is a new line + # It shouldn't be treated as ';', i.e. shouldn't be highlighted + # as unknown-token when appears after command-starting arg like "{" + if [[ "${proc_buf[offset+1]}" = $'\n' ]]; then + (( in_array_assignment )) && (( this_word = 2 )) || { (( this_word = 1 )); highlight_glob=1; } + in_redirection=0 + proc_buf="${proc_buf[offset + $#arg + 1,len]}" + start_pos=$end_pos + continue + else + # One more short path – for ';' command separator + (( in_array_assignment )) && (( this_word = 2 )) || { (( this_word = 1 )); highlight_glob=1; } + in_redirection=0 + [[ "${FAST_HIGHLIGHT_STYLES[commandseparator]}" != "none" ]] && (( start=start_pos-${#PREBUFFER}, end=end_pos-${#PREBUFFER}, start >= 0 )) && reply+=("$start $end ${FAST_HIGHLIGHT_STYLES[commandseparator]}") + proc_buf="${proc_buf[offset + $#arg + 1,len]}" + start_pos=$end_pos + continue + fi + + arg_type=3 + else + offset=0 + if [[ "$proc_buf" = (#b)(#s)(([[:space:]]|\\[[:space:]])##)* ]]; then + # The first, outer parenthesis + offset="${mend[1]}" + fi + ((start_pos+=offset)) + ((end_pos=start_pos+${#arg})) + + # No-hit will result in value 0 + arg_type=${__FAST_HIGHLIGHT_TOKEN_TYPES[$arg]} + fi + + proc_buf="${proc_buf[offset + $#arg + 1,len]}" + + # Handle the INTERACTIVE_COMMENTS option. + # + # We use the (Z+c+) flag so the entire comment is presented as one token in $arg. + if [[ -n ${interactive_comments+'set'} && $arg[1] == $histchars[3] ]]; then + if (( this_word & 3 )); then + style=comment + else + style=unknown-token # prematurely terminated + fi + # ADD + (( start=start_pos-${#PREBUFFER}, end=end_pos-${#PREBUFFER}, start >= 0 )) && reply+=("$start $end ${FAST_HIGHLIGHT_STYLES[$style]}") + start_pos=$end_pos + continue + fi + + # Analyse the current word. + if [[ $arg == (<0-9>|)(\<|\>)* ]] && [[ $arg != (\<|\>)$'\x28'* ]]; then + # A '<' or '>', possibly followed by a digit + in_redirection=2 + fi + + # Special-case the first word after 'sudo'. + if (( ! in_redirection )); then + if (( this_word & 4 )) && [[ $arg != -* ]]; then + (( this_word = this_word ^ 4 )) + fi + + # Parse the sudo command line + if (( this_word & 4 )); then + case "$arg" in + # Flag that requires an argument + '-'[Cgprtu]) + (( this_word & 1 )) && (( this_word = this_word ^ 1 )) + (( next_word = 8 )) + ;; + # This prevents misbehavior with sudo -u -otherargument + '-'*) + (( this_word & 1 )) && (( this_word = this_word ^ 1 )) + (( next_word = next_word | 1 )) + (( next_word = next_word | 4 )) + ;; + *) ;; + esac + elif (( this_word & 8 )); then + (( next_word = next_word | 4 )) + (( next_word = next_word | 1 )) + fi + fi + + expanded_path="" + + # The Great Fork: is this a command word? Is this a non-command word? + if (( this_word & 16 )) && [[ $arg == 'always' ]]; then + # try-always construct + style=reserved-word # de facto a reserved word, although not de jure + (( next_word = 1 )) + elif (( this_word & 1 )) && (( in_redirection == 0 )); then # $arg is the command word + cur_cmd="$arg" + if (( arg_type == 1 )); then + style=precommand + elif [[ "$arg" = "sudo" ]]; then + style=precommand + (( next_word & 2 )) && (( next_word = next_word ^ 2 )) + (( next_word = next_word | 4 )) + (( next_word = next_word | 1 )) + else + # Special-case: command word is '$foo', like that, without braces or anything. + # + # That's not entirely correct --- if the parameter's value happens to be a reserved + # word, the parameter expansion will be highlighted as a reserved word --- but that + # incorrectness is outweighed by the usability improvement of permitting the use of + # parameters that refer to commands, functions, and builtins. + if [[ ${arg[1]} == \$ ]] && (( ${+parameters} )) && [[ ${arg:1} = (#m)([a-zA-Z_][a-zA-Z0-9_]#|[0-9]##) ]] && (( ${+parameters[${MATCH}]} )); then + -fast-highlight-main-type ${(P)MATCH} + else + : ${expanded_path::=${(Q)~arg}} + -fast-highlight-main-type $expanded_path + fi + + case $REPLY in + reserved) # reserved word + style=reserved-word + if [[ $arg == $'\x7b' ]]; then + braces_stack='Y'"$braces_stack" + elif [[ $arg == $'\x7d' && $braces_stack[1] == "Y" ]]; then + # We're at command word, so no need to check right_brace_is_recognised_everywhere + braces_stack[1]="" + style=reserved-word + (( next_word = next_word | 16 )) + elif [[ $arg == "[[" ]]; then + braces_stack='A'"$braces_stack" + fi + ;; + 'suffix alias') style=suffix-alias;; + alias) + insane_alias=0 + case $arg in + # Issue #263: aliases with '=' on their LHS. + # + # There are three cases: + # + # - Unsupported, breaks 'alias -L' output, but invokable: + ('='*) :;; + # - Unsupported, not invokable: + (*'='*) insane_alias=1;; + # - The common case: + (*) :;; + esac + if (( insane_alias )); then + style=unknown-token + else + style=alias + zmodload -e zsh/parameter && alias_target=${aliases[$arg]} || alias_target="${"$(alias -- $arg)"#*=}" + [[ ${__FAST_HIGHLIGHT_TOKEN_TYPES[$alias_target]} = "1" && "$arg_type" != "1" ]] && __FAST_HIGHLIGHT_TOKEN_TYPES[$arg]="1" + fi + ;; + builtin) style=builtin;; + function) style=function;; + command) style=command;; + hashed) style=hashed-command;; + dirpath) style=path;; + none) # Assign? + if [[ $arg == [[:alpha:]_][[:alnum:]_]#(|\[[^\]]#\])(|[+])=* ]] || [[ $arg == [0-9]##(|[+])=* ]]; then + style=assign + # Assignment to a scalar parameter or to array + # (For array assignments, the command doesn't start until the ")" token.) + [[ $arg[-1] == '(' ]] && in_array_assignment=1 || (( next_word = next_word | 1 )) + elif [[ $arg[1] = $histchars[1] && -n "${arg[2]}" ]]; then + style=history-expansion + elif [[ $arg[1] == $histchars[2] ]]; then + style=history-expansion + elif (( arg_type == 3 )); then + # This highlights empty commands (semicolon follows nothing) as an error. + # Zsh accepts them, though. + (( this_word & 2 )) && style=commandseparator + elif [[ $arg[1,2] == '((' ]]; then + # Arithmetic evaluation. + # + # Note: prior to zsh-5.1.1-52-g4bed2cf (workers/36669), the ${(z)...} + # splitter would only output the '((' token if the matching '))' had + # been typed. Therefore, under those versions of zsh, BUFFER="(( 42" + # would be highlighted as an error until the matching "))" are typed. + # + # We highlight just the opening parentheses, as a reserved word; this + # is how [[ ... ]] is highlighted, too. + + # ADD + (( start=start_pos-${#PREBUFFER}, end=end_pos-${#PREBUFFER}, start >= 0 )) && reply+=("$start $(( start + 2 )) ${FAST_HIGHLIGHT_STYLES[reserved-word]}") + already_added=1 + # ADD + [[ $arg[-2,-1] == '))' ]] && (( start=start_pos-${#PREBUFFER}, end=end_pos-${#PREBUFFER}, start >= 0 )) && reply+=("$(( end - 2 )) $end ${FAST_HIGHLIGHT_STYLES[reserved-word]}") + elif [[ $arg == '()' ]]; then + # anonymous function + style=reserved-word + elif [[ $arg == $'\x28' ]]; then + # subshell + style=reserved-word + braces_stack='R'"$braces_stack" + elif [[ $arg == $'\x29' ]]; then + [[ $braces_stack[1] == "R" ]] && { braces_stack[1]=""; style=reserved-word; } + elif (( this_word & 14 )); then + style=default + fi + ;; + *) + # ADD + # (( start=start_pos-${#PREBUFFER}, end=end_pos-${#PREBUFFER}, start >= 0 )) && reply+=("$start $end commandtypefromthefuture-$REPLY") + already_added=1 + ;; + esac + fi + # in_redirection || BIT_regular || BIT_sudo_opt || BIT_sudo_arg + elif (( in_redirection + this_word & 14 )) + then # $arg is a non-command word + case $arg in + ']]') + style=reserved-word + [[ $braces_stack[1] == "A" ]] && braces_stack[1]="" + ;; + ']') + style=builtin + ;; + $'\x28') + # '(' inside [[ + style=reserved-word + braces_stack='R'"$braces_stack" + ;; + $'\x29') # subshell or end of array assignment + if (( in_array_assignment )); then + style=assign + in_array_assignment=0 + (( next_word = next_word | 1 )) + elif [[ $braces_stack[1] == "R" ]]; then + braces_stack[1]="" + style=reserved-word + fi;; + $'\x28\x29') # possibly a function definition + # || false # TODO: or if the previous word was a command word + (( FAST_HIGHLIGHT[multi_func_def] )) && (( next_word = next_word | 1 )) + style=reserved-word + # Remove possible annoying unknown-token style, or misleading function style + reply[-1]=() + ;; + '--'*) style=double-hyphen-option;; + '-'*) style=single-hyphen-option;; + "'"*) style=single-quoted-argument;; + '"'*) + # ADD + (( start=start_pos-${#PREBUFFER}, end=end_pos-${#PREBUFFER}, start >= 0 )) && reply+=("$start $end ${FAST_HIGHLIGHT_STYLES[double-quoted-argument]}") + -fast-highlight-string + already_added=1 + ;; + \$\'*) + # ADD + (( start=start_pos-${#PREBUFFER}, end=end_pos-${#PREBUFFER}, start >= 0 )) && reply+=("$start $end ${FAST_HIGHLIGHT_STYLES[dollar-quoted-argument]}") + -fast-highlight-dollar-string + already_added=1 + ;; + \$[^\(]*) + style=variable + ;; + '`'*) style=back-quoted-argument;; + [*?]*|*[^\\][*?]*) + (( highlight_glob )) && style=globbing || style=default;; + *) if [[ $arg = $'\x7d' && $braces_stack[1] == "Y" && "$FAST_HIGHLIGHT[right_brace_is_recognised_everywhere]" = "1" ]]; then + # right brace + # Parsing rule: # { + # + # Additionally, `tt(})' is recognized in any position if neither the + # tt(IGNORE_BRACES) option nor the tt(IGNORE_CLOSE_BRACES) option is set.""" + braces_stack[1]="" + style=reserved-word + (( next_word = next_word | 16 )) + elif [[ $arg[1] = $histchars[1] && -n "${arg[2]}" ]]; then + style=history-expansion + elif (( arg_type == 3 )); then + style=commandseparator + elif (( in_redirection == 2 )); then + style=redirection + else + if [[ -z "${FAST_HIGHLIGHT[no_check_paths]}" ]] && -fast-highlight-check-path; then + # ADD + (( start=start_pos-${#PREBUFFER}, end=end_pos-${#PREBUFFER}, start >= 0 )) && reply+=("$start $end ${FAST_HIGHLIGHT_STYLES[path]}") + already_added=1 + + [[ -n "$FAST_HIGHLIGHT_STYLES[path_pathseparator]" && "$FAST_HIGHLIGHT_STYLES[path]" != "$FAST_HIGHLIGHT_STYLES[path_pathseparator]" ]] && { + for (( pos = start_pos; pos <= end_pos; pos++ )) ; do + # ADD + [[ ${buf[pos]} == "/" ]] && (( start=pos-${#PREBUFFER}, start >= 0 )) && reply+=("$(( start - 1 )) $start ${FAST_HIGHLIGHT_STYLES[path_pathseparator]}") + done + } + else + style=default + fi + fi + ;; + esac + fi + + # ADD + (( already_added == 0 )) && [[ "${FAST_HIGHLIGHT_STYLES[$style]}" != "none" ]] && (( start=start_pos-${#PREBUFFER}, end=end_pos-${#PREBUFFER}, start >= 0 )) && reply+=("$start $end ${FAST_HIGHLIGHT_STYLES[$style]}") + + if (( arg_type == 3 )); then + if [[ $arg == ';' ]] && (( in_array_assignment )); then + # literal newline inside an array assignment + (( next_word = 2 )) + elif [[ -n "${braces_stack[(r)A]}" ]]; then + (( next_word = 2 )) + else + (( next_word = 1 )) + highlight_glob=1 + fi + elif (( arg_type == 1 || arg_type == 2 )) && (( this_word & 1 )); then + (( next_word = 1 )) + elif [[ $arg == "repeat" ]] && (( this_word & 1 )); then + # skip the repeat-count word + in_redirection=2 + # The redirection mechanism assumes $this_word describes the word + # following the redirection. Make it so. + # + # That word can be a command word with shortloops (`repeat 2 ls`) + # or a command separator (`repeat 2; ls` or `repeat 2; do ls; done`). + # + # The repeat-count word will be handled like a redirection target. + (( this_word = 3 )) + fi + start_pos=$end_pos + # This is the default/common codepath. + (( in_redirection == 0 )) && (( this_word = next_word )) #else # Stall $this_word. + done + + return 0 +} + +# Check if $arg is a path. +# If yes, return 0 and in $REPLY the style to use. +# Else, return non-zero (and the contents of $REPLY is undefined). +-fast-highlight-check-path() +{ + : ${expanded_path:=${(Q)~arg}} + + [[ -z $expanded_path ]] && return 1 + [[ -e $expanded_path ]] && return 0 + + # Search the path in CDPATH, only for CD command + [[ "$cur_cmd" = "cd" ]] && for cdpath_dir in $cdpath ; do + [[ -e "$cdpath_dir/$expanded_path" ]] && return 0 + done + + # It's not a path. + return 1 +} + +# Highlight special chars inside double-quoted strings +-fast-highlight-string() +{ + mybuf="$arg" + idx=start_pos + + while [[ "$mybuf" = (#b)[^\$\\]#((\$(#B)([a-zA-Z_:][a-zA-Z0-9_:]#|[0-9]##)(#b)(\[[^\]]#\])(#c0,1))|(\$[{](\([a-zA-Z0@%#]##\))(#c0,1)[a-zA-Z0-9_:#]##(\[[^\]]#\])(#c0,1)[}])|[\\][\'\"\$]|[\\](*))(*) ]]; do + [[ -n "${match[7]}" ]] && { + # Skip following char – it is quoted. Choice is + # made to not highlight such quoting + idx+=${mbegin[1]}+1 + mybuf="${match[7]:1}" + } || { + idx+=${mbegin[1]}-1 + end_idx=idx+${mend[1]}-${mbegin[1]}+1 + mybuf="${match[8]}" + + # ADD + (( start=idx-${#PREBUFFER}, end=end_idx-${#PREBUFFER}, start >= 0 )) && reply+=("$start $end ${FAST_HIGHLIGHT_STYLES[back-or-dollar-double-quoted-argument]}") + + idx=end_idx + } + done +} + +# Highlight special chars inside dollar-quoted strings +-fast-highlight-dollar-string() +{ + local i j k style + local AA + integer c + # Starting dollar-quote is at 1:2, so start parsing at offset 3 in the string. + for (( i = 3 ; i < end_pos - start_pos ; i += 1 )) ; do + (( j = i + start_pos - 1 )) + (( k = j + 1 )) + case "$arg[$i]" in + "\\") style=back-dollar-quoted-argument + for (( c = i + 1 ; c <= end_pos - start_pos ; c += 1 )); do + [[ "$arg[$c]" != ([0-9xXuUa-fA-F]) ]] && break + done + AA=$arg[$i+1,$c-1] + # Matching for HEX and OCT values like \0xA6, \xA6 or \012 + if [[ "$AA" =~ "^(x|X)[0-9a-fA-F]{1,2}" + || "$AA" =~ "^[0-7]{1,3}" + || "$AA" =~ "^u[0-9a-fA-F]{1,4}" + || "$AA" =~ "^U[0-9a-fA-F]{1,8}" + ]]; then + (( k += $#MATCH )) + (( i += $#MATCH )) + else + if (( $#arg > $i+1 )) && [[ $arg[$i+1] == [xXuU] ]]; then + # \x not followed by hex digits is probably an error + style=unknown-token + fi + (( k += 1 )) # Color following char too. + (( i += 1 )) # Skip parsing the escaped char. + fi + ;; + *) continue ;; + + esac + # ADD + (( start=j-${#PREBUFFER}, end=k-${#PREBUFFER}, start >= 0 )) && reply+=("$start $end ${FAST_HIGHLIGHT_STYLES[$style]}") + done +} + +# ------------------------------------------------------------------------------------------------- +# Main highlighter initialization +# ------------------------------------------------------------------------------------------------- + +-fast-highlight-init() { + __fast_highlight_main__command_type_cache=() +} + +# vim:ft=zsh:sw=2:sts=2 +# -*- mode: zsh; sh-indentation: 2; indent-tabs-mode: nil; sh-basic-offset: 2; -*- diff --git a/base/zsh/fast-syntax-highlighting/fast-syntax-highlighting.plugin.zsh b/base/zsh/fast-syntax-highlighting/fast-syntax-highlighting.plugin.zsh new file mode 100644 index 0000000..235d425 --- /dev/null +++ b/base/zsh/fast-syntax-highlighting/fast-syntax-highlighting.plugin.zsh @@ -0,0 +1,272 @@ +# ------------------------------------------------------------------------------------------------- +# Copyright (c) 2010-2016 zsh-syntax-highlighting contributors +# Copyright (c) 2017 Sebastian Gniazdowski (modifications) +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, are permitted +# provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, this list of conditions +# and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright notice, this list of +# conditions and the following disclaimer in the documentation and/or other materials provided +# with the distribution. +# * Neither the name of the zsh-syntax-highlighting contributors nor the names of its contributors +# may be used to endorse or promote products derived from this software without specific prior +# written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR +# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +# FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER +# IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT +# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# ------------------------------------------------------------------------------------------------- +# -*- mode: zsh; sh-indentation: 2; indent-tabs-mode: nil; sh-basic-offset: 2; -*- +# vim: ft=zsh sw=2 ts=2 et +# ------------------------------------------------------------------------------------------------- + + +# Set $ZERO to the expected value, regardless of functionargzero. +typeset -g ZERO=${(%):-%N} + +# Invokes each highlighter that needs updating. +# This function is supposed to be called whenever the ZLE state changes. +_zsh_highlight() +{ + # Store the previous command return code to restore it whatever happens. + local ret=$? + + # Remove all highlighting in isearch, so that only the underlining done by zsh itself remains. + # For details see FAQ entry 'Why does syntax highlighting not work while searching history?'. + if [[ $WIDGET == zle-isearch-update ]] && ! (( $+ISEARCHMATCH_ACTIVE )); then + region_highlight=() + return $ret + fi + + setopt localoptions warncreateglobal noksharrays + local REPLY # don't leak $REPLY into global scope + local -a reply + + # Do not highlight if there are more than 300 chars in the buffer. It's most + # likely a pasted command or a huge list of files in that case.. + [[ -n ${ZSH_HIGHLIGHT_MAXLENGTH:-} ]] && [[ $#BUFFER -gt $ZSH_HIGHLIGHT_MAXLENGTH ]] && return $ret + + # Do not highlight if there are pending inputs (copy/paste). + [[ $PENDING -gt 0 ]] && return $ret + + # Reset region highlight to build it from scratch + # may need to remove path_prefix highlighting when the line ends + if [[ $WIDGET == zle-line-finish ]] || _zsh_highlight_buffer_modified; then + -fast-highlight-init + -fast-highlight-process && region_highlight=( $reply ) || region_highlight=() + fi + + { + local cache_place + local -a region_highlight_copy + + # Re-apply zle_highlight settings + + # region + if (( REGION_ACTIVE == 1 )); then + _zsh_highlight_apply_zle_highlight region standout "$MARK" "$CURSOR" + elif (( REGION_ACTIVE == 2 )); then + () { + local needle=$'\n' + integer min max + if (( MARK > CURSOR )) ; then + min=$CURSOR max=$MARK + else + min=$MARK max=$CURSOR + fi + (( min = ${${BUFFER[1,$min]}[(I)$needle]} )) + (( max += ${${BUFFER:($max-1)}[(i)$needle]} - 1 )) + _zsh_highlight_apply_zle_highlight region standout "$min" "$max" + } + fi + + # yank / paste (zsh-5.1.1 and newer) + (( $+YANK_ACTIVE )) && (( YANK_ACTIVE )) && _zsh_highlight_apply_zle_highlight paste standout "$YANK_START" "$YANK_END" + + # isearch + (( $+ISEARCHMATCH_ACTIVE )) && (( ISEARCHMATCH_ACTIVE )) && _zsh_highlight_apply_zle_highlight isearch underline "$ISEARCHMATCH_START" "$ISEARCHMATCH_END" + + # suffix + (( $+SUFFIX_ACTIVE )) && (( SUFFIX_ACTIVE )) && _zsh_highlight_apply_zle_highlight suffix bold "$SUFFIX_START" "$SUFFIX_END" + + return $ret + + } always { + typeset -g _ZSH_HIGHLIGHT_PRIOR_BUFFER="$BUFFER" + typeset -gi _ZSH_HIGHLIGHT_PRIOR_CURSOR=$CURSOR + } +} + +# Apply highlighting based on entries in the zle_highlight array. +# This function takes four arguments: +# 1. The exact entry (no patterns) in the zle_highlight array: +# region, paste, isearch, or suffix +# 2. The default highlighting that should be applied if the entry is unset +# 3. and 4. Two integer values describing the beginning and end of the +# range. The order does not matter. +_zsh_highlight_apply_zle_highlight() { + local entry="$1" default="$2" + integer first="$3" second="$4" + + # read the relevant entry from zle_highlight + local region="${zle_highlight[(r)${entry}:*]}" + + if [[ -z "$region" ]]; then + # entry not specified at all, use default value + region=$default + else + # strip prefix + region="${region#${entry}:}" + + # no highlighting when set to the empty string or to 'none' + if [[ -z "$region" ]] || [[ "$region" == none ]]; then + return + fi + fi + + integer start end + if (( first < second )); then + start=$first end=$second + else + start=$second end=$first + fi + region_highlight+=("$start $end $region") +} + + +# ------------------------------------------------------------------------------------------------- +# API/utility functions for highlighters +# ------------------------------------------------------------------------------------------------- + +# Whether the command line buffer has been modified or not. +# +# Returns 0 if the buffer has changed since _zsh_highlight was last called. +_zsh_highlight_buffer_modified() +{ + [[ "${_ZSH_HIGHLIGHT_PRIOR_BUFFER:-}" != "$BUFFER" ]] +} + +# Whether the cursor has moved or not. +# +# Returns 0 if the cursor has moved since _zsh_highlight was last called. +_zsh_highlight_cursor_moved() +{ + [[ -n $CURSOR ]] && [[ -n ${_ZSH_HIGHLIGHT_PRIOR_CURSOR-} ]] && (($_ZSH_HIGHLIGHT_PRIOR_CURSOR != $CURSOR)) +} + +# ------------------------------------------------------------------------------------------------- +# Setup functions +# ------------------------------------------------------------------------------------------------- + +# Helper for _zsh_highlight_bind_widgets +# $1 is name of widget to call +_zsh_highlight_call_widget() +{ + builtin zle "$@" && _zsh_highlight +} + +# Rebind all ZLE widgets to make them invoke _zsh_highlights. +_zsh_highlight_bind_widgets() +{ + setopt localoptions noksharrays + typeset -F SECONDS + local prefix=orig-s$SECONDS-r$RANDOM # unique each time, in case we're sourced more than once + + # Load ZSH module zsh/zleparameter, needed to override user defined widgets. + zmodload zsh/zleparameter 2>/dev/null || { + print -r -- >&2 'zsh-syntax-highlighting: failed loading zsh/zleparameter.' + return 1 + } + + # Override ZLE widgets to make them invoke _zsh_highlight. + local -U widgets_to_bind + widgets_to_bind=(${${(k)widgets}:#(.*|run-help|which-command|beep|set-local-history|yank)}) + + # Always wrap special zle-line-finish widget. This is needed to decide if the + # current line ends and special highlighting logic needs to be applied. + # E.g. remove cursor imprint, don't highlight partial paths, ... + widgets_to_bind+=(zle-line-finish) + + # Always wrap special zle-isearch-update widget to be notified of updates in isearch. + # This is needed because we need to disable highlighting in that case. + widgets_to_bind+=(zle-isearch-update) + + local cur_widget + for cur_widget in $widgets_to_bind; do + case $widgets[$cur_widget] in + + # Already rebound event: do nothing. + user:_zsh_highlight_widget_*);; + + # The "eval"'s are required to make $cur_widget a closure: the value of the parameter at function + # definition time is used. + # + # We can't use ${0/_zsh_highlight_widget_} because these widgets are always invoked with + # NO_function_argzero, regardless of the option's setting here. + + # User defined widget: override and rebind old one with prefix "orig-". + user:*) zle -N $prefix-$cur_widget ${widgets[$cur_widget]#*:} + eval "_zsh_highlight_widget_${(q)prefix}-${(q)cur_widget}() { _zsh_highlight_call_widget ${(q)prefix}-${(q)cur_widget} -- \"\$@\" }" + zle -N $cur_widget _zsh_highlight_widget_$prefix-$cur_widget;; + + # Completion widget: override and rebind old one with prefix "orig-". + completion:*) zle -C $prefix-$cur_widget ${${(s.:.)widgets[$cur_widget]}[2,3]} + eval "_zsh_highlight_widget_${(q)prefix}-${(q)cur_widget}() { _zsh_highlight_call_widget ${(q)prefix}-${(q)cur_widget} -- \"\$@\" }" + zle -N $cur_widget _zsh_highlight_widget_$prefix-$cur_widget;; + + # Builtin widget: override and make it call the builtin ".widget". + builtin) eval "_zsh_highlight_widget_${(q)prefix}-${(q)cur_widget}() { _zsh_highlight_call_widget .${(q)cur_widget} -- \"\$@\" }" + zle -N $cur_widget _zsh_highlight_widget_$prefix-$cur_widget;; + + # Incomplete or nonexistent widget: Bind to z-sy-h directly. + *) + if [[ $cur_widget == zle-* ]] && [[ -z $widgets[$cur_widget] ]]; then + _zsh_highlight_widget_${cur_widget}() { :; _zsh_highlight } + zle -N $cur_widget _zsh_highlight_widget_$cur_widget + else + # Default: unhandled case. + print -r -- >&2 "zsh-syntax-highlighting: unhandled ZLE widget ${(qq)cur_widget}" + fi + esac + done +} + +# ------------------------------------------------------------------------------------------------- +# Setup +# ------------------------------------------------------------------------------------------------- + +# Try binding widgets. +_zsh_highlight_bind_widgets || { + print -r -- >&2 'zsh-syntax-highlighting: failed binding ZLE widgets, exiting.' + return 1 +} + +# Reset scratch variables when commandline is done. +_zsh_highlight_preexec_hook() +{ + typeset -g _ZSH_HIGHLIGHT_PRIOR_BUFFER= + typeset -gi _ZSH_HIGHLIGHT_PRIOR_CURSOR=0 +} + +autoload -U add-zsh-hook +add-zsh-hook preexec _zsh_highlight_preexec_hook 2>/dev/null || { + print -r -- >&2 'zsh-syntax-highlighting: failed loading add-zsh-hook.' +} + +# Load zsh/parameter module if available +zmodload zsh/parameter 2>/dev/null + +autoload -U is-at-least +source "${ZERO:h}/fast-highlight" + +[[ "${+termcap[Co]}" = 1 && "${termcap[Co]}" = "256" ]] && FAST_HIGHLIGHT_STYLES[variable]="fg=112" + +-fast-highlight-fill-option-variables diff --git a/base/zsh/functions.zsh b/base/zsh/functions.zsh new file mode 100644 index 0000000..d2905ad --- /dev/null +++ b/base/zsh/functions.zsh @@ -0,0 +1,18 @@ +function todo { + a="" + for i; do a="$a,$i"; done + a="{$(echo "$a" | cut -d',' -f2-)}" + echo "grep -R --exclude-dir=$a TODO | sed -e 's/.*TODO //;s/ \*\/$//;s/ -->//' | LC_ALL=C sort -u" | zsh +} + +function which { + (alias; declare -f) | /usr/bin/which --tty-only --read-alias --read-functions --show-tilde --show-dot $@ +} #export -f which + +function trash { + mkdir -p "$HOME/.trash" + for file in "$@"; do + mv "$file" "$HOME/.trash/$(basename $file).$(date +%Y%m%d-%H%M%S)" + done +} # Add this to your crontab: +# 43 0 * * 3 find ~/.trash -mindepth 1 -mtime +90 -delete diff --git a/base/zsh/history.zsh b/base/zsh/history.zsh new file mode 100644 index 0000000..f21023d --- /dev/null +++ b/base/zsh/history.zsh @@ -0,0 +1,15 @@ +if [ -z $HISTFILE ]; then + HISTFILE=$HOME/.zsh_history +fi +HISTSIZE=100000 +SAVEHIST=100000 +HISTCONTROL=ignoredups + +setopt append_history +setopt extended_history +setopt hist_expire_dups_first +setopt hist_ignore_dups # ignore duplication command history list +setopt hist_ignore_space +setopt hist_verify +setopt inc_append_history + diff --git a/base/zsh/k.zsh b/base/zsh/k.zsh new file mode 100644 index 0000000..e7dc9fb --- /dev/null +++ b/base/zsh/k.zsh @@ -0,0 +1,540 @@ +zmodload zsh/datetime +zmodload -F zsh/stat b:zstat + +k () { + # ---------------------------------------------------------------------------- + # Setup + # ---------------------------------------------------------------------------- + + # Stop stat failing when a directory contains either no files or no hidden files + # Track if we _accidentally_ create a new global variable + setopt local_options null_glob typeset_silent no_auto_pushd + + # Process options and get files/directories + typeset -a o_all o_almost_all o_human o_si o_directory o_no_directory o_no_vcs o_help + zparseopts -E -D \ + a=o_all -all=o_all \ + A=o_almost_all -almost-all=o_almost_all \ + d=o_directory -directory=o_directory \ + h=o_human -human=o_human \ + -si=o_si \ + n=o_no_directory -no-directory=o_no_directory \ + -no-vcs=o_no_vcs \ + -help=o_help + + # Print Help if bad usage, or they asked for it + if [[ $? != 0 || "$o_help" != "" ]] + then + print -u2 "Usage: k [options] DIR" + print -u2 "Options:" + print -u2 "\t-a --all list entries starting with ." + print -u2 "\t-A --almost-all list all except . and .." + print -u2 "\t-d --directory list only directories" + print -u2 "\t-n --no-directory do not list directories" + print -u2 "\t-h --human show filesizes in human-readable format" + print -u2 "\t --si with -h, use powers of 1000 not 1024" + print -u2 "\t --no-vcs do not get VCS status (much faster)" + print -u2 "\t --help show this help" + return 1 + fi + + # Check for conflicts + if [[ "$o_directory" != "" && "$o_no_directory" != "" ]]; then + print -u2 "$o_directory and $o_no_directory cannot be used together" + return 1 + fi + + # Check which numfmt available (if any), warn user if not available + typeset -i numfmt_available=0 + typeset -i gnumfmt_available=0 + if [[ "$o_human" != "" ]]; then + if [[ $+commands[numfmt] == 1 ]]; then + numfmt_available=1 + elif [[ $+commands[gnumfmt] == 1 ]]; then + gnumfmt_available=1 + else + print -u2 "'numfmt' or 'gnumfmt' command not found, human readable output will not work." + print -u2 "\tFalling back to normal file size output" + # Set o_human to off + o_human="" + fi + fi + + # Create numfmt local function + numfmt_local () { + if [[ "$o_si" != "" ]]; then + if (( $numfmt_available )); then + numfmt --to=si $1 + elif (( $gnumfmt_available )); then + gnumfmt --to=si $1 + fi + else + if (( $numfmt_available )); then + numfmt --to=iec $1 + elif (( $gnumfmt_available )); then + gnumfmt --to=iec $1 + fi + fi + } + + # Set if we're in a repo or not + typeset -i INSIDE_WORK_TREE=0 + if [[ $(command git rev-parse --is-inside-work-tree 2>/dev/null) == true ]]; then + INSIDE_WORK_TREE=1 + fi + + # Setup array of directories to print + typeset -a base_dirs + typeset base_dir + + if [[ "$@" == "" ]]; then + base_dirs=. + else + base_dirs=($@) + fi + + + # Colors + # ---------------------------------------------------------------------------- + # default colors + K_COLOR_DI="0;34" # di:directory + K_COLOR_LN="0;35" # ln:symlink + K_COLOR_SO="0;32" # so:socket + K_COLOR_PI="0;33" # pi:pipe + K_COLOR_EX="0;31" # ex:executable + K_COLOR_BD="34;46" # bd:block special + K_COLOR_CD="34;43" # cd:character special + K_COLOR_SU="30;41" # su:executable with setuid bit set + K_COLOR_SG="30;46" # sg:executable with setgid bit set + K_COLOR_TW="30;42" # tw:directory writable to others, with sticky bit + K_COLOR_OW="30;43" # ow:directory writable to others, without sticky bit + + # read colors if osx and $LSCOLORS is defined + if [[ $(uname) == 'Darwin' && -n $LSCOLORS ]]; then + # Translate OSX/BSD's LSCOLORS so we can use the same here + K_COLOR_DI=$(_k_bsd_to_ansi $LSCOLORS[1] $LSCOLORS[2]) + K_COLOR_LN=$(_k_bsd_to_ansi $LSCOLORS[3] $LSCOLORS[4]) + K_COLOR_SO=$(_k_bsd_to_ansi $LSCOLORS[5] $LSCOLORS[6]) + K_COLOR_PI=$(_k_bsd_to_ansi $LSCOLORS[7] $LSCOLORS[8]) + K_COLOR_EX=$(_k_bsd_to_ansi $LSCOLORS[9] $LSCOLORS[10]) + K_COLOR_BD=$(_k_bsd_to_ansi $LSCOLORS[11] $LSCOLORS[12]) + K_COLOR_CD=$(_k_bsd_to_ansi $LSCOLORS[13] $LSCOLORS[14]) + K_COLOR_SU=$(_k_bsd_to_ansi $LSCOLORS[15] $LSCOLORS[16]) + K_COLOR_SG=$(_k_bsd_to_ansi $LSCOLORS[17] $LSCOLORS[18]) + K_COLOR_TW=$(_k_bsd_to_ansi $LSCOLORS[19] $LSCOLORS[20]) + K_COLOR_OW=$(_k_bsd_to_ansi $LSCOLORS[21] $LSCOLORS[22]) + fi + + # read colors if linux and $LS_COLORS is defined + # if [[ $(uname) == 'Linux' && -n $LS_COLORS ]]; then + + # fi + + # ---------------------------------------------------------------------------- + # Loop over passed directories and files to display + # ---------------------------------------------------------------------------- + for base_dir in $base_dirs + do + # ---------------------------------------------------------------------------- + # Display name if multiple paths were passed + # ---------------------------------------------------------------------------- + if [[ "$#base_dirs" > 1 ]]; then + # Only add a newline if its not the first iteration + if [[ "$base_dir" != "${base_dirs[1]}" ]]; then + print + fi + print -r "${base_dir}:" + fi + # ---------------------------------------------------------------------------- + # Vars + # ---------------------------------------------------------------------------- + + typeset -a MAX_LEN A RESULTS STAT_RESULTS + typeset TOTAL_BLOCKS + + # Get now + typeset K_EPOCH="${EPOCHSECONDS:?}" + + typeset -i TOTAL_BLOCKS=0 + + MAX_LEN=(0 0 0 0 0 0) + + # Array to hold results from `stat` call + RESULTS=() + + # only set once per directory so must be out of the main loop + typeset -i IS_GIT_REPO=0 + typeset GIT_TOPLEVEL + + typeset -i LARGE_FILE_COLOR=196 + typeset -a SIZELIMITS_TO_COLOR + SIZELIMITS_TO_COLOR=( + 1024 46 # <= 1kb + 2048 82 # <= 2kb + 3072 118 # <= 3kb + 5120 154 # <= 5kb + 10240 190 # <= 10kb + 20480 226 # <= 20kb + 40960 220 # <= 40kb + 102400 214 # <= 100kb + 262144 208 # <= 0.25mb || 256kb + 524288 202 # <= 0.5mb || 512kb + ) + typeset -i ANCIENT_TIME_COLOR=236 # > more than 2 years old + typeset -a FILEAGES_TO_COLOR + FILEAGES_TO_COLOR=( + 0 196 # < in the future, #spooky + 60 255 # < less than a min old + 3600 252 # < less than an hour old + 86400 250 # < less than 1 day old + 604800 244 # < less than 1 week old + 2419200 244 # < less than 28 days (4 weeks) old + 15724800 242 # < less than 26 weeks (6 months) old + 31449600 240 # < less than 1 year old + 62899200 238 # < less than 2 years old + ) + + # ---------------------------------------------------------------------------- + # Build up list of files/directories to show + # ---------------------------------------------------------------------------- + + typeset -a show_list + show_list=() + + # Check if it even exists + if [[ ! -e $base_dir ]]; then + print -u2 "k: cannot access $base_dir: No such file or directory" + + # If its just a file, skip the directory handling + elif [[ -f $base_dir ]]; then + show_list=($base_dir) + + #Directory, add its contents + else + # Break total blocks of the front of the stat call, then push the rest to results + if [[ "$o_all" != "" && "$o_almost_all" == "" && "$o_no_directory" == "" ]]; then + show_list+=($base_dir/.) + show_list+=($base_dir/..) + fi + + if [[ "$o_all" != "" || "$o_almost_all" != "" ]]; then + if [[ "$o_directory" != "" ]]; then + show_list+=($base_dir/*(D/)) + elif [[ "$o_no_directory" != "" ]]; then + #Use (^/) instead of (.) so sockets and symlinks get displayed + show_list+=($base_dir/*(D^/)) + else + show_list+=($base_dir/*(D)) + fi + else + if [[ "$o_directory" != "" ]]; then + show_list+=($base_dir/*(/)) + elif [[ "$o_no_directory" != "" ]]; then + #Use (^/) instead of (.) so sockets and symlinks get displayed + show_list+=($base_dir/*(^/)) + else + show_list+=($base_dir/*) + fi + fi + fi + + # ---------------------------------------------------------------------------- + # Stat call to get directory listing + # ---------------------------------------------------------------------------- + typeset -i i=1 j=1 k=1 + typeset -a STATS_PARAMS_LIST + typeset fn statvar h + typeset -A sv + + STATS_PARAMS_LIST=() + for fn in $show_list + do + statvar="stats_$i" + typeset -A $statvar + zstat -H $statvar -Lsn -F "%s^%d^%b^%H:%M^%Y" -- "$fn" # use lstat, render mode/uid/gid to strings + STATS_PARAMS_LIST+=($statvar) + i+=1 + done + + + # On each result calculate padding by getting max length on each array member + for statvar in "${STATS_PARAMS_LIST[@]}" + do + sv=("${(@Pkv)statvar}") + if [[ ${#sv[mode]} -gt $MAX_LEN[1] ]]; then MAX_LEN[1]=${#sv[mode]} ; fi + if [[ ${#sv[nlink]} -gt $MAX_LEN[2] ]]; then MAX_LEN[2]=${#sv[nlink]} ; fi + if [[ ${#sv[uid]} -gt $MAX_LEN[3] ]]; then MAX_LEN[3]=${#sv[uid]} ; fi + if [[ ${#sv[gid]} -gt $MAX_LEN[4] ]]; then MAX_LEN[4]=${#sv[gid]} ; fi + + if [[ "$o_human" != "" ]]; then + h=$(numfmt_local ${sv[size]}) + if (( ${#h} > $MAX_LEN[5] )); then MAX_LEN[5]=${#h}; fi + else + if [[ ${#sv[size]} -gt $MAX_LEN[5] ]]; then MAX_LEN[5]=${#sv[size]}; fi + fi + + TOTAL_BLOCKS+=$sv[blocks] + done + + # Print total block before listing + echo "total $TOTAL_BLOCKS" + + # ---------------------------------------------------------------------------- + # Loop through each line of stat, pad where appropriate and do git dirty checking + # ---------------------------------------------------------------------------- + + typeset REPOMARKER + typeset PERMISSIONS HARDLINKCOUNT OWNER GROUP FILESIZE FILESIZE_OUT DATE NAME SYMLINK_TARGET + typeset FILETYPE PER1 PER2 PER3 PERMISSIONS_OUTPUT STATUS + typeset TIME_DIFF TIME_COLOR DATE_OUTPUT + typeset -i IS_DIRECTORY IS_SYMLINK IS_SOCKET IS_PIPE IS_EXECUTABLE IS_BLOCK_SPECIAL IS_CHARACTER_SPECIAL HAS_UID_BIT HAS_GID_BIT HAS_STICKY_BIT IS_WRITABLE_BY_OTHERS + typeset -i COLOR + + k=1 + for statvar in "${STATS_PARAMS_LIST[@]}" + do + sv=("${(@Pkv)statvar}") + + # We check if the result is a git repo later, so set a blank marker indication the result is not a git repo + REPOMARKER=" " + IS_DIRECTORY=0 + IS_SYMLINK=0 + IS_SOCKET=0 + IS_PIPE=0 + IS_EXECUTABLE=0 + IS_BLOCK_SPECIAL=0 + IS_CHARACTER_SPECIAL=0 + HAS_UID_BIT=0 + HAS_GID_BIT=0 + HAS_STICKY_BIT=0 + IS_WRITABLE_BY_OTHERS=0 + + PERMISSIONS="${sv[mode]}" + HARDLINKCOUNT="${sv[nlink]}" + OWNER="${sv[uid]}" + GROUP="${sv[gid]}" + FILESIZE="${sv[size]}" + DATE=(${(s:^:)sv[mtime]}) # Split date on ^ + NAME="${sv[name]}" + SYMLINK_TARGET="${sv[link]}" + + # Check for file types + if [[ -d "$NAME" ]]; then IS_DIRECTORY=1; fi + if [[ -L "$NAME" ]]; then IS_SYMLINK=1; fi + if [[ -S "$NAME" ]]; then IS_SOCKET=1; fi + if [[ -p "$NAME" ]]; then IS_PIPE=1; fi + if [[ -x "$NAME" ]]; then IS_EXECUTABLE=1; fi + if [[ -b "$NAME" ]]; then IS_BLOCK_SPECIAL=1; fi + if [[ -c "$NAME" ]]; then IS_CHARACTER_SPECIAL=1; fi + if [[ -u "$NAME" ]]; then HAS_UID_BIT=1; fi + if [[ -g "$NAME" ]]; then HAS_GID_BIT=1; fi + if [[ -k "$NAME" ]]; then HAS_STICKY_BIT=1; fi + if [[ $PERMISSIONS[9] == 'w' ]]; then IS_WRITABLE_BY_OTHERS=1; fi + + # IS_GIT_REPO is a 1 if $NAME is a file/directory in a git repo, OR if $NAME is a git-repo itself + # GIT_TOPLEVEL is set to the directory containing the .git folder of a git-repo + + # is this a git repo + if [[ "$o_no_vcs" != "" ]]; then + IS_GIT_REPO=0 + GIT_TOPLEVEL='' + else + if (( IS_DIRECTORY )); + then builtin cd -q $NAME 2>/dev/null || builtin cd -q - >/dev/null && IS_GIT_REPO=0 #Say no if we don't have permissions there + else builtin cd -q $NAME:a:h 2>/dev/null || builtin cd -q - >/dev/null && IS_GIT_REPO=0 + fi + if [[ $(command git rev-parse --is-inside-work-tree 2>/dev/null) == true ]]; then + IS_GIT_REPO=1 + GIT_TOPLEVEL=$(command git rev-parse --show-toplevel) + else + IS_GIT_REPO=0 + fi + builtin cd -q - >/dev/null + fi + + # Get human readable output if necessary + if [[ "$o_human" != "" ]]; then + # I hate making this call twice, but its either that, or do a bunch + # of calculations much earlier. + FILESIZE_OUT=$(numfmt_local $FILESIZE) + else + FILESIZE_OUT=$FILESIZE + fi + + # Pad so all the lines align - firstline gets padded the other way + PERMISSIONS="${(r:MAX_LEN[1]:)PERMISSIONS}" + HARDLINKCOUNT="${(l:MAX_LEN[2]:)HARDLINKCOUNT}" + OWNER="${(l:MAX_LEN[3]:)OWNER}" + GROUP="${(l:MAX_LEN[4]:)GROUP}" + FILESIZE_OUT="${(l:MAX_LEN[5]:)FILESIZE_OUT}" + + # -------------------------------------------------------------------------- + # Colour the permissions - TODO + # -------------------------------------------------------------------------- + # Colour the first character based on filetype + FILETYPE="${PERMISSIONS[1]}" + + # Permissions Owner + PER1="${PERMISSIONS[2,4]}" + + # Permissions Group + PER2="${PERMISSIONS[5,7]}" + + # Permissions User + PER3="${PERMISSIONS[8,10]}" + + PERMISSIONS_OUTPUT="$FILETYPE$PER1$PER2$PER3" + + # -------------------------------------------------------------------------- + # Colour the symlinks + # -------------------------------------------------------------------------- + + # -------------------------------------------------------------------------- + # Colour Owner and Group + # -------------------------------------------------------------------------- + OWNER=$'\e[38;5;241m'"$OWNER"$'\e[0m' + GROUP=$'\e[38;5;241m'"$GROUP"$'\e[0m' + + # -------------------------------------------------------------------------- + # Colour file weights + # -------------------------------------------------------------------------- + COLOR=LARGE_FILE_COLOR + for i j in ${SIZELIMITS_TO_COLOR[@]} + do + (( FILESIZE <= i )) || continue + COLOR=$j + break + done + + FILESIZE_OUT=$'\e[38;5;'"${COLOR}m$FILESIZE_OUT"$'\e[0m' + + # -------------------------------------------------------------------------- + # Colour the date and time based on age, then format for output + # -------------------------------------------------------------------------- + # Setup colours based on time difference + TIME_DIFF=$(( K_EPOCH - DATE[1] )) + TIME_COLOR=$ANCIENT_TIME_COLOR + for i j in ${FILEAGES_TO_COLOR[@]} + do + (( TIME_DIFF < i )) || continue + TIME_COLOR=$j + break + done + + # Format date to show year if more than 6 months since last modified + if (( TIME_DIFF < 15724800 )); then + DATE_OUTPUT="${DATE[2]} ${(r:5:: :)${DATE[3][0,5]}} ${DATE[4]}" + else + DATE_OUTPUT="${DATE[2]} ${(r:6:: :)${DATE[3][0,5]}} ${DATE[5]}" # extra space; 4 digit year instead of 5 digit HH:MM + fi; + DATE_OUTPUT[1]="${DATE_OUTPUT[1]//0/ }" # If day of month begins with zero, replace zero with space + + # Apply colour to formated date + DATE_OUTPUT=$'\e[38;5;'"${TIME_COLOR}m${DATE_OUTPUT}"$'\e[0m' + + # -------------------------------------------------------------------------- + # Colour the repomarker + # -------------------------------------------------------------------------- + if [[ "$o_no_vcs" != "" ]]; then + REPOMARKER="" + elif (( IS_GIT_REPO != 0)); then + # If we're not in a repo, still check each directory if it's a repo, and + # then mark appropriately + if (( INSIDE_WORK_TREE == 0 )); then + if (( IS_DIRECTORY )); then + if command git --git-dir="$GIT_TOPLEVEL/.git" --work-tree="${NAME}" diff --stat --quiet --ignore-submodules HEAD &>/dev/null # if dirty + then REPOMARKER=$'\e[38;5;46m|\e[0m' # Show a green vertical bar for clean + else REPOMARKER=$'\e[0;31m+\e[0m' # Show a red vertical bar if dirty + fi + fi + else + if (( IS_DIRECTORY )); then + # If the directory isn't ignored or clean, we'll just say it's dirty + if command git check-ignore --quiet ${NAME} 2>/dev/null; then STATUS='!!' + elif command git diff --stat --quiet --ignore-submodules ${NAME} 2> /dev/null; then STATUS=''; + else STATUS=' M' + fi + else + # File + STATUS=$(command git status --porcelain --ignored --untracked-files=normal $GIT_TOPLEVEL/${${${NAME:a}##$GIT_TOPLEVEL}#*/}) + fi + STATUS=${STATUS[1,2]} + if [[ $STATUS == ' M' ]]; then REPOMARKER=$'\e[0;31m+\e[0m'; # Tracked & Dirty + elif [[ $STATUS == 'M ' ]]; then REPOMARKER=$'\e[38;5;082m+\e[0m'; # Tracked & Dirty & Added + elif [[ $STATUS == '??' ]]; then REPOMARKER=$'\e[38;5;214m+\e[0m'; # Untracked + elif [[ $STATUS == '!!' ]]; then REPOMARKER=$'\e[38;5;238m|\e[0m'; # Ignored + elif [[ $STATUS == 'A ' ]]; then REPOMARKER=$'\e[38;5;082m+\e[0m'; # Added + else REPOMARKER=$'\e[38;5;082m|\e[0m'; # Good + fi + fi + fi + + # -------------------------------------------------------------------------- + # Colour the filename + # -------------------------------------------------------------------------- + # Unfortunately, the choices for quoting which escape ANSI color sequences are q & qqqq; none of q- qq qqq work. + # But we don't want to quote '.'; so instead we escape the escape manually and use q- + NAME="${${NAME##*/}//$'\e'/\\e}" # also propagate changes to SYMLINK_TARGET below + + if [[ $IS_DIRECTORY == 1 ]]; then + if [[ $IS_WRITABLE_BY_OTHERS == 1 ]]; then + if [[ $HAS_STICKY_BIT == 1 ]]; then + NAME=$'\e['"$K_COLOR_TW"'m'"$NAME"$'\e[0m'; + fi + NAME=$'\e['"$K_COLOR_OW"'m'"$NAME"$'\e[0m'; + fi + NAME=$'\e['"$K_COLOR_DI"'m'"$NAME"$'\e[0m'; + elif [[ $IS_SYMLINK == 1 ]]; then NAME=$'\e['"$K_COLOR_LN"'m'"$NAME"$'\e[0m'; + elif [[ $IS_SOCKET == 1 ]]; then NAME=$'\e['"$K_COLOR_SO"'m'"$NAME"$'\e[0m'; + elif [[ $IS_PIPE == 1 ]]; then NAME=$'\e['"$K_COLOR_PI"'m'"$NAME"$'\e[0m'; + elif [[ $HAS_UID_BIT == 1 ]]; then NAME=$'\e['"$K_COLOR_SU"'m'"$NAME"$'\e[0m'; + elif [[ $HAS_GID_BIT == 1 ]]; then NAME=$'\e['"$K_COLOR_SG"'m'"$NAME"$'\e[0m'; + elif [[ $IS_EXECUTABLE == 1 ]]; then NAME=$'\e['"$K_COLOR_EX"'m'"$NAME"$'\e[0m'; + elif [[ $IS_BLOCK_SPECIAL == 1 ]]; then NAME=$'\e['"$K_COLOR_BD"'m'"$NAME"$'\e[0m'; + elif [[ $IS_CHARACTER_SPECIAL == 1 ]]; then NAME=$'\e['"$K_COLOR_CD"'m'"$NAME"$'\e[0m'; + fi + + # -------------------------------------------------------------------------- + # Format symlink target + # -------------------------------------------------------------------------- + if [[ $SYMLINK_TARGET != "" ]]; then SYMLINK_TARGET="-> ${SYMLINK_TARGET//$'\e'/\\e}"; fi + + # -------------------------------------------------------------------------- + # Display final result + # -------------------------------------------------------------------------- + print -r -- "$PERMISSIONS_OUTPUT $HARDLINKCOUNT $OWNER $GROUP $FILESIZE_OUT $DATE_OUTPUT $REPOMARKER $NAME $SYMLINK_TARGET" + + k=$((k+1)) # Bump loop index + done + done +} + +_k_bsd_to_ansi() { + local foreground=$1 background=$2 foreground_ansi background_ansi + case $foreground in + a) foreground_ansi=30;; + b) foreground_ansi=31;; + c) foreground_ansi=32;; + d) foreground_ansi=33;; + e) foreground_ansi=34;; + f) foreground_ansi=35;; + g) foreground_ansi=36;; + h) foreground_ansi=37;; + x) foreground_ansi=0;; + esac + case $background in + a) background_ansi=40;; + b) background_ansi=41;; + c) background_ansi=42;; + d) background_ansi=43;; + e) background_ansi=44;; + f) background_ansi=45;; + g) background_ansi=46;; + h) background_ansi=47;; + x) background_ansi=0;; + esac + printf "%s;%s" $background_ansi $foreground_ansi +} + +# http://upload.wikimedia.org/wikipedia/en/1/15/Xterm_256color_chart.svg +# vim: set ts=2 sw=2 ft=zsh et : diff --git a/base/zsh/prompt.zsh b/base/zsh/prompt.zsh new file mode 100644 index 0000000..2e4dca9 --- /dev/null +++ b/base/zsh/prompt.zsh @@ -0,0 +1,6 @@ +if [[ `tty | sed -ne "\_^/dev/tty[0-9]*_p"` ]]; then + PROMPT='%F{0}%B[ %F{6}%b%M %B%1~ %F{0}]%(!.#.$)%f%b ' +else + autoload -U promptinit && promptinit + prompt pure +fi diff --git a/base/zsh/prompt_pure_setup b/base/zsh/prompt_pure_setup new file mode 100644 index 0000000..d9b7f2d --- /dev/null +++ b/base/zsh/prompt_pure_setup @@ -0,0 +1,385 @@ +# Quickref +# git: +# %b => current branch +# %a => current action (rebase/merge) +# prompt: +# %F => color dict +# %f => reset color +# %~ => current path +# %* => time +# %n => username +# %m => shortname host +# %(?..) => prompt conditional - %(condition.true.false) +# terminal codes: +# \e7 => save cursor position +# \e[2A => move cursor 2 lines up +# \e[1G => go to position 1 in terminal +# \e8 => restore cursor position +# \e[K => clears everything after the cursor on the current line +# \e[2K => clear everything on the current line + +PURER_PROMPT_COMMAND_COUNT=0 +STATUS_COLOR=6 + +# turns seconds into human readable time +# 165392 => 1d 21h 56m 32s +# https://github.com/sindresorhus/pretty-time-zsh +prompt_pure_human_time_to_var() { + local human=" [" total_seconds=$1 var=$2 + local days=$(( total_seconds / 60 / 60 / 24 )) + local hours=$(( total_seconds / 60 / 60 % 24 )) + local minutes=$(( total_seconds / 60 % 60 )) + local seconds=$(( total_seconds % 60 )) + (( days > 0 )) && human+="${days}d " + (( hours > 0 )) && human+="${hours}h " + (( minutes > 0 )) && human+="${minutes}m " + human+="${seconds}s]" + + # store human readable time in variable as specified by caller + typeset -g "${var}"="${human}" +} + +# stores (into prompt_pure_cmd_exec_time) the exec time of the last command if set threshold was exceeded +prompt_pure_check_cmd_exec_time() { + integer elapsed + (( elapsed = EPOCHSECONDS - ${prompt_pure_cmd_timestamp:-$EPOCHSECONDS} )) + prompt_pure_cmd_exec_time= + (( elapsed > ${PURE_CMD_MAX_EXEC_TIME:=15} )) && { + prompt_pure_human_time_to_var $elapsed "prompt_pure_cmd_exec_time" + } +} + +prompt_pure_clear_screen() { + # enable output to terminal + zle -I + # clear screen and move cursor to (0, 0) + print -n '\e[2J\e[0;0H' + # reset command count to zero so we don't start with a blank line + PURER_PROMPT_COMMAND_COUNT=0 + # print preprompt + prompt_pure_preprompt_render precmd +} + +# set STATUS_COLOR: cyan for "insert", green for "normal" mode. +prompt_purer_vim_mode() { + STATUS_COLOR="${${KEYMAP/vicmd/16}/(main|viins)/6}" + prompt_pure_preprompt_render +} + +prompt_pure_set_title() { + # emacs terminal does not support settings the title + (( ${+EMACS} )) && return + + # tell the terminal we are setting the title + print -n '\e]0;' + # show hostname if connected through ssh + [[ -n $SSH_CONNECTION ]] && print -Pn '(%m) ' + case $1 in + expand-prompt) + print -Pn $2;; + ignore-escape) + print -rn $2;; + esac + # end set title + print -n '\a' +} + +prompt_pure_preexec() { + # attempt to detect and prevent prompt_pure_async_git_fetch from interfering with user initiated git or hub fetch + [[ $2 =~ (git|hub)\ .*(pull|fetch) ]] && async_flush_jobs 'prompt_pure' + + prompt_pure_cmd_timestamp=$EPOCHSECONDS + + # shows the current dir and executed command in the title while a process is active + prompt_pure_set_title 'ignore-escape' "$PWD:t: $2" +} + +# string length ignoring ansi escapes +prompt_pure_string_length_to_var() { + local str=$1 var=$2 length + # perform expansion on str and check length + length=$(( ${#${(S%%)str//(\%([KF1]|)\{*\}|\%[Bbkf])}} )) + + # store string length in variable as specified by caller + typeset -g "${var}"="${length}" +} + +prompt_pure_preprompt_render() { + # store the current prompt_subst setting so that it can be restored later + local prompt_subst_status=$options[prompt_subst] + + # make sure prompt_subst is unset to prevent parameter expansion in preprompt + setopt local_options no_prompt_subst + + # check that no command is currently running, the preprompt will otherwise be rendered in the wrong place + [[ -n ${prompt_pure_cmd_timestamp+x} && "$1" != "precmd" ]] && return + + # set color for git branch/dirty status, change color if dirty checking has been delayed + local git_color=20 + [[ -n ${prompt_pure_git_last_dirty_check_timestamp+x} ]] && git_color=1 + + # construct preprompt + local preprompt="" + + # add a newline between commands + FIRST_COMMAND_THRESHOLD=1 + if [[ "$PURER_PROMPT_COMMAND_COUNT" -gt "$FIRST_COMMAND_THRESHOLD" ]]; then + preprompt+=$'\n' + fi + + # host ID + if [[ "$PROMPT_HOST_COLOR" ]]; then + preprompt+="%b%F{black}%K{$PROMPT_HOST_COLOR} " + [[ "$PROMPT_SHORT_HOSTNAME" ]] && preprompt+="$PROMPT_SHORT_HOSTNAME " + preprompt+="%F{$PROMPT_HOST_COLOR}%K{18}%f" + fi + preprompt+="%K{18} " + # directory, colored by vim status + preprompt+="%B%F{$STATUS_COLOR}%c%f%b" + # git info + preprompt+="%F{$git_color}${vcs_info_msg_0_}${prompt_pure_git_dirty}%f" + # git pull/push arrows + preprompt+="%F{cyan}${prompt_pure_git_arrows}%f" + # username and machine if applicable + #preprompt+=$prompt_pure_username + # execution time + preprompt+="%F{20}${prompt_pure_cmd_exec_time}%f" + # end with symbol, colored by previous command exit code + # local symbol_color="%(?.${PURE_PROMPT_SYMBOL_COLOR:-magenta}.red)" + # preprompt+=" %F{$symbol_color}${PURE_PROMPT_SYMBOL:-❯}%f" + preprompt+=" %F{18}%(?.%k.%K{1}%F{1}%k)%f" + #  + + preprompt+=" " + + # make sure prompt_pure_last_preprompt is a global array + typeset -g -a prompt_pure_last_preprompt + + PROMPT="$preprompt" + + # if executing through precmd, do not perform fancy terminal editing + if [[ "$1" != "precmd" ]]; then + # only redraw if the expanded preprompt has changed + # [[ "${prompt_pure_last_preprompt[2]}" != "${(S%%)preprompt}" ]] || return + + # redraw prompt (also resets cursor position) + zle && zle .reset-prompt + + setopt no_prompt_subst + fi + + # store both unexpanded and expanded preprompt for comparison + prompt_pure_last_preprompt=("$preprompt" "${(S%%)preprompt}") +} + +prompt_pure_precmd() { + # check exec time and store it in a variable + prompt_pure_check_cmd_exec_time + + # by making sure that prompt_pure_cmd_timestamp is defined here the async functions are prevented from interfering + # with the initial preprompt rendering + prompt_pure_cmd_timestamp= + + # shows the full path in the title + prompt_pure_set_title 'expand-prompt' '%~' + + # get vcs info + vcs_info + + # preform async git dirty check and fetch + prompt_pure_async_tasks + + # Increment command counter + PURER_PROMPT_COMMAND_COUNT=$((PURER_PROMPT_COMMAND_COUNT+1)) + + # print the preprompt + prompt_pure_preprompt_render "precmd" + + # remove the prompt_pure_cmd_timestamp, indicating that precmd has completed + unset prompt_pure_cmd_timestamp +} + +# fastest possible way to check if repo is dirty +prompt_pure_async_git_dirty() { + setopt localoptions noshwordsplit + local untracked_dirty=$1 dir=$2 + + # use cd -q to avoid side effects of changing directory, e.g. chpwd hooks + builtin cd -q $dir + + if [[ $untracked_dirty = 0 ]]; then + command git diff --no-ext-diff --quiet --exit-code + else + test -z "$(command git status --porcelain --ignore-submodules -unormal)" + fi + + return $? +} + +prompt_pure_async_git_fetch() { + setopt localoptions noshwordsplit + # use cd -q to avoid side effects of changing directory, e.g. chpwd hooks + builtin cd -q $1 + + # set GIT_TERMINAL_PROMPT=0 to disable auth prompting for git fetch (git 2.3+) + export GIT_TERMINAL_PROMPT=0 + # set ssh BachMode to disable all interactive ssh password prompting + export GIT_SSH_COMMAND=${GIT_SSH_COMMAND:-"ssh -o BatchMode=yes"} + + command git -c gc.auto=0 fetch &>/dev/null || return 1 + + # check arrow status after a successful git fetch + prompt_pure_async_git_arrows $1 +} + +prompt_pure_async_git_arrows() { + setopt localoptions noshwordsplit + builtin cd -q $1 + command git rev-list --left-right --count HEAD...@'{u}' +} + +prompt_pure_async_tasks() { + setopt localoptions noshwordsplit + + # initialize async worker + ((!${prompt_pure_async_init:-0})) && { + async_start_worker "prompt_pure" -u -n + async_register_callback "prompt_pure" prompt_pure_async_callback + prompt_pure_async_init=1 + } + + # store working_tree without the "x" prefix + local working_tree="${vcs_info_msg_1_#x}" + + # check if the working tree changed (prompt_pure_current_working_tree is prefixed by "x") + if [[ ${prompt_pure_current_working_tree#x} != $working_tree ]]; then + # stop any running async jobs + async_flush_jobs "prompt_pure" + + # reset git preprompt variables, switching working tree + unset prompt_pure_git_dirty + unset prompt_pure_git_last_dirty_check_timestamp + prompt_pure_git_arrows= + + # set the new working tree and prefix with "x" to prevent the creation of a named path by AUTO_NAME_DIRS + prompt_pure_current_working_tree="x${working_tree}" + fi + + # only perform tasks inside git working tree + [[ -n $working_tree ]] || return + + async_job "prompt_pure" prompt_pure_async_git_arrows $working_tree + + # do not preform git fetch if it is disabled or working_tree == HOME + if (( ${PURE_GIT_PULL:-1} )) && [[ $working_tree != $HOME ]]; then + # tell worker to do a git fetch + async_job "prompt_pure" prompt_pure_async_git_fetch $working_tree + fi + + # if dirty checking is sufficiently fast, tell worker to check it again, or wait for timeout + integer time_since_last_dirty_check=$(( EPOCHSECONDS - ${prompt_pure_git_last_dirty_check_timestamp:-0} )) + if (( time_since_last_dirty_check > ${PURE_GIT_DELAY_DIRTY_CHECK:-1800} )); then + unset prompt_pure_git_last_dirty_check_timestamp + # check check if there is anything to pull + async_job "prompt_pure" prompt_pure_async_git_dirty ${PURE_GIT_UNTRACKED_DIRTY:-1} $working_tree + fi +} + +prompt_pure_check_git_arrows() { + setopt localoptions noshwordsplit + local arrows left=${1:-0} right=${2:-0} + + (( right > 0 )) && arrows+=${PURE_GIT_DOWN_ARROW:-⇣} + (( left > 0 )) && arrows+=${PURE_GIT_UP_ARROW:-⇡} + + [[ -n $arrows ]] || return + typeset -g REPLY=" $arrows" +} + +prompt_pure_async_callback() { + setopt localoptions noshwordsplit + local job=$1 code=$2 output=$3 exec_time=$4 + + case $job in + prompt_pure_async_git_dirty) + local prev_dirty=$prompt_pure_git_dirty + if (( code == 0 )); then + prompt_pure_git_dirty= + else + prompt_pure_git_dirty="*" + fi + + [[ $prev_dirty != $prompt_pure_git_dirty ]] && prompt_pure_preprompt_render + + # When prompt_pure_git_last_dirty_check_timestamp is set, the git info is displayed in a different color. + # To distinguish between a "fresh" and a "cached" result, the preprompt is rendered before setting this + # variable. Thus, only upon next rendering of the preprompt will the result appear in a different color. + (( $exec_time > 2 )) && prompt_pure_git_last_dirty_check_timestamp=$EPOCHSECONDS + ;; + prompt_pure_async_git_fetch|prompt_pure_async_git_arrows) + # prompt_pure_async_git_fetch executes prompt_pure_async_git_arrows + # after a successful fetch. + if (( code == 0 )); then + local REPLY + prompt_pure_check_git_arrows ${(ps:\t:)output} + if [[ $prompt_pure_git_arrows != $REPLY ]]; then + prompt_pure_git_arrows=$REPLY + prompt_pure_preprompt_render + fi + fi + ;; + esac +} + +prompt_pure_setup() { + # prevent percentage showing up + # if output doesn't end with a newline + export PROMPT_EOL_MARK='' + + # prompt_opts=(subst percent) + + # borrowed from promptinit, sets the prompt options in case pure was not + # initialized via promptinit. + # setopt noprompt{bang,cr,percent,subst} "prompt${^prompt_opts[@]}" + + zmodload zsh/datetime + zmodload zsh/zle + zmodload zsh/parameter + + autoload -Uz add-zsh-hook + autoload -Uz vcs_info + autoload -Uz async && async + + add-zsh-hook precmd prompt_pure_precmd + add-zsh-hook preexec prompt_pure_preexec + + zstyle ':vcs_info:*' enable git + zstyle ':vcs_info:*' use-simple true + # only export two msg variables from vcs_info + zstyle ':vcs_info:*' max-exports 2 + # vcs_info_msg_0_ = ' %b' (for branch) + # vcs_info_msg_1_ = 'x%R' git top level (%R), x-prefix prevents creation of a named path (AUTO_NAME_DIRS) + zstyle ':vcs_info:git*' formats ' %b' 'x%R' + zstyle ':vcs_info:git*' actionformats ' %b|%a' 'x%R' + + # if the user has not registered a custom zle widget for clear-screen, + # override the builtin one so that the preprompt is displayed correctly when + # ^L is issued. + if [[ $widgets[clear-screen] == 'builtin' ]]; then + zle -N clear-screen prompt_pure_clear_screen + fi + + # register custom function for vim-mode + zle -N zle-keymap-select prompt_purer_vim_mode + + # show username@host if logged in through SSH + [[ "$SSH_CONNECTION" != '' ]] && prompt_pure_username=' %F{242}%n@%m%f' + + # show username@host if root, with username in white + [[ $UID -eq 0 ]] && prompt_pure_username=' %F{white}%n%f%F{242}@%m%f' + + # create prompt + prompt_pure_preprompt_render 'precmd' +} + +prompt_pure_setup "$@" diff --git a/base/zsh/stack.zsh b/base/zsh/stack.zsh new file mode 100644 index 0000000..444b88d --- /dev/null +++ b/base/zsh/stack.zsh @@ -0,0 +1,3 @@ +DIRSTACKSIZE=8 +setopt autocd autopushd pushdminus pushdsilent pushdtohome +alias dh='dirs -v' diff --git a/base/zsh/tipz.zsh b/base/zsh/tipz.zsh new file mode 100644 index 0000000..bb1e224 --- /dev/null +++ b/base/zsh/tipz.zsh @@ -0,0 +1,84 @@ +### +# Search the defined aliases for a match +### +function _tipz_find_match() { + local bits alias command result="" + local -a aliases args; args="$@" + + # Load the current aliases into an array + local oldIFS=$IFS + IFS=$'\n' aliases=($(alias)) + IFS=$oldIFS + + # Loop through each of the aliases + for line in "${aliases[@]}"; do + # Split the line on '=' to separate the command + # and its alias + bits=("${(s/=/)line}") + alias=$bits[1] + command=$bits[2] + + # Create a regex that finds an exact match for + # the current argument string + args="${(@)args[@]}" + local pattern=$'^[\'\"]?'${args//([\{\}\(\)\[\]\*\?\:\\\.\|])/\\\$1}$'[\'\"]?$' + + # Check if the command matches the regex + if [[ "$command" =~ $pattern ]]; then + # Ensure that the longest matching command is stored + if [[ ${#command} > ${#result} ]]; then + result=$alias + fi + fi + done + + # If a result has been found, output it + if [[ -n $result ]]; then + echo $result + return 0 + fi + + return 1 +} + +### +# Search for alias tips for the currently executing command +### +function _tipz_process { + local -a cmd; cmd=($@) + integer i=$(( ${#cmd} + 1 )) + + # Loop for the length of the argument list, knocking + # an argument from the end of the list each time, and + # then using the remaining arguments to search for aliases + while [[ $i > 0 ]]; do + # Check the current string for a match + result=$(_tipz_find_match "${(@)cmd:0:$i}") + + # If the search exited successfully, + # output the tip to the user + if [[ $? -eq 0 ]]; then + print -P "%B%F{8}Alias tip: %b$result ${(@)cmd:$i}%f" + return 0 + fi + + # Decrement the counter + i=$(( i - 1 )) + done + + return 1 +} + +### +# A small function to filter out strange arguments +# sent from the add-zsh-hook preexec hook +### +function _tipz_prexec() { + _tipz_process $(echo $1) +} + +### +# Register the preexec hook +### +autoload -Uz add-zsh-hook +add-zsh-hook preexec _tipz_prexec diff --git a/base/zshrc b/base/zshrc new file mode 100644 index 0000000..b2ddd15 --- /dev/null +++ b/base/zshrc @@ -0,0 +1,17 @@ +path=( $HOME/.bin $path ) +fpath=( $HOME/.zsh $fpath ) + +export EDITOR=vim +export NCURSES_NO_UTF8_ACS=1 + +if [ -d $HOME/.zsh ]; then + for file in $HOME/.zsh/*.zsh; do + source $file + done +fi + +if [ -f $HOME/.zshrc.local ]; then + source $HOME/.zshrc.local +fi + +#~/.motd diff --git a/dotbot b/dotbot new file mode 160000 index 0000000..fe9ca6f --- /dev/null +++ b/dotbot @@ -0,0 +1 @@ +Subproject commit fe9ca6f5ede35d16f28e0c5db781fb39437fd171 diff --git a/install b/install new file mode 100755 index 0000000..ed8b710 --- /dev/null +++ b/install @@ -0,0 +1,19 @@ +#!/usr/bin/env bash + +set -e + +DEFAULT_CONFIG_PREFIX="base" +CONFIG_SUFFIX=".yaml" +DOTBOT_DIR="dotbot" + +DOTBOT_BIN="bin/dotbot" +BASEDIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" + +cd "${BASEDIR}" +git submodule update --init --recursive "${DOTBOT_DIR}" + +for conf in ${DEFAULT_CONFIG_PREFIX} ${@}; do + "${BASEDIR}/${DOTBOT_DIR}/${DOTBOT_BIN}" -d "${BASEDIR}" -c "${conf}${CONFIG_SUFFIX}" +done + +echo ${@} > .dot.args diff --git a/stowsh b/stowsh deleted file mode 100755 index af3c7b1..0000000 --- a/stowsh +++ /dev/null @@ -1,182 +0,0 @@ -#!/usr/bin/env bash - -_runcommands() { - local prefix='' - if [[ $DRYRUN == 1 ]] || [[ $VERBOSE -gt 1 ]]; then - echo "$@" - fi - if [[ $DRYRUN != 1 ]]; then - eval "$@" - fi -} - -echoerr() { - printf "%s\n" "$*" >&2; -} - -deperr() { - echoerr "stowsh requires $1" -} - -stowsh_setpaths() { - if command -v grealpath >/dev/null 2>&1; then - rpcmd="grealpath" - elif command -v realpath >/dev/null 2>&1; then - rpcmd="realpath" - else - deperr "GNU coreutils" - return 1 - fi - if ! strings "$(which "$rpcmd")" | grep -q "GNU coreutils" ; then - deperr "GNU coreutils" - return 1 - fi - if command -v gfind >/dev/null 2>&1; then - findcmd="gfind" - elif command -v find >/dev/null 2>&1; then - findcmd="find" - else - deperr "GNU findutils" - return 1 - fi - if ! strings "$(which "$findcmd")" | grep -q "GNU findutils" ; then - deperr "GNU findutils" - return 1 - fi -} - -stowsh_install() { - stowsh_setpaths || return 1 - local pkg=$1 - local target - target=$( "$rpcmd" "${2-$PWD}" ) - local commands=() - - ( - cd "$pkg" || return 1 - dirs="$($findcmd . -mindepth 1 -type d | sed "s|./||")" - for d in $dirs ; do - commands+=("mkdir -p '$target/$d'") - done - - local files - files="$($findcmd . -type f -or -type l | sed "s|./||")" - for f in $files ; do - local targetf="$target/$f" - local thisdir - thisdir=$(dirname "$targetf") - local relative - relative=$($rpcmd "$f" --relative-to="$thisdir" --canonicalize-missing) - if [[ ! -f "$targetf" ]] ; then - commands+=("ln -s '$relative' '$targetf'") - else - echoerr "$targetf already exists." - if [[ ! $SKIP -eq 1 ]]; then - echoerr "Aborting. Rerun with the -s flag to skip errors."; - return - fi - fi - done - for cmd in "${commands[@]}"; do - _runcommands "$cmd" - done; - ) -} - -stowsh_uninstall() { - stowsh_setpaths || return 1 - local pkg=$1 - local target - target=$( "$rpcmd" "${2-$PWD}" ) - local commands=() - - ( - cd "$pkg" || return 1 - local files - files="$($findcmd . -type f -or -type l | sed "s|./||")" - for f in $files ; do - local targetf="$target/$f" - if [[ $($rpcmd "$targetf") == $(realpath "$f") ]] ; then - commands+=("rm '$targetf'") - elif [[ -f "$targetf" ]] ; then - echoerr "$targetf does not point to to $(realpath "$f")." - if [[ ! $SKIP -eq 1 ]]; then - echoerr "Aborting. Rerun with the -s flag to skip errors."; - return - fi - elif [[ ! -f "$targetf" ]] ; then - echoerr "$targetf does not exist. Nothing to do." - if [[ ! $SKIP -eq 1 ]]; then - echoerr "Aborting. Rerun with the -s flag to skip errors."; - return - fi - fi - done - - dirs="$($findcmd . -mindepth 1 -type d | sed "s|./||")" - for d in $dirs ; do - commands+=("[[ -d '$target/$d' ]] && $findcmd '$target/$d' -type d -empty -delete") - done - for cmd in "${commands[@]}"; do - _runcommands "$cmd" - done; - ) -} - -stowsh_help() { - echo "Usage: $0 [-D] [-n] [-s] [-v[v]] [-t TARGET] PACKAGES..." -} - -if [ "$0" = "$BASH_SOURCE" ]; then - UNINSTALL=0 - DRYRUN=0 - SKIP=0 - TARGET="$PWD" - PACKAGES=() - while [[ "$@" ]]; do - if [[ $1 =~ ^- ]]; then - OPTIND=1 - while getopts ":vhDsnt:" opt; do - case $opt in - h) - stowsh_help - exit 0 - ;; - D) UNINSTALL=1 - ;; - n) DRYRUN=1 - ;; - s) SKIP=1 - ;; - v) VERBOSE=$((VERBOSE + 1)) - ;; - t) TARGET="$OPTARG" - ;; - *) echo "'$OPTARG' is an invalid option/flag" - exit 1 - ;; - esac - done - shift $((OPTIND-1)) - else - PACKAGES+=("$1") - shift - fi - done - - if [[ ${#PACKAGES[@]} -eq 0 ]] ; then - stowsh_help - exit 1 - fi - - for i in ${!PACKAGES[*]}; do - pkg=${PACKAGES[$i]} - if [[ $UNINSTALL -eq 1 ]]; then - if [[ $VERBOSE -gt 0 ]] ; then echoerr "Uninstalling $pkg from $TARGET" ; fi - stowsh_uninstall "$pkg" "$TARGET" - else - if [[ $VERBOSE -gt 0 ]] ; then echoerr "Installing $pkg to $TARGET" ; fi - stowsh_install "$pkg" "$TARGET" - fi - done -fi -- cgit v1.2.3-70-g09d2