├── .gitignore ├── Brewfile ├── License.md ├── README.md ├── ag └── agignore ├── asdf ├── asdfrc └── tool-versions ├── bin ├── atomic-ctags ├── branch_files ├── bundler-search ├── do-not-disturb ├── git-abort ├── git-close-pull-request ├── git-cm ├── git-continue ├── git-opr ├── git-publish ├── git-unreleased ├── mdiff ├── open-tab ├── play-spotify-playlist ├── rbfix ├── servit ├── table-name-rails ├── tat ├── tmux-git-branch ├── tmux-open-session ├── tmux-popup ├── tmux-switch-session ├── vlc-seek └── yr ├── ctags └── ctags ├── git ├── gitconfig └── gitignore ├── hammerspoon ├── fn.lua ├── hyper.lua └── init.lua ├── karabiner ├── generate_space_hyper_json.rb └── karabiner.json ├── nvim ├── .gitignore ├── .stylua.toml ├── doc │ └── kickstart.txt ├── init.lua ├── lua │ ├── config │ │ └── lazy.lua │ └── plugins │ │ ├── comment.lua │ │ ├── conform.lua │ │ ├── gitsigns.lua │ │ ├── jellybeans.lua │ │ ├── mini.lua │ │ ├── nvim-cmp.lua │ │ ├── nvim-lspconfig.lua │ │ ├── oil.lua │ │ ├── scala-metals.lua │ │ ├── surround.lua │ │ ├── telescope.lua │ │ ├── todo-comments.lua │ │ ├── treesitter.lua │ │ ├── trusted-local.lua │ │ ├── unimpaired.lua │ │ ├── vim-sleuth.lua │ │ ├── vim-tmux-nagivator.lua │ │ └── which-key.lua └── rcfiles │ └── chrome ├── postgres └── psqlrc ├── raycast └── script-commands │ ├── checkall.sh │ ├── github-pr-link.rb │ ├── github-prs.sh │ ├── icons │ ├── github-logo.png │ ├── gmail-logo.png │ └── trello-logo.png │ ├── open-email.sh │ ├── open-trello.sh │ ├── open-work-email.sh │ ├── rich-text-clipboard-to-markdown.sh │ └── unreleased.sh ├── ruby ├── default-gems └── pryrc.rb ├── tmux └── tmux.conf ├── vim ├── coc-settings.json ├── ftdetect │ └── dotenv.vim ├── ftplugin │ ├── ruby.vim │ ├── scss.vim │ └── svelte.vim ├── init.vim ├── rcfiles │ ├── chrome │ ├── completion │ ├── convenience │ ├── folding │ ├── general │ ├── git │ ├── help-files │ ├── html │ ├── project-notes │ ├── prose │ ├── search-and-replace │ ├── tabs-windows │ ├── todo │ ├── trusted-local │ ├── visual │ └── vlc ├── rcplugins │ ├── abolish │ ├── ack │ ├── arglist-thank-you-next │ ├── auto-pairs.vim │ ├── better-whitespace │ ├── coc │ ├── commentary │ ├── conflicted │ ├── css3 │ ├── display-table-name │ ├── easy-align │ ├── emmet │ ├── endwise │ ├── eunuch │ ├── exchange │ ├── file-line │ ├── fugitive │ ├── fzf │ ├── fzf-branch-files │ ├── github-colorscheme │ ├── golden-ratio │ ├── goyo-limelight-writing │ ├── graphql │ ├── gsub │ ├── html5 │ ├── javascript │ ├── jellybeans │ ├── json │ ├── lexima.vim │ ├── lightline │ ├── markdown │ ├── markdown-header-mappings │ ├── mkdir │ ├── one-colorscheme │ ├── polyglot │ ├── projectionist │ ├── quicklink │ ├── rake │ ├── repeat │ ├── replace-with-register │ ├── rfactory │ ├── rhubarb │ ├── rsi │ ├── ruby │ ├── scala │ ├── sort-motion │ ├── spec-runner │ ├── surround │ ├── svelte │ ├── system-copy │ ├── text-objects │ ├── titlecase │ ├── tmux-navigator │ ├── tmux-runner │ ├── trusted-local │ ├── typescript │ ├── unimpaired │ ├── vim-pad │ ├── vinegar │ ├── vip │ └── visual-star-search └── vimrc └── zsh ├── completion ├── _flyctl ├── _heroku └── _yarn ├── configs ├── colors.zsh ├── completion.zsh ├── general.zsh ├── git.zsh ├── heroku.zsh ├── history.zsh ├── javascript.zsh ├── keybindings.zsh ├── navigation.zsh ├── ruby.zsh ├── tmux.zsh ├── tmux_man.zsh └── wvim.zsh ├── zshenv └── zshrc /.gitignore: -------------------------------------------------------------------------------- 1 | .netrwhist 2 | vim/autoload/plug.vim 3 | vim/bundle 4 | vim/sessions 5 | karabiner/assets 6 | karabiner/automatic_backups 7 | -------------------------------------------------------------------------------- /Brewfile: -------------------------------------------------------------------------------- 1 | tap 'caskroom/cask' 2 | tap 'goles/battery' 3 | tap 'homebrew/boneyard' 4 | tap 'homebrew/bundle' 5 | tap 'homebrew/core' 6 | tap 'homebrew/services' 7 | tap 'homebrew/versions' 8 | tap 'thoughtbot/formulae' 9 | tap 'universal-ctags/universal-ctags' 10 | brew 'openssl' 11 | brew 'readline' 12 | brew 'sqlite' 13 | brew 'python' 14 | brew 'libxml2' 15 | brew 'autoconf' 16 | brew 'automake' 17 | brew 'awscli' 18 | brew 'git' 19 | brew 'carthage' 20 | brew 'chrome-cli' 21 | brew 'chruby' 22 | brew 'ctags' 23 | brew 'diff-so-fancy' 24 | brew 'jpeg' 25 | brew 'libpng' 26 | brew 'libtiff' 27 | brew 'wxmac' 28 | brew 'erlang' 29 | brew 'elixir' 30 | brew 'ffind' 31 | brew 'fzf' 32 | brew 'go' 33 | brew 'graphviz' 34 | brew 'heroku' 35 | brew 'lua' 36 | brew 'highlight' 37 | brew 'hub' 38 | brew 'perl' 39 | brew 'imagemagick' 40 | brew 'oniguruma' 41 | brew 'jq' 42 | brew 'libevent' 43 | brew 'libffi' 44 | brew 'libyaml' 45 | brew 'mercurial' 46 | brew 'node' 47 | brew 'node@4' 48 | brew 'pcre' 49 | brew 'postgresql', restart_service: true 50 | brew 'pgcli' 51 | brew 'phantomjs' 52 | brew 'pkg-config' 53 | brew 'pngcrush' 54 | brew 'qt5' 55 | brew 'qt@5.5' 56 | brew 'reattach-to-user-namespace' 57 | brew 'redis', restart_service: true 58 | brew 'ruby' 59 | brew 'ruby-install' 60 | brew 'shellcheck' 61 | brew 'source-highlight' 62 | brew 'spark' 63 | brew 'the_silver_searcher' 64 | brew 'tmux' 65 | brew 'trash' 66 | brew 'tree' 67 | brew 'utf8proc' 68 | brew 'vim' 69 | brew 'watch' 70 | brew 'watchman' 71 | brew 'wget' 72 | brew 'youtube-dl' 73 | brew 'zplug' 74 | brew 'goles/battery/battery' 75 | brew 'thoughtbot/formulae/gitsh' 76 | brew 'thoughtbot/formulae/parity' 77 | brew 'thoughtbot/formulae/rcm' 78 | brew 'universal-ctags/universal-ctags/universal-ctags', args: ['HEAD'] 79 | cask 'acorn' 80 | cask 'arq' 81 | cask 'caffeine' 82 | cask 'cloak' 83 | cask 'dash' 84 | cask 'firefox' 85 | cask 'haskell-platform' 86 | cask 'licecap' 87 | cask 'marked' 88 | cask 'ngrok' 89 | cask 'omnifocus' 90 | cask 'qlcolorcode' 91 | cask 'qlimagesize' 92 | cask 'qlmarkdown' 93 | cask 'qlprettypatch' 94 | cask 'qlstephen' 95 | cask 'quicklook-csv' 96 | cask 'quicklook-json' 97 | cask 'screenflow' 98 | cask 'screenhero' 99 | cask 'skype' 100 | cask 'suspicious-package' 101 | cask 'vlc' 102 | cask 'webpquicklook' 103 | cask 'yakyak' 104 | -------------------------------------------------------------------------------- /License.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Chris Toomey 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Dotfiles 2 | ======== 3 | 4 | My dotfiles, a constantly evolving set of configurations which I arguably spend 5 | too much time tweaking, but they make the command line feel like home, so here 6 | we are. 7 | 8 | Vim 9 | --- 10 | 11 | I do love me some Vim, that's for sure. I run Vim with [vim-plug][] to manage 12 | plugins. I have _many_ plugins and customizations (stored in `vim/rcfiles` and 13 | `vim/rcplugins` respectively) which may not be everyone's cup of tea, but I sure 14 | do love a sharp tool. 15 | 16 | [vim-plug]: https://github.com/junegunn/vim-plug 17 | 18 | 19 | Zsh 20 | --- 21 | 22 | I run zsh as my shell, finding it to be a great middle ground between adding 23 | additional niceties and features, while remaining a largely compatible shell 24 | scripting target. I use [zplug][] to manage zsh plugins (like the amazing 25 | [zsh-syntax-highlighting][] plugin), and I use [pure][] as my prompt. 26 | 27 | [zplug]: https://github.com/zplug/zplug 28 | [zsh-syntax-highlighting]: https://github.com/zsh-users/zsh-syntax-highlighting 29 | [pure]: https://github.com/sindresorhus/pure 30 | 31 | 32 | Tmux 33 | ---- 34 | 35 | Tmux allows me to combine processes, shells, and Vim in any way I need for the 36 | project at hand. I'm able to build my own IDE-like experience at the command 37 | line while still using the best tool for any given job. I'm a big fan. 38 | 39 | Core to my tmux work is the combination of two plugins that bring Vim & tmux 40 | together, [vim-tmux-navigator][] for navigation, and [vim-tmux-runner][] for 41 | sending commands from vim to tmux. 42 | 43 | [vim-tmux-navigator]: https://github.com/christoomey/vim-tmux-navigator 44 | [vim-tmux-runner]: https://github.com/christoomey/vim-tmux-runner 45 | 46 | 47 | fzf 48 | --- 49 | 50 | Lastly have [fzf][], "a command-line fuzzy finder". In the end this is a much 51 | smaller component being just a shell command, but I find I use it across each of 52 | Vim, zsh, and tmux, and it has become absolutely core to many of my workflows, 53 | thus it gets top billing. 54 | 55 | [fzf]: https://github.com/junegunn/fzf 56 | 57 | Inspiration 58 | ----------- 59 | 60 | - [thoughtbot](https://github.com/thoughtbot/dotfiles) 61 | - [Ryanb](https://github.com/ryanb/dotfiles) 62 | - [Gary Bernhardt](https://github.com/garybernhardt/dotfiles) 63 | - [Rtomayko](https://github.com/rtomayko/dotfiles) 64 | -------------------------------------------------------------------------------- /ag/agignore: -------------------------------------------------------------------------------- 1 | log 2 | tags 3 | tmp 4 | vendor 5 | .git/ 6 | bower_components/ 7 | node_modules/ 8 | -------------------------------------------------------------------------------- /asdf/asdfrc: -------------------------------------------------------------------------------- 1 | legacy_version_file = yes 2 | -------------------------------------------------------------------------------- /asdf/tool-versions: -------------------------------------------------------------------------------- 1 | nodejs 16.14.2 2 | yarn 1.22.19 3 | ruby 2.6.1 4 | python 2.7.18 5 | -------------------------------------------------------------------------------- /bin/atomic-ctags: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | 5 | if [ -d .git ]; then 6 | tempfile=$(mktemp ".git/tags.XXXXX") 7 | ctags -R --tag-relative=yes --exclude=node_modules --exclude=tmp --exclude=elm-stuff -f "$tempfile" && mv "$tempfile" .git/tags 8 | fi 9 | -------------------------------------------------------------------------------- /bin/branch_files: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | def main(arg) 4 | if arg == "-w" 5 | formatted_list(working_modified_files).each { |file| puts file } 6 | else 7 | formatted_list(branch_modified_files + working_modified_files). 8 | each { |file| puts file } 9 | end 10 | end 11 | 12 | def formatted_list(list) 13 | list.sort.reverse.uniq 14 | end 15 | 16 | def branch_modified_files 17 | `git diff --name-status $(git merge-base master HEAD) HEAD | grep -v '^D'`. 18 | chomp. 19 | split("\n"). 20 | map { |status| current_file(status) } 21 | end 22 | 23 | def working_modified_files 24 | `git status --porcelain | grep -v '^D'`. 25 | chomp. 26 | split("\n"). 27 | map { |status| status.gsub(/^.../, "").split(" -> ").last } 28 | end 29 | 30 | def current_file(status) 31 | _first, *rest = *status.split("\t") 32 | rest.last 33 | end 34 | 35 | main ARGV[0] 36 | -------------------------------------------------------------------------------- /bin/bundler-search: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Search your bundle for the provided pattern 4 | # Requires bundler 1.8+ for execution as a bundler subcommand. 5 | # Examples: 6 | # bundle search Kernel.warn 7 | # bundle search current_user clearance 8 | # bundle search "Change your password" clearance 9 | # 10 | # Arguments: 11 | # 1. What to search for 12 | # 2. Which gem names to search (defaults to all gems) 13 | 14 | pattern="$1"; shift 15 | ag "$pattern" $(bundle show --paths "$@") 16 | -------------------------------------------------------------------------------- /bin/do-not-disturb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | require 'base64' 4 | require 'nokogiri' 5 | require 'open3' 6 | require 'optparse' 7 | require 'pathname' 8 | require 'time' 9 | 10 | # Helpers 11 | def consider_control_center 12 | check_file = Pathname.new('/tmp/calm-notifications-control-center-check.txt') 13 | return if check_file.exist? 14 | 15 | check_file.write( 16 | 'The first time after boot that DND is programatically turned off, ' \ 17 | 'the interface doesn’t update until Control Center is restarted. ' \ 18 | 'This file exists to confirm that has been done.' 19 | ) 20 | system('/usr/bin/killall', 'ControlCenter') 21 | end 22 | 23 | def grab_dnd_xml 24 | prefs_file = Pathname.new(ENV['HOME']).join('Library/Preferences/com.apple.ncprefs.plist') 25 | 26 | outer_xml = Nokogiri::XML(Open3.capture2( 27 | '/usr/bin/plutil', '-extract', 'dnd_prefs', 'xml1', prefs_file.to_path, '-o', '-' 28 | ).first) 29 | 30 | Nokogiri::XML(Open3.capture2( 31 | '/usr/bin/plutil', '-convert', 'xml1', '-', '-o', '-', 32 | stdin_data: Base64.decode64(outer_xml.at('data').text) 33 | ).first) 34 | end 35 | 36 | def commit_status(xml) 37 | binary_plist = Open3.capture2( 38 | '/usr/bin/plutil', '-convert', 'binary1', '-', '-o', '-', 39 | stdin_data: xml.to_s 40 | ).first 41 | 42 | hex_data = binary_plist.unpack1('H*') 43 | 44 | system('/usr/bin/defaults', 'write', 'com.apple.ncprefs.plist', 'dnd_prefs', '-data', hex_data) 45 | system('/usr/bin/killall', 'usernoted') 46 | end 47 | 48 | def dnd_on?(xml) 49 | xml.xpath('boolean(//key[text()="userPref"]/following-sibling::dict/key[text()="enabled"])') 50 | end 51 | 52 | def status_dnd 53 | xml = grab_dnd_xml 54 | puts(dnd_on?(xml) ? 'on' : 'off') 55 | end 56 | 57 | def enable_dnd 58 | xml = grab_dnd_xml 59 | return if dnd_on?(xml) 60 | 61 | user_pref = <<~XML.freeze 62 | userPref 63 | 64 | date 65 | #{Time.now.utc.iso8601} 66 | enabled 67 | 68 | reason 69 | 1 70 | 71 | XML 72 | 73 | xml.at('dict').add_child(user_pref) 74 | 75 | commit_status(xml) 76 | end 77 | 78 | def disable_dnd 79 | xml = grab_dnd_xml 80 | return unless dnd_on?(xml) 81 | 82 | xml.xpath('//key[text()="userPref"]/following-sibling::dict').remove 83 | xml.xpath('//key[text()="userPref"]').remove 84 | 85 | commit_status(xml) 86 | consider_control_center 87 | end 88 | 89 | def toggle_dnd 90 | xml = grab_dnd_xml 91 | dnd_on?(xml) ? disable_dnd : enable_dnd 92 | end 93 | 94 | # Options 95 | ARGV.push('--help') if ARGV.empty? 96 | 97 | OptionParser.new do |parser| 98 | parser.banner = <<~BANNER 99 | Enable, disable, toggle, and show status of Do Not Disturb on macOS Big Sur. 100 | 101 | Settings may take a few seconds to visually come into effect. 102 | 103 | Usage: 104 | #{Pathname.new($PROGRAM_NAME).basename} [-h|--help] 105 | BANNER 106 | end.parse! 107 | 108 | # Main 109 | if Open3.capture2('/usr/bin/sw_vers', '-productVersion').first.split('.').first != '11' 110 | abort 'This script only works on macOS Big Sur. For Monterey and above, use the Shortcuts command line tool.' 111 | end 112 | 113 | case ARGV[0] 114 | when 'status' 115 | status_dnd 116 | when 'on' 117 | enable_dnd 118 | when 'off' 119 | disable_dnd 120 | when 'toggle' 121 | toggle_dnd 122 | else 123 | warn('Invalid command! Try "--help"') 124 | end 125 | -------------------------------------------------------------------------------- /bin/git-abort: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Abort a rebase, merge, `am`, a cherry-pick or a revert, depending on the situation. 4 | 5 | set -eou pipefail 6 | 7 | GIT_REPO_ROOT=$(git rev-parse --show-toplevel) 8 | 9 | if [[ -e "$GIT_REPO_ROOT/.git/CHERRY_PICK_HEAD" ]] ; then 10 | exec git cherry-pick --abort "$@" 11 | elif [[ -e "$GIT_REPO_ROOT/.git/REVERT_HEAD" ]] ; then 12 | exec git revert --abort "$@" 13 | elif [[ -e "$GIT_REPO_ROOT/.git/rebase-apply/applying" ]] ; then 14 | exec git am --abort "$@" 15 | elif [[ -e "$GIT_REPO_ROOT/.git/rebase-apply" ]] ; then 16 | exec git rebase --abort "$@" 17 | elif [[ -e "$GIT_REPO_ROOT/.git/rebase-merge" ]] ; then 18 | exec git rebase --abort "$@" 19 | elif [[ -e "$GIT_REPO_ROOT/.git/MERGE_MODE" ]] ; then 20 | exec git merge --abort "$@" 21 | else 22 | echo git-abort: unknown state 23 | exit 1 24 | fi 25 | -------------------------------------------------------------------------------- /bin/git-close-pull-request: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # Usage: git cpr 3 | # 4 | # Run this from a branch which has an upstream remote branch, and an associated 5 | # pull request. 6 | # 7 | # The script will merge the branch into master, push master (which will 8 | # automatically close the pull request), and delete both the local and remote 9 | # branches. 10 | 11 | GitCall = Struct.new(:cmd, :type, :pretend_resp) 12 | 13 | class ClosesPullRequests 14 | def initialize(args) 15 | @args = args 16 | end 17 | 18 | def run 19 | remember_current_branch 20 | confirm_ci_status_green 21 | confirm_upstream_tracking_branch 22 | ensure_working_dir_and_index_clean 23 | fetch_origin 24 | ensure_feature_branch_in_sync 25 | ensure_master_in_sync 26 | checkout_master 27 | merge_local_banch 28 | push_master 29 | delete_remote_branch 30 | delete_local_branch 31 | end 32 | 33 | private 34 | 35 | def die_with_msg(msg) 36 | puts " -> \e[31m#{msg}\e[0m" 37 | exit 1 38 | end 39 | 40 | def exit_with_warning(msg) 41 | puts " -> \e[33m#{msg}\e[0m" 42 | exit 2 43 | end 44 | 45 | def has_ci_enabled? 46 | `hub ci-status`.chomp != "no status" 47 | end 48 | 49 | def confirm_ci_status_green 50 | # gc = GitCall.new("hub ci-status > /dev/null 2>&1", :command, true) 51 | if has_ci_enabled? 52 | puts "Confirming ci-status on PR is green..." 53 | if force? 54 | puts " --force ignroing CI" 55 | else 56 | ci_status = `hub ci-status`.chomp 57 | if ci_status == "failure" 58 | die_with_msg " CI failed. Aborting" 59 | elsif ci_status == "pending" 60 | exit_with_warning " CI pending. Aborting" 61 | elsif `echo $?`.chomp.to_i != 0 62 | die_with_msg " Non-zero exit from CI check. Aborting" 63 | end 64 | end 65 | else 66 | puts " CI not enabled, skipping check..." 67 | end 68 | end 69 | 70 | def remember_current_branch 71 | puts "Capturing current branch name..." 72 | current_branch_cmd = "git rev-parse --abbrev-ref HEAD" 73 | gc = GitCall.new(current_branch_cmd, :query, "my-feature-branch") 74 | @current_branch = run_or_print(gc) 75 | end 76 | 77 | def confirm_upstream_tracking_branch 78 | puts "Confirming upstream tracking branch configured..." 79 | confirm_cmd = "git config branch.#{@current_branch}.remote" 80 | gc = GitCall.new(confirm_cmd, :command, true) 81 | if run_or_print(gc) 82 | upstream_branch_cmd = 83 | "git rev-parse --abbrev-ref --symbolic-full-name @{u}" 84 | gc = GitCall.new(upstream_branch_cmd, :query, "upstream-feature-branch") 85 | @upstream_branch = run_or_print(gc).gsub("origin/", "") 86 | else 87 | die_with_msg "no upstream branch configured. Aborting" 88 | end 89 | end 90 | 91 | def ensure_working_dir_and_index_clean 92 | puts "Ensuring that index and working directory are clean..." 93 | index_clean_cmd = "git diff --cached --exit-code" 94 | index_gc = GitCall.new(index_clean_cmd, :command, true) 95 | working_dir_clean_cmd = "git diff --exit-code" 96 | working_dir_gc = GitCall.new(working_dir_clean_cmd, :command, true) 97 | unless run_or_print(index_gc) && run_or_print(working_dir_gc) 98 | die_with_msg "Index or working dir not clean. Aborting." 99 | end 100 | end 101 | 102 | def checkout_master 103 | puts "Checking out master..." 104 | gc = GitCall.new("git checkout master", :command, true) 105 | run_or_print(gc) 106 | end 107 | 108 | def fetch_origin 109 | puts "Fetching origin to confirm local and remote in sync..." 110 | gc = GitCall.new("git fetch origin", :command, true) 111 | run_or_print(gc) 112 | end 113 | 114 | def ensure_master_in_sync 115 | ensure_branch_in_sync_with_upstream("master", "master") 116 | end 117 | 118 | def ensure_feature_branch_in_sync 119 | ensure_branch_in_sync_with_upstream(@current_branch, @upstream_branch) 120 | end 121 | 122 | def ensure_branch_in_sync_with_upstream(branch, upstream) 123 | puts "Ensuring branch [#{branch}] is in sync with its upstream..." 124 | local_tip_commit = tip_commit_of_branch(branch) 125 | remote_tip_commit = tip_commit_of_branch("origin/#{upstream}") 126 | unless local_tip_commit == remote_tip_commit 127 | die_with_msg "Branch [#{branch}] was out of date; rebase needed. Aborting" 128 | end 129 | end 130 | 131 | def merge_local_banch 132 | puts "Merging branch into master..." 133 | merge_cmd = "git merge --ff-only #{@current_branch}" 134 | gc = GitCall.new(merge_cmd, :command, true) 135 | unless run_or_print(gc) 136 | run_or_print GitCall.new("git checkout -", :command, true) 137 | die_with_msg "Branch '#{@current_branch}' is not fast-forwardable" 138 | end 139 | end 140 | 141 | def push_master 142 | puts "Pushing updated master branch..." 143 | gc = GitCall.new("git push origin master", :command, true) 144 | run_or_print(gc) 145 | end 146 | 147 | def delete_remote_branch 148 | puts "Deleting remote branch..." 149 | gc = GitCall.new("git push origin :#{@upstream_branch}", :command, true) 150 | run_or_print(gc) 151 | end 152 | 153 | def delete_local_branch 154 | puts "Deleting local branch..." 155 | gc = GitCall.new("git branch -d #{@current_branch}", :command, true) 156 | run_or_print(gc) 157 | end 158 | 159 | def tip_commit_of_branch(branch) 160 | gc = GitCall.new("git rev-parse #{branch}", :query, "2ab342f") 161 | run_or_print(gc) 162 | end 163 | 164 | def force? 165 | has_arg? ["-f", "--force"] 166 | end 167 | 168 | def pretend? 169 | has_arg? ["-p", "--pretend"] 170 | end 171 | 172 | def has_arg?(flags) 173 | (flags & @args).any? 174 | end 175 | 176 | def run_or_print(gc) 177 | if pretend? 178 | gc.pretend_resp 179 | elsif gc.type == :command 180 | system("#{gc.cmd} > /dev/null 2>&1") 181 | else 182 | `#{gc.cmd}`.chomp 183 | end 184 | end 185 | end 186 | 187 | ClosesPullRequests.new(ARGV).run 188 | -------------------------------------------------------------------------------- /bin/git-cm: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Small wrapper around git commit. Bare 'cm' will enter normal git commit 4 | # editor, but with args it will do a direct `commit -m` 5 | 6 | if [[ $# > 0 ]]; then 7 | git commit -m "$@" 8 | else 9 | git commit -v 10 | fi 11 | -------------------------------------------------------------------------------- /bin/git-continue: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Continue a rebase or cherry-pick in the event of conflicts. 4 | 5 | set -eou pipefail 6 | 7 | GIT_REPO_ROOT=$(git rev-parse --show-toplevel) 8 | 9 | if [[ -e "$GIT_REPO_ROOT/.git/CHERRY_PICK_HEAD" ]] ; then 10 | exec git cherry-pick --continue "$@" 11 | elif [[ -e "$GIT_REPO_ROOT/.git/rebase-apply/applying" ]] ; then 12 | exec git rebase --continue "$@" 13 | elif [[ -e "$GIT_REPO_ROOT/.git/rebase-apply" ]] ; then 14 | exec git rebase --continue "$@" 15 | elif [[ -e "$GIT_REPO_ROOT/.git/rebase-merge" ]] ; then 16 | exec git rebase --continue "$@" 17 | elif [[ -e "$GIT_REPO_ROOT/.git/MERGE_MSG" ]] ; then 18 | exec git commit 19 | else 20 | echo git-abort: unknown state 21 | exit 1 22 | fi 23 | -------------------------------------------------------------------------------- /bin/git-opr: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | #/ Usage: git pr [] 3 | #/ Open the pull request page for , or the current branch if not 4 | #/ specified. Lands on the new pull request page when no PR exists yet. 5 | #/ The local branch must be tracking the remote branch. 6 | 7 | # Based on script from @rtomayko. Translated into ruby and now uses branch 8 | # tracking rather than expecting local and remote branch to have same name 9 | 10 | require "json" 11 | require "yaml" 12 | 13 | OPEN_SWITCHES = %{-o --open} 14 | 15 | def remote_url 16 | url = chomped_system_call('git config --get remote.origin.url') 17 | repo_with_owner = url.match(/:(.*)\.git/) 18 | 19 | if repo_with_owner 20 | repo_with_owner[1] 21 | else 22 | die 'Unable to determine repo/owner for remote origin. Using https?' 23 | end 24 | end 25 | 26 | def oauth_token 27 | hub_config = YAML.load_file(File.expand_path('~/.config/hub')) 28 | hub_config['github.com'][0]['oauth_token'] 29 | end 30 | 31 | def open_or_build_pull_request 32 | auth = "Authorization: token #{oauth_token}" 33 | pulls_endpoint = "https://api.github.com/repos/#{remote_url}/pulls" 34 | response = `curl --silent -H '#{auth}' #{pulls_endpoint}` 35 | pulls = JSON.parse(response) 36 | pull = pulls.detect { |pull| pull["head"]["ref"] == remote_tracking_branch } 37 | if !pull.nil? 38 | system "open-tab --reload #{pull['html_url']}" 39 | else 40 | system("open https://github.com/#{remote_url}/pull/#{remote_tracking_branch}") 41 | end 42 | end 43 | 44 | def remote_tracking_branch 45 | command = 'git rev-parse --abbrev-ref --symbolic-full-name @{u} 2>/dev/null' 46 | tracking = chomped_system_call(command) 47 | 48 | if tracking == '@{u}' 49 | die 'Current local branch not setup to track remote branch.' 50 | else 51 | branch_without_remote_name(tracking) 52 | end 53 | end 54 | 55 | def branch_without_remote_name(branch_and_remote) 56 | branch = branch_and_remote.match(/origin\/(.*)/) 57 | 58 | if branch 59 | branch[1] 60 | else 61 | die 'Expected remote to be \'origin\'' 62 | end 63 | end 64 | 65 | def chomped_system_call(command) 66 | `#{command}`.chomp 67 | end 68 | 69 | def open_pull_request_for_repo_branch(repo, branch) 70 | system("open https://github.com/#{repo}/pull/#{branch}") 71 | end 72 | 73 | def opening? 74 | argument = ARGV.pop 75 | argument && OPEN_SWITCHES.include?(argument) 76 | end 77 | 78 | def ensure_published 79 | if not_published? 80 | system("git publish") 81 | end 82 | end 83 | 84 | def not_published? 85 | !system("git upstream > /dev/null 2>&1") 86 | end 87 | 88 | def main 89 | # repo = remote_url 90 | # branch = remote_tracking_branch 91 | if opening? 92 | system 'git log --reverse master..HEAD --format="%H%n%s%n%b" > .git/pr-commits' 93 | system 'gh compare' 94 | system 'gh pull-request' 95 | else 96 | ensure_published 97 | open_or_build_pull_request 98 | end 99 | end 100 | 101 | def die(msg) 102 | puts msg 103 | exit 1 104 | end 105 | 106 | main 107 | -------------------------------------------------------------------------------- /bin/git-publish: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # 3 | # Usage: git publish 4 | # Open the pull request page for , or the current branch if not 5 | # specified. Lands on the new pull request page when no PR exists yet. 6 | # The local branch must be tracking the remote branch. 7 | 8 | def get_current_branch 9 | `git rev-parse --abbrev-ref HEAD`.chomp 10 | end 11 | 12 | def main 13 | current_branch = get_current_branch 14 | if current_branch == 'master' 15 | $stderr.puts "Currently on master, aborting." 16 | exit 1 17 | else 18 | system("git push -u origin #{current_branch}:#{current_branch}") 19 | end 20 | end 21 | 22 | main 23 | -------------------------------------------------------------------------------- /bin/git-unreleased: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | 5 | git fetch --all 6 | git pull 7 | 8 | echo "\nStaging unreleased" 9 | git log --oneline --decorate staging/master..master 10 | 11 | 12 | echo "\nProduction unreleased" 13 | git log --oneline --decorate production/master..master 14 | -------------------------------------------------------------------------------- /bin/mdiff: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | if git ls-files | grep -qF "$1"; then 6 | git diff --color=always master -- "$1" 7 | else 8 | git diff --color=always /dev/null "$1" 9 | fi 10 | -------------------------------------------------------------------------------- /bin/open-tab: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env -S ruby --disable-gems -x 2 | 3 | require 'optparse' 4 | 5 | class TabOpener 6 | TAB_NOT_FOUND = :tab_not_found 7 | 8 | def initialize(app_url, options) 9 | @app_url = app_url 10 | @options = options 11 | end 12 | 13 | def self.open_for(app_url, options) 14 | new(app_url, options).open! 15 | end 16 | 17 | def open! 18 | if tab_exists? 19 | activate app_tab 20 | else 21 | open_app_in_new_tab 22 | end 23 | unless options[:detached] 24 | focus_chrome 25 | end 26 | end 27 | 28 | private 29 | 30 | attr_reader :app_url, :options 31 | 32 | def app_tab 33 | @app_tab ||= 34 | begin 35 | tab_info = `/opt/homebrew/bin/chrome-cli list links | grep -Fn '#{app_url}' | cut -d ':' -f 1`.chomp.to_i 36 | if tab_info != 0 37 | tab_info 38 | else 39 | TAB_NOT_FOUND 40 | end 41 | end 42 | end 43 | 44 | def open_app_in_new_tab 45 | system "/opt/homebrew/bin/chrome-cli open #{app_url} > /dev/null 2>&1" 46 | end 47 | 48 | def tab_exists? 49 | app_tab != TAB_NOT_FOUND 50 | end 51 | 52 | def activate(tab_index) 53 | system "osascript -e 'tell application \"Google Chrome\" to set active tab index of first window to #{tab_index}'" 54 | end 55 | 56 | def focus_chrome 57 | system %{osascript -e 'tell application \"Google Chrome\" to activate'} 58 | end 59 | end 60 | 61 | def desired_app_url 62 | if app_url = ARGV[0] 63 | app_url 64 | else 65 | project_name = Dir.pwd.split("/").last 66 | "http://#{project_name}.dev" 67 | end 68 | end 69 | 70 | options = {} 71 | OptionParser.new do |opts| 72 | opts.banner = "Usage: open-tab [options] []" 73 | 74 | opts.on("-r", "--[no-]reload", "Reload tab after activating") do |r| 75 | options[:reload] = r 76 | end 77 | 78 | opts.on("-d", "--detached", "Detached -- do not focus chrome") do |d| 79 | options[:detached] = d 80 | end 81 | end.parse! 82 | 83 | TabOpener.open_for(desired_app_url, options) 84 | -------------------------------------------------------------------------------- /bin/play-spotify-playlist: -------------------------------------------------------------------------------- 1 | #!/usr/bin/osascript 2 | 3 | on run argv 4 | tell application "Spotify" 5 | play track ("spotify:playlist:" & (item 1 of argv)) 6 | end tell 7 | end run 8 | -------------------------------------------------------------------------------- /bin/rbfix: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | 5 | cat - > ./tmp/rubocop-fix 6 | rubocop ./tmp/rubocop-fix --auto-correct &>/dev/null || true 7 | cat ./tmp/rubocop-fix 8 | -------------------------------------------------------------------------------- /bin/servit: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # starts rails or middleman server 4 | # opens with the port configured for pow DNS 5 | # copies the ".dev" URL 6 | 7 | app_name=$(basename "`pwd`") 8 | port=`cat ~/.pow/$app_name 2> /dev/null || [[ -f .vimrc.local ]] && cat .vimrc.local | grep 'g:app_url' | grep -oE '[0-9]+' || echo 3312` 9 | 10 | if [[ -f Procfile.dev ]]; then 11 | server_cmd="bundle check || bundle install && yarn && heroku local -f Procfile.dev -e .env.local" 12 | elif [[ -f config/environment.rb ]]; then 13 | server_cmd="bundle check || bundle install && PORT='$port' bin/rails server" 14 | elif [[ -f yarn.lock ]]; then 15 | server_cmd="yarn start --port=$port" 16 | elif [[ -f nwb.config.js ]]; then 17 | server_cmd="PORT=$port npm start" 18 | elif [[ -f package.json ]]; then 19 | server_cmd="PORT=$port npm start" 20 | elif grep -q 'razzle start' package.json > /dev/null 2>&1; then 21 | server_cmd="PORT=$port npm start" 22 | elif [[ -f config.rb ]] && [[ -d source ]]; then 23 | server_cmd="bundle && bundle exec middleman -p $port" 24 | else 25 | server_cmd="python -m SimpleHTTPServer $port" 26 | fi 27 | 28 | if [[ -n $port ]]; then 29 | echo "http://`basename $(pwd)`.dev" | pbcopy 30 | echo "Dev URL loaded into clipboard" 31 | eval $server_cmd 32 | else 33 | echo "App port not set in ~/.pow" 34 | fi 35 | -------------------------------------------------------------------------------- /bin/table-name-rails: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | require 'active_support/inflector' 4 | 5 | puts ARGV.first.gsub("app/models/", "").gsub(/\.rb$/, "").gsub("\/","_").tableize 6 | -------------------------------------------------------------------------------- /bin/tat: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # Attach or create tmux session named the same as current directory. 4 | 5 | path_name="$(basename "$PWD" | tr . -)" 6 | session_name=${1-$path_name} 7 | 8 | not_in_tmux() { 9 | [ -z "$TMUX" ] 10 | } 11 | 12 | session_exists() { 13 | tmux list-sessions | sed -E 's/:.*$//' | grep -q "^$session_name$" 14 | } 15 | 16 | create_detached_session() { 17 | (TMUX='' tmux new-session -Ad -s "$session_name") 18 | } 19 | 20 | create_if_needed_and_attach() { 21 | if not_in_tmux; then 22 | tmux new-session -As "$session_name" 23 | else 24 | if ! session_exists; then 25 | create_detached_session 26 | fi 27 | tmux switch-client -t "$session_name" 28 | fi 29 | } 30 | 31 | create_if_needed_and_attach 32 | -------------------------------------------------------------------------------- /bin/tmux-git-branch: -------------------------------------------------------------------------------- 1 | #!/bin/zsh 2 | 3 | set -e 4 | 5 | git branch --color=always --sort=-committerdate | \ 6 | grep -v '^* ' | \ 7 | grep -v '^\s\+master' | \ 8 | grep -v '^\s\+main' | \ 9 | grep -v '^\s\+develop' | \ 10 | grep -v '^\s\+development' | \ 11 | fzf --reverse --ansi --select-1 --multi | \ 12 | xargs echo | \ 13 | sed -E 's/^[ \t]*//' | \ 14 | xargs git checkout 15 | 16 | tmux refresh-client -S 17 | -------------------------------------------------------------------------------- /bin/tmux-open-session: -------------------------------------------------------------------------------- 1 | #!/bin/zsh 2 | 3 | set -e 4 | 5 | source ~/.zsh/configs/navigation.zsh 6 | 7 | main() { 8 | project=$(projects | fzf --reverse) 9 | if [ ! -z "$project" ]; then 10 | (cd "$project" && tat) 11 | fi 12 | } 13 | 14 | _cdpath_directories() { 15 | modified_in_last_days=${1:-999} 16 | echo "${CDPATH//:/\n}" | while read dir; do 17 | find -L "$dir" \ 18 | -not -path '*/\.*' \ 19 | -type d \ 20 | -atime -"$modified_in_last_days" \ 21 | -maxdepth 1 22 | done 23 | } 24 | 25 | _is_a_git_repo() { 26 | while read dir; do 27 | if [[ -d "$dir/.git" ]]; then 28 | basename "$dir" 29 | fi 30 | done 31 | } 32 | 33 | projects() { 34 | _cdpath_directories $1 | _is_a_git_repo 35 | } 36 | 37 | main 38 | -------------------------------------------------------------------------------- /bin/tmux-popup: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | width=${2:-85%} 4 | 5 | tmux popup -d '#{pane_current_path}' -xC -yC -w$width -h85% -E "${1:-zsh}" || true 6 | -------------------------------------------------------------------------------- /bin/tmux-switch-session: -------------------------------------------------------------------------------- 1 | #!/bin/zsh 2 | 3 | set -e 4 | 5 | tmux list-sessions -F '#{session_activity}:#{session_name}' | \ 6 | sort -nr | \ 7 | cut -d ':' -f 2 | \ 8 | grep -v "^$(tmux display-message -p '#S')$" | \ 9 | fzf --reverse | \ 10 | xargs tmux switch-client -t 11 | -------------------------------------------------------------------------------- /bin/vlc-seek: -------------------------------------------------------------------------------- 1 | #!/usr/bin/osascript 2 | # Step forward. The step width can be changed below. 3 | 4 | # nmap :call system("vlc-seek forward") 5 | # nmap :call system("vlc-seek") 6 | 7 | on run argv 8 | if running of application "/Applications/VLC.app" is true then 9 | tell application "/Applications/VLC.app" 10 | # Step width (1=extraShort, 2=short, 3=medium, 4=long). 11 | if (count of argv) > 0 and item 1 of argv is equal to "forward" then 12 | step forward 2 13 | else 14 | step backward 2 15 | end if 16 | end tell 17 | end if 18 | end run 19 | -------------------------------------------------------------------------------- /bin/yr: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -eou pipefail 4 | 5 | frontend_proc_index=3 6 | 7 | main() { 8 | yarn 9 | run_mprocs_cmd "{c: select-proc, index: $frontend_proc_index}" 10 | run_mprocs_cmd "{c: restart-proc}" 11 | echo 12 | echo " >> Frontend server restarting..." 13 | } 14 | 15 | run_mprocs_cmd() { 16 | mprocs --server 127.0.0.1:4050 --ctl "$@" 17 | } 18 | 19 | main 20 | -------------------------------------------------------------------------------- /ctags/ctags: -------------------------------------------------------------------------------- 1 | --sort=yes 2 | --tag-relative=yes 3 | --recurse 4 | --exclude=node_modules 5 | --exclude=build 6 | --exclude=coverage 7 | --exclude=vendor 8 | --exclude=bower_components 9 | 10 | 11 | --langdef=Elm 12 | --langmap=Elm:.elm 13 | --regex-Elm=/^ *([[:lower:]][[:alnum:]_]+)[[:blank:]]*:[^:].*->.*/\1/f,function,functions/ 14 | --regex-Elm=/^ *([[:lower:]][[:alnum:]_]+)[[:blank:]]*:[^:][^-]+$/\1/c,constant,constants/ 15 | --regex-Elm=/^port +([[:lower:]][[:alnum:]_]+)[[:blank:]]*:[^:]/\1/p,port,ports/ 16 | --regex-Elm=/^type +([[:upper:]][[:alnum:]_]+)/\1/t,type,types/ 17 | --regex-Elm=/^type[[:blank:]]+alias[[:blank:]]+([[:upper:]][[:alnum:]_]+)/\1/a,type-alias,type-aliases/ 18 | -------------------------------------------------------------------------------- /git/gitconfig: -------------------------------------------------------------------------------- 1 | [alias] 2 | aa = add --all 3 | bselect = !git branch | grep -v '^*' | fzf-tmux --reverse | xargs git checkout 4 | ca = commit --amend --verbose 5 | car = commit --amend --no-edit 6 | co = checkout 7 | conflicted = !vim +Conflicted 8 | copysha = !git rev-parse HEAD | pbcopy 9 | df = "!f() { [ \"$GIT_PREFIX\" != \"\" ] && cd "$GIT_PREFIX"; git diff --color $@ | diff-so-fancy | less --tabs=4 -RFX; }; f" 10 | dfw = !git df -w 11 | dc = "!f() { [ \"$GIT_PREFIX\" != \"\" ] && cd "$GIT_PREFIX"; git diff --color --cached $@ | diff-so-fancy | less --tabs=4 -RFX; }; f" 12 | dcw = !git dc -w 13 | yep = !vim hello.md 14 | down = !git checkout $(git trunkname) && git pull && git gone 15 | fall = fetch --all 16 | fad = !git add $(git ls-files --others --exclude-standard -m | fzf --reverse --multi) 17 | fadd = !git fadd 18 | glog = log -E -i --grep 19 | gone = !"git fetch -p && git for-each-ref --format '%(refname:short) %(upstream:track)' | awk '$2 == \"[gone]\" {print $1}' | xargs -r git branch -D" 20 | dup = !git checkout development && git fetch origin && echo && git sl development..origin/development && echo && git pull --quiet && git checkout - 21 | mup = !git checkout $(git trunkname) && git fetch origin && echo && git sl $(git trunkname)..origin/$(git trunkname) && echo && git pull --quiet && git checkout - 22 | pl = pull 23 | ps = push 24 | rbc = rebase --continue 25 | riu = !git rebase -i $(git rev-parse --abbrev-ref --symbolic-full-name @{u}) 26 | rid = !git rebase -i $(git merge-base development HEAD) 27 | rim = !git rebase -i $(git merge-base $(git trunkname) HEAD) 28 | dim = !git rebase -i $(git merge-base development HEAD) 29 | rdup = !git dup && git rebase development 30 | rmup = !git mup && git rebase master 31 | sl = log --oneline --decorate -20 32 | sla = log --oneline --decorate --graph --all -20 33 | slp = log --oneline --decorate 34 | slap = log --oneline --decorate --graph --all 35 | todo = !git log --format=%B -n 1 | grep -A999 '^This change$' 36 | trunkname = !git branch -l main master --format '%(refname:short)' 37 | uncommit = reset --soft HEAD^ 38 | unstage = reset 39 | upstream = rev-parse --abbrev-ref --symbolic-full-name @{u} 40 | ureset = !git reset --hard $(git upstream) 41 | [color] 42 | ui = auto 43 | [core] 44 | pager = delta --dark 45 | excludesfile = ~/.gitignore 46 | autocrlf = input 47 | editor = vim 48 | commentChar = ";" 49 | [interactive] 50 | diffFilter = delta --color-only 51 | [merge] 52 | ff = only 53 | [push] 54 | default = upstream 55 | [fetch] 56 | prune = true 57 | [gitsh "color"] 58 | default = cyan 59 | [gitsh] 60 | defaultcommand = status -sb 61 | gitcommand = hub 62 | nogreeting = true 63 | prompt = "\n%D %c(%b%#)%w ➜" 64 | [user] 65 | name = Chris Toomey 66 | email = chris@ctoomey.com 67 | signingkey = Chris Toomey 68 | [filter "lfs"] 69 | clean = git-lfs clean -- %f 70 | smudge = git-lfs smudge -- %f 71 | process = git-lfs filter-process 72 | required = true 73 | [pull] 74 | ff = only 75 | [init] 76 | defaultBranch = main 77 | -------------------------------------------------------------------------------- /git/gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | *.sw[nop] 3 | .bundle 4 | .byebug_history 5 | db/*.sqlite3 6 | log/*.log 7 | rerun.txt 8 | tags 9 | !tags/ 10 | tmp/**/* 11 | !tmp/cache/.keep 12 | *.pyc 13 | vim/view 14 | 15 | .project-notes 16 | .vimrc.local 17 | node_modules 18 | .project-notes/* 19 | **/.notes/* 20 | .notes 21 | .notes-archive/* 22 | .vim/ 23 | -------------------------------------------------------------------------------- /hammerspoon/fn.lua: -------------------------------------------------------------------------------- 1 | local function openApp(name) 2 | return function() 3 | hs.application.launchOrFocus(name) 4 | if name == 'Finder' then 5 | hs.appfinder.appFromName(name):activate() 6 | end 7 | end 8 | end 9 | 10 | local function execute(command) 11 | print("Debug: running command `" .. command .. "`") 12 | local _, exitedSuccessfully, _, _ = hs.execute(command) 13 | if not exitedSuccessfully then 14 | hs.notify.show("Command exited non-zero", "Command: `" .. command .."`") 15 | end 16 | end 17 | 18 | -- https://manual.raycast.com/deeplinks#e460b1f1c034468db3fbf9f028d8f01c 19 | -- Get the deep link from Cmd-k in the menu 20 | local function openRaycastExtension(extensionDeepLinkPath) 21 | return function() 22 | execute("open -g " .. "raycast://extensions/" .. extensionDeepLinkPath) 23 | end 24 | end 25 | 26 | local function windowCommand(commandName) 27 | return function() 28 | print("Debug: running function 'windowCommand' with: `" .. commandName .. "`") 29 | openRaycastExtension("raycast/window-management/" .. commandName)() 30 | end 31 | end 32 | 33 | local function openRaycastScriptCommand(scriptCommand) 34 | return function() 35 | execute("open " .. "raycast://script-commands/" .. scriptCommand) 36 | end 37 | end 38 | 39 | local function reloadHammerspoonConfig() 40 | hs.reload() 41 | hs.notify.show("Hammerspoon", "Config reloaded", "") 42 | end 43 | 44 | local function sendKeys(mods, key) 45 | return function() 46 | hs.eventtap.keyStroke(mods, key) 47 | end 48 | end 49 | 50 | local function runShortcut(shortcutName) 51 | return function() 52 | execute('shortcuts run "' .. shortcutName .. '"') 53 | end 54 | end 55 | 56 | local function openTab(tabUrl) 57 | return function() 58 | execute("~/bin/open-tab '" .. "https://" .. tabUrl .. "'") 59 | end 60 | end 61 | 62 | return { 63 | openApp = openApp, 64 | openTab = openTab, 65 | openRaycastExtension = openRaycastExtension, 66 | openRaycastScriptCommand = openRaycastScriptCommand, 67 | sendKeys = sendKeys, 68 | reloadHammerspoonConfig = reloadHammerspoonConfig, 69 | runShortcut = runShortcut, 70 | windowCommand = windowCommand, 71 | } 72 | -------------------------------------------------------------------------------- /hammerspoon/hyper.lua: -------------------------------------------------------------------------------- 1 | -- A variable for the Hyper Mode 2 | local k = hs.hotkey.modal.new({}, 'F19') 3 | 4 | local menuItem = hs.menubar.new(true, 'hyperKey') 5 | menuItem:setTitle("Hyper") 6 | 7 | local function table_is_empty(t) 8 | if type(t) ~= "table" then 9 | return false 10 | end 11 | return next(t) == nil 12 | end 13 | 14 | function k:entered() 15 | menuItem:setTitle("HYPER") 16 | hs.timer.doAfter(1, function() k:exit() end) 17 | end 18 | 19 | function k:exited() 20 | menuItem:setTitle("Hyper") 21 | end 22 | 23 | local function exit() 24 | k:exit() 25 | end 26 | 27 | local function runAndExit(action) 28 | return function() 29 | k:exit() 30 | action() 31 | end 32 | end 33 | 34 | local function bind(mods, key, action) 35 | k:bind(mods, key, runAndExit(action)) 36 | -- hs.logger.i("hello") 37 | if table_is_empty(mods) then 38 | hs.hotkey.bind({ "ctrl", "alt", "cmd" }, key, action) 39 | else 40 | hs.hotkey.bind({ "ctrl", "alt", "cmd", "shift" }, key, action) 41 | end 42 | end 43 | 44 | local function bindAll(keyMap) 45 | for key, bindings in pairs(keyMap) do 46 | if type(bindings) == 'table' then 47 | for _, binding in pairs(bindings) do 48 | if type(binding) == "table" then 49 | for mods, action in pairs(binding) do 50 | bind(mods, key, action) 51 | end 52 | else 53 | bind({}, key, binding) 54 | end 55 | end 56 | elseif type(bindings) == 'function' then 57 | bind({}, key, bindings) 58 | else 59 | print('config value for ' .. key .. ' is neither a table nor a function') 60 | end 61 | 62 | end 63 | end 64 | 65 | return { 66 | exit = exit, 67 | bind = bind, 68 | bindAll = bindAll, 69 | } 70 | -------------------------------------------------------------------------------- /hammerspoon/init.lua: -------------------------------------------------------------------------------- 1 | -- local fn = require("fn") 2 | -- local hyper = require("hyper") 3 | 4 | -- local windowModal = hs.hotkey.modal.new({}, nil) 5 | 6 | -- local old_hyper = { "cmd", "shift", "ctrl" } 7 | 8 | -- hyper.bindAll({ 9 | -- ["\\"] = fn.openRaycastExtension("raycast/clipboard-history/clipboard-history"), 10 | -- ["]"] = fn.openRaycastExtension("raycast/snippets/search-snippets"), 11 | -- ["0"] = function() windowModal:enter() end, 12 | -- ["1"] = { 13 | -- fn.openApp("1Password"), 14 | -- { ["shift"] = fn.sendKeys(old_hyper, "1") }, 15 | -- }, 16 | -- ["."] = { 17 | -- fn.runShortcut("Start Session"), 18 | -- { ["shift"] = fn.openRaycastExtension("jameslyons/session/session-finish") }, 19 | -- }, 20 | -- ["space"] = fn.openApp("Finder"), 21 | -- a = fn.openRaycastExtension("raycast/floating-notes/toggle-floating-notes-window"), 22 | -- b = fn.sendKeys(old_hyper, "y"), -- Bartender quick search 23 | -- c = { 24 | -- fn.openTab("calendar.google.com/calendar/u/0/r"), 25 | -- { ["shift"] = fn.openTab("calendar.google.com/calendar/u/1/r") }, 26 | -- }, 27 | -- e = { 28 | -- fn.sendKeys(old_hyper, "e"), -- Expose 29 | -- { ["shift"] = fn.sendKeys(old_hyper, "d") }, -- Desktop 30 | -- }, 31 | -- f = fn.openApp("Slack"), 32 | -- g = { 33 | -- fn.openTab("github.com"), 34 | -- { ["shift"] = fn.openRaycastExtension("raycast/github/search-repositories") }, 35 | -- }, 36 | -- h = { 37 | -- fn.openApp("Hammerspoon"), 38 | -- { ["shift"] = fn.reloadHammerspoonConfig }, 39 | -- }, 40 | -- i = { 41 | -- fn.openApp("Google Chrome"), 42 | -- { ["shift"] = fn.openRaycastExtension("Codely/google-chrome/search-bookmarks") }, 43 | -- }, 44 | -- j = fn.openApp("IntelliJ IDEA"), 45 | -- k = fn.openApp("Slack"), 46 | -- l = { 47 | -- fn.openApp("Linear"), 48 | -- { ["shift"] = fn.openRaycastExtension("thomaslombart/linear/assigned-issues") }, 49 | -- }, 50 | -- m = { 51 | -- fn.openTab("mail.google.com/mail/u/0"), 52 | -- { ["shift"] = fn.openTab("mail.google.com/mail/u/1") }, 53 | -- }, 54 | -- n = { 55 | -- fn.openApp("Notes"), 56 | -- { ["shift"] = fn.openRaycastExtension("tumtum/apple-notes/index") }, 57 | -- }, 58 | -- o = { 59 | -- fn.openApp("Obsidian"), 60 | -- { ["shift"] = fn.openRaycastExtension("KevinBatdorf/obsidian/searchNoteCommand") }, 61 | -- }, 62 | -- p = fn.openRaycastExtension("raycast/raycast-ai/ai-chat"), 63 | -- s = fn.openApp("iTerm"), 64 | -- r = { 65 | -- fn.openApp("Spotify"), 66 | -- { ["shift"] = fn.openRaycastExtension("mattisssa/spotify-player/yourLibrary") }, 67 | -- }, 68 | -- t = { 69 | -- fn.openApp("TablePlus"), 70 | -- -- { ["shift"] = fn.openRaycastExtension("ChrisChinchilla/trello/searchBoards") } 71 | -- }, 72 | -- u = { 73 | -- fn.openApp("Things3"), 74 | -- { ["shift"] = fn.sendKeys(old_hyper, "u") }, 75 | -- }, 76 | -- w = { -- Notion ("w" for "wiki") 77 | -- fn.openTab("notion.so"), 78 | -- { ["shift"] = fn.openRaycastExtension("notion/notion/search-page") } 79 | -- }, 80 | -- z = fn.openApp("zoom.us") 81 | -- }) 82 | 83 | -- local windowModalTimer = nil 84 | -- local function resetTimer() 85 | -- if type(windowModalTimer) == 'table' then windowModalTimer:stop() end 86 | -- windowModalTimer = hs.timer.doAfter(5, function() windowModal:exit() end) 87 | -- print("5 more seconds on the clock") 88 | -- end 89 | 90 | -- local function bind(key, action) 91 | -- windowModal:bind({}, key, nil, function() 92 | -- action() 93 | -- resetTimer() 94 | -- end) 95 | -- end 96 | 97 | -- bind("0", function() windowModal:exit() end) 98 | -- bind("escape", function() windowModal:exit() end) 99 | 100 | -- bind("tab", fn.windowCommand("next-display")) 101 | 102 | -- bind("a", fn.windowCommand("almost-maximize")) 103 | 104 | -- bind("q", fn.windowCommand("first-two-thirds")) 105 | -- bind("p", fn.windowCommand("last-third")) 106 | 107 | -- bind("h", fn.windowCommand("maximize-height")) 108 | -- bind("w", fn.windowCommand("maximize-width")) 109 | 110 | -- bind("f", fn.windowCommand("maximize")) 111 | -- bind("m", fn.windowCommand("center-three-fourths")) 112 | 113 | -- bind("h", fn.windowCommand("move-left")) 114 | -- bind("k", fn.windowCommand("move-up")) 115 | -- bind("j", fn.windowCommand("move-down")) 116 | -- bind("l", fn.windowCommand("move-right")) 117 | 118 | -- bind("r", fn.windowCommand("restore")) 119 | 120 | -- bind("-", fn.windowCommand("make-smaller")) 121 | -- bind("=", fn.windowCommand("make-larger")) 122 | 123 | 124 | -- local menuItem = hs.menubar.new(true, 'window') 125 | -- menuItem:setTitle("Window") 126 | 127 | -- function windowModal:entered() 128 | -- hyper.exit() 129 | -- menuItem:setTitle("WINDOW") 130 | -- end 131 | 132 | -- function windowModal:exited() 133 | -- menuItem:setTitle("Window") 134 | -- end 135 | 136 | 137 | -- -- TODO things, 1password, etc even when the app is closed 138 | -- -- https://evantravers.com/articles/2020/06/08/hammerspoon-a-better-better-hyper-key/#even-when-the-app-is-closed 139 | -------------------------------------------------------------------------------- /karabiner/generate_space_hyper_json.rb: -------------------------------------------------------------------------------- 1 | require "json" 2 | 3 | keys = ('a'..'z').to_a + ('0'..'9').to_a + ['open_bracket', 'close_bracket', 'comma', 'period', 'backslash'] 4 | 5 | 6 | rules = keys.map do |key| 7 | { 8 | 'type' => 'basic', 9 | 'conditions' => [ 10 | { 11 | 'type' => 'variable_if', 12 | 'name' => 'hyper_key_mode', 13 | 'value' => 1 14 | } 15 | ], 16 | 'from' => { 17 | 'key_code' => key, 18 | 'modifiers' => { 19 | 'optional' => ['any'] 20 | } 21 | }, 22 | 'to' => [ 23 | { 24 | 'key_code' => key, 25 | 'modifiers' => ['left_command', 'left_option', 'left_control'] 26 | } 27 | ] 28 | } 29 | end 30 | 31 | config = { 32 | 'title' => 'Space plus Key based Hyper Key Configuration', 33 | 'rules' => [ 34 | { 35 | 'description' => 'Map space + key to left_command+left_option+left_control + key', 36 | 'manipulators' => [ 37 | { 38 | 'type' => 'basic', 39 | 'from' => { 40 | 'key_code' => 'spacebar', 41 | 'modifiers' => { 42 | 'optional' => ['any'] 43 | } 44 | }, 45 | 'to' => [ 46 | { 47 | 'set_variable' => { 48 | 'name' => 'hyper_key_mode', 49 | 'value' => 1 50 | } 51 | } 52 | ], 53 | 'to_after_key_up' => [ 54 | { 55 | 'set_variable' => { 56 | 'name' => 'hyper_key_mode', 57 | 'value' => 0 58 | } 59 | } 60 | ], 61 | 'to_if_alone' => [ 62 | { 63 | 'key_code' => 'spacebar' 64 | } 65 | ] 66 | } 67 | ] + rules 68 | } 69 | ] 70 | } 71 | 72 | File.write('space-hyper.json', JSON.pretty_generate(config)) 73 | -------------------------------------------------------------------------------- /karabiner/karabiner.json: -------------------------------------------------------------------------------- 1 | { 2 | "global": { 3 | "ask_for_confirmation_before_quitting": true, 4 | "check_for_updates_on_startup": true, 5 | "show_in_menu_bar": true, 6 | "show_profile_name_in_menu_bar": false, 7 | "unsafe_ui": false 8 | }, 9 | "profiles": [ 10 | { 11 | "complex_modifications": { 12 | "parameters": { 13 | "basic.simultaneous_threshold_milliseconds": 50, 14 | "basic.to_delayed_action_delay_milliseconds": 500, 15 | "basic.to_if_alone_timeout_milliseconds": 1000, 16 | "basic.to_if_held_down_threshold_milliseconds": 500, 17 | "mouse_motion_to_scroll.speed": 100 18 | }, 19 | "rules": [ 20 | { 21 | "manipulators": [ 22 | { 23 | "description": "Cmd-based hyper key! (left)", 24 | "from": { 25 | "key_code": "left_command", 26 | "modifiers": { 27 | "optional": [ 28 | "any" 29 | ] 30 | } 31 | }, 32 | "to": [ 33 | { 34 | "key_code": "left_command" 35 | } 36 | ], 37 | "to_if_alone": [ 38 | { 39 | "key_code": "f19" 40 | } 41 | ], 42 | "type": "basic" 43 | }, 44 | { 45 | "description": "Cmd-based hyper key! (right)", 46 | "from": { 47 | "key_code": "right_command", 48 | "modifiers": { 49 | "optional": [ 50 | "any" 51 | ] 52 | } 53 | }, 54 | "to": [ 55 | { 56 | "key_code": "right_command" 57 | } 58 | ], 59 | "to_if_alone": [ 60 | { 61 | "key_code": "f19" 62 | } 63 | ], 64 | "type": "basic" 65 | } 66 | ] 67 | } 68 | ] 69 | }, 70 | "devices": [ 71 | { 72 | "disable_built_in_keyboard_if_exists": false, 73 | "fn_function_keys": [], 74 | "identifiers": { 75 | "is_keyboard": true, 76 | "is_pointing_device": false, 77 | "product_id": 0, 78 | "vendor_id": 0 79 | }, 80 | "ignore": false, 81 | "manipulate_caps_lock_led": true, 82 | "simple_modifications": [], 83 | "treat_as_built_in_keyboard": false 84 | }, 85 | { 86 | "disable_built_in_keyboard_if_exists": false, 87 | "fn_function_keys": [], 88 | "identifiers": { 89 | "is_keyboard": false, 90 | "is_pointing_device": true, 91 | "product_id": 0, 92 | "vendor_id": 0 93 | }, 94 | "ignore": true, 95 | "manipulate_caps_lock_led": false, 96 | "simple_modifications": [], 97 | "treat_as_built_in_keyboard": false 98 | }, 99 | { 100 | "disable_built_in_keyboard_if_exists": false, 101 | "fn_function_keys": [], 102 | "identifiers": { 103 | "is_keyboard": true, 104 | "is_pointing_device": false, 105 | "product_id": 1296, 106 | "vendor_id": 1204 107 | }, 108 | "ignore": false, 109 | "manipulate_caps_lock_led": true, 110 | "simple_modifications": [ 111 | { 112 | "from": { 113 | "key_code": "right_option" 114 | }, 115 | "to": [ 116 | { 117 | "key_code": "right_command" 118 | } 119 | ] 120 | } 121 | ], 122 | "treat_as_built_in_keyboard": false 123 | }, 124 | { 125 | "disable_built_in_keyboard_if_exists": false, 126 | "fn_function_keys": [], 127 | "identifiers": { 128 | "is_keyboard": false, 129 | "is_pointing_device": true, 130 | "product_id": 50479, 131 | "vendor_id": 1133 132 | }, 133 | "ignore": true, 134 | "manipulate_caps_lock_led": false, 135 | "simple_modifications": [], 136 | "treat_as_built_in_keyboard": false 137 | } 138 | ], 139 | "fn_function_keys": [ 140 | { 141 | "from": { 142 | "key_code": "f1" 143 | }, 144 | "to": [ 145 | { 146 | "consumer_key_code": "display_brightness_decrement" 147 | } 148 | ] 149 | }, 150 | { 151 | "from": { 152 | "key_code": "f2" 153 | }, 154 | "to": [ 155 | { 156 | "consumer_key_code": "display_brightness_increment" 157 | } 158 | ] 159 | }, 160 | { 161 | "from": { 162 | "key_code": "f3" 163 | }, 164 | "to": [ 165 | { 166 | "apple_vendor_keyboard_key_code": "mission_control" 167 | } 168 | ] 169 | }, 170 | { 171 | "from": { 172 | "key_code": "f4" 173 | }, 174 | "to": [ 175 | { 176 | "apple_vendor_keyboard_key_code": "spotlight" 177 | } 178 | ] 179 | }, 180 | { 181 | "from": { 182 | "key_code": "f5" 183 | }, 184 | "to": [ 185 | { 186 | "consumer_key_code": "dictation" 187 | } 188 | ] 189 | }, 190 | { 191 | "from": { 192 | "key_code": "f6" 193 | }, 194 | "to": [ 195 | { 196 | "key_code": "f6" 197 | } 198 | ] 199 | }, 200 | { 201 | "from": { 202 | "key_code": "f7" 203 | }, 204 | "to": [ 205 | { 206 | "consumer_key_code": "rewind" 207 | } 208 | ] 209 | }, 210 | { 211 | "from": { 212 | "key_code": "f8" 213 | }, 214 | "to": [ 215 | { 216 | "consumer_key_code": "play_or_pause" 217 | } 218 | ] 219 | }, 220 | { 221 | "from": { 222 | "key_code": "f9" 223 | }, 224 | "to": [ 225 | { 226 | "consumer_key_code": "fast_forward" 227 | } 228 | ] 229 | }, 230 | { 231 | "from": { 232 | "key_code": "f10" 233 | }, 234 | "to": [ 235 | { 236 | "consumer_key_code": "mute" 237 | } 238 | ] 239 | }, 240 | { 241 | "from": { 242 | "key_code": "f11" 243 | }, 244 | "to": [ 245 | { 246 | "consumer_key_code": "volume_decrement" 247 | } 248 | ] 249 | }, 250 | { 251 | "from": { 252 | "key_code": "f12" 253 | }, 254 | "to": [ 255 | { 256 | "consumer_key_code": "volume_increment" 257 | } 258 | ] 259 | } 260 | ], 261 | "name": "Default profile", 262 | "parameters": { 263 | "delay_milliseconds_before_open_device": 1000 264 | }, 265 | "selected": true, 266 | "simple_modifications": [], 267 | "virtual_hid_keyboard": { 268 | "country_code": 0, 269 | "indicate_sticky_modifier_keys_state": true, 270 | "mouse_key_xy_scale": 100 271 | } 272 | } 273 | ] 274 | } 275 | -------------------------------------------------------------------------------- /nvim/.gitignore: -------------------------------------------------------------------------------- 1 | tags 2 | test.sh 3 | .luarc.json 4 | nvim 5 | 6 | spell/ 7 | lazy-lock.json 8 | -------------------------------------------------------------------------------- /nvim/.stylua.toml: -------------------------------------------------------------------------------- 1 | column_width = 160 2 | line_endings = "Unix" 3 | indent_type = "Spaces" 4 | indent_width = 2 5 | quote_style = "AutoPreferSingle" 6 | call_parentheses = "None" 7 | -------------------------------------------------------------------------------- /nvim/doc/kickstart.txt: -------------------------------------------------------------------------------- 1 | ================================================================================ 2 | INTRODUCTION *kickstart.nvim* 3 | 4 | Kickstart.nvim is a project to help you get started on your neovim journey. 5 | 6 | *kickstart-is-not* 7 | It is not: 8 | - Complete framework for every plugin under the sun 9 | - Place to add every plugin that could ever be useful 10 | 11 | *kickstart-is* 12 | It is: 13 | - Somewhere that has a good start for the most common "IDE" type features: 14 | - autocompletion 15 | - goto-definition 16 | - find references 17 | - fuzzy finding 18 | - and hinting at what more can be done :) 19 | - A place to _kickstart_ your journey. 20 | - You should fork this project and use/modify it so that it matches your 21 | style and preferences. If you don't want to do that, there are probably 22 | other projects that would fit much better for you (and that's great!)! 23 | 24 | vim:tw=78:ts=8:ft=help:norl: 25 | -------------------------------------------------------------------------------- /nvim/init.lua: -------------------------------------------------------------------------------- 1 | --[[ 2 | 3 | ===================================================================== 4 | ==================== READ THIS BEFORE CONTINUING ==================== 5 | ===================================================================== 6 | ======== .-----. ======== 7 | ======== .----------------------. | === | ======== 8 | ======== |.-""""""""""""""""""-.| |-----| ======== 9 | ======== || || | === | ======== 10 | ======== || KICKSTART.NVIM || |-----| ======== 11 | ======== || || | === | ======== 12 | ======== || || |-----| ======== 13 | ======== ||:Tutor || |:::::| ======== 14 | ======== |'-..................-'| |____o| ======== 15 | ======== `"")----------------(""` ___________ ======== 16 | ======== /::::::::::| |::::::::::\ \ no mouse \ ======== 17 | ======== /:::========| |==hjkl==:::\ \ required \ ======== 18 | ======== '""""""""""""' '""""""""""""' '""""""""""' ======== 19 | ======== ======== 20 | ===================================================================== 21 | ===================================================================== 22 | 23 | What is Kickstart? 24 | 25 | Kickstart.nvim is *not* a distribution. 26 | 27 | Kickstart.nvim is a starting point for your own configuration. 28 | The goal is that you can read every line of code, top-to-bottom, understand 29 | what your configuration is doing, and modify it to suit your needs. 30 | 31 | Once you've done that, you can start exploring, configuring and tinkering to 32 | make Neovim your own! That might mean leaving Kickstart just the way it is for a while 33 | or immediately breaking it into modular pieces. It's up to you! 34 | 35 | If you don't know anything about Lua, I recommend taking some time to read through 36 | a guide. One possible example which will only take 10-15 minutes: 37 | - https://learnxinyminutes.com/docs/lua/ 38 | 39 | After understanding a bit more about Lua, you can use `:help lua-guide` as a 40 | reference for how Neovim integrates Lua. 41 | - :help lua-guide 42 | - (or HTML version): https://neovim.io/doc/user/lua-guide.html 43 | 44 | Kickstart Guide: 45 | 46 | TODO: The very first thing you should do is to run the command `:Tutor` in Neovim. 47 | 48 | If you don't know what this means, type the following: 49 | - 50 | - : 51 | - Tutor 52 | - 53 | 54 | (If you already know the Neovim basics, you can skip this step.) 55 | 56 | Once you've completed that, you can continue working through **AND READING** the rest 57 | of the kickstart init.lua. 58 | 59 | Next, run AND READ `:help`. 60 | This will open up a help window with some basic information 61 | about reading, navigating and searching the builtin help documentation. 62 | 63 | This should be the first place you go to look when you're stuck or confused 64 | with something. It's one of my favorite Neovim features. 65 | 66 | MOST IMPORTANTLY, we provide a keymap "sh" to [s]earch the [h]elp documentation, 67 | which is very useful when you're not exactly sure of what you're looking for. 68 | 69 | I have left several `:help X` comments throughout the init.lua 70 | These are hints about where to find more information about the relevant settings, 71 | plugins or Neovim features used in Kickstart. 72 | 73 | NOTE: Look for lines like this 74 | 75 | Throughout the file. These are for you, the reader, to help you understand what is happening. 76 | Feel free to delete them once you know what you're doing, but they should serve as a guide 77 | for when you are first encountering a few different constructs in your Neovim config. 78 | 79 | If you experience any errors while trying to install kickstart, run `:checkhealth` for more info. 80 | 81 | I hope you enjoy your Neovim journey, 82 | - TJ 83 | 84 | P.S. You can delete this when you're done too. It's your config now! :) 85 | --]] 86 | 87 | -- Set as the leader key 88 | -- See `:help mapleader` 89 | -- NOTE: Must happen before plugins are loaded (otherwise wrong leader will be used) 90 | vim.g.mapleader = ' ' 91 | vim.g.maplocalleader = ' ' 92 | 93 | -- Set to true if you have a Nerd Font installed and selected in the terminal 94 | vim.g.have_nerd_font = false 95 | 96 | -- [[ Setting options ]] 97 | -- See `:help vim.opt` 98 | -- NOTE: You can change these options as you wish! 99 | -- For more options, you can see `:help option-list` 100 | 101 | -- Make line numbers default 102 | vim.opt.number = true 103 | -- You can also add relative line numbers, to help with jumping. 104 | -- Experiment for yourself to see if you like it! 105 | -- vim.opt.relativenumber = true 106 | 107 | -- Enable mouse mode, can be useful for resizing splits for example! 108 | vim.opt.mouse = 'a' 109 | 110 | -- Don't show the mode, since it's already in the status line 111 | vim.opt.showmode = false 112 | 113 | -- Sync clipboard between OS and Neovim. 114 | -- Remove this option if you want your OS clipboard to remain independent. 115 | -- See `:help 'clipboard'` 116 | vim.opt.clipboard = 'unnamedplus' 117 | 118 | -- Enable break indent 119 | vim.opt.breakindent = true 120 | 121 | -- Save undo history 122 | vim.opt.undofile = true 123 | 124 | -- Case-insensitive searching UNLESS \C or one or more capital letters in the search term 125 | vim.opt.ignorecase = true 126 | vim.opt.smartcase = true 127 | 128 | -- Keep signcolumn on by default 129 | vim.opt.signcolumn = 'yes' 130 | 131 | -- Decrease update time 132 | vim.opt.updatetime = 250 133 | 134 | -- Decrease mapped sequence wait time 135 | -- Displays which-key popup sooner 136 | vim.opt.timeoutlen = 300 137 | 138 | -- Configure how new splits should be opened 139 | vim.opt.splitright = true 140 | vim.opt.splitbelow = true 141 | 142 | -- Sets how neovim will display certain whitespace characters in the editor. 143 | -- See `:help 'list'` 144 | -- and `:help 'listchars'` 145 | vim.opt.list = true 146 | vim.opt.listchars = { tab = '» ', trail = '·', nbsp = '␣' } 147 | 148 | -- Preview substitutions live, as you type! 149 | vim.opt.inccommand = 'split' 150 | 151 | -- Show which line your cursor is on 152 | vim.opt.cursorline = true 153 | 154 | -- Minimal number of screen lines to keep above and below the cursor. 155 | vim.opt.scrolloff = 10 156 | 157 | -- [[ Basic Keymaps ]] 158 | -- See `:help vim.keymap.set()` 159 | 160 | -- Set highlight on search, but clear on pressing in normal mode 161 | vim.opt.hlsearch = true 162 | vim.keymap.set('n', '', 'nohlsearch') 163 | 164 | -- Diagnostic keymaps 165 | vim.keymap.set('n', '[d', vim.diagnostic.goto_prev, { desc = 'Go to previous [D]iagnostic message' }) 166 | vim.keymap.set('n', ']d', vim.diagnostic.goto_next, { desc = 'Go to next [D]iagnostic message' }) 167 | vim.keymap.set('n', 'e', vim.diagnostic.open_float, { desc = 'Show diagnostic [E]rror messages' }) 168 | vim.keymap.set('n', 'q', vim.diagnostic.setloclist, { desc = 'Open diagnostic [Q]uickfix list' }) 169 | 170 | -- Exit terminal mode in the builtin terminal with a shortcut that is a bit easier 171 | -- for people to discover. Otherwise, you normally need to press , which 172 | -- is not what someone will guess without a bit more experience. 173 | -- 174 | -- NOTE: This won't work in all terminal emulators/tmux/etc. Try your own mapping 175 | -- or just use to exit terminal mode 176 | vim.keymap.set('t', '', '', { desc = 'Exit terminal mode' }) 177 | 178 | -- TIP: Disable arrow keys in normal mode 179 | -- vim.keymap.set('n', '', 'echo "Use h to move!!"') 180 | -- vim.keymap.set('n', '', 'echo "Use l to move!!"') 181 | -- vim.keymap.set('n', '', 'echo "Use k to move!!"') 182 | -- vim.keymap.set('n', '', 'echo "Use j to move!!"') 183 | 184 | -- Keybinds to make split navigation easier. 185 | -- Use CTRL+ to switch between windows 186 | -- 187 | -- See `:help wincmd` for a list of all window commands 188 | vim.keymap.set('n', '', '', { desc = 'Move focus to the left window' }) 189 | vim.keymap.set('n', '', '', { desc = 'Move focus to the right window' }) 190 | vim.keymap.set('n', '', '', { desc = 'Move focus to the lower window' }) 191 | vim.keymap.set('n', '', '', { desc = 'Move focus to the upper window' }) 192 | 193 | -- [[ Basic Autocommands ]] 194 | -- See `:help lua-guide-autocommands` 195 | 196 | -- Highlight when yanking (copying) text 197 | -- Try it with `yap` in normal mode 198 | -- See `:help vim.highlight.on_yank()` 199 | vim.api.nvim_create_autocmd('TextYankPost', { 200 | desc = 'Highlight when yanking (copying) text', 201 | group = vim.api.nvim_create_augroup('kickstart-highlight-yank', { clear = true }), 202 | callback = function() 203 | vim.highlight.on_yank() 204 | end, 205 | }) 206 | 207 | require 'config.lazy' 208 | 209 | local paths = vim.split(vim.fn.glob '~/.config/nvim/rcfiles/*', '\n') 210 | 211 | for _, file in pairs(paths) do 212 | vim.cmd('source ' .. file) 213 | end 214 | 215 | -- The line beneath this is called `modeline`. See `:help modeline` 216 | -- vim: ts=2 sts=2 sw=2 et 217 | -------------------------------------------------------------------------------- /nvim/lua/config/lazy.lua: -------------------------------------------------------------------------------- 1 | -- [[ Install `lazy.nvim` plugin manager ]] 2 | -- See `:help lazy.nvim.txt` or https://github.com/folke/lazy.nvim for more info 3 | local lazypath = vim.fn.stdpath 'data' .. '/lazy/lazy.nvim' 4 | if not vim.loop.fs_stat(lazypath) then 5 | local lazyrepo = 'https://github.com/folke/lazy.nvim.git' 6 | vim.fn.system { 'git', 'clone', '--filter=blob:none', '--branch=stable', lazyrepo, lazypath } 7 | end ---@diagnostic disable-next-line: undefined-field 8 | vim.opt.rtp:prepend(lazypath) 9 | 10 | require('lazy').setup({ 11 | { import = 'plugins' }, 12 | }, { 13 | ui = { 14 | -- If you are using a Nerd Font: set icons to an empty table which will use the 15 | -- default lazy.nvim defined Nerd Font icons, otherwise define a unicode icons table 16 | icons = vim.g.have_nerd_font and {} or { 17 | cmd = '⌘', 18 | config = '🛠', 19 | event = '📅', 20 | ft = '📂', 21 | init = '⚙', 22 | keys = '🗝', 23 | plugin = '🔌', 24 | runtime = '💻', 25 | require = '🌙', 26 | source = '📄', 27 | start = '🚀', 28 | task = '📌', 29 | lazy = '💤 ', 30 | }, 31 | }, 32 | }) 33 | -------------------------------------------------------------------------------- /nvim/lua/plugins/comment.lua: -------------------------------------------------------------------------------- 1 | return { 'numToStr/Comment.nvim', opts = {} } 2 | -------------------------------------------------------------------------------- /nvim/lua/plugins/conform.lua: -------------------------------------------------------------------------------- 1 | return { -- Autoformat 2 | 'stevearc/conform.nvim', 3 | lazy = true, 4 | event = { 'BufWritePre' }, 5 | keys = { 6 | { 7 | 'f', 8 | function() 9 | require('conform').format { async = true, lsp_fallback = true } 10 | end, 11 | mode = '', 12 | desc = '[F]ormat buffer', 13 | }, 14 | }, 15 | opts = { 16 | notify_on_error = true, 17 | format_on_save = function(bufnr) 18 | -- Disable "format_on_save lsp_fallback" for languages that don't 19 | -- have a well standardized coding style. You can add additional 20 | -- languages here or re-enable it for the disabled ones. 21 | local disable_filetypes = { c = true, cpp = true } 22 | return { 23 | timeout_ms = 1000, 24 | lsp_fallback = not disable_filetypes[vim.bo[bufnr].filetype], 25 | } 26 | end, 27 | formatters_by_ft = { 28 | lua = { 'stylua' }, 29 | ruby = { { 'prettierd', 'prettier' } }, 30 | json = { { 'prettierd', 'prettier' } }, 31 | }, 32 | }, 33 | } 34 | -------------------------------------------------------------------------------- /nvim/lua/plugins/gitsigns.lua: -------------------------------------------------------------------------------- 1 | return { -- Adds git related signs to the gutter, as well as utilities for managing changes 2 | 'lewis6991/gitsigns.nvim', 3 | opts = { 4 | signs = { 5 | add = { text = '+' }, 6 | change = { text = '~' }, 7 | delete = { text = '_' }, 8 | topdelete = { text = '‾' }, 9 | changedelete = { text = '~' }, 10 | }, 11 | }, 12 | } 13 | -------------------------------------------------------------------------------- /nvim/lua/plugins/jellybeans.lua: -------------------------------------------------------------------------------- 1 | return { 2 | 'metalelf0/jellybeans-nvim', 3 | dependencies = { 'rktjmp/lush.nvim' }, 4 | priority = 1000, 5 | init = function() 6 | vim.cmd.colorscheme 'jellybeans-nvim' 7 | end, 8 | } 9 | -------------------------------------------------------------------------------- /nvim/lua/plugins/mini.lua: -------------------------------------------------------------------------------- 1 | return { -- Collection of various small independent plugins/modules 2 | 'echasnovski/mini.nvim', 3 | config = function() 4 | -- Better Around/Inside textobjects 5 | -- 6 | -- Examples: 7 | -- - va) - [V]isually select [A]round [)]paren 8 | -- - yinq - [Y]ank [I]nside [N]ext [']quote 9 | -- - ci' - [C]hange [I]nside [']quote 10 | require('mini.ai').setup { n_lines = 500 } 11 | 12 | -- Simple and easy statusline. 13 | -- You could remove this setup call if you don't like it, 14 | -- and try some other statusline plugin 15 | local statusline = require 'mini.statusline' 16 | -- set use_icons to true if you have a Nerd Font 17 | statusline.setup { use_icons = vim.g.have_nerd_font } 18 | 19 | -- You can configure sections in the statusline by overriding their 20 | -- default behavior. For example, here we set the section for 21 | -- cursor location to LINE:COLUMN 22 | ---@diagnostic disable-next-line: duplicate-set-field 23 | statusline.section_location = function() 24 | return '%2l:%-2v' 25 | end 26 | 27 | -- ... and there is more! 28 | -- Check out: https://github.com/echasnovski/mini.nvim 29 | end, 30 | } 31 | -------------------------------------------------------------------------------- /nvim/lua/plugins/nvim-cmp.lua: -------------------------------------------------------------------------------- 1 | return { -- Autocompletion 2 | 'hrsh7th/nvim-cmp', 3 | event = 'InsertEnter', 4 | dependencies = { 5 | -- Snippet Engine & its associated nvim-cmp source 6 | { 7 | 'L3MON4D3/LuaSnip', 8 | build = 'make install_jsregexp', 9 | version = 'v2.*', 10 | dependencies = { 11 | -- `friendly-snippets` contains a variety of premade snippets. 12 | -- See the README about individual language/framework/plugin snippets: 13 | -- https://github.com/rafamadriz/friendly-snippets 14 | -- { 15 | -- 'rafamadriz/friendly-snippets', 16 | -- config = function() 17 | -- require('luasnip.loaders.from_vscode').lazy_load() 18 | -- end, 19 | -- }, 20 | }, 21 | }, 22 | 'saadparwaiz1/cmp_luasnip', 23 | 24 | -- Adds other completion capabilities. 25 | -- nvim-cmp does not ship with all sources by default. They are split 26 | -- into multiple repos for maintenance purposes. 27 | 'hrsh7th/cmp-nvim-lsp', 28 | 'hrsh7th/cmp-path', 29 | }, 30 | config = function() 31 | -- See `:help cmp` 32 | local cmp = require 'cmp' 33 | local luasnip = require 'luasnip' 34 | luasnip.config.setup {} 35 | 36 | cmp.setup { 37 | snippet = { 38 | expand = function(args) 39 | luasnip.lsp_expand(args.body) 40 | end, 41 | }, 42 | completion = { completeopt = 'menu,menuone,noinsert' }, 43 | 44 | -- For an understanding of why these mappings were 45 | -- chosen, you will need to read `:help ins-completion` 46 | -- 47 | -- No, but seriously. Please read `:help ins-completion`, it is really good! 48 | mapping = cmp.mapping.preset.insert { 49 | -- Select the [n]ext item 50 | [''] = cmp.mapping.select_next_item(), 51 | -- Select the [p]revious item 52 | [''] = cmp.mapping.select_prev_item(), 53 | 54 | -- Scroll the documentation window [b]ack / [f]orward 55 | [''] = cmp.mapping.scroll_docs(-4), 56 | [''] = cmp.mapping.scroll_docs(4), 57 | 58 | -- Accept ([y]es) the completion. 59 | -- This will auto-import if your LSP supports it. 60 | -- This will expand snippets if the LSP sent a snippet. 61 | [''] = cmp.mapping.confirm { select = true }, 62 | 63 | -- If you prefer more traditional completion keymaps, 64 | -- you can uncomment the following lines 65 | [''] = cmp.mapping.confirm { select = true }, 66 | [''] = cmp.mapping.select_next_item(), 67 | [''] = cmp.mapping.select_prev_item(), 68 | 69 | -- Manually trigger a completion from nvim-cmp. 70 | -- Generally you don't need this, because nvim-cmp will display 71 | -- completions whenever it has completion options available. 72 | [''] = cmp.mapping.complete {}, 73 | 74 | -- Think of as moving to the right of your snippet expansion. 75 | -- So if you have a snippet that's like: 76 | -- function $name($args) 77 | -- $body 78 | -- end 79 | -- 80 | -- will move you to the right of each of the expansion locations. 81 | -- is similar, except moving you backwards. 82 | [''] = cmp.mapping(function() 83 | if luasnip.expand_or_locally_jumpable() then 84 | luasnip.expand_or_jump() 85 | end 86 | end, { 'i', 's' }), 87 | [''] = cmp.mapping(function() 88 | if luasnip.locally_jumpable(-1) then 89 | luasnip.jump(-1) 90 | end 91 | end, { 'i', 's' }), 92 | 93 | -- For more advanced Luasnip keymaps (e.g. selecting choice nodes, expansion) see: 94 | -- https://github.com/L3MON4D3/LuaSnip?tab=readme-ov-file#keymaps 95 | }, 96 | sources = { 97 | { name = 'nvim_lsp' }, 98 | { name = 'luasnip' }, 99 | { name = 'path' }, 100 | }, 101 | } 102 | end, 103 | } 104 | -------------------------------------------------------------------------------- /nvim/lua/plugins/nvim-lspconfig.lua: -------------------------------------------------------------------------------- 1 | return { -- LSP Configuration & Plugins 2 | 'neovim/nvim-lspconfig', 3 | dependencies = { 4 | -- Automatically install LSPs and related tools to stdpath for Neovim 5 | { 'williamboman/mason.nvim', config = true }, -- NOTE: Must be loaded before dependants 6 | 'williamboman/mason-lspconfig.nvim', 7 | 'WhoIsSethDaniel/mason-tool-installer.nvim', 8 | 9 | -- Useful status updates for LSP. 10 | -- NOTE: `opts = {}` is the same as calling `require('fidget').setup({})` 11 | { 'j-hui/fidget.nvim', opts = {} }, 12 | 13 | -- `neodev` configures Lua LSP for your Neovim config, runtime and plugins 14 | -- used for completion, annotations and signatures of Neovim apis 15 | { 'folke/neodev.nvim', opts = {} }, 16 | }, 17 | config = function() 18 | -- Brief aside: **What is LSP?** 19 | -- 20 | -- LSP is an initialism you've probably heard, but might not understand what it is. 21 | -- 22 | -- LSP stands for Language Server Protocol. It's a protocol that helps editors 23 | -- and language tooling communicate in a standardized fashion. 24 | -- 25 | -- In general, you have a "server" which is some tool built to understand a particular 26 | -- language (such as `gopls`, `lua_ls`, `rust_analyzer`, etc.). These Language Servers 27 | -- (sometimes called LSP servers, but that's kind of like ATM Machine) are standalone 28 | -- processes that communicate with some "client" - in this case, Neovim! 29 | -- 30 | -- LSP provides Neovim with features like: 31 | -- - Go to definition 32 | -- - Find references 33 | -- - Autocompletion 34 | -- - Symbol Search 35 | -- - and more! 36 | -- 37 | -- Thus, Language Servers are external tools that must be installed separately from 38 | -- Neovim. This is where `mason` and related plugins come into play. 39 | -- 40 | -- If you're wondering about lsp vs treesitter, you can check out the wonderfully 41 | -- and elegantly composed help section, `:help lsp-vs-treesitter` 42 | 43 | -- This function gets run when an LSP attaches to a particular buffer. 44 | -- That is to say, every time a new file is opened that is associated with 45 | -- an lsp (for example, opening `main.rs` is associated with `rust_analyzer`) this 46 | -- function will be executed to configure the current buffer 47 | vim.api.nvim_create_autocmd('LspAttach', { 48 | group = vim.api.nvim_create_augroup('kickstart-lsp-attach', { clear = true }), 49 | callback = function(event) 50 | -- NOTE: Remember that Lua is a real programming language, and as such it is possible 51 | -- to define small helper and utility functions so you don't have to repeat yourself. 52 | -- 53 | -- In this case, we create a function that lets us more easily define mappings specific 54 | -- for LSP related items. It sets the mode, buffer and description for us each time. 55 | local map = function(keys, func, desc) 56 | vim.keymap.set('n', keys, func, { buffer = event.buf, desc = 'LSP: ' .. desc }) 57 | end 58 | 59 | -- Jump to the definition of the word under your cursor. 60 | -- This is where a variable was first declared, or where a function is defined, etc. 61 | -- To jump back, press . 62 | map('gd', require('telescope.builtin').lsp_definitions, '[G]oto [D]efinition') 63 | 64 | -- Find references for the word under your cursor. 65 | map('gr', require('telescope.builtin').lsp_references, '[G]oto [R]eferences') 66 | 67 | -- Jump to the implementation of the word under your cursor. 68 | -- Useful when your language has ways of declaring types without an actual implementation. 69 | map('gI', require('telescope.builtin').lsp_implementations, '[G]oto [I]mplementation') 70 | 71 | -- Jump to the type of the word under your cursor. 72 | -- Useful when you're not sure what type a variable is and you want to see 73 | -- the definition of its *type*, not where it was *defined*. 74 | map('D', require('telescope.builtin').lsp_type_definitions, 'Type [D]efinition') 75 | 76 | -- Fuzzy find all the symbols in your current document. 77 | -- Symbols are things like variables, functions, types, etc. 78 | map('ds', require('telescope.builtin').lsp_document_symbols, '[D]ocument [S]ymbols') 79 | 80 | -- Fuzzy find all the symbols in your current workspace. 81 | -- Similar to document symbols, except searches over your entire project. 82 | map('ws', require('telescope.builtin').lsp_dynamic_workspace_symbols, '[W]orkspace [S]ymbols') 83 | 84 | -- Rename the variable under your cursor. 85 | -- Most Language Servers support renaming across files, etc. 86 | map('rn', vim.lsp.buf.rename, '[R]e[n]ame') 87 | 88 | -- Execute a code action, usually your cursor needs to be on top of an error 89 | -- or a suggestion from your LSP for this to activate. 90 | map('ca', vim.lsp.buf.code_action, '[C]ode [A]ction') 91 | map('do', vim.lsp.buf.code_action, '(do) Code Action') 92 | 93 | -- Opens a popup that displays documentation about the word under your cursor 94 | -- See `:help K` for why this keymap. 95 | map('K', vim.lsp.buf.hover, 'Hover Documentation') 96 | map('k', vim.lsp.buf.hover, 'Hover Documentation') 97 | 98 | -- WARN: This is not Goto Definition, this is Goto Declaration. 99 | -- For example, in C this would take you to the header. 100 | map('gD', vim.lsp.buf.declaration, '[G]oto [D]eclaration') 101 | 102 | -- The following two autocommands are used to highlight references of the 103 | -- word under your cursor when your cursor rests there for a little while. 104 | -- See `:help CursorHold` for information about when this is executed 105 | -- 106 | -- When you move your cursor, the highlights will be cleared (the second autocommand). 107 | local client = vim.lsp.get_client_by_id(event.data.client_id) 108 | if client and client.server_capabilities.documentHighlightProvider then 109 | local highlight_augroup = vim.api.nvim_create_augroup('kickstart-lsp-highlight', { clear = false }) 110 | vim.api.nvim_create_autocmd({ 'CursorHold', 'CursorHoldI' }, { 111 | buffer = event.buf, 112 | group = highlight_augroup, 113 | callback = vim.lsp.buf.document_highlight, 114 | }) 115 | 116 | vim.api.nvim_create_autocmd({ 'CursorMoved', 'CursorMovedI' }, { 117 | buffer = event.buf, 118 | group = highlight_augroup, 119 | callback = vim.lsp.buf.clear_references, 120 | }) 121 | 122 | vim.api.nvim_create_autocmd('LspDetach', { 123 | group = vim.api.nvim_create_augroup('kickstart-lsp-detach', { clear = true }), 124 | callback = function(event2) 125 | vim.lsp.buf.clear_references() 126 | vim.api.nvim_clear_autocmds { group = 'kickstart-lsp-highlight', buffer = event2.buf } 127 | end, 128 | }) 129 | end 130 | 131 | -- The following autocommand is used to enable inlay hints in your 132 | -- code, if the language server you are using supports them 133 | -- 134 | -- This may be unwanted, since they displace some of your code 135 | if client and client.server_capabilities.inlayHintProvider and vim.lsp.inlay_hint then 136 | map('th', function() 137 | vim.lsp.inlay_hint.enable(not vim.lsp.inlay_hint.is_enabled()) 138 | end, '[T]oggle Inlay [H]ints') 139 | end 140 | end, 141 | }) 142 | 143 | -- LSP servers and clients are able to communicate to each other what features they support. 144 | -- By default, Neovim doesn't support everything that is in the LSP specification. 145 | -- When you add nvim-cmp, luasnip, etc. Neovim now has *more* capabilities. 146 | -- So, we create new capabilities with nvim cmp, and then broadcast that to the servers. 147 | local capabilities = vim.lsp.protocol.make_client_capabilities() 148 | capabilities = vim.tbl_deep_extend('force', capabilities, require('cmp_nvim_lsp').default_capabilities()) 149 | 150 | -- Enable the following language servers 151 | -- Feel free to add/remove any LSPs that you want here. They will automatically be installed. 152 | -- 153 | -- Add any additional override configuration in the following tables. Available keys are: 154 | -- - cmd (table): Override the default command used to start the server 155 | -- - filetypes (table): Override the default list of associated filetypes for the server 156 | -- - capabilities (table): Override fields in capabilities. Can be used to disable certain LSP features. 157 | -- - settings (table): Override the default settings passed when initializing the server. 158 | -- For example, to see the options for `lua_ls`, you could go to: https://luals.github.io/wiki/settings/ 159 | local servers = { 160 | -- clangd = {}, 161 | -- gopls = {}, 162 | -- pyright = {}, 163 | -- rust_analyzer = {}, 164 | -- ... etc. See `:help lspconfig-all` for a list of all the pre-configured LSPs 165 | -- 166 | -- Some languages (like typescript) have entire language plugins that can be useful: 167 | -- https://github.com/pmizio/typescript-tools.nvim 168 | -- 169 | -- But for many setups, the LSP (`tsserver`) will work just fine 170 | -- tsserver = {}, 171 | -- 172 | 173 | lua_ls = { 174 | -- cmd = {...}, 175 | -- filetypes = { ...}, 176 | -- capabilities = {}, 177 | settings = { 178 | Lua = { 179 | completion = { 180 | callSnippet = 'Replace', 181 | }, 182 | -- You can toggle below to ignore Lua_LS's noisy `missing-fields` warnings 183 | -- diagnostics = { disable = { 'missing-fields' } }, 184 | }, 185 | }, 186 | }, 187 | } 188 | 189 | -- Ensure the servers and tools above are installed 190 | -- To check the current status of installed tools and/or manually install 191 | -- other tools, you can run 192 | -- :Mason 193 | -- 194 | -- You can press `g?` for help in this menu. 195 | require('mason').setup() 196 | 197 | -- You can add other tools here that you want Mason to install 198 | -- for you, so that they are available from within Neovim. 199 | local ensure_installed = vim.tbl_keys(servers or {}) 200 | vim.list_extend(ensure_installed, { 201 | 'stylua', -- Used to format Lua code 202 | }) 203 | require('mason-tool-installer').setup { ensure_installed = ensure_installed } 204 | 205 | require('mason-lspconfig').setup { 206 | handlers = { 207 | function(server_name) 208 | local server = servers[server_name] or {} 209 | -- This handles overriding only values explicitly passed 210 | -- by the server configuration above. Useful when disabling 211 | -- certain features of an LSP (for example, turning off formatting for tsserver) 212 | server.capabilities = vim.tbl_deep_extend('force', {}, capabilities, server.capabilities or {}) 213 | require('lspconfig')[server_name].setup(server) 214 | end, 215 | }, 216 | } 217 | end, 218 | } 219 | -------------------------------------------------------------------------------- /nvim/lua/plugins/oil.lua: -------------------------------------------------------------------------------- 1 | return { 2 | 'stevearc/oil.nvim', 3 | config = function() 4 | require('oil').setup() 5 | vim.keymap.set('n', '-', 'Oil', { desc = 'Open parent directory' }) 6 | end, 7 | dependencies = { { 'echasnovski/mini.icons', opts = {} } }, 8 | } 9 | -------------------------------------------------------------------------------- /nvim/lua/plugins/scala-metals.lua: -------------------------------------------------------------------------------- 1 | return { 2 | 'scalameta/nvim-metals', 3 | dependencies = { 4 | 'nvim-lua/plenary.nvim', 5 | }, 6 | ft = { 'scala', 'sbt', 'java' }, 7 | opts = function() 8 | local metals_config = require('metals').bare_config() 9 | metals_config.on_attach = function(client, bufnr) 10 | -- your on_attach function 11 | end 12 | 13 | return metals_config 14 | end, 15 | config = function(self, metals_config) 16 | local nvim_metals_group = vim.api.nvim_create_augroup('nvim-metals', { clear = true }) 17 | vim.api.nvim_create_autocmd('FileType', { 18 | pattern = self.ft, 19 | callback = function() 20 | require('metals').initialize_or_attach(metals_config) 21 | end, 22 | group = nvim_metals_group, 23 | }) 24 | end, 25 | } 26 | -------------------------------------------------------------------------------- /nvim/lua/plugins/surround.lua: -------------------------------------------------------------------------------- 1 | return { 2 | 'kylechui/nvim-surround', 3 | version = '*', -- Use for stability; omit to use `main` branch for the latest features 4 | event = 'VeryLazy', 5 | config = function() 6 | require('nvim-surround').setup { 7 | -- Configuration here, or leave empty to use defaults 8 | } 9 | end, 10 | } 11 | -------------------------------------------------------------------------------- /nvim/lua/plugins/telescope.lua: -------------------------------------------------------------------------------- 1 | local function buildFinder(cwd) 2 | return function() 3 | require('telescope.builtin').find_files { cwd = cwd } 4 | end 5 | end 6 | 7 | return { -- Fuzzy Finder (files, lsp, etc) 8 | 'nvim-telescope/telescope.nvim', 9 | event = 'VimEnter', 10 | branch = '0.1.x', 11 | dependencies = { 12 | 'nvim-lua/plenary.nvim', 13 | { -- If encountering errors, see telescope-fzf-native README for installation instructions 14 | 'nvim-telescope/telescope-fzf-native.nvim', 15 | 16 | -- `build` is used to run some command when the plugin is installed/updated. 17 | -- This is only run then, not every time Neovim starts up. 18 | build = 'make', 19 | 20 | -- `cond` is a condition used to determine whether this plugin should be 21 | -- installed and loaded. 22 | cond = function() 23 | return vim.fn.executable 'make' == 1 24 | end, 25 | }, 26 | { 'nvim-telescope/telescope-ui-select.nvim' }, 27 | 28 | -- Useful for getting pretty icons, but requires a Nerd Font. 29 | { 'nvim-tree/nvim-web-devicons', enabled = vim.g.have_nerd_font }, 30 | }, 31 | keys = { 32 | { '', 'Telescope git_files' }, 33 | { 'gj', buildFinder 'app/frontend' }, 34 | { 'gc', buildFinder 'app/controllers' }, 35 | { 'gm', buildFinder 'app/models' }, 36 | }, 37 | config = function() 38 | -- Telescope is a fuzzy finder that comes with a lot of different things that 39 | -- it can fuzzy find! It's more than just a "file finder", it can search 40 | -- many different aspects of Neovim, your workspace, LSP, and more! 41 | -- 42 | -- The easiest way to use Telescope, is to start by doing something like: 43 | -- :Telescope help_tags 44 | -- 45 | -- After running this command, a window will open up and you're able to 46 | -- type in the prompt window. You'll see a list of `help_tags` options and 47 | -- a corresponding preview of the help. 48 | -- 49 | -- Two important keymaps to use while in Telescope are: 50 | -- - Insert mode: 51 | -- - Normal mode: ? 52 | -- 53 | -- This opens a window that shows you all of the keymaps for the current 54 | -- Telescope picker. This is really useful to discover what Telescope can 55 | -- do as well as how to actually do it! 56 | 57 | -- [[ Configure Telescope ]] 58 | -- See `:help telescope` and `:help telescope.setup()` 59 | require('telescope').setup { 60 | -- You can put your default mappings / updates / etc. in here 61 | -- All the info you're looking for is in `:help telescope.setup()` 62 | -- 63 | defaults = { 64 | mappings = { 65 | i = { 66 | [''] = false, 67 | }, 68 | }, 69 | sorting_strategy = 'ascending', 70 | layout_config = { 71 | prompt_position = 'top', 72 | }, 73 | }, 74 | extensions = { 75 | ['ui-select'] = { 76 | require('telescope.themes').get_dropdown(), 77 | }, 78 | }, 79 | } 80 | 81 | -- Enable Telescope extensions if they are installed 82 | pcall(require('telescope').load_extension, 'fzf') 83 | pcall(require('telescope').load_extension, 'ui-select') 84 | 85 | -- See `:help telescope.builtin` 86 | local builtin = require 'telescope.builtin' 87 | vim.keymap.set('n', 'sh', builtin.help_tags, { desc = '[S]earch [H]elp' }) 88 | vim.keymap.set('n', 'sk', builtin.keymaps, { desc = '[S]earch [K]eymaps' }) 89 | vim.keymap.set('n', 'sf', builtin.find_files, { desc = '[S]earch [F]iles' }) 90 | vim.keymap.set('n', 'ss', builtin.builtin, { desc = '[S]earch [S]elect Telescope' }) 91 | vim.keymap.set('n', 'sw', builtin.grep_string, { desc = '[S]earch current [W]ord' }) 92 | vim.keymap.set('n', 'sg', builtin.live_grep, { desc = '[S]earch by [G]rep' }) 93 | vim.keymap.set('n', 'sd', builtin.diagnostics, { desc = '[S]earch [D]iagnostics' }) 94 | vim.keymap.set('n', 'sr', builtin.resume, { desc = '[S]earch [R]esume' }) 95 | vim.keymap.set('n', 's.', builtin.oldfiles, { desc = '[S]earch Recent Files ("." for repeat)' }) 96 | vim.keymap.set('n', '', builtin.buffers, { desc = '[ ] Find existing buffers' }) 97 | 98 | -- Slightly advanced example of overriding default behavior and theme 99 | vim.keymap.set('n', '/', function() 100 | -- You can pass additional configuration to Telescope to change the theme, layout, etc. 101 | builtin.current_buffer_fuzzy_find(require('telescope.themes').get_dropdown { 102 | winblend = 10, 103 | previewer = false, 104 | }) 105 | end, { desc = '[/] Fuzzily search in current buffer' }) 106 | 107 | -- It's also possible to pass additional configuration options. 108 | -- See `:help telescope.builtin.live_grep()` for information about particular keys 109 | vim.keymap.set('n', 's/', function() 110 | builtin.live_grep { 111 | grep_open_files = true, 112 | prompt_title = 'Live Grep in Open Files', 113 | } 114 | end, { desc = '[S]earch [/] in Open Files' }) 115 | 116 | -- Shortcut for searching your Neovim configuration files 117 | vim.keymap.set('n', 'sn', function() 118 | builtin.find_files { cwd = vim.fn.stdpath 'config' } 119 | end, { desc = '[S]earch [N]eovim files' }) 120 | end, 121 | } 122 | -------------------------------------------------------------------------------- /nvim/lua/plugins/todo-comments.lua: -------------------------------------------------------------------------------- 1 | return { -- Highlight todo, notes, etc in comments 2 | 'folke/todo-comments.nvim', 3 | event = 'VimEnter', 4 | dependencies = { 'nvim-lua/plenary.nvim' }, 5 | opts = { signs = false }, 6 | } 7 | -------------------------------------------------------------------------------- /nvim/lua/plugins/treesitter.lua: -------------------------------------------------------------------------------- 1 | return { -- Highlight, edit, and navigate code 2 | 'nvim-treesitter/nvim-treesitter', 3 | build = ':TSUpdate', 4 | opts = { 5 | ensure_installed = { 'bash', 'c', 'diff', 'html', 'lua', 'luadoc', 'markdown', 'vim', 'vimdoc' }, 6 | -- Autoinstall languages that are not installed 7 | auto_install = true, 8 | highlight = { 9 | enable = true, 10 | -- Some languages depend on vim's regex highlighting system (such as Ruby) for indent rules. 11 | -- If you are experiencing weird indenting issues, add the language to 12 | -- the list of additional_vim_regex_highlighting and disabled languages for indent. 13 | additional_vim_regex_highlighting = { 'ruby' }, 14 | }, 15 | indent = { enable = true, disable = { 'ruby' } }, 16 | }, 17 | config = function(_, opts) 18 | -- [[ Configure Treesitter ]] See `:help nvim-treesitter` 19 | 20 | -- Prefer git instead of curl in order to improve connectivity in some environments 21 | require('nvim-treesitter.install').prefer_git = true 22 | ---@diagnostic disable-next-line: missing-fields 23 | require('nvim-treesitter.configs').setup(opts) 24 | 25 | -- There are additional nvim-treesitter modules that you can use to interact 26 | -- with nvim-treesitter. You should go explore a few and see what interests you: 27 | -- 28 | -- - Incremental selection: Included, see `:help nvim-treesitter-incremental-selection-mod` 29 | -- - Show your current context: https://github.com/nvim-treesitter/nvim-treesitter-context 30 | -- - Treesitter + textobjects: https://github.com/nvim-treesitter/nvim-treesitter-textobjects 31 | end, 32 | } 33 | -------------------------------------------------------------------------------- /nvim/lua/plugins/trusted-local.lua: -------------------------------------------------------------------------------- 1 | return { 2 | 'christoomey/trusted-local', 3 | lazy = false, 4 | keys = { { 'el', '(EditVimrcLocal)' } }, 5 | dir = '~/code/vim/trusted-local/', 6 | } 7 | -------------------------------------------------------------------------------- /nvim/lua/plugins/unimpaired.lua: -------------------------------------------------------------------------------- 1 | return { 2 | 'tummetott/unimpaired.nvim', 3 | event = 'VeryLazy', 4 | opts = { 5 | -- add options here if you wish to override the default settings 6 | }, 7 | } 8 | -------------------------------------------------------------------------------- /nvim/lua/plugins/vim-sleuth.lua: -------------------------------------------------------------------------------- 1 | return { 'tpope/vim-sleuth' } 2 | -------------------------------------------------------------------------------- /nvim/lua/plugins/vim-tmux-nagivator.lua: -------------------------------------------------------------------------------- 1 | return { 2 | 'christoomey/vim-tmux-navigator', 3 | cmd = { 4 | 'TmuxNavigateLeft', 5 | 'TmuxNavigateDown', 6 | 'TmuxNavigateUp', 7 | 'TmuxNavigateRight', 8 | 'TmuxNavigatePrevious', 9 | }, 10 | keys = { 11 | { '', 'TmuxNavigateLeft' }, 12 | { '', 'TmuxNavigateDown' }, 13 | { '', 'TmuxNavigateUp' }, 14 | { '', 'TmuxNavigateRight' }, 15 | { '', 'TmuxNavigatePrevious' }, 16 | }, 17 | } 18 | -------------------------------------------------------------------------------- /nvim/lua/plugins/which-key.lua: -------------------------------------------------------------------------------- 1 | return { -- Useful plugin to show you pending keybinds. 2 | 'folke/which-key.nvim', 3 | event = 'VimEnter', -- Sets the loading event to 'VimEnter' 4 | config = function() -- This is the function that runs, AFTER loading 5 | require('which-key').setup() 6 | 7 | -- Document existing key chains 8 | require('which-key').register { 9 | ['c'] = { name = '[C]ode', _ = 'which_key_ignore' }, 10 | ['d'] = { name = '[D]ocument', _ = 'which_key_ignore' }, 11 | ['r'] = { name = '[R]ename', _ = 'which_key_ignore' }, 12 | ['s'] = { name = '[S]earch', _ = 'which_key_ignore' }, 13 | ['w'] = { name = '[W]orkspace', _ = 'which_key_ignore' }, 14 | ['t'] = { name = '[T]oggle', _ = 'which_key_ignore' }, 15 | ['h'] = { name = 'Git [H]unk', _ = 'which_key_ignore' }, 16 | } 17 | -- visual mode 18 | require('which-key').register({ 19 | ['h'] = { 'Git [H]unk' }, 20 | }, { mode = 'v' }) 21 | end, 22 | } 23 | -------------------------------------------------------------------------------- /nvim/rcfiles/chrome: -------------------------------------------------------------------------------- 1 | " Chrome Cli bindings 2 | "-------------------- 3 | 4 | function! s:HasFile() 5 | return expand("%") != "" 6 | endfunction 7 | 8 | function! s:OpenTab(reload, detached) 9 | let open_tab_command = "open-tab" 10 | if s:HasFile() 11 | update 12 | endif 13 | if a:reload 14 | let open_tab_command .= " --reload" 15 | endif 16 | if a:detached 17 | let open_tab_command .= " --detached" 18 | endif 19 | if exists("g:app_url") 20 | let open_tab_command .= " " . g:app_url 21 | endif 22 | call system(open_tab_command) 23 | endfunction 24 | 25 | command! OpenAndReloadTab call OpenTab(1, 0) 26 | command! OpenTab call OpenTab(0, 0) 27 | command! OpenTabDetached call OpenTab(0, 1) 28 | nnoremap gl :OpenAndReloadTab 29 | nnoremap gL :OpenTabDetached 30 | 31 | " vim:ft=vim 32 | -------------------------------------------------------------------------------- /postgres/psqlrc: -------------------------------------------------------------------------------- 1 | \timing on 2 | -------------------------------------------------------------------------------- /raycast/script-commands/checkall.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Required parameters: 4 | # @raycast.schemaVersion 1 5 | # @raycast.title Checkall 6 | # @raycast.mode silent 7 | 8 | # Optional parameters: 9 | # @raycast.icon 🔄 10 | 11 | # Documentation: 12 | # @raycast.description Check all work sources 13 | # @raycast.author Chris Toomey 14 | # @raycast.authorURL https://ctoomey.com 15 | 16 | # open -a Terminal ~/code/things-report/bin/checkall 17 | 18 | open -a iTerm 19 | tmux display-popup -d "$HOME/code/things-report" -xC -yC -w80% -h80% "bin/checkall" 20 | -------------------------------------------------------------------------------- /raycast/script-commands/github-pr-link.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | # Required parameters: 4 | # @raycast.schemaVersion 1 5 | # @raycast.title github-pr-link 6 | # @raycast.mode silent 7 | 8 | # Optional parameters: 9 | # @raycast.icon icons/github-logo.png 10 | 11 | # Documentation: 12 | # @raycast.description Copy GitHub PR Markdown Link 13 | # @raycast.author Chris Toomey 14 | # @raycast.authorURL https://ctoomey.com 15 | 16 | class GithubMarkdownUrl 17 | def self.run 18 | new.send(:run) 19 | end 20 | 21 | private 22 | 23 | def run 24 | system "printf '[#{title}](#{url})' | pbcopy" 25 | puts "Copied to clipboard -- [#{title}](#{url})" 26 | end 27 | 28 | def url 29 | raw_url = `chrome-cli info | grep Url:`.chomp 30 | raw_url.split(" ").last 31 | end 32 | 33 | def title 34 | regex = /Title: (?.*?) by .* · Pull Request (?<pr_number>#[0-9]+) ·/ 35 | raw_title = `chrome-cli info | grep Title:`.chomp 36 | 37 | if match = raw_title.match(regex) 38 | title = match[:title] 39 | pr_number = match[:pr_number] 40 | 41 | "#{title} (#{pr_number})" 42 | else 43 | puts "No match found" 44 | exit 1 45 | end 46 | end 47 | end 48 | 49 | GithubMarkdownUrl.run 50 | 51 | -------------------------------------------------------------------------------- /raycast/script-commands/github-prs.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -eo 4 | 5 | # Required parameters: 6 | # @raycast.schemaVersion 1 7 | # @raycast.title GitHub PRs 8 | # @raycast.mode silent 9 | 10 | # Optional parameters: 11 | # @raycast.icon icons/github-logo.png 12 | 13 | # Documentation: 14 | # @raycast.description Open filtered GitHub PRs search 15 | # @raycast.author Chris Toomey 16 | # @raycast.authorURL https://ctoomey.com 17 | 18 | date_range="$(gdate --date='5 days ago' +%Y-%m-%d)..$(gdate +%Y-%m-%d)" 19 | 20 | open "https://github.com/augusthealth/august-backend/pulls?q=\ 21 | is:pr+is:open+\ 22 | -is:draft+\ 23 | -author:christoomey+\ 24 | -reviewed-by:@me+\ 25 | -author:app%2Fscala-steward-augusthealth+\ 26 | created:$date_range" 27 | -------------------------------------------------------------------------------- /raycast/script-commands/icons/github-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/christoomey/dotfiles/ec6261dc9075d993860b60e8c84c412c15f56b18/raycast/script-commands/icons/github-logo.png -------------------------------------------------------------------------------- /raycast/script-commands/icons/gmail-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/christoomey/dotfiles/ec6261dc9075d993860b60e8c84c412c15f56b18/raycast/script-commands/icons/gmail-logo.png -------------------------------------------------------------------------------- /raycast/script-commands/icons/trello-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/christoomey/dotfiles/ec6261dc9075d993860b60e8c84c412c15f56b18/raycast/script-commands/icons/trello-logo.png -------------------------------------------------------------------------------- /raycast/script-commands/open-email.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Required parameters: 4 | # @raycast.schemaVersion 1 5 | # @raycast.title Open Email 6 | # @raycast.mode silent 7 | 8 | # Optional parameters: 9 | # @raycast.icon icons/gmail-logo.png 10 | 11 | # Documentation: 12 | # @raycast.description Opens gmail in Chrome 13 | # @raycast.author Chris Toomey 14 | # @raycast.authorURL https://ctoomey.com 15 | 16 | ~/bin/open-tab 'https://mail.google.com/mail/u/0' 17 | -------------------------------------------------------------------------------- /raycast/script-commands/open-trello.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Required parameters: 4 | # @raycast.schemaVersion 1 5 | # @raycast.title Open Trello 6 | # @raycast.mode silent 7 | 8 | # Optional parameters: 9 | # @raycast.icon icons/trello-logo.png 10 | 11 | # Documentation: 12 | # @raycast.author Chris Toomey 13 | # @raycast.authorURL https://ctoomey.com 14 | 15 | ~/bin/open-tab 'https://trello.com/' 16 | -------------------------------------------------------------------------------- /raycast/script-commands/open-work-email.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Required parameters: 4 | # @raycast.schemaVersion 1 5 | # @raycast.title Open Work Email 6 | # @raycast.mode silent 7 | 8 | # Optional parameters: 9 | # @raycast.icon 📧 10 | 11 | # Documentation: 12 | # @raycast.description Opens work gmail in Chrome (assumes work is /u/1) 13 | # @raycast.author Chris Toomey 14 | # @raycast.authorURL https://ctoomey.com 15 | 16 | ~/bin/open-tab 'https://mail.google.com/mail/u/1/' 17 | -------------------------------------------------------------------------------- /raycast/script-commands/rich-text-clipboard-to-markdown.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Dependency: This script requires the `pandoc` cli to be installed: https://pandoc.org/ 4 | # Install via homebrew: `brew install pandoc` 5 | 6 | # @raycast.title Rich Text to Markdown 7 | # @raycast.author Adam Zethraeus 8 | # @raycast.authorURL https://github.com/adam-zethraeus 9 | # @raycast.description Convert rich text clipboard data to GitHub Flavored Markdown using Pandoc 10 | # 11 | # @raycast.icon 📝 12 | # 13 | # @raycast.mode silent 14 | # @raycast.packageName Conversions 15 | # @raycast.schemaVersion 1 16 | 17 | if ! command -v pandoc &> /dev/null; then 18 | echo "pandoc is required (https://pandoc.org/)."; 19 | exit 1; 20 | fi 21 | 22 | export LC_CTYPE=UTF-8 23 | osascript -e 'the clipboard as "HTML"'| perl -ne 'print chr foreach unpack("C*",pack("H*",substr($_,11,-3)))' | pandoc --from=html --to=gfm | pbcopy 24 | -------------------------------------------------------------------------------- /raycast/script-commands/unreleased.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Required parameters: 4 | # @raycast.schemaVersion 1 5 | # @raycast.title Unreleased 6 | # @raycast.mode silent 7 | 8 | # Optional parameters: 9 | # @raycast.icon 🤖 10 | # @raycast.argument1 { "type": "dropdown", "placeholder": "Repo", "data": [{ "title": "Backend", "value": "augusthealth/august-backend" }, { "title": "Frontend", "value": "augusthealth/august-frontend" }] } 11 | 12 | # Documentation: 13 | # @raycast.author Chris Toomey 14 | # @raycast.authorURL https://ctoomey.com 15 | 16 | set -euxo pipefail 17 | 18 | main() { 19 | repo=$1 20 | if ! command -v gh &> /dev/null; then 21 | echo "gh could not be found" 22 | exit 1 23 | fi 24 | 25 | latest_release=$(gh release list --exclude-drafts --exclude-pre-releases --json tagName -L 1 -R "$repo" | jq '.[0].tagName' | sed s/\"//g) 26 | 27 | open "https://github.com/$repo/compare/$latest_release...master" 28 | } 29 | 30 | main $1 31 | -------------------------------------------------------------------------------- /ruby/default-gems: -------------------------------------------------------------------------------- 1 | bundler 2 | pry 3 | solargraph 4 | -------------------------------------------------------------------------------- /ruby/pryrc.rb: -------------------------------------------------------------------------------- 1 | def pbcopy(input) 2 | input.to_s.tap do |str| 3 | IO.popen('pbcopy', 'w') { |f| f << str } 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /tmux/tmux.conf: -------------------------------------------------------------------------------- 1 | # Ctrl-s prefix key. Default => C-b. Send C-s with repeat option via C-s C-s 2 | unbind-key C-b 3 | set -g prefix C-s 4 | bind -r C-s send-prefix 5 | 6 | set -g default-command "zsh" 7 | 8 | set -g base-index 1 9 | set -g renumber-windows on 10 | 11 | set -g display-panes-time 350 12 | 13 | # improve colors 14 | set -g default-terminal 'xterm-256color' 15 | 16 | # Keep plenty of history for scrollback 17 | set -g history-limit 10000 18 | 19 | # Use emacs / readline key-bindings at the tmux command prompt `<prefix>:` 20 | set -g status-keys emacs 21 | 22 | # address vim mode switching delay (http://superuser.com/a/252717/65504) 23 | set -s escape-time 0 24 | 25 | set -g mouse on 26 | 27 | # Use vim keybindings in copy mode 28 | setw -g mode-keys vi 29 | bind-key -T copy-mode-vi v send -X begin-selection 30 | bind-key -T copy-mode-vi y send -X copy-pipe-and-cancel "pbcopy" 31 | unbind -T copy-mode-vi Enter 32 | bind-key -T copy-mode-vi Enter send -X copy-pipe-and-cancel "pbcopy" 33 | unbind -T copy-mode-vi Space 34 | bind -T copy-mode-vi Space send -X jump-again 35 | bind-key -T copy-mode-vi 0 send -X back-to-indentation 36 | bind y run 'tmux save-buffer - | pbcopy ' 37 | bind C-y run 'tmux save-buffer - | pbcopy ' 38 | 39 | # Default to incremental search in copy-mode 40 | bind-key -T copy-mode-vi / command-prompt -i -p "search down" "send -X search-forward-incremental \"%%%\"" 41 | bind-key -T copy-mode-vi ? command-prompt -i -p "search up" "send -X search-backward-incremental "%%%"" 42 | bind-key / copy-mode\; command-prompt -i -p "search up" "send -X search-backward-incremental "%%%"" 43 | 44 | # Toggle status bar display with "s" 45 | bind-key s set -g status 46 | 47 | # bind-key s split-window -v "capture-pane -t 1 -p | sed '/^$/d' | tr ' ' '\n' | awk 'length>10' | sort |uniq | fzf --reverse | pbcopy" 48 | 49 | # Simplify status bar display. 50 | set -g status-left-length 40 51 | set -g status-fg black 52 | set -g status-bg green 53 | set -g status-left '[#S - #(cd #{pane_current_path}; git rev-parse --abbrev-ref HEAD)] ' 54 | set -g status-right "#{?pane_synchronized,--SYNCED--,} #(is-online) #(date '+%a, %b %d - %I:%M') " 55 | 56 | # Dismiss current pane to background window 57 | bind b break-pane -d 58 | bind C-b send-keys 'tat && exit' 'C-m' 59 | bind-key ! run-shell '(tmux switch-client -l || tmux switch-client -n) && tmux kill-session -t "#S" || tmux kill-session' 60 | bind-key J command-prompt -p "join pane from: " "join-pane -h -s '%%'" 61 | 62 | bind-key C-t run-shell "tmux-popup 'tmux-open-session' 100" 63 | bind C popup -d "~/code/things-report/" -xC -yC -w80% -h80% -E "bin/checkall" 64 | 65 | bind c new-window -c "#{pane_current_path}" 66 | bind C-d popup -d "~/code/dotfiles/" -xC -yC -w80% -h80% -E "vim +Files" 67 | bind g run-shell "github ." 68 | bind-key g run-shell "tmux-popup 'lazygit'" 69 | bind-key r run-shell "touch tmp/restart.txt" 70 | bind w split-window -h -c ~/wiki "vim +Files" 71 | 72 | bind o run-shell "open '#{pane_current_path}'" 73 | 74 | # bind t split-window -h -c "#{pane_current_path}" "source ~/.zsh/configs/navigation.zsh && itree | less -R" 75 | bind-key t send-keys -t 2 "tree -C .git/objects -I 'info|pack'" 'C-m' 76 | 77 | bind-key C-t run-shell "tmux-popup 'tmux-open-session' 100" 78 | bind-key C-j run-shell "tmux-popup 'tmux-switch-session' 100" 79 | # bind-key C-b run-shell "tmux-popup 'tmux-git-branch' 100" 80 | 81 | bind-key p run-shell "tmux-popup" 82 | 83 | bind-key n run-shell "tmux-popup 'vim ~/notes.md'" 84 | 85 | bind-key O split-window -v "grep \"^$(tail -n +2 ~/.bookmarks.csv | cut -f 1 -d ',' | fzf --reverse)\" ~/.bookmarks.csv | cut -f 2 -d ',' | xargs open" 86 | 87 | 88 | # Open urls in the current pane 89 | bind-key u capture-pane -J \; \ 90 | save-buffer "/tmp/tmux-buffer" \; \ 91 | delete-buffer \; \ 92 | display-popup -E -h '80%' "extract_url -l /tmp/tmux-buffer | fzf --select-1 | xargs open" 93 | 94 | # Quick session switching back and forth. I never use the built in layouts 95 | # (default mapping for Space), so I reclaimed the key for this 96 | bind-key Space switch-client -l 97 | 98 | # more intuitive keybindings for splitting 99 | bind \\ split-window -h -c "#{pane_current_path}" 100 | bind - split-window -v -c "#{pane_current_path}" 101 | 102 | bind-key C-k split-pane -t 1 -p 100 'overmind connect' 103 | 104 | # Smart pane switching with awareness of Vim splits. 105 | # See: https://github.com/christoomey/vim-tmux-navigator 106 | is_vim="ps -o state=,tty=,comm= | grep -iqE '^[^TXZ ]+ +#{s|/dev/||:pane_tty}\s+(\\S+\\/)?g?(view|n?vim?x?)(diff)?$'" 107 | bind-key -n C-h if-shell "$is_vim" "send-keys C-h" "select-pane -L" 108 | bind-key -n C-j if-shell "$is_vim" "send-keys C-j" "select-pane -D" 109 | bind-key -n C-k if-shell "$is_vim" "send-keys C-k" "select-pane -U" 110 | bind-key -n C-l if-shell "$is_vim" "send-keys C-l" "select-pane -R" 111 | bind-key -n C-\\ if-shell "$is_vim" "send-keys C-\\" "select-pane -l" 112 | bind-key -T copy-mode-vi C-h select-pane -L 113 | bind-key -T copy-mode-vi C-j select-pane -D 114 | bind-key -T copy-mode-vi C-k select-pane -U 115 | bind-key -T copy-mode-vi C-l select-pane -R 116 | bind-key -T copy-mode-vi C-\\ select-pane -l 117 | 118 | # Secondary binding for C-l to retain redraw 119 | is_overmind="tmux display-message -p '#{pane_current_command}' | grep overmind" 120 | bind C-l if-shell "$is_overmind" "send-prefix \; send-keys 'C-l'" "send-keys 'C-l'" 121 | bind C-\\ send-prefix \; send-keys d 122 | 123 | # Reload tmux.conf with prefix-r 124 | bind C-r source-file ~/.tmux.conf \; display "Reloaded ~/.tmux.conf" 125 | 126 | # bind resizing of panes to H,J,K,L (resizes by steps of 10 lines/columns) 127 | bind -n S-Left resize-pane -L 2 128 | bind -n S-Right resize-pane -R 2 129 | bind -n S-Down resize-pane -D 1 130 | bind -n S-Up resize-pane -U 1 131 | bind -n C-S-Left resize-pane -L 10 132 | bind -n C-S-Right resize-pane -R 10 133 | bind -n C-S-Down resize-pane -D 5 134 | bind -n C-S-Up resize-pane -U 5 135 | 136 | run-shell ~/.tmux/plugins/tmux-fingers/tmux-fingers.tmux 137 | -------------------------------------------------------------------------------- /vim/coc-settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "coc.preferences.jumpCommand": "drop", 3 | "eslint.autoFixOnSave": true, 4 | "eslint.probe": [ 5 | "javascript", 6 | "javascriptreact", 7 | "typescript", 8 | "typescriptreact", 9 | "html", 10 | "vue", 11 | "markdown", 12 | "svelte" 13 | ], 14 | "eslint.options": { 15 | "ignorePath": ".gitignore" 16 | }, 17 | "eslint.lintTask.options": ["--ignore-path", ".gitignore", "."], 18 | "eslint.validate": ["svelte"], 19 | "diagnostic.refreshOnInsertMode": true, 20 | "suggest.noselect": false, 21 | "suggest.acceptSuggestionOnCommitCharacter": true, 22 | "suggest.autoTrigger": "trigger", 23 | "suggest.enablePreselect": true, 24 | "diagnostic.enableSign": false, 25 | "diagnostic.errorSign": "!!", 26 | "diagnostic.warningSign": "!!", 27 | "diagnostic.infoSign": "!!", 28 | "diagnostic.hintSign": "!!", 29 | "diagnostic.checkCurrentLine": true, 30 | "coc.preferences.currentFunctionSymbolAutoUpdate": true, 31 | "prettier.requireConfig": true, 32 | "coc.preferences.formatOnType": false, 33 | "tailwindCSS.headwind.runOnSave": false, 34 | "tailwindCSS.trace.server": "verbose", 35 | "svelte.plugin.typescript.diagnostics.enable": true, 36 | "languageserver": { 37 | "elmLS": { 38 | "command": "elm-language-server", 39 | "filetypes": ["elm"], 40 | "rootPatterns": ["elm.json"] 41 | } 42 | }, 43 | "svelte.ask-to-enable-ts-plugin": false, 44 | "svelte.enable-ts-plugin": false, 45 | "coc.preferences.formatOnSave": true, 46 | "[ruby][typescript][svelte]": { 47 | "coc.preferences.formatOnSave": true 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /vim/ftdetect/dotenv.vim: -------------------------------------------------------------------------------- 1 | au BufNewFile,BufRead .env set filetype=sh 2 | au BufNewFile,BufRead .env.sample set filetype=sh 3 | au BufNewFile,BufRead .env.local set filetype=sh 4 | au BufNewFile,BufRead .env.test set filetype=sh 5 | -------------------------------------------------------------------------------- /vim/ftplugin/ruby.vim: -------------------------------------------------------------------------------- 1 | nnoremap <leader>bp obinding.pry<esc> 2 | 3 | setl iskeyword+=! 4 | setl iskeyword+=? 5 | -------------------------------------------------------------------------------- /vim/ftplugin/scss.vim: -------------------------------------------------------------------------------- 1 | " Allow variables to include dashes 2 | set iskeyword+=- 3 | set iskeyword+=$ 4 | 5 | inoremap <buffer> <expr> <Tab> (pumvisible() ? (col('.') > 1 ? '<Esc>i<Right>' : '<Esc>i') : '') . 6 | \ '<C-x><C-o><C-r>=pumvisible() ? "\<lt>C-n>\<lt>C-p>\<lt>Down>" : ""<CR>' 7 | " open user completion menu closing previous if open and opening new menu without changing the text 8 | inoremap <buffer> <expr> <S-Tab> (pumvisible() ? (col('.') > 1 ? '<Esc>i<Right>' : '<Esc>i') : '') . 9 | \ '<C-x><C-u><C-r>=pumvisible() ? "\<lt>C-n>\<lt>C-p>\<lt>Down>" : ""<CR>' 10 | -------------------------------------------------------------------------------- /vim/ftplugin/svelte.vim: -------------------------------------------------------------------------------- 1 | " Allow variables to include dashes 2 | setlocal iskeyword+=- 3 | -------------------------------------------------------------------------------- /vim/init.vim: -------------------------------------------------------------------------------- 1 | set runtimepath^=~/.vim runtimepath+=~/.vim/after 2 | let $NVIM_TUI_ENABLE_CURSOR_SHAPE=0 3 | let &packpath = &runtimepath 4 | set guicursor= 5 | autocmd OptionSet guicursor noautocmd set guicursor= 6 | source ~/.vimrc 7 | -------------------------------------------------------------------------------- /vim/rcfiles/chrome: -------------------------------------------------------------------------------- 1 | " Chrome Cli bindings 2 | "-------------------- 3 | 4 | function! s:HasFile() 5 | return expand("%") != "" 6 | endfunction 7 | 8 | function! s:OpenTab(reload, detached) 9 | let open_tab_command = "open-tab" 10 | if s:HasFile() 11 | update 12 | endif 13 | if a:reload 14 | let open_tab_command .= " --reload" 15 | endif 16 | if a:detached 17 | let open_tab_command .= " --detached" 18 | endif 19 | if exists("g:app_url") 20 | let open_tab_command .= " " . g:app_url 21 | endif 22 | call system(open_tab_command) 23 | endfunction 24 | 25 | command! OpenAndReloadTab call <sid>OpenTab(1, 0) 26 | command! OpenTab call <sid>OpenTab(0, 0) 27 | command! OpenTabDetached call <sid>OpenTab(0, 1) 28 | nnoremap gl :OpenAndReloadTab<cr> 29 | nnoremap gL :OpenTabDetached<cr> 30 | 31 | " vim:ft=vim 32 | -------------------------------------------------------------------------------- /vim/rcfiles/completion: -------------------------------------------------------------------------------- 1 | " Completion related settings 2 | 3 | " " Tab completion 4 | " " will insert tab at beginning of line, 5 | " " will use completion if not at beginning 6 | " set wildmode=list:longest,list:full 7 | " function! InsertTabWrapper() 8 | " let col = col('.') - 1 9 | " if !col || getline('.')[col - 1] !~ '\k' 10 | " return "\<tab>" 11 | " else 12 | " return "\<c-p>" 13 | " endif 14 | " endfunction 15 | " inoremap <Tab> <c-r>=InsertTabWrapper()<cr> 16 | " inoremap <S-Tab> <c-n> 17 | 18 | " vim:ft=vim 19 | -------------------------------------------------------------------------------- /vim/rcfiles/convenience: -------------------------------------------------------------------------------- 1 | " Convience - configs & mappings to smooth out rough edges and make vim feel like home 2 | 3 | " Move between wrapped lines, rather than jumping over wrapped segments 4 | nmap j gj 5 | nmap k gk 6 | 7 | " Use C-Space to Esc out of any mode 8 | nnoremap <C-Space> <Esc>:noh<cr> 9 | vnoremap <C-Space> <Esc>gV 10 | onoremap <C-Space> <Esc> 11 | cnoremap <C-Space> <C-c> 12 | inoremap <C-Space> <Esc> 13 | " Terminal sees <C-@> as <C-space> 14 | nnoremap <C-@> <Esc>:noh<cr> 15 | vnoremap <C-@> <Esc>gV 16 | onoremap <C-@> <Esc> 17 | cnoremap <C-@> <C-c> 18 | inoremap <C-@> <Esc> 19 | 20 | nnoremap <leader>cc :ClearEmAll<cr> 21 | 22 | command! ClearEmAll call s:ClearEmAll() 23 | 24 | function! s:ClearEmAll() 25 | nohlsearch 26 | cclose 27 | pclose 28 | lclose 29 | " call coc#util#float_hide() 30 | call popup_clear() 31 | endfunction 32 | 33 | " Quick sourcing of the current file, allowing for quick vimrc testing 34 | nnoremap <leader>sop :source %<cr> 35 | 36 | nnoremap <leader>df :Files ~/code/dotfiles<cr> 37 | nnoremap <leader>; : 38 | nmap <leader>bi :PlugInstall<cr> 39 | 40 | " Q for Ex mode is useless. This will run the macro in q register 41 | nnoremap Q @q 42 | 43 | " Swap 0 and ^. I tend to want to jump to the first non-whitespace character 44 | " so make that the easier one to do. 45 | nnoremap 0 ^ 46 | nnoremap ^ 0 47 | 48 | augroup vimrcEx 49 | autocmd! 50 | " When editing a file, always jump to the last known cursor position. 51 | " Don't do it for commit messages, when the position is invalid, or when 52 | " inside an event handler (happens when dropping a file on gvim). 53 | autocmd BufReadPost * 54 | \ if &ft != 'gitcommit' && line("'\"") > 0 && line("'\"") <= line("$") | 55 | \ exe "normal g`\"" | 56 | \ endif 57 | augroup END 58 | 59 | " Switch between the last two files 60 | nnoremap <leader><leader> <c-^> 61 | 62 | " vim:ft=vim 63 | -------------------------------------------------------------------------------- /vim/rcfiles/folding: -------------------------------------------------------------------------------- 1 | " Folding configurations 2 | "------------------------ 3 | 4 | "Enable indent folding 5 | set foldenable 6 | set foldmethod=indent 7 | set foldlevel=999 8 | 9 | " So I never use s, and I want a single key map to toggle folds, thus 10 | " lower s = toggle <=> upper S = toggle recursive 11 | nnoremap <leader>ff za 12 | nnoremap <leader>FF zA 13 | 14 | "Maps for folding, unfolding all 15 | nnoremap <LEADER>fu zM<CR> 16 | nnoremap <LEADER>uf zR<CR> 17 | 18 | " vim:ft=vim 19 | -------------------------------------------------------------------------------- /vim/rcfiles/general: -------------------------------------------------------------------------------- 1 | " General Vim Settings 2 | " -------------------- 3 | 4 | filetype plugin indent on 5 | 6 | set backspace=2 " Backspace deletes like most programs in insert mode 7 | set nobackup 8 | set nowritebackup 9 | set noswapfile 10 | set history=50 11 | set ruler " show the cursor position all the time 12 | set showcmd " display incomplete commands 13 | set incsearch " do incremental searching 14 | set laststatus=2 " Always display the status line 15 | set autowrite " Automatically :write before running commands 16 | set formatoptions-=t " Don't auto-break long lines (re-enable this for prose) 17 | 18 | " Softtabs, 2 spaces 19 | set tabstop=2 20 | set shiftwidth=2 21 | set shiftround 22 | set expandtab 23 | 24 | " Display extra whitespace 25 | set list listchars=tab:»·,trail:·,nbsp:· 26 | 27 | " Use one space, not two, after punctuation. 28 | set nojoinspaces 29 | 30 | " Display relative line numbers, with absolute line number for current line 31 | set number 32 | set numberwidth=5 33 | set relativenumber 34 | 35 | " When the type of shell script is /bin/sh, assume a POSIX-compatible 36 | " shell for syntax highlighting purposes. 37 | let g:is_posix = 1 38 | 39 | " Set spellfile to location that is guaranteed to exist, can be symlinked to 40 | " Dropbox or kept in Git and managed outside of thoughtbot/dotfiles using rcm. 41 | set spellfile=$HOME/.vim-spell-en.utf-8.add 42 | 43 | " Autocomplete with dictionary words when spell check is on 44 | set complete+=kspell 45 | 46 | set splitright 47 | 48 | " Don't require saving before closing a buffer 49 | set hidden 50 | 51 | " vim:ft=vim 52 | -------------------------------------------------------------------------------- /vim/rcfiles/git: -------------------------------------------------------------------------------- 1 | " Git 2 | "---- 3 | 4 | autocmd BufEnter PULLREQ_EDITMSG setlocal filetype=gitcommit 5 | autocmd BufEnter PULLREQ_EDITMSG setlocal filetype=gitcommit 6 | autocmd FileType gitrebase silent! RebaseSquash 7 | autocmd FileType gitcommit set spell 8 | autocmd BufRead,BufNewFile git/config set filetype=gitconfig 9 | " command! RebaseSquash silent execute '2,$s/^pick/s/|silent! w!|2' 10 | 11 | " vim:ft=vim 12 | -------------------------------------------------------------------------------- /vim/rcfiles/help-files: -------------------------------------------------------------------------------- 1 | " Help File Speedups 2 | "------------------- 3 | 4 | au filetype help call HelpFileMode() 5 | 6 | function! HelpFileMode() 7 | wincmd _ " Maximze the help on open 8 | nnoremap <buffer> <tab> :call search('\|.\{-}\|', 'w')<cr>:noh<cr>2l 9 | nnoremap <buffer> <S-tab> F\|:call search('\|.\{-}\|', 'wb')<cr>:noh<cr>2l 10 | nnoremap <buffer> <cr> <c-]> 11 | nnoremap <buffer> <bs> <c-T> 12 | nnoremap <buffer> q :q<CR> 13 | setlocal nonumber 14 | endfunction 15 | 16 | nnoremap <leader>rh :h local-additions<cr> 17 | 18 | " vim:ft=vim 19 | -------------------------------------------------------------------------------- /vim/rcfiles/html: -------------------------------------------------------------------------------- 1 | " HTML settings 2 | "-------------- 3 | 4 | " Load matchit.vim, but only if the user hasn't installed a newer version. 5 | if !exists('g:loaded_matchit') && findfile('plugin/matchit.vim', &rtp) ==# '' 6 | runtime! macros/matchit.vim 7 | endif 8 | 9 | " Treat <li> and <p> tags like the block tags they are 10 | let g:html_indent_tags = 'li\|p' 11 | 12 | " vim:ft=vim 13 | -------------------------------------------------------------------------------- /vim/rcfiles/project-notes: -------------------------------------------------------------------------------- 1 | " Project Notes 2 | " ------------- 3 | 4 | " Quick access to a local notes file for keeping track of things in a given 5 | " project. Add `.project-notes` to global ~/.gitignore 6 | 7 | let s:PROJECT_NOTES_FILE = '.project-notes' 8 | 9 | command! EditProjectNotes call <sid>SmartSplit(s:PROJECT_NOTES_FILE) 10 | nnoremap <leader>ep :EditProjectNotes<cr> 11 | 12 | autocmd BufEnter .project-notes call <sid>LoadNotes() 13 | 14 | function! s:SmartSplit(file) 15 | let split_cmd = (winwidth(0) >= 100) ? 'vsplit' : 'split' 16 | execute split_cmd . " " . a:file 17 | endfunction 18 | 19 | function! s:LoadNotes() 20 | setlocal filetype=markdown 21 | endfunction 22 | 23 | " vim:ft=vim 24 | -------------------------------------------------------------------------------- /vim/rcfiles/prose: -------------------------------------------------------------------------------- 1 | " Prose - Configurations related to those times I write things that aren't code 2 | 3 | function! s:PreviewInMarked() 4 | silent! call system("open -a 'Marked 2' " . expand("%:p")) 5 | endfunction 6 | command! PreviewInMarked call <sid>PreviewInMarked() 7 | nnoremap <leader>md :PreviewInMarked<cr> 8 | 9 | function! s:FixLastSpellingError() 10 | let position = getpos('.')[1:3] 11 | let current_line_length = len(getline('.')) 12 | normal! [s1z= 13 | let new_line_length = len(getline('.')) 14 | let position[1] += (new_line_length - current_line_length) 15 | call cursor(position) 16 | silent! call repeat#set("\<Plug>FixLastSpellingError", 0) 17 | endfunction 18 | command! FixLastSpellingError call <sid>FixLastSpellingError() 19 | nnoremap <Plug>FixLastSpellingError :FixLastSpellingError<cr> 20 | imap <C-j> <C-o>:write<cr><C-o>:FixLastSpellingError<cr> 21 | " map <leader>sp <Plug>FixLastSpellingError 22 | " imap <C-y> <C-o>:w<cr><C-o><leader>sp 23 | 24 | " vim:ft=vim 25 | -------------------------------------------------------------------------------- /vim/rcfiles/search-and-replace: -------------------------------------------------------------------------------- 1 | " Search / Substitute related configurations 2 | "------------------------------------------- 3 | 4 | set hlsearch 5 | set incsearch 6 | set ignorecase 7 | set smartcase 8 | nnoremap <leader>sub :%s///g<left><left> 9 | vnoremap <leader>sub :s///g<left><left> 10 | 11 | colorscheme jellybeans 12 | 13 | " vim:ft=vim 14 | -------------------------------------------------------------------------------- /vim/rcfiles/tabs-windows: -------------------------------------------------------------------------------- 1 | " Tab & Window related configurations 2 | 3 | command! TO tabonly|only 4 | 5 | nnoremap <C-w>1 1gt 6 | nnoremap <C-w>2 2gt 7 | nnoremap <C-w>3 3gt 8 | nnoremap <C-w>4 4gt 9 | nnoremap <C-w>5 5gt 10 | nnoremap <C-w>6 6gt 11 | nnoremap <C-w>9 :tablast<cr> 12 | 13 | nnoremap <leader>w1 1gt 14 | nnoremap <leader>w2 2gt 15 | nnoremap <leader>w3 3gt 16 | nnoremap <leader>w4 4gt 17 | nnoremap <leader>w5 5gt 18 | nnoremap <leader>w6 6gt 19 | nnoremap <leader>w9 :tablast<cr> 20 | 21 | " vim:ft=vim 22 | -------------------------------------------------------------------------------- /vim/rcfiles/todo: -------------------------------------------------------------------------------- 1 | " Todo file functionality 2 | "------------------------ 3 | 4 | " Simple todo function 5 | nnoremap <leader>dn :ToggleCompletion<cr>ddGpggj 6 | 7 | function! s:ToggleCompletion() 8 | let save_cursor = getpos(".") 9 | if match(getline('.'), '- \[\s\]') != -1 10 | substitute/\[\s\]/[x]/ 11 | else 12 | substitute/\[x\]/[ ]/ 13 | endif 14 | call setpos('.', save_cursor) 15 | endfunction 16 | 17 | command! ToggleCompletion call <sid>ToggleCompletion() 18 | nnoremap X :ToggleCompletion<cr> 19 | 20 | syntax match doneTodo "\v%(\s+)?- \[x\].*" 21 | highlight link doneTodo Comment 22 | 23 | function! s:MakeTodo() 24 | let save_cursor = getpos(".") 25 | let has_dash = (match(getline('.'), '\v^\s?- \w') != -1) 26 | if has_dash 27 | s/\v(\s+)?- (.*)/\1- [ ] \2/ 28 | call setpos('.', save_cursor) 29 | normal! 4l 30 | else 31 | s/\v(\s+)?(.*)/\1- [ ] \2/ 32 | call setpos('.', save_cursor) 33 | normal! 6l 34 | endif 35 | silent! call repeat#set("\<Plug>MakeTodo", 0) 36 | endfunction 37 | command! MakeTodo call <sid>MakeTodo() 38 | nnoremap <Plug>MakeTodo :MakeTodo<cr> 39 | map <leader>ut <Plug>MakeTodo 40 | 41 | " vim:ft=vim 42 | -------------------------------------------------------------------------------- /vim/rcfiles/trusted-local: -------------------------------------------------------------------------------- 1 | " " Trusted Local 2 | " "-------------- 3 | 4 | " autocmd VimEnter * call s:LoadTrustedVimrcLocal() 5 | " autocmd BufWrite .vimrc.local call s:TrustVimrcLocal() 6 | 7 | " let s:GIT_SAFE_DIR = ".git/safe" 8 | " let s:VIMRC_LOCAL = ".vimrc.local" 9 | 10 | " function! s:TrustVimrcLocal() 11 | " if isdirectory('.git') && !isdirectory(s:GIT_SAFE_DIR) 12 | " call mkdir(s:GIT_SAFE_DIR) 13 | " endif 14 | " endfunction 15 | 16 | " function! s:LoadTrustedVimrcLocal() 17 | " let s:trused_local_path = s:GIT_SAFE_DIR . "/../../" . s:VIMRC_LOCAL 18 | " if filereadable(s:trused_local_path) 19 | " execute "source " . s:trused_local_path 20 | " endif 21 | " endfunction 22 | 23 | " function! s:EditVimrcLocal() 24 | " execute "edit " . s:VIMRC_LOCAL 25 | " endfunction 26 | 27 | " function! s:SmartSplit() 28 | " let split_cmd = (winwidth(0) >= 100) ? 'vsplit' : 'split' 29 | " execute split_cmd . " " . s:VIMRC_LOCAL 30 | " endfunction 31 | 32 | " command! EditVimrcLocal call <sid>SmartSplit() 33 | 34 | " nnoremap <leader>el :EditVimrcLocal<cr> 35 | 36 | " " vim:ft=vim 37 | -------------------------------------------------------------------------------- /vim/rcfiles/visual: -------------------------------------------------------------------------------- 1 | " Visual settings 2 | "---------------- 3 | 4 | " Make it obvious where 80 characters is 5 | set textwidth=80 6 | set colorcolumn=+1 7 | set noshowmode 8 | 9 | " automatically rebalance windows on vim resize 10 | autocmd VimResized * GoldenRatioResize 11 | 12 | " zoom a vim pane, <C-w>= to re-balance 13 | nnoremap <leader>- :wincmd _<cr>:wincmd \|<cr> 14 | nnoremap <leader>= :wincmd =<cr> 15 | 16 | " Open new split panes to right and bottom 17 | set splitbelow 18 | set splitright 19 | 20 | " For neovim, in hopes of making the 'spurious `q`s' go away 21 | " https://github.com/neovim/neovim/issues/8234 22 | set guicursor= 23 | 24 | " vim:ft=vim 25 | -------------------------------------------------------------------------------- /vim/rcfiles/vlc: -------------------------------------------------------------------------------- 1 | nmap <right> :call system("vlc-seek forward")<cr> 2 | nmap <left> :call system("vlc-seek")<cr> 3 | 4 | " vim:ft=vim 5 | -------------------------------------------------------------------------------- /vim/rcplugins/abolish: -------------------------------------------------------------------------------- 1 | " Abolish - Coerce strings to different cases (and some other stuff) 2 | 3 | Plug 'tpope/tpope-vim-abolish' 4 | 5 | " vim:ft=vim 6 | -------------------------------------------------------------------------------- /vim/rcplugins/ack: -------------------------------------------------------------------------------- 1 | " Ack - Integrata ack (grep replacement) into vim 2 | 3 | Plug 'mileszs/ack.vim' 4 | 5 | nmap <LEADER>ck :Ack!<space> 6 | nnoremap <leader>cc :cclose<cr>:pclose<cr> 7 | 8 | function! s:VisualAck() 9 | let temp = @" 10 | normal! gvy 11 | let escaped_pattern = escape(@", "[]().*") 12 | let @" = temp 13 | execute "Ack! '" . escaped_pattern . "'" 14 | endfunction 15 | 16 | nnoremap K :Ack! '<C-r><C-w>'<cr> 17 | vnoremap K :<C-u>call <sid>VisualAck()<cr> 18 | 19 | let g:ackprg = 'ag --nogroup --nocolor --column' 20 | 21 | " vim:ft=vim 22 | -------------------------------------------------------------------------------- /vim/rcplugins/arglist-thank-you-next: -------------------------------------------------------------------------------- 1 | " Thank you Next - Small wrapper around using the arglist as todo list 2 | 3 | function! s:ThankYouNext() abort 4 | update 5 | argdelete % 6 | bdelete 7 | if empty(argv()) 8 | echohl String | echon "All files processed!" | echohl None 9 | else 10 | argument 11 | endif 12 | endfunction 13 | 14 | command! ThankYouNext call <sid>ThankYouNext() 15 | 16 | " vim:ft=vim 17 | -------------------------------------------------------------------------------- /vim/rcplugins/auto-pairs.vim: -------------------------------------------------------------------------------- 1 | " Auto Pairs - auto close parens, brackets, quotes, etc 2 | 3 | " Plug 'jiangmiao/auto-pairs' 4 | " 5 | " Don't like this one either unfortunately 6 | -------------------------------------------------------------------------------- /vim/rcplugins/better-whitespace: -------------------------------------------------------------------------------- 1 | " Better Whitespace - Highlight trailing whitespace and provide command to kill 2 | 3 | Plug 'ntpeters/vim-better-whitespace' 4 | 5 | nnoremap <leader>wht :StripWhitespace<cr>:w<cr> 6 | 7 | " vim:ft=vim 8 | -------------------------------------------------------------------------------- /vim/rcplugins/coc: -------------------------------------------------------------------------------- 1 | " COC - the Conquerer of Completion 2 | 3 | let g:coc_node_path = '/Users/christoomey/.asdf/shims/node' 4 | 5 | Plug 'neoclide/coc.nvim', {'branch': 'release'} 6 | let g:coc_global_extensions = [ 7 | \ 'coc-css', 8 | \ 'coc-json', 9 | \ 'coc-tsserver', 10 | \ 'coc-tailwindcss', 11 | \ 'coc-elixir', 12 | \ 'coc-svelte', 13 | \ 'coc-html', 14 | \ 'coc-yaml', 15 | \ 'coc-vimlsp', 16 | \ 'coc-svg', 17 | \ 'coc-lists', 18 | \ 'coc-json', 19 | \ 'coc-yank', 20 | \ 'coc-highlight', 21 | \ ] 22 | 23 | " \ 'coc-solargraph', 24 | 25 | " autocmd FileType * let b:coc_suggest_disable = 1 26 | " inoremap <silent><expr> <c-j> coc#refresh() 27 | 28 | nmap <leader>rn <Plug>(coc-rename) 29 | 30 | inoremap <silent><expr> <TAB> 31 | \ coc#pum#visible() ? coc#pum#next(1) : 32 | \ CheckBackspace() ? "\<Tab>" : 33 | \ coc#refresh() 34 | 35 | " \ 'coc-actions', 36 | 37 | if isdirectory('./node_modules') && isdirectory('./node_modules/prettier') 38 | let g:coc_global_extensions += ['coc-prettier'] 39 | endif 40 | 41 | if isdirectory('./node_modules') && isdirectory('./node_modules/eslint') 42 | let g:coc_global_extensions += ['coc-eslint'] 43 | endif 44 | 45 | if isdirectory('./node_modules') && isdirectory('./node_modules/stylelint') 46 | let g:coc_global_extensions += ['coc-stylelintplus'] 47 | endif 48 | 49 | function! s:check_eslint() 50 | if !isdirectory('./node_modules') || !isdirectory('./node_modules/eslint') 51 | call coc#config('eslint', { 52 | \ 'enable': v:false, 53 | \ }) 54 | endif 55 | endfunction 56 | 57 | autocmd BufEnter *.{js,jsx,ts,tsx} :call <SID>check_eslint() 58 | 59 | function! s:RestartCoc() abort 60 | silent! CocRestart 61 | echohl String | echom 'Restarting COC...' | echohl None 62 | endfunction 63 | command! RestartCoc call s:RestartCoc() 64 | nnoremap <leader>re :RestartCoc<cr> 65 | 66 | inoremap <silent><expr> <CR> coc#pum#visible() ? coc#pum#confirm() : "\<CR>" 67 | inoremap <silent><expr> <Tab> coc#pum#visible() ? "\<C-n>" : "\<Tab>" 68 | 69 | " hi! CocMenuSel ctermbg=8 70 | 71 | nmap <silent> <C-]> <Plug>(coc-definition) 72 | nmap <leader>do <Plug>(coc-codeaction) 73 | 74 | nmap <leader>du <Plug>(coc-references) 75 | 76 | " Jump to next / previous error 77 | nmap <silent> ]r <Plug>(coc-diagnostic-next-error) 78 | nmap <silent> [r <Plug>(coc-diagnostic-prev-error) 79 | 80 | " show documentation 81 | function! s:show_documentation() 82 | if (index(['vim','help'], &filetype) >= 0) 83 | execute 'h '.expand('<cword>') 84 | else 85 | call CocAction('doHover') 86 | endif 87 | endfunction 88 | nnoremap <silent> K :call <SID>show_documentation()<CR> 89 | 90 | " show error, otherwise documentation, on hold 91 | function! ShowDocIfNoDiagnostic(timer_id) 92 | " if (coc#util#has_float() == 0) 93 | silent call CocActionAsync('doHover') 94 | " endif 95 | endfunction 96 | function! s:show_hover_doc() 97 | call timer_start(200, 'ShowDocIfNoDiagnostic') 98 | endfunction 99 | nnoremap <leader>k :call <SID>show_hover_doc()<cr> 100 | 101 | " vim:ft=vim 102 | -------------------------------------------------------------------------------- /vim/rcplugins/commentary: -------------------------------------------------------------------------------- 1 | " Commentary - Comment / uncomment via text operator w/ text objects 2 | "------------------------------------------------------------------- 3 | 4 | Plug 'tpope/vim-commentary' 5 | 6 | " vim:ft=vim 7 | -------------------------------------------------------------------------------- /vim/rcplugins/conflicted: -------------------------------------------------------------------------------- 1 | " Conflicted - Enhancements build on fugitive to handle git conflicts 2 | " ------------------------------------------------------------------- 3 | 4 | " Plug 'christoomey/vim-conflicted' 5 | Plug '~/code/vim/conflicted' 6 | nnoremap <leader>gnc :GitNextConflict<cr> 7 | 8 | " set stl+=%{ConflictedVersion()} 9 | 10 | " vim:ft=vim 11 | -------------------------------------------------------------------------------- /vim/rcplugins/css3: -------------------------------------------------------------------------------- 1 | " CSS3 - Enhanced keyword and syntax definitions for CSS3 2 | 3 | Plug 'hail2u/vim-css3-syntax' 4 | 5 | " vim:ft=vim 6 | -------------------------------------------------------------------------------- /vim/rcplugins/display-table-name: -------------------------------------------------------------------------------- 1 | " Display Table Name for current Rails model file 2 | 3 | Plug '~/code/vim/display-table-summary' 4 | 5 | nnoremap <leader>dt :DisplayTableSummary<cr> 6 | 7 | " function! s:DisplayTableDetail() abort 8 | " call popup_create(systemlist(s:table_info_query()), s:popup_options) 9 | " endfunction 10 | 11 | " let s:popup_options = 12 | " \ { 13 | " \ 'close': 'button', 14 | " \ 'border': [1,1,1,1], 15 | " \ 'drag': 1, 16 | " \ 'maxheight': 50, 17 | " \ 'scrollbar': 1, 18 | " \ 'resize': 1 19 | " \ } 20 | 21 | " command! DisplayTableDetail call s:DisplayTableDetail() 22 | 23 | " function! s:table_info_query() abort 24 | " return "psql -d " . s:database_name() . " -c '\\d " . s:table_name() . "'" 25 | " endfunction 26 | 27 | " function! s:table_name() abort 28 | " return system("table-name-rails " . expand("%")) 29 | " endfunction 30 | 31 | " function! s:database_name() abort 32 | " if exists('g:display_table_database_name') 33 | " return g:display_table_database_name 34 | " else 35 | " if executable('yq') 36 | " return trim(system("cat config/database.yml | yq read - development.database")) 37 | " else 38 | " return trim(system("basename $(pwd)")) . "_development" 39 | " end 40 | " endif 41 | " endfunction 42 | 43 | " nnoremap <leader>dt :DisplayTableDetail<cr> 44 | 45 | " " vim:ft=vim 46 | -------------------------------------------------------------------------------- /vim/rcplugins/easy-align: -------------------------------------------------------------------------------- 1 | " Easy Align - operators for aligning characters across lines 2 | 3 | Plug 'junegunn/vim-easy-align' 4 | command! ReformatTable normal vip<cr>**| 5 | nmap <leader>rt :ReformatTable<cr> 6 | vmap <cr> <Plug>(EasyAlign) 7 | 8 | " vim:ft=vim 9 | -------------------------------------------------------------------------------- /vim/rcplugins/emmet: -------------------------------------------------------------------------------- 1 | " Emmet - Generate HTML markup from css-like selector strings 2 | 3 | Plug 'mattn/emmet-vim' 4 | let g:user_emmet_leader_key = '<c-e>' 5 | 6 | " vim:ft=vim 7 | -------------------------------------------------------------------------------- /vim/rcplugins/endwise: -------------------------------------------------------------------------------- 1 | " Endwise - Automatic insertion of closings like do..end 2 | 3 | Plug 'tpope/vim-endwise' 4 | 5 | " vim:ft=vim 6 | -------------------------------------------------------------------------------- /vim/rcplugins/eunuch: -------------------------------------------------------------------------------- 1 | " Eunuch - Add handful of UNIXy commands to Vim 2 | 3 | Plug 'tpope/vim-eunuch' 4 | 5 | let g:eunuch_no_maps = 1 6 | 7 | " vim:ft=vim 8 | -------------------------------------------------------------------------------- /vim/rcplugins/exchange: -------------------------------------------------------------------------------- 1 | " Exchange.vim - Operator for exchanging text regions 2 | 3 | Plug 'tommcdo/vim-exchange' 4 | 5 | " vim:ft=vim 6 | -------------------------------------------------------------------------------- /vim/rcplugins/file-line: -------------------------------------------------------------------------------- 1 | " File Line - Accept file_name.rb:23 style files 2 | 3 | Plug 'bogado/file-line' 4 | 5 | " vim:ft=vim 6 | -------------------------------------------------------------------------------- /vim/rcplugins/fugitive: -------------------------------------------------------------------------------- 1 | " Fugitive - Vim meets git. Gstatus, Gdiff, etc. 2 | 3 | Plug 'tpope/vim-fugitive' 4 | 5 | nnoremap \<space> :Git<cr>:wincmd _<cr> 6 | nnoremap \gr :Git rebase -i master<cr> 7 | nnoremap \gd :Gvdiffsplit<cr> 8 | 9 | " vim:ft=vim 10 | -------------------------------------------------------------------------------- /vim/rcplugins/fzf: -------------------------------------------------------------------------------- 1 | " fzf - the fuzzy finder of all the things 2 | 3 | Plug 'junegunn/fzf', { 'dir': '~/.fzf', 'do': './install --all' } 4 | Plug 'junegunn/fzf.vim' 5 | 6 | let g:fzf_files_options = 7 | \ '--reverse ' . 8 | \ '--preview "(coderay {} || cat {}) 2> /dev/null | head -'.&lines.'"' 9 | let g:fzf_layout = { 'down': '~60%' } 10 | nnoremap <C-p> :Files<cr> 11 | let $FZF_DEFAULT_COMMAND = 'ag -g "" --hidden --ignore .git' 12 | 13 | " let g:fzf_layout = { 'window': { 'width': 0.9, 'height': 0.6, 'highlight': 'Todo', 'border': 'sharp' } } 14 | " " Creates a floating window with a most recent buffer to be used 15 | " function! CreateCenteredFloatingWindow() 16 | " let width = float2nr(&columns * 0.75) 17 | " let height = float2nr(&lines * 0.6) 18 | " let top = ((&lines - height) / 2) - 1 19 | " let left = (&columns - width) / 2 20 | " let opts = {'relative': 'editor', 'row': top, 'col': left, 'width': width, 'height': height, 'style': 'minimal'} 21 | 22 | " let top = "╭" . repeat("─", width - 2) . "╮" 23 | " let mid = "│" . repeat(" ", width - 2) . "│" 24 | " let bot = "╰" . repeat("─", width - 2) . "╯" 25 | " let lines = [top] + repeat([mid], height - 2) + [bot] 26 | " let s:buf = nvim_create_buf(v:false, v:true) 27 | " call nvim_buf_set_lines(s:buf, 0, -1, v:true, lines) 28 | " call nvim_open_win(s:buf, v:true, opts) 29 | " set winhl=Normal:Floating 30 | " let opts.row += 1 31 | " let opts.height -= 2 32 | " let opts.col += 2 33 | " let opts.width -= 4 34 | " call nvim_open_win(nvim_create_buf(v:false, v:true), v:true, opts) 35 | " au BufWipeout <buffer> exe 'bw '.s:buf 36 | " endfunction 37 | 38 | " function! OpenTerm(cmd) 39 | " call CreateCenteredFloatingWindow() 40 | " call termopen(a:cmd, { 'on_exit': function('OnTermExit') }) 41 | " endfunction 42 | 43 | " let g:fzf_layout = { 'window': 'call CreateCenteredFloatingWindow()' } 44 | 45 | nnoremap <leader>ga :Files app/<cr> 46 | nnoremap <leader>gm :Files app/models/<cr> 47 | nnoremap <leader>gv :Files app/views/<cr> 48 | nnoremap <leader>gc :Files app/controllers/<cr> 49 | nnoremap <leader>gy :Files app/assets/stylesheets/<cr> 50 | nnoremap <leader>gj :Files app/assets/javascripts/<cr> 51 | nnoremap <leader>gs :Files spec/<cr> 52 | nnoremap <leader>. :Files %:p:h<cr> 53 | 54 | " vim:ft=vim 55 | -------------------------------------------------------------------------------- /vim/rcplugins/fzf-branch-files: -------------------------------------------------------------------------------- 1 | " FZF Branch Files - Fuzzy select from files on the current branch 2 | 3 | Plug '~/code/vim/fzf-branch-files' 4 | 5 | let g:fzf_branch_files_default_branch = 'main' 6 | 7 | nnoremap <silent> <leader>gp :FzfBranchFiles<cr> 8 | nnoremap <silent> <leader>GP :FzfWorkingFiles<cr> 9 | 10 | " vim:ft=vim 11 | -------------------------------------------------------------------------------- /vim/rcplugins/github-colorscheme: -------------------------------------------------------------------------------- 1 | Plug 'cormacrelf/vim-colors-github' 2 | 3 | " vim:ft=vim 4 | -------------------------------------------------------------------------------- /vim/rcplugins/golden-ratio: -------------------------------------------------------------------------------- 1 | " Golden Ratio - resize buffers to keep active one sane 2 | 3 | Plug 'roman/golden-ratio' 4 | 5 | " vim:ft=vim 6 | -------------------------------------------------------------------------------- /vim/rcplugins/goyo-limelight-writing: -------------------------------------------------------------------------------- 1 | " Goyo & Limelight - Distraction free writing 2 | 3 | Plug 'junegunn/goyo.vim' 4 | Plug 'junegunn/limelight.vim' 5 | 6 | autocmd! User GoyoEnter Limelight 7 | autocmd! User GoyoLeave Limelight! 8 | 9 | " Color name (:help cterm-colors) or ANSI code 10 | let g:limelight_conceal_ctermfg = 'gray' 11 | let g:limelight_conceal_ctermfg = 240 12 | 13 | " Color name (:help gui-colors) or RGB color 14 | let g:limelight_conceal_guifg = 'DarkGray' 15 | let g:limelight_conceal_guifg = '#777777' 16 | 17 | " vim:ft=vim 18 | -------------------------------------------------------------------------------- /vim/rcplugins/graphql: -------------------------------------------------------------------------------- 1 | " GraphQL - filetype settings for GraphQL 2 | 3 | Plug 'jparise/vim-graphql' 4 | 5 | " vim:ft=vim 6 | -------------------------------------------------------------------------------- /vim/rcplugins/gsub: -------------------------------------------------------------------------------- 1 | " Gsub - Project wide find and replace 2 | 3 | Plug '~/code/vim/gsub' 4 | 5 | " Mappings to search for the <cword> or visual highlight, and run Gsearch 6 | nmap K *:Gsearch<cr> 7 | vmap K *:Gsearch<cr> 8 | 9 | autocmd FileType gsub nnoremap <buffer> <cr><cr> :Gsub<cr> 10 | 11 | " vim:ft=vim 12 | -------------------------------------------------------------------------------- /vim/rcplugins/html5: -------------------------------------------------------------------------------- 1 | Plug 'othree/html5.vim' 2 | -------------------------------------------------------------------------------- /vim/rcplugins/javascript: -------------------------------------------------------------------------------- 1 | " JavaScript - JS syntax and indent settings, along with JSX support 2 | 3 | Plug 'pangloss/vim-javascript' 4 | Plug 'mxw/vim-jsx' 5 | let g:jsx_ext_required = 0 6 | 7 | Plug 'chemzqm/vim-jsx-improve', { 'for': 'javascript.jsx' } 8 | 9 | autocmd BufEnter *.es6 setf javascript 10 | 11 | command! EslintDStop call system("./node_modules/.bin/eslint_d stop") 12 | 13 | " vim:ft=vim 14 | -------------------------------------------------------------------------------- /vim/rcplugins/jellybeans: -------------------------------------------------------------------------------- 1 | " Jellybeans colorscheme 2 | 3 | Plug 'nanotech/jellybeans.vim' 4 | 5 | " vim:ft=vim 6 | -------------------------------------------------------------------------------- /vim/rcplugins/json: -------------------------------------------------------------------------------- 1 | " JSON - Syntax highlighting for JSON 2 | 3 | " Fancy tricks with hiding quotes around attributes, includes ftdetect 4 | Plug 'elzr/vim-json' 5 | 6 | let g:vim_json_syntax_conceal = 0 7 | 8 | " Requires 'jq' (brew install jq) 9 | function! s:PrettyJSON() 10 | %!jq . 11 | set filetype=json 12 | endfunction 13 | command! PrettyJSON :call <sid>PrettyJSON() 14 | 15 | " vim:ft=vim 16 | -------------------------------------------------------------------------------- /vim/rcplugins/lexima.vim: -------------------------------------------------------------------------------- 1 | " Lexima - auto-close pairs 2 | 3 | " Plug 'cohama/lexima.vim' 4 | 5 | " let g:lexima_accept_pum_with_enter = 1 6 | -------------------------------------------------------------------------------- /vim/rcplugins/lightline: -------------------------------------------------------------------------------- 1 | " Lightline - Minimal statusline 2 | 3 | Plug 'itchyny/lightline.vim' 4 | 5 | let g:lightline = { 6 | \ 'colorscheme': 'wombat', 7 | \ 'active': { 8 | \ 'left': [ [ 'mode', 'paste' ], 9 | \ [ 'cocstatus', 'readonly', 'filename', 'modified' ] ] 10 | \ }, 11 | \ 'component_function': { 12 | \ 'cocstatus': 'coc#status' 13 | \ }, 14 | \ } 15 | 16 | " vim:ft=vim 17 | -------------------------------------------------------------------------------- /vim/rcplugins/markdown: -------------------------------------------------------------------------------- 1 | " Markdown - Syntax file for Markdowm files 2 | 3 | Plug 'plasticboy/vim-markdown' 4 | 5 | nnoremap <leader>co :Toch<cr> 6 | 7 | autocmd FileType markdown setlocal conceallevel=2 8 | autocmd FileType markdown nnoremap <buffer> <tab> :call search('\s[\w', 'w')<cr>:noh<cr>2l 9 | autocmd FileType markdown nnoremap <buffer> <S-tab> F[h:call search('\s[\w', 'wb')<cr>:noh<cr>2l 10 | autocmd FileType markdown nmap <buffer> <cr> <Plug>Markdown_OpenUrlUnderCursor 11 | autocmd FileType markdown setlocal nowrap 12 | 13 | let g:vim_markdown_new_list_item_indent = 0 14 | let g:vim_markdown_fenced_languages = ['rb=ruby'] 15 | let g:vim_markdown_conceal_code_blocks = 0 16 | 17 | hi def link htmlH2 Type 18 | hi def link htmlH3 PreProc 19 | 20 | " vim:ft=vim 21 | -------------------------------------------------------------------------------- /vim/rcplugins/markdown-header-mappings: -------------------------------------------------------------------------------- 1 | " Markdown Header Mappings - Easy setting of markdown headers 2 | "------------------------------------------------------------ 3 | 4 | function! s:SmartLevelFourHeader() 5 | call s:DeleteExistingUnderline() 6 | call s:DeleteExistingLeadingHeaderMarks() 7 | s/^/#### / 8 | silent! call repeat#set("\<Plug>SmartLevelFourHeader") 9 | endfunction 10 | 11 | function! s:SmartLevelThreeHeader() 12 | call s:DeleteExistingUnderline() 13 | call s:DeleteExistingLeadingHeaderMarks() 14 | s/^/### / 15 | silent! call repeat#set("\<Plug>SmartLevelThreeHeader") 16 | endfunction 17 | 18 | function! s:OnLastLineOfFile() 19 | return line('.') == line('$') 20 | endfunction 21 | 22 | function! s:DeleteExistingLeadingHeaderMarks() 23 | silent! s/^#\{1,6} // 24 | endfunction 25 | 26 | function! s:DeleteExistingUnderline() 27 | if !s:OnLastLineOfFile() 28 | let saved_cursor = getpos(".") 29 | +1g/\v^[-=]+$/d 30 | call setpos('.', saved_cursor) 31 | endif 32 | endfunction 33 | 34 | function! s:SmartUnderline(char) 35 | call s:DeleteExistingUnderline() 36 | call s:DeleteExistingLeadingHeaderMarks() 37 | let underline = repeat(a:char, len(getline('.'))) 38 | call append(line('.'), underline) 39 | if a:char == '=' 40 | silent! call repeat#set("\<Plug>UnderlineH1", v:count) 41 | else 42 | silent! call repeat#set("\<Plug>UnderlineH2", v:count) 43 | end 44 | endfunction 45 | 46 | nnoremap <silent> <Plug>UnderlineH1 :call <sid>SmartUnderline('=')<cr> 47 | nnoremap <silent> <Plug>UnderlineH2 :call <sid>SmartUnderline('-')<cr> 48 | nnoremap <silent> <Plug>SmartLevelThreeHeader :call <sid>SmartLevelThreeHeader()<cr> 49 | nnoremap <silent> <Plug>SmartLevelFourHeader :call <sid>SmartLevelFourHeader()<cr> 50 | nmap <leader>u1 <Plug>UnderlineH1 51 | nmap <leader>u2 <Plug>UnderlineH2 52 | nmap <leader>u3 <Plug>SmartLevelThreeHeader 53 | nmap <leader>u4 <Plug>SmartLevelFourHeader 54 | 55 | " vim:ft=vim 56 | -------------------------------------------------------------------------------- /vim/rcplugins/mkdir: -------------------------------------------------------------------------------- 1 | " Vim mkdir - automatically make intermediate directories if needed 2 | 3 | Plug 'pbrisbin/vim-mkdir' 4 | 5 | " vim:ft=vim 6 | -------------------------------------------------------------------------------- /vim/rcplugins/one-colorscheme: -------------------------------------------------------------------------------- 1 | Plug 'rakr/vim-one' 2 | 3 | " colorscheme one 4 | " call one#highlight('Normal', '', 'ffffff', 'none') 5 | 6 | " vim:ft=vim 7 | -------------------------------------------------------------------------------- /vim/rcplugins/polyglot: -------------------------------------------------------------------------------- 1 | " Polyglot - Syntax & related files for variety of languages 2 | 3 | " Plug 'sheerun/vim-polyglot' 4 | 5 | " vim:ft=vim 6 | -------------------------------------------------------------------------------- /vim/rcplugins/projectionist: -------------------------------------------------------------------------------- 1 | " Projectionist 2 | 3 | Plug 'tpope/vim-projectionist' 4 | 5 | let g:projectionist_heuristics = { 6 | \ "app/|spec/": { 7 | \ "app/*.rb": { "alternate": "spec/{}_spec.rb" }, 8 | \ "spec/*_spec.rb": { "alternate": "app/{}.rb" }, 9 | \ } 10 | \ } 11 | 12 | " vim:ft=vim 13 | -------------------------------------------------------------------------------- /vim/rcplugins/quicklink: -------------------------------------------------------------------------------- 1 | " Quicklink - quickly add markdown links to documents 2 | 3 | Plug 'mattn/webapi-vim' 4 | " Plug 'christoomey/vim-quicklink' 5 | Plug '~/code/vim/quicklink' 6 | 7 | " vim:ft=vim 8 | -------------------------------------------------------------------------------- /vim/rcplugins/rake: -------------------------------------------------------------------------------- 1 | " Rake - Additional Ruby smarts in Vim 2 | 3 | Plug 'tpope/vim-rake' 4 | 5 | " vim:ft=vim 6 | -------------------------------------------------------------------------------- /vim/rcplugins/repeat: -------------------------------------------------------------------------------- 1 | " Repeat - Repeat custom mappings with `.` 2 | 3 | Plug 'tpope/vim-repeat' 4 | 5 | " vim:ft=vim 6 | -------------------------------------------------------------------------------- /vim/rcplugins/replace-with-register: -------------------------------------------------------------------------------- 1 | " ReplaceWithRegister - add `gr` operator to 'replace' over a text object 2 | 3 | Plug 'vim-scripts/ingo-library' 4 | Plug 'vim-scripts/ReplaceWithRegister' 5 | Plug 'vim-scripts/ReplaceWithSameIndentRegister' 6 | 7 | nmap <leader>gr "*gr 8 | nmap <leader>gR "*gR 9 | 10 | " vim:ft=vim 11 | -------------------------------------------------------------------------------- /vim/rcplugins/rfactory: -------------------------------------------------------------------------------- 1 | " Rfactory - Rapid navigation to FactoryGirl factories ala Rails.vim 2 | 3 | Plug 'christoomey/vim-rfactory' 4 | 5 | nnoremap <leader>gf :call <sid>SmartSplit()<cr> 6 | 7 | function! s:SmartSplit() 8 | let split_cmd = (winwidth(0) > 106) ? 'RVfactory' : 'RSfactory' 9 | execute split_cmd 10 | endfunction 11 | 12 | " vim:ft=vim 13 | -------------------------------------------------------------------------------- /vim/rcplugins/rhubarb: -------------------------------------------------------------------------------- 1 | " Rhubarb - GitHub smarts for fugitive 2 | 3 | Plug 'tpope/vim-rhubarb' 4 | 5 | " vim:ft=vim 6 | -------------------------------------------------------------------------------- /vim/rcplugins/rsi: -------------------------------------------------------------------------------- 1 | " Rsi - Readline mappings at the Vim command line 2 | 3 | Plug 'tpope/vim-rsi' 4 | 5 | " vim:ft=vim 6 | -------------------------------------------------------------------------------- /vim/rcplugins/ruby: -------------------------------------------------------------------------------- 1 | " Ruby - More up to date Ruby filetype settings 2 | 3 | Plug 'vim-ruby/vim-ruby' 4 | 5 | " vim:ft=vim 6 | -------------------------------------------------------------------------------- /vim/rcplugins/scala: -------------------------------------------------------------------------------- 1 | " Scala - Syntax and filetype settings for Scala 2 | 3 | Plug 'derekwyatt/vim-scala' 4 | Plug 'gre/play2vim' 5 | 6 | " vim:ft=vim 7 | -------------------------------------------------------------------------------- /vim/rcplugins/sort-motion: -------------------------------------------------------------------------------- 1 | " Sort motion - sort based on motion or text object 2 | 3 | " Plug 'christoomey/vim-sort-motion' 4 | Plug '~/code/vim/sort-motion' 5 | 6 | " vim:ft=vim 7 | -------------------------------------------------------------------------------- /vim/rcplugins/spec-runner: -------------------------------------------------------------------------------- 1 | " Vim Spec Runner - Smart spec (rspec) runner 2 | 3 | Plug 'gabebw/vim-spec-runner' 4 | map <leader>t <Plug>RunFocusedSpec 5 | 6 | let g:spec_runner_dispatcher = "VtrSendCommand! bin/{command}" 7 | 8 | " vim:ft=vim 9 | -------------------------------------------------------------------------------- /vim/rcplugins/surround: -------------------------------------------------------------------------------- 1 | " Surround - Mappings for adding, removing, and changing surrounding characters 2 | 3 | Plug 'tpope/vim-surround' 4 | 5 | let g:surround_99 = "```\r```" 6 | 7 | " vim:ft=vim 8 | -------------------------------------------------------------------------------- /vim/rcplugins/svelte: -------------------------------------------------------------------------------- 1 | " Svelte runtime and syntax files 2 | 3 | Plug 'evanleck/vim-svelte', {'branch': 'main'} 4 | Plug 'isRuslan/vim-es6' 5 | 6 | let g:svelte_preprocessor_tags = [ 7 | \ { 'name': 'ts', 'tag': 'script', 'as': 'typescript' } 8 | \ ] 9 | let g:svelte_preprocessors = ['ts', 'scss'] 10 | 11 | " vim:ft=vim 12 | -------------------------------------------------------------------------------- /vim/rcplugins/system-copy: -------------------------------------------------------------------------------- 1 | " System Copy - add `cp` operator to copy text to system clipboard via text 2 | " object or motion 3 | 4 | " Plug 'christoomey/vim-system-copy' 5 | Plug '~/code/vim/system-copy' 6 | 7 | " vim:ft=vim 8 | -------------------------------------------------------------------------------- /vim/rcplugins/text-objects: -------------------------------------------------------------------------------- 1 | " TextObj - Custom text objects for the line, indent level, entier file, etc 2 | 3 | Plug 'kana/vim-textobj-user' 4 | Plug 'kana/vim-textobj-line' 5 | Plug 'kana/vim-textobj-indent' 6 | Plug 'kana/vim-textobj-entire' 7 | Plug 'beloglazov/vim-textobj-quotes' 8 | 9 | " Plug 'christoomey/vim-textobj-codeblock' 10 | Plug '~/code/vim/textobj-codeblock' 11 | 12 | " vim:ft=vim 13 | -------------------------------------------------------------------------------- /vim/rcplugins/titlecase: -------------------------------------------------------------------------------- 1 | " Titlecase - operator for titlecasing over a motion or text object 2 | 3 | " Plug 'christoomey/vim-titlecase' 4 | Plug '~/code/vim/titlecase' 5 | let g:titlecase_map_keys = 0 6 | nmap <leader>gt <Plug>Titlecase 7 | vmap <leader>gt <Plug>Titlecase 8 | nmap <leader>gT <Plug>TitlecaseLine 9 | 10 | " vim:ft=vim 11 | -------------------------------------------------------------------------------- /vim/rcplugins/tmux-navigator: -------------------------------------------------------------------------------- 1 | " Vim Tmux Navigator - Seamlessly navigate between vim splits and tmux panes 2 | 3 | " Plug 'christoomey/vim-tmux-navigator' 4 | Plug '~/code/vim/tmux-navigator' 5 | 6 | " vim:ft=vim 7 | -------------------------------------------------------------------------------- /vim/rcplugins/tmux-runner: -------------------------------------------------------------------------------- 1 | " Vim Tmux Runner - Connect Vim and tmux to allow running lines & commands 2 | 3 | " Plug 'christoomey/vim-tmux-runner' 4 | Plug '~/code/vim/tmux-runner' 5 | nnoremap <leader>v- :VtrOpenRunner { "orientation": "v", "percentage": 30 }<cr> 6 | nnoremap <leader>v\ :VtrOpenRunner { "orientation": "h", "percentage": 30 }<cr> 7 | nnoremap <leader>vk :VtrKillRunner<cr> 8 | " nnoremap <leader>va :VtrAttachToPane<cr> 9 | nnoremap <leader>v0 :VtrAttachToPane 0<cr>:call system("tmux clock-mode -t 0 && sleep 0.1 && tmux send-keys -t 0 q")<cr> 10 | nnoremap <leader>v1 :VtrAttachToPane 1<cr>:call system("tmux clock-mode -t 1 && sleep 0.1 && tmux send-keys -t 1 q")<cr> 11 | nnoremap <leader>v2 :VtrAttachToPane 2<cr>:call system("tmux clock-mode -t 2 && sleep 0.1 && tmux send-keys -t 2 q")<cr> 12 | nnoremap <leader>v3 :VtrAttachToPane 3<cr>:call system("tmux clock-mode -t 3 && sleep 0.1 && tmux send-keys -t 3 q")<cr> 13 | nnoremap <leader>v4 :VtrAttachToPane 4<cr>:call system("tmux clock-mode -t 4 && sleep 0.1 && tmux send-keys -t 4 q")<cr> 14 | nnoremap <leader>v5 :VtrAttachToPane 5<cr>:call system("tmux clock-mode -t 5 && sleep 0.1 && tmux send-keys -t 5 q")<cr> 15 | nnoremap <leader>fr :VtrFocusRunner<cr> 16 | " noremap <C-f> :VtrSendLinesToRunner<cr> 17 | 18 | nnoremap <leader>sq :VtrSendKeysRaw q<cr> 19 | nnoremap <leader>sd :VtrSendKeysRaw ^D<cr> 20 | nnoremap <leader>sl :VtrSendKeysRaw ^L<cr> 21 | nnoremap <leader>sc :VtrSendKeysRaw ^C<cr> 22 | nnoremap <leader>vs :VtrSendCommandToRunner<space> 23 | nnoremap <leader>s1 :VtrSendKeysRaw C-p C-m<cr> 24 | 25 | " vim:ft=vim 26 | -------------------------------------------------------------------------------- /vim/rcplugins/trusted-local: -------------------------------------------------------------------------------- 1 | " Trusted Local - Read in a .vimrc.local config using `.git/safe/../../` trust 2 | " bridge as used to put binstubs in path 3 | 4 | " Plug 'christoomey/vim-trusted-local' 5 | Plug '~/code/vim/trusted-local' 6 | 7 | nmap <leader>el <Plug>(EditVimrcLocal) 8 | 9 | " vim:ft=vim 10 | -------------------------------------------------------------------------------- /vim/rcplugins/typescript: -------------------------------------------------------------------------------- 1 | " TypeScript - Filetype and syntax settings 2 | 3 | Plug 'leafgarland/typescript-vim' 4 | Plug 'peitalin/vim-jsx-typescript', { 'for': 'typescript.jsx' } 5 | 6 | " vim:ft=vim 7 | -------------------------------------------------------------------------------- /vim/rcplugins/unimpaired: -------------------------------------------------------------------------------- 1 | " Unimpaired - Pairs of mappings for changing options, adding lines, etc. 2 | 3 | Plug 'tpope/vim-unimpaired' 4 | 5 | " vim:ft=vim 6 | -------------------------------------------------------------------------------- /vim/rcplugins/vim-pad: -------------------------------------------------------------------------------- 1 | " Vim Pad - quick access notes, project specific and global 2 | 3 | Plug 'fmoralesc/vim-pad' 4 | 5 | let g:pad#dir = '~/.notes' 6 | let g:pad#local_dir = '.notes' 7 | 8 | " vim:ft=vim 9 | -------------------------------------------------------------------------------- /vim/rcplugins/vinegar: -------------------------------------------------------------------------------- 1 | " Vinegar - Minimal useful additions to netrw 2 | 3 | Plug 'tpope/vim-vinegar' 4 | 5 | " vim:ft=vim 6 | -------------------------------------------------------------------------------- /vim/rcplugins/vip: -------------------------------------------------------------------------------- 1 | " VIP - Vim Integrated Presentations 2 | 3 | " Plug 'christoomey/vim-vip' 4 | Plug '~/code/vim/vip' 5 | 6 | " vim:ft=vim 7 | -------------------------------------------------------------------------------- /vim/rcplugins/visual-star-search: -------------------------------------------------------------------------------- 1 | " Visual-star-search - 2 | 3 | Plug 'nelstrom/vim-visual-star-search' 4 | 5 | " vim:ft=vim 6 | -------------------------------------------------------------------------------- /vim/vimrc: -------------------------------------------------------------------------------- 1 | " Vimrc 2 | " 3 | " This file contains the minimal settings to set the foundation, with the 4 | " majority of the configuration and settings living in files spread between 5 | " vim/rcfiles and vim/rcplugins 6 | 7 | set nocompatible 8 | 9 | " Need to set the leader before defining any leader mappings 10 | let mapleader = "\<Space>" 11 | 12 | function! s:SourceConfigFilesIn(directory) 13 | let directory_splat = '~/.vim/' . a:directory . '/*' 14 | for config_file in split(glob(directory_splat), '\n') 15 | if filereadable(config_file) 16 | execute 'source' config_file 17 | endif 18 | endfor 19 | endfunction 20 | 21 | " Force shell to /bin/bash to avoid E484 can't find tmp files in /var/folders/* 22 | set shell=/bin/bash 23 | 24 | call plug#begin('~/.vim/bundle') 25 | call s:SourceConfigFilesIn('rcplugins') 26 | call plug#end() 27 | 28 | call s:SourceConfigFilesIn('rcfiles') 29 | -------------------------------------------------------------------------------- /zsh/completion/_flyctl: -------------------------------------------------------------------------------- 1 | #compdef fly 2 | compdef _fly fly 3 | 4 | # zsh completion for fly -*- shell-script -*- 5 | 6 | __fly_debug() 7 | { 8 | local file="$BASH_COMP_DEBUG_FILE" 9 | if [[ -n ${file} ]]; then 10 | echo "$*" >> "${file}" 11 | fi 12 | } 13 | 14 | _fly() 15 | { 16 | local shellCompDirectiveError=1 17 | local shellCompDirectiveNoSpace=2 18 | local shellCompDirectiveNoFileComp=4 19 | local shellCompDirectiveFilterFileExt=8 20 | local shellCompDirectiveFilterDirs=16 21 | local shellCompDirectiveKeepOrder=32 22 | 23 | local lastParam lastChar flagPrefix requestComp out directive comp lastComp noSpace keepOrder 24 | local -a completions 25 | 26 | __fly_debug "\n========= starting completion logic ==========" 27 | __fly_debug "CURRENT: ${CURRENT}, words[*]: ${words[*]}" 28 | 29 | # The user could have moved the cursor backwards on the command-line. 30 | # We need to trigger completion from the $CURRENT location, so we need 31 | # to truncate the command-line ($words) up to the $CURRENT location. 32 | # (We cannot use $CURSOR as its value does not work when a command is an alias.) 33 | words=("${=words[1,CURRENT]}") 34 | __fly_debug "Truncated words[*]: ${words[*]}," 35 | 36 | lastParam=${words[-1]} 37 | lastChar=${lastParam[-1]} 38 | __fly_debug "lastParam: ${lastParam}, lastChar: ${lastChar}" 39 | 40 | # For zsh, when completing a flag with an = (e.g., fly -n=<TAB>) 41 | # completions must be prefixed with the flag 42 | setopt local_options BASH_REMATCH 43 | if [[ "${lastParam}" =~ '-.*=' ]]; then 44 | # We are dealing with a flag with an = 45 | flagPrefix="-P ${BASH_REMATCH}" 46 | fi 47 | 48 | # Prepare the command to obtain completions 49 | requestComp="${words[1]} __complete ${words[2,-1]}" 50 | if [ "${lastChar}" = "" ]; then 51 | # If the last parameter is complete (there is a space following it) 52 | # We add an extra empty parameter so we can indicate this to the go completion code. 53 | __fly_debug "Adding extra empty parameter" 54 | requestComp="${requestComp} \"\"" 55 | fi 56 | 57 | __fly_debug "About to call: eval ${requestComp}" 58 | 59 | # Use eval to handle any environment variables and such 60 | out=$(eval ${requestComp} 2>/dev/null) 61 | __fly_debug "completion output: ${out}" 62 | 63 | # Extract the directive integer following a : from the last line 64 | local lastLine 65 | while IFS='\n' read -r line; do 66 | lastLine=${line} 67 | done < <(printf "%s\n" "${out[@]}") 68 | __fly_debug "last line: ${lastLine}" 69 | 70 | if [ "${lastLine[1]}" = : ]; then 71 | directive=${lastLine[2,-1]} 72 | # Remove the directive including the : and the newline 73 | local suffix 74 | (( suffix=${#lastLine}+2)) 75 | out=${out[1,-$suffix]} 76 | else 77 | # There is no directive specified. Leave $out as is. 78 | __fly_debug "No directive found. Setting do default" 79 | directive=0 80 | fi 81 | 82 | __fly_debug "directive: ${directive}" 83 | __fly_debug "completions: ${out}" 84 | __fly_debug "flagPrefix: ${flagPrefix}" 85 | 86 | if [ $((directive & shellCompDirectiveError)) -ne 0 ]; then 87 | __fly_debug "Completion received error. Ignoring completions." 88 | return 89 | fi 90 | 91 | local activeHelpMarker="_activeHelp_ " 92 | local endIndex=${#activeHelpMarker} 93 | local startIndex=$((${#activeHelpMarker}+1)) 94 | local hasActiveHelp=0 95 | while IFS='\n' read -r comp; do 96 | # Check if this is an activeHelp statement (i.e., prefixed with $activeHelpMarker) 97 | if [ "${comp[1,$endIndex]}" = "$activeHelpMarker" ];then 98 | __fly_debug "ActiveHelp found: $comp" 99 | comp="${comp[$startIndex,-1]}" 100 | if [ -n "$comp" ]; then 101 | compadd -x "${comp}" 102 | __fly_debug "ActiveHelp will need delimiter" 103 | hasActiveHelp=1 104 | fi 105 | 106 | continue 107 | fi 108 | 109 | if [ -n "$comp" ]; then 110 | # If requested, completions are returned with a description. 111 | # The description is preceded by a TAB character. 112 | # For zsh's _describe, we need to use a : instead of a TAB. 113 | # We first need to escape any : as part of the completion itself. 114 | comp=${comp//:/\\:} 115 | 116 | local tab="$(printf '\t')" 117 | comp=${comp//$tab/:} 118 | 119 | __fly_debug "Adding completion: ${comp}" 120 | completions+=${comp} 121 | lastComp=$comp 122 | fi 123 | done < <(printf "%s\n" "${out[@]}") 124 | 125 | # Add a delimiter after the activeHelp statements, but only if: 126 | # - there are completions following the activeHelp statements, or 127 | # - file completion will be performed (so there will be choices after the activeHelp) 128 | if [ $hasActiveHelp -eq 1 ]; then 129 | if [ ${#completions} -ne 0 ] || [ $((directive & shellCompDirectiveNoFileComp)) -eq 0 ]; then 130 | __fly_debug "Adding activeHelp delimiter" 131 | compadd -x "--" 132 | hasActiveHelp=0 133 | fi 134 | fi 135 | 136 | if [ $((directive & shellCompDirectiveNoSpace)) -ne 0 ]; then 137 | __fly_debug "Activating nospace." 138 | noSpace="-S ''" 139 | fi 140 | 141 | if [ $((directive & shellCompDirectiveKeepOrder)) -ne 0 ]; then 142 | __fly_debug "Activating keep order." 143 | keepOrder="-V" 144 | fi 145 | 146 | if [ $((directive & shellCompDirectiveFilterFileExt)) -ne 0 ]; then 147 | # File extension filtering 148 | local filteringCmd 149 | filteringCmd='_files' 150 | for filter in ${completions[@]}; do 151 | if [ ${filter[1]} != '*' ]; then 152 | # zsh requires a glob pattern to do file filtering 153 | filter="\*.$filter" 154 | fi 155 | filteringCmd+=" -g $filter" 156 | done 157 | filteringCmd+=" ${flagPrefix}" 158 | 159 | __fly_debug "File filtering command: $filteringCmd" 160 | _arguments '*:filename:'"$filteringCmd" 161 | elif [ $((directive & shellCompDirectiveFilterDirs)) -ne 0 ]; then 162 | # File completion for directories only 163 | local subdir 164 | subdir="${completions[1]}" 165 | if [ -n "$subdir" ]; then 166 | __fly_debug "Listing directories in $subdir" 167 | pushd "${subdir}" >/dev/null 2>&1 168 | else 169 | __fly_debug "Listing directories in ." 170 | fi 171 | 172 | local result 173 | _arguments '*:dirname:_files -/'" ${flagPrefix}" 174 | result=$? 175 | if [ -n "$subdir" ]; then 176 | popd >/dev/null 2>&1 177 | fi 178 | return $result 179 | else 180 | __fly_debug "Calling _describe" 181 | if eval _describe $keepOrder "completions" completions $flagPrefix $noSpace; then 182 | __fly_debug "_describe found some completions" 183 | 184 | # Return the success of having called _describe 185 | return 0 186 | else 187 | __fly_debug "_describe did not find completions." 188 | __fly_debug "Checking if we should do file completion." 189 | if [ $((directive & shellCompDirectiveNoFileComp)) -ne 0 ]; then 190 | __fly_debug "deactivating file completion" 191 | 192 | # We must return an error code here to let zsh know that there were no 193 | # completions found by _describe; this is what will trigger other 194 | # matching algorithms to attempt to find completions. 195 | # For example zsh can match letters in the middle of words. 196 | return 1 197 | else 198 | # Perform file completion 199 | __fly_debug "Activating file completion" 200 | 201 | # We must return the result of this command, so it must be the 202 | # last command, or else we must store its result to return it. 203 | _arguments '*:filename:_files'" ${flagPrefix}" 204 | fi 205 | fi 206 | fi 207 | } 208 | 209 | # don't run the completion function when being source-ed or eval-ed 210 | if [ "$funcstack[1]" = "_fly" ]; then 211 | _fly 212 | fi 213 | -------------------------------------------------------------------------------- /zsh/completion/_heroku: -------------------------------------------------------------------------------- 1 | #compdef heroku 2 | # ------------------------------------------------------------------------------ 3 | # Description 4 | # ----------- 5 | # 6 | # Completion script for the Heroku client gem (https://github.com/heroku/heroku) 7 | # 8 | # ------------------------------------------------------------------------------ 9 | # Authors 10 | # ------- 11 | # 12 | # * Ali B. (http://awhitebox.com) 13 | # 14 | # ------------------------------------------------------------------------------ 15 | 16 | local -a _1st_arguments 17 | _1st_arguments=( 18 | "account\:confirm_billing":"Confirm that your account can be billed at the end of the month" 19 | "addons":"list installed addons" 20 | "addons\:list":"list all available addons" 21 | "addons\:add":"install an addon" 22 | "addons\:upgrade":"upgrade an existing addon" 23 | "addons\:downgrade":"downgrade an existing addon" 24 | "addons\:remove":"uninstall an addon" 25 | "addons\:open":"open an addon's dashboard in your browser" 26 | "apps":"list your apps" 27 | "apps\:info":"show detailed app information" 28 | "apps\:create":"create a new app" 29 | "apps\:rename":"rename the app" 30 | "apps\:open":"open the app in a web browser" 31 | "apps\:destroy":"permanently destroy an app" 32 | "auth\:login":"log in with your heroku credentials" 33 | "auth\:logout":"clear local authentication credentials" 34 | "backup":"capture a backup of the DB" 35 | "browse":"open the configuration page for the app on Heroku's dashboard" 36 | "config":"display a config vars for an app" 37 | "config\:get":"display a config value for an app" 38 | "config\:set":"set one or more config vars" 39 | "config\:unset":"unset one or more config vars" 40 | "db\:push":"push local data up to your app" 41 | "db\:pull":"pull heroku data down into your local database" 42 | "deploy":"deploy the application" 43 | "domains":"list custom domains for an app" 44 | "domains\:add":"add a custom domain to an app" 45 | "domains\:remove":"remove a custom domain from an app" 46 | "domains\:clear":"remove all custom domains from an app" 47 | "help":"list available commands or display help for a specific command" 48 | "keys":"display keys for the current user" 49 | "keys\:add":"add a key for the current user" 50 | "keys\:remove":"remove a key from the current user" 51 | "keys\:clear":"remove all authentication keys from the current user" 52 | "logs":"display recent log output" 53 | "logs\:cron":"DEPRECATED: display cron logs from legacy logging" 54 | "logs\:drains":"manage syslog drains" 55 | "maintenance\:on":"put the app into maintenance mode" 56 | "maintenance\:off":"take the app out of maintenance mode" 57 | "open":"open app in a web browser" 58 | "pg\:info":"display database information" 59 | "pg\:ingress":"allow direct connections to the database from this IP for one minute" 60 | "pg\:promote":"sets DATABASE as your DATABASE_URL" 61 | "pg\:psql":"open a psql shell to the database" 62 | "pg\:reset":"delete all data in DATABASE" 63 | "pg\:unfollow":"stop a replica from following and make it a read/write database" 64 | "pg\:wait":"monitor database creation, exit when complete" 65 | "pgbackups":"list captured backups" 66 | "pgbackups\:url":"get a temporary URL for a backup" 67 | "pgbackups\:capture":"capture a backup from a database id" 68 | "pgbackups\:restore":"restore a backup to a database" 69 | "pgbackups\:destroy":"destroys a backup" 70 | "plugins":"list installed plugins" 71 | "plugins\:install":"install a plugin" 72 | "plugins\:uninstall":"uninstall a plugin" 73 | "plugins\:update":"updates all plugins or a single plugin by name" 74 | "ps\:dynos":"scale to QTY web processes" 75 | "ps\:workers":"scale to QTY background processes" 76 | "ps":"list processes for an app" 77 | "ps\:restart":"restart an app process" 78 | "ps\:scale":"scale processes by the given amount" 79 | "releases":"list releases" 80 | "releases\:info":"view detailed information for a release" 81 | "restore":"restore the DB from the most recent backup" 82 | "rollback":"roll back to an older release" 83 | "run":"run an attached process" 84 | "run\:rake":"remotely execute a rake command" 85 | "run\:console":"open a remote console session" 86 | "sharing":"list collaborators on an app" 87 | "sharing\:add":"add a collaborator to an app" 88 | "sharing\:remove":"remove a collaborator from an app" 89 | "sharing\:transfer":"transfer an app to a new owner" 90 | "ssl":"list certificates for an app" 91 | "ssl\:add":"add an ssl certificate to an app" 92 | "ssl\:remove":"remove an ssl certificate from an app" 93 | "ssl\:clear":"remove all ssl certificates from an app" 94 | "stack":"show the list of available stacks" 95 | "stack\:migrate":"prepare migration of this app to a new stack" 96 | "version":"show heroku client version" 97 | ) 98 | 99 | _arguments '*:: :->command' 100 | 101 | if (( CURRENT == 1 )); then 102 | _describe -t commands "heroku command" _1st_arguments 103 | return 104 | fi 105 | 106 | local -a _command_args 107 | case "$words[1]" in 108 | apps:info) 109 | _command_args=( 110 | '(-r|--raw)'{-r,--raw}'[output info as raw key/value pairs]' \ 111 | ) 112 | ;; 113 | apps:create) 114 | _command_args=( 115 | '(-a|--addons)'{-a,--addons}'[a list of addons to install]' \ 116 | '(-r|--remote)'{-r,--remote}'[the git remote to create, default "heroku"]' \ 117 | '(-s|--stack)'{-s,--stack}'[the stack on which to create the app]' \ 118 | ) 119 | ;; 120 | config) 121 | _command_args=( 122 | '(-s|--shell)'{-s,--shell}'[output config vars in shell format]' \ 123 | ) 124 | ;; 125 | db:push) 126 | _command_args=( 127 | '(-c|--chunksize)'{-c,--chunksize}'[specify the number of rows to send in each batch]' \ 128 | '(-d|--debug)'{-d,--debug}'[enable debugging output]' \ 129 | '(-e|--exclude)'{-e,--exclude}'[exclude the specified tables from the push]' \ 130 | '(-f|--filter)'{-f,--filter}'[only push certain tables]' \ 131 | '(-r|--resume)'{-r,--resume}'[resume transfer described by a .dat file]' \ 132 | '(-t|--tables)'{-t,--tables}'[only push the specified tables]' \ 133 | ) 134 | ;; 135 | db:pull) 136 | _command_args=( 137 | '(-c|--chunksize)'{-c,--chunksize}'[specify the number of rows to send in each batch]' \ 138 | '(-d|--debug)'{-d,--debug}'[enable debugging output]' \ 139 | '(-e|--exclude)'{-e,--exclude}'[exclude the specified tables from the pull]' \ 140 | '(-f|--filter)'{-f,--filter}'[only pull certain tables]' \ 141 | '(-r|--resume)'{-r,--resume}'[resume transfer described by a .dat file]' \ 142 | '(-t|--tables)'{-t,--tables}'[only pull the specified tables]' \ 143 | ) 144 | ;; 145 | keys) 146 | _command_args=( 147 | '(-l|--long)'{-l,--long}'[display extended information for each key]' \ 148 | ) 149 | ;; 150 | logs) 151 | _command_args=( 152 | '(-n|--num)'{-n,--num}'[the number of lines to display]' \ 153 | '(-p|--ps)'{-p,--ps}'[only display logs from the given process]' \ 154 | '(-s|--source)'{-s,--source}'[only display logs from the given source]' \ 155 | '(-t|--tail)'{-t,--tail}'[continually stream logs]' \ 156 | ) 157 | ;; 158 | pgbackups:capture) 159 | _command_args=( 160 | '(-e|--expire)'{-e,--expire}'[if no slots are available to capture, delete the oldest backup to make room]' \ 161 | ) 162 | ;; 163 | stack) 164 | _command_args=( 165 | '(-a|--all)'{-a,--all}'[include deprecated stacks]' \ 166 | ) 167 | ;; 168 | esac 169 | 170 | _arguments \ 171 | $_command_args \ 172 | '(-a|--app)'{-a,--app}'[the app name]' \ 173 | '(-r|--remote)'{-r,--remote}'[the git remote name]:remote:->remotes' \ 174 | && return 0 175 | 176 | __heroku_git_remotes () { 177 | local expl gitdir remotes 178 | 179 | gitdir=$(_call_program gitdir git rev-parse --git-dir 2>/dev/null) 180 | __heroku_git_command_successful || return 181 | 182 | remotes=(${${(f)"$(_call_program remotes git config --get-regexp '"^remote\..*\.url$"')"}//#(#b)remote.(*).url */$match[1]}) 183 | __heroku_git_command_successful || return 184 | 185 | # TODO: Should combine the two instead of either or. 186 | if (( $#remotes > 0 )); then 187 | _wanted remotes expl remote compadd $* - $remotes 188 | else 189 | _wanted remotes expl remote _files $* - -W "($gitdir/remotes)" -g "$gitdir/remotes/*" 190 | fi 191 | } 192 | 193 | __heroku_git_command_successful () { 194 | if (( ${#pipestatus:#0} > 0 )); then 195 | _message 'not a git repository' 196 | return 1 197 | fi 198 | return 0 199 | } 200 | 201 | case $state in 202 | (remotes) 203 | __heroku_git_remotes && return 0 204 | ;; 205 | esac 206 | 207 | # Local Variables: 208 | # mode: Shell-Script 209 | # sh-indentation: 2 210 | # indent-tabs-mode: nil 211 | # sh-basic-offset: 2 212 | # End: 213 | # vim: ft=zsh sw=2 ts=2 et 214 | -------------------------------------------------------------------------------- /zsh/completion/_yarn: -------------------------------------------------------------------------------- 1 | #compdef yarn 2 | # ------------------------------------------------------------------------------ 3 | # Redistribution and use in source and binary forms, with or without 4 | # modification, are permitted provided that the following conditions are met: 5 | # * Redistributions of source code must retain the above copyright 6 | # notice, this list of conditions and the following disclaimer. 7 | # * Redistributions in binary form must reproduce the above copyright 8 | # notice, this list of conditions and the following disclaimer in the 9 | # documentation and/or other materials provided with the distribution. 10 | # * Neither the name of the zsh-users nor the 11 | # names of its contributors may be used to endorse or promote products 12 | # derived from this software without specific prior written permission. 13 | # 14 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 15 | # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 16 | # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 17 | # DISCLAIMED. IN NO EVENT SHALL ZSH-USERS BE LIABLE FOR ANY 18 | # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 19 | # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 20 | # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 21 | # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 | # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 23 | # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 | # ------------------------------------------------------------------------------ 25 | # Description 26 | # ----------- 27 | # 28 | # Completion script for yarn (https://yarnpkg.com/) 29 | # 30 | # ------------------------------------------------------------------------------ 31 | # Authors 32 | # ------- 33 | # 34 | # * Massimiliano Torromeo <massimiliano.torromeo@gmail.com> 35 | # 36 | # ------------------------------------------------------------------------------ 37 | 38 | _commands=( 39 | 'access' 40 | 'autoclean:Clean and remove unnecessary files from package dependencies' 41 | 'cache:List or clean every cached package' 42 | "check:Verify package dependencies agains yarn's lock file" 43 | 'config:Manages the yarn configuration files' 44 | 'generate-lock-entry:Generates a lock file entry' 45 | 'global:Install packages globally on your operating system' 46 | 'help:Show information about a command' 47 | 'import:Generate yarn.lock from an existing npm-installed node_modules folder' 48 | 'info:Show information about a package' 49 | 'init:Interactively creates or updates a package.json file' 50 | 'install:Install all the dependencies listed within package.json' 51 | 'licenses:List licenses for installed packages' 52 | 'link:Symlink a package folder during development' 53 | 'list:List installed packages' 54 | 'login:Store registry username and email' 55 | 'logout:Clear registry username and email' 56 | 'outdated:Check for outdated package dependencies' 57 | 'owner:Manage package owners' 58 | 'pack:Create a compressed gzip archive of package dependencies' 59 | 'publish:Publish a package to the npm registry' 60 | 'run:Run a defined package script' 61 | 'tag:Add, remove, or list tags on a package' 62 | 'team:Maintain team memberships' 63 | 'unlink:Unlink a previously created symlink for a package' 64 | 'version:Update the package version' 65 | 'versions:Display version information of currently installed Yarn, Node.js, and its dependencies' 66 | 'why:Show information about why a package is installed' 67 | ) 68 | 69 | _global_commands=( 70 | 'add:Installs a package and any packages that it depends on' 71 | 'bin:Displays the location of the yarn bin folder' 72 | 'remove:Remove installed package from dependencies updating package.json' 73 | 'upgrade:Upgrades packages to their latest version based on the specified range' 74 | 'upgrade-interactive' 75 | ) 76 | 77 | _yarn_commands_scripts() { 78 | local -a scripts 79 | scripts=($(yarn run --json 2>/dev/null | sed -E '/Commands available|possibleCommands/!d;s/.*Commands available from binary scripts: ([^"]+)".*/\1/;s/.*"items":\[([^]]+).*/\1/;s/[" ]//g' | tr , '\n' | sed -e 's/:/\\:/g')) 80 | _describe 'command or script' _commands -- _global_commands -- scripts 81 | } 82 | 83 | _yarn_scripts() { 84 | local -a scripts 85 | scripts=($(yarn run --json 2>/dev/null | sed -E '/Commands available|possibleCommands/!d;s/.*Commands available from binary scripts: ([^"]+)".*/\1/;s/.*"items":\[([^]]+).*/\1/;s/[" ]//g' | tr , '\n' | sed -e 's/:/\\:/g')) 86 | _describe 'script' scripts 87 | } 88 | 89 | _yarn_global_commands() { 90 | local -a cmds 91 | cmds=('ls:List installed packages') 92 | _describe 'command' _global_commands 93 | } 94 | 95 | _yarn_commands() { 96 | _describe 'command' _commands -- _global_commands 97 | } 98 | 99 | _yarn() { 100 | local context state state_descr line 101 | typeset -A opt_args 102 | 103 | _arguments \ 104 | '(-h --help)'{-h,--help}'[output usage information]' \ 105 | '(-V --version)'{-V,--version}'[output the version number]' \ 106 | '--verbose[output verbose messages on internal operations]' \ 107 | '--offline[trigger an error if any required dependencies are not available in local cache]' \ 108 | '--prefer-offline[use network only if dependencies are not available in local cache]' \ 109 | '--strict-semver' \ 110 | '--json' \ 111 | "--ignore-scripts[don't run lifecycle scripts]" \ 112 | '--har[save HAR output of network traffic]' \ 113 | '--ignore-platform[ignore platform checks]' \ 114 | '--ignore-engines[ignore engines check]' \ 115 | '--ignore-optional[ignore optional dependencies]' \ 116 | '--force[install and build packages even if they were built before, overwrite lockfile]' \ 117 | '--skip-integrity-check[run install without checking if node_modules is installed]' \ 118 | '--check-files[install will verify file tree of packages for consistency]' \ 119 | "--no-bin-links[don't generate bin links when setting up packages]" \ 120 | '--flat[only allow one version of a package]' \ 121 | '(--prod --production)'{--prod,--production} \ 122 | "--no-lockfile[don't read or generate a lockfile]" \ 123 | "--pure-lockfile[don't generate a lockfile]" \ 124 | "--frozen-lockfile[don't generate a lockfile and fail if an update is needed]" \ 125 | '--link-duplicates[create hardlinks to the repeated modules in node_modules]' \ 126 | '--global-folder=[modules folder]:folder:_files -/' \ 127 | '--modules-folder=[rather than installing modules into the node_modules folder relative to the cwd, output them here]:folder:_files -/' \ 128 | '--cache-folder=[specify a custom folder to store the yarn cache]:folder:_files -/' \ 129 | '--mutex=[use a mutex to ensure only one yarn instance is executing]:type[\:specifier]' \ 130 | '--no-emoji[disable emoji in output]' \ 131 | '(-s --silent)'{-s,--silent}'[skip Yarn console logs, other types of logs (script output) will be printed]' \ 132 | '--proxy=:host:_hosts' \ 133 | '--https-proxy=:host:_hosts' \ 134 | '--no-progress[disable progress bar]' \ 135 | '--network-concurrency=[maximum number of concurrent network requests]:number' \ 136 | '--network-timeout=[TCP timeout for network requests]:milliseconds' \ 137 | '--non-interactive[do not show interactive prompts]' \ 138 | '1: :_yarn_commands_scripts' \ 139 | '*:: :->command_args' 140 | 141 | 142 | case $state in 143 | command_args) 144 | case $words[1] in 145 | help) 146 | _arguments \ 147 | '1: :_yarn_commands' \ 148 | ;; 149 | 150 | access) 151 | _arguments \ 152 | '1: :(public restricted grant revoke ls-packages ls-collaborators edit)' 153 | ;; 154 | 155 | add) 156 | _arguments \ 157 | '(-D --dev)'{-D,--dev}'[install packages in devDependencies]' \ 158 | '(-P --peer)'{-P,--peer}'[install packages in peerDependencies]' \ 159 | '(-O --optional)'{-O,--optional}'[install packages in optionalDependencies]' \ 160 | '(-E --exact)'{-E,--exact}'[install packages as exact versions]' \ 161 | '(-T --tilde)'{-T,--tilde}'[install the most recent release of the packages that have the same minor version]' \ 162 | '*:package-name:' 163 | ;; 164 | 165 | cache) 166 | _arguments \ 167 | '1: :(ls dir clean)' 168 | ;; 169 | 170 | check) 171 | _arguments \ 172 | '--integrity' \ 173 | '--verify-tree' 174 | ;; 175 | 176 | config) 177 | _arguments \ 178 | '1: :(set get delete list)' \ 179 | '*:: :->config_args' 180 | ;; 181 | 182 | global) 183 | _arguments \ 184 | '--prefix=[bin prefix to use to install binaries]' \ 185 | '1: :_yarn_global_commands' \ 186 | '*:: :->command_args' 187 | ;; 188 | 189 | info) 190 | _arguments \ 191 | '1:package:' \ 192 | '2:field' 193 | ;; 194 | 195 | init) 196 | _arguments \ 197 | '(-y --yes)'{-y,--yes}'[install packages in devDependencies]' 198 | ;; 199 | 200 | licenses) 201 | _arguments \ 202 | '1: :(ls generate-disclaimer)' \ 203 | ;; 204 | 205 | link|unlink|outdated) 206 | _arguments \ 207 | '1:package' \ 208 | ;; 209 | 210 | list) 211 | _arguments \ 212 | '--depth[Limit the depth of the shown dependencies]:depth' 213 | ;; 214 | 215 | owner) 216 | _arguments \ 217 | '1: :(ls add rm)' \ 218 | '*:: :->owner_args' 219 | ;; 220 | 221 | pack) 222 | _arguments \ 223 | '(-f --filename)'{-f,--filename}':filename:_files' 224 | ;; 225 | 226 | publish) 227 | _arguments \ 228 | '--new-version:version:' \ 229 | '--message:message:' \ 230 | '--no-git-tag-version' \ 231 | '--access:access:' \ 232 | '--tag:tag:' \ 233 | '1: :_files' 234 | ;; 235 | 236 | remove|upgrade) 237 | _arguments \ 238 | '*:package:' 239 | ;; 240 | 241 | run) 242 | _arguments \ 243 | '1: :_yarn_scripts' 244 | ;; 245 | 246 | tag) 247 | _arguments \ 248 | '1: :(ls add rm)' \ 249 | '*:: :->tag_args' 250 | ;; 251 | 252 | team) 253 | _arguments \ 254 | '1: :(create destroy add rm ls)' \ 255 | '*:: :->team_args' 256 | ;; 257 | 258 | version) 259 | _arguments \ 260 | '--new-version:version:' \ 261 | '--message:message:' \ 262 | '--no-git-tag-version' 263 | ;; 264 | 265 | why) 266 | _arguments \ 267 | '1:query:_files' 268 | ;; 269 | esac 270 | ;; 271 | esac 272 | 273 | case $state in 274 | config_args) 275 | case $words[1] in 276 | get|delete) 277 | _arguments \ 278 | '1:key:' 279 | ;; 280 | 281 | set) 282 | _arguments \ 283 | '(-g --global)'{-g,--global} \ 284 | '1:key:' \ 285 | '2:value:' 286 | ;; 287 | esac 288 | ;; 289 | 290 | owner_args) 291 | case $words[1] in 292 | ls) 293 | _arguments \ 294 | '1:package:' 295 | ;; 296 | 297 | add|rm) 298 | _arguments \ 299 | '1:user:' \ 300 | '2:package:' 301 | ;; 302 | esac 303 | ;; 304 | 305 | tag_args) 306 | case $words[1] in 307 | ls) 308 | _arguments \ 309 | '1:package' 310 | ;; 311 | 312 | add|rm) 313 | _arguments \ 314 | '1:package:' \ 315 | '2:tag:' 316 | ;; 317 | esac 318 | ;; 319 | 320 | team_args) 321 | case $words[1] in 322 | create|destroy|ls) 323 | _arguments \ 324 | '1:scope\:team:' 325 | ;; 326 | 327 | add|rm) 328 | _arguments \ 329 | '1:scope\:team:' \ 330 | '2:user:' 331 | ;; 332 | esac 333 | ;; 334 | esac 335 | } 336 | 337 | _yarn "$@" 338 | 339 | # Local Variables: 340 | # mode: Shell-Script 341 | # sh-indentation: 2 342 | # indent-tabs-mode: nil 343 | # sh-basic-offset: 2 344 | # End: 345 | # vim: ft=zsh sw=2 ts=2 et 346 | -------------------------------------------------------------------------------- /zsh/configs/colors.zsh: -------------------------------------------------------------------------------- 1 | # Color settings 2 | 3 | # makes color constants available 4 | autoload -U colors 5 | colors 6 | 7 | # enable colored output from ls, etc. on FreeBSD-based systems 8 | export CLICOLOR=1 9 | -------------------------------------------------------------------------------- /zsh/configs/completion.zsh: -------------------------------------------------------------------------------- 1 | fpath=(~/.zsh/completion $fpath) 2 | 3 | autoload -U compinit 4 | compinit 5 | 6 | ## case-insensitive (all), partial-word and then substring completion 7 | zstyle ':completion:*' matcher-list 'm:{a-zA-Z}={A-Za-z}' \ 8 | 'r:|[._-]=* r:|=*' 'l:|=* r:|=*' 9 | -------------------------------------------------------------------------------- /zsh/configs/general.zsh: -------------------------------------------------------------------------------- 1 | # General ZSH configurations 2 | 3 | export EDITOR="vim" 4 | 5 | alias vim=nvim 6 | 7 | sz() { source ~/.zshrc } 8 | 9 | 10 | first() { awk '{print $1}' } 11 | second() { awk '{print $2}' } 12 | sum() { paste -sd+ - | bc } 13 | 14 | igrep() { grep -i $@ } 15 | 16 | restart-postgres() { 17 | rm /usr/local/var/postgres/postmaster.pid && ( \ 18 | cd ~/Library/LaunchAgents && \ 19 | launchctl unload homebrew.mxcl.postgresql.plist && \ 20 | launchctl load -w homebrew.mxcl.postgresql.plist \ 21 | ) 22 | } 23 | -------------------------------------------------------------------------------- /zsh/configs/git.zsh: -------------------------------------------------------------------------------- 1 | compdef g=git 2 | function g { 3 | if [[ $# -gt 0 ]]; then 4 | git "$@" 5 | else 6 | git status --short --branch 7 | fi 8 | } 9 | -------------------------------------------------------------------------------- /zsh/configs/heroku.zsh: -------------------------------------------------------------------------------- 1 | # compdef pdn=heroku 2 | function pdn { 3 | if [[ $# -gt 0 ]]; then 4 | production "$@" 5 | else 6 | production console 7 | fi 8 | } 9 | # compdef sgn=heroku 10 | function sgn { 11 | if [[ $# -gt 0 ]]; then 12 | staging "$@" 13 | else 14 | staging console 15 | fi 16 | } 17 | function dev { 18 | if [[ $# -gt 0 ]]; then 19 | if [[ $1 == 'migrate' ]]; then 20 | bundle exec rake db:migrate db:test:prepare 21 | else 22 | bundle exec rails "$@" 23 | fi 24 | else 25 | bundle exec rails console 26 | fi 27 | } 28 | compdef production=heroku 29 | compdef pdn=heroku 30 | 31 | compdef staging=heroku 32 | compdef sgn=heroku 33 | 34 | copy-production-to() { 35 | if [ "$1" != "staging" ] && [ "$1" != "development" ]; then 36 | echo >&2 "Usage: copy-production-to <staging|development>" 37 | return 1 38 | else 39 | production backup && "$1" restore production 40 | fi 41 | } 42 | 43 | _copy-production-to() { reply=(development staging) } 44 | compctl -K _copy-production-to copy-production-to 45 | 46 | _bin-deploy() { reply=(production staging) } 47 | compctl -K _bin-deploy bin/deploy 48 | -------------------------------------------------------------------------------- /zsh/configs/history.zsh: -------------------------------------------------------------------------------- 1 | ## Command history configuration 2 | if [ -z "$HISTFILE" ]; then 3 | HISTFILE=$HOME/.zsh_history 4 | fi 5 | 6 | HISTSIZE=10000 7 | SAVEHIST=10000 8 | 9 | # Show history 10 | case $HIST_STAMPS in 11 | "mm/dd/yyyy") alias history='fc -fl 1' ;; 12 | "dd.mm.yyyy") alias history='fc -El 1' ;; 13 | "yyyy-mm-dd") alias history='fc -il 1' ;; 14 | *) alias history='fc -l 1' ;; 15 | esac 16 | 17 | setopt append_history 18 | setopt extended_history 19 | setopt hist_expire_dups_first 20 | setopt hist_ignore_dups # ignore duplication command history list 21 | setopt hist_ignore_space 22 | setopt hist_verify 23 | setopt inc_append_history 24 | setopt share_history # share command history data 25 | -------------------------------------------------------------------------------- /zsh/configs/javascript.zsh: -------------------------------------------------------------------------------- 1 | alias y=yarn 2 | -------------------------------------------------------------------------------- /zsh/configs/keybindings.zsh: -------------------------------------------------------------------------------- 1 | # handy keybindings 2 | bindkey "^a" beginning-of-line 3 | bindkey "^e" end-of-line 4 | bindkey "^f" forward-char 5 | bindkey "^b" backward-char 6 | bindkey "^k" kill-line 7 | bindkey "^d" delete-char 8 | bindkey "^p" history-search-backward 9 | bindkey "^n" history-search-forward 10 | bindkey "^y" accept-and-hold 11 | bindkey "^w" backward-kill-word 12 | bindkey "^u" backward-kill-line 13 | 14 | # Open current command in Vim 15 | autoload -z edit-command-line 16 | zle -N edit-command-line 17 | bindkey "^x^e" edit-command-line 18 | 19 | # Copy the most recent command to the clipboard 20 | function _pbcopy_last_command(){ 21 | history | tail -1 | sed 's/ *[0-9]* *//' | pbcopy && \ 22 | tmux display-message "Previous command coppied to clipboard" 23 | } 24 | zle -N pbcopy-last-command _pbcopy_last_command 25 | bindkey '^x^y' pbcopy-last-command 26 | 27 | # Git branches 28 | _fuzzy_git_branches() { 29 | zle -U "$( 30 | git branch --color=always --sort=-committerdate | \ 31 | grep -v '^* ' | \ 32 | grep -v '^\s\+master' | \ 33 | grep -v '^\s\+main' | \ 34 | grep -v '^\s\+develop' | \ 35 | grep -v '^\s\+development' | \ 36 | fzf --reverse --ansi --select-1 --multi | \ 37 | xargs echo | \ 38 | sed -E 's/^[ \t]*//' 39 | )" 40 | } 41 | zle -N fuzzy-git-branches _fuzzy_git_branches 42 | bindkey '^g^b' fuzzy-git-branches 43 | 44 | # cat package.json| jq '.scripts | keys[]' | tr -d '"' | 45 | # fzf-tmux --reverse --ansi --preview 'cat package.json | jq ".scripts" | jq .["{}"]' 46 | _yarn_scripts() { 47 | zle -U "$( 48 | cat package.json| jq '.scripts | keys[]' | tr -d '"' | 49 | fzf --reverse --ansi 50 | )" 51 | } 52 | zle -N yarn-scripts _yarn_scripts 53 | bindkey '^g^y' yarn-scripts 54 | 55 | # Git files 56 | _fuzzy_git_status_files() { 57 | zle -U "$( 58 | git -c color.status=always status --short | \ 59 | fzf --ansi --reverse --no-sort --multi | \ 60 | cut -d ' ' -f 3 61 | )" 62 | } 63 | zle -N fuzzy-git-status-files _fuzzy_git_status_files 64 | bindkey '^g^f' fuzzy-git-status-files 65 | 66 | # Git files 67 | _fuzzy_git_shalector() { 68 | commit=$( 69 | git log --color=always --oneline --decorate -35 | \ 70 | fzf --ansi --reverse --no-sort 71 | ) 72 | zle -U "$(echo $commit | cut -d ' ' -f 1)" 73 | zle -M "$commit" 74 | } 75 | zle -N fuzzy-git-shalector _fuzzy_git_shalector 76 | bindkey '^g^g' fuzzy-git-shalector 77 | 78 | # Ctrl-w stops at `/`s 79 | my-backward-delete-word() { 80 | local WORDCHARS=${WORDCHARS/\//} 81 | zle backward-delete-word 82 | } 83 | zle -N my-backward-delete-word 84 | bindkey '^W' my-backward-delete-word 85 | -------------------------------------------------------------------------------- /zsh/configs/navigation.zsh: -------------------------------------------------------------------------------- 1 | unsetopt auto_cd # with cdpath enabled, auto_cd gives too many false positives 2 | cdpath=( 3 | $HOME/code \ 4 | $HOME/code/work/current \ 5 | $HOME/code/work/current-two \ 6 | $HOME/code/work \ 7 | $HOME/code/vim \ 8 | $HOME/code/alfred \ 9 | $HOME 10 | ) 11 | 12 | itree() { 13 | if [ -f .gitignore ]; then 14 | tree -I "$(cat .gitignore | paste -s -d'|' -)" -C | less -R 15 | else 16 | tree -I node_modules -C 17 | fi 18 | } 19 | 20 | function cdup() { 21 | cd "$(git rev-parse --show-toplevel)" 22 | } 23 | -------------------------------------------------------------------------------- /zsh/configs/ruby.zsh: -------------------------------------------------------------------------------- 1 | alias be="bundle exec " 2 | 3 | rspec_failures() { 4 | grep 'failed' spec/examples.txt | \ 5 | awk '{print $1}' | \ 6 | sed 's/\[.*$//' | \ 7 | sed 's/\.\///' | \ 8 | sort | \ 9 | uniq 10 | } 11 | 12 | export OBJC_DISABLE_INITIALIZE_FORK_SAFETY=YES 13 | -------------------------------------------------------------------------------- /zsh/configs/tmux.zsh: -------------------------------------------------------------------------------- 1 | _tmux_orientation() { 2 | width=$(tmux display -p '#{pane_width}') 3 | height=$(tmux display -p '#{pane_height}') 4 | normalized_height=$( echo "$height * 2.2" | bc | xargs printf "%.0f") 5 | 6 | if (( normalized_height > width )); then 7 | echo 'portrait' 8 | else 9 | echo 'landscape' 10 | fi 11 | } 12 | 13 | tmux-smart-pane() { 14 | [[ $(_tmux_orientation) = 'portrait' ]] && orient='-v' || orient='-h' 15 | eval "tmux split-window $orient $@" 16 | } 17 | 18 | _not_inside_tmux() { 19 | [[ -z "$TMUX" ]] 20 | } 21 | 22 | ensure_tmux_is_running() { 23 | if _not_inside_tmux; then 24 | tat 25 | fi 26 | } 27 | -------------------------------------------------------------------------------- /zsh/configs/tmux_man.zsh: -------------------------------------------------------------------------------- 1 | tmux-man-for-current-word() { 2 | cmd=$(echo "$BUFFER" | rev | sed -E 's/^ +//' | cut -d ' ' -f 1 | rev) 3 | width=$(tmux display -p '#{pane_width}') 4 | height=$(tmux display -p '#{pane_height}') 5 | normalized_height=$( echo "$height * 2.2" | bc ) 6 | 7 | if (( normalized_height > width )); then 8 | tmux split-window -v "man $cmd" 9 | else 10 | tmux split-window -h "man $cmd" 11 | fi 12 | } 13 | zle -N tmux-man-for-current-word 14 | bindkey '^Q' tmux-man-for-current-word 15 | -------------------------------------------------------------------------------- /zsh/configs/wvim.zsh: -------------------------------------------------------------------------------- 1 | wvim() { 2 | command_name="$1" 3 | case "$(_definition_type "$command_name")" in 4 | "alias") _edit_shell_alias "$command_name";; 5 | "function") _edit_shell_function "$command_name";; 6 | "script") _edit_script "$command_name";; 7 | "git-alias") _edit_git_alias "$command_name";; 8 | "not found") _handle_unknown_command "$command_name" 9 | esac 10 | } 11 | compdef wvim=which 12 | 13 | _handle_unknown_command() { 14 | echo "\"$1\" is not recognized as a script, function, or alias" >&2 15 | return 1 16 | } 17 | 18 | _definition_type() { 19 | arg_type_string=$(type -a "$1") 20 | if [[ "$arg_type_string" == *"is an alias"* ]]; then 21 | echo "alias" 22 | elif [[ "$arg_type_string" == *"is a shell function"* ]]; then 23 | echo "function" 24 | elif which "$1" > /dev/null 2>&1; then 25 | echo "script" 26 | elif _is_git_alias "$1"; then 27 | echo "git-alias" 28 | else 29 | echo "not found" 30 | fi 31 | } 32 | 33 | _is_git_alias() { 34 | echo "$1" | grep -q 'git-.*' && _git_aliases | grep -qF $(_git_alias_name "$1") 35 | } 36 | 37 | _git_alias_name() { 38 | echo "$1" | sed 's/^git-//' 39 | } 40 | 41 | _git_aliases() { 42 | git config --get-regexp ^alias\. |\ 43 | sed -e s/^alias\.// -e s/\ /\ =\ / |\ 44 | awk '{print $1}' 45 | } 46 | 47 | _edit_git_alias() { 48 | line=$(grep -En "^\s+$(_git_alias_name "$1") =" ~/.gitconfig | cut -d ":" -f 1) 49 | $EDITOR ~/.gitconfig "+$line" 50 | } 51 | 52 | _edit_script() { 53 | $EDITOR "$(which "$1")" 54 | } 55 | 56 | _definition_field_for_pattern() { 57 | definition=$(grep -En "$2" ~/.zshrc ~/.zshenv ~/.zsh/**/*.zsh 2>/dev/null) 58 | echo "$definition" | cut -d ":" -f "$1" 59 | } 60 | 61 | _edit_based_on_pattern() { 62 | file=$(_definition_field_for_pattern 1 "$1") 63 | line=$(_definition_field_for_pattern 2 "$1") 64 | $EDITOR "$file" "+$line" 65 | } 66 | 67 | _edit_shell_function() { 68 | _edit_based_on_pattern "(^function $1)|(^$1\(\))" 69 | } 70 | 71 | _edit_shell_alias() { 72 | _edit_based_on_pattern "alias $1=" 73 | } 74 | -------------------------------------------------------------------------------- /zsh/zshenv: -------------------------------------------------------------------------------- 1 | eval "$(/opt/homebrew/bin/brew shellenv)" 2 | 3 | # Add homebrew binaries 4 | export PATH="/usr/local/bin:$PATH" 5 | export HOMEBREW_NO_AUTO_UPDATE=1 6 | 7 | # Add my custom commands 8 | export PATH="$HOME/bin:$PATH" 9 | 10 | export PATH="$HOME/.npm-packages/bin:$PATH" 11 | 12 | export JAVA_HOME="$HOME/.java_home" 13 | export NODE_GYP_FORCE_PYTHON=/opt/homebrew/bin/python3.10 14 | 15 | # Use postgres.app versions of pg utilites 16 | export PATH=/Applications/Postgres.app/Contents/Versions/latest/bin:$PATH 17 | -------------------------------------------------------------------------------- /zsh/zshrc: -------------------------------------------------------------------------------- 1 | export ZPLUG_HOME=/opt/homebrew/opt/zplug 2 | source $ZPLUG_HOME/init.zsh 3 | 4 | zplug 'mafredri/zsh-async' 5 | zplug 'sindresorhus/pure' 6 | zplug "plugins/gh", from:gh-r 7 | zplug "source ~/.config/gh/completion.zsh", defer:2 8 | zplug 'zsh-users/zsh-syntax-highlighting', defer:2 9 | zplug 'zsh-users/zsh-completions', defer:2 10 | zplug 'zsh-users/zsh-autosuggestions', defer:2 11 | ZSH_AUTOSUGGEST_HIGHLIGHT_STYLE='fg=8' 12 | 13 | zplug load 14 | 15 | for zsh_source in $HOME/.zsh/configs/*.zsh; do 16 | source $zsh_source 17 | done 18 | 19 | ensure_tmux_is_running 20 | 21 | . $HOME/.asdf/asdf.sh 22 | autoload bashcompinit; bashcompinit 23 | . $HOME/.asdf/completions/asdf.bash 24 | 25 | [ -f ~/.client-config.zsh ] && source ~/.client-config.zsh 26 | [ -f ~/.fzf.zsh ] && source ~/.fzf.zsh 27 | 28 | export PATH="$HOME/.yarn/bin:$HOME/.config/yarn/global/node_modules/.bin:$PATH" 29 | 30 | #THIS MUST BE AT THE END OF THE FILE FOR SDKMAN TO WORK!!! 31 | export SDKMAN_DIR="$HOME/.sdkman" 32 | [[ -s "$HOME/.sdkman/bin/sdkman-init.sh" ]] && source "$HOME/.sdkman/bin/sdkman-init.sh" 33 | compdef _flyctl fly 34 | --------------------------------------------------------------------------------