├── rc ├── bashrc ├── config │ ├── nvim │ │ ├── .gitignore │ │ ├── .stylua.toml │ │ ├── lua │ │ │ ├── terminal.lua │ │ │ ├── editor.lua │ │ │ ├── wiki.lua │ │ │ ├── colorscheme.lua │ │ │ ├── languages.lua │ │ │ ├── formatter.lua │ │ │ ├── common.lua │ │ │ ├── statusline.lua │ │ │ ├── finder.lua │ │ │ ├── treesitter.lua │ │ │ ├── options.lua │ │ │ ├── completion.lua │ │ │ ├── mappings.lua │ │ │ ├── autocmds.lua │ │ │ └── pack.lua │ │ └── init.lua │ ├── ghostty │ │ └── config │ ├── alacritty │ │ └── alacritty.toml │ └── karabiner │ │ └── karabiner.json ├── work │ └── .gitconfig ├── gemrc ├── zsh_alias ├── bash_profile ├── gitconfig ├── vimrc ├── zshrc └── tmux.conf ├── app ├── go │ ├── init │ └── test ├── nvim │ ├── test │ ├── README.md │ └── init ├── VSCode │ ├── test │ └── init ├── fzf │ └── init ├── bash │ ├── init │ └── motd ├── rust │ ├── init │ └── test ├── zsh │ ├── test │ ├── init │ └── crispy.zsh-theme ├── ruby │ ├── init │ └── test ├── git │ └── test ├── vim │ └── init ├── tmux │ └── init └── bootstrap ├── .rubocop.yml ├── Brewfile-work ├── screenshots ├── v2-nvim-lsp.png ├── screenshot-1.0.jpg ├── v2-nvim-and-tmux.png └── v2-nvim-telescope.png ├── test ├── check ├── .github └── workflows │ └── ci.yml ├── bootstrap ├── macOS └── settings ├── Brewfile └── README.md /rc/bashrc: -------------------------------------------------------------------------------- 1 | export EDITOR="nvim" 2 | -------------------------------------------------------------------------------- /app/go/init: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | mkdir -p ~/go 4 | -------------------------------------------------------------------------------- /rc/config/nvim/.gitignore: -------------------------------------------------------------------------------- 1 | plugin/packer_compiled.lua 2 | -------------------------------------------------------------------------------- /.rubocop.yml: -------------------------------------------------------------------------------- 1 | Style/FrozenStringLiteralComment: 2 | Enabled: false 3 | -------------------------------------------------------------------------------- /app/nvim/test: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | test -x "$(which nvim)" 4 | -------------------------------------------------------------------------------- /app/VSCode/test: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | test -s /usr/local/bin/code 4 | -------------------------------------------------------------------------------- /app/fzf/init: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | "$(brew --prefix)"/opt/fzf/install 4 | -------------------------------------------------------------------------------- /app/go/test: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | test -x "$(which go)" 4 | test -d ~/go 5 | -------------------------------------------------------------------------------- /rc/work/.gitconfig: -------------------------------------------------------------------------------- 1 | [user] 2 | name = David Zhang 3 | email = name@yourcompany.com 4 | -------------------------------------------------------------------------------- /Brewfile-work: -------------------------------------------------------------------------------- 1 | tap 'homebrew/cask' 2 | 3 | cask 'feishu' 4 | cask 'postman' 5 | cask 'workflowy' 6 | -------------------------------------------------------------------------------- /app/bash/init: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | echo "Setup motd" 4 | sudo cp ./app/bash/motd /etc/motd 5 | -------------------------------------------------------------------------------- /screenshots/v2-nvim-lsp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/crispgm/dotfiles/HEAD/screenshots/v2-nvim-lsp.png -------------------------------------------------------------------------------- /app/rust/init: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh 4 | -------------------------------------------------------------------------------- /app/zsh/test: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | 5 | test -x "$(which zsh)" 6 | test -d ~/.oh-my-zsh 7 | -------------------------------------------------------------------------------- /screenshots/screenshot-1.0.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/crispgm/dotfiles/HEAD/screenshots/screenshot-1.0.jpg -------------------------------------------------------------------------------- /screenshots/v2-nvim-and-tmux.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/crispgm/dotfiles/HEAD/screenshots/v2-nvim-and-tmux.png -------------------------------------------------------------------------------- /screenshots/v2-nvim-telescope.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/crispgm/dotfiles/HEAD/screenshots/v2-nvim-telescope.png -------------------------------------------------------------------------------- /app/rust/test: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | test -x "$(which rustc)" 4 | test -x "$(which rustfmt)" 5 | test -d ~/.cargo 6 | -------------------------------------------------------------------------------- /app/ruby/init: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | gem install bundler 4 | bundle config mirror.https://rubygems.org https://gems.ruby-china.com 5 | -------------------------------------------------------------------------------- /app/ruby/test: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | GEM_SOURCE=$(gem sources | tail -n 1) 4 | test "$GEM_SOURCE" = "https://gems.ruby-china.com/" 5 | -------------------------------------------------------------------------------- /app/git/test: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | test -x "$(which git)" 4 | GIT_NAME="$(git config --global --get user.name)" 5 | test "$GIT_NAME" = "David Zhang" 6 | -------------------------------------------------------------------------------- /rc/config/nvim/.stylua.toml: -------------------------------------------------------------------------------- 1 | column_width = 80 2 | line_endings = "Unix" 3 | indent_type = "Spaces" 4 | indent_width = 4 5 | quote_style = "AutoPreferSingle" 6 | -------------------------------------------------------------------------------- /app/VSCode/init: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | mkdir -p ~/Applications/ 4 | sudo ln -s /Applications/Visual\ Studio\ Code.app/Contents/Resources/app/bin/code /usr/local/bin/code 5 | -------------------------------------------------------------------------------- /app/vim/init: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | curl -fLo ~/.vim/autoload/plug.vim --create-dirs \ 4 | https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim 5 | 6 | echo "Run \`vim +PlugInstall\` to finish setup" 7 | -------------------------------------------------------------------------------- /rc/gemrc: -------------------------------------------------------------------------------- 1 | --- 2 | :backtrace: false 3 | :bulk_threshold: 1000 4 | :sources: 5 | - https://gems.ruby-china.com/ 6 | :update_sources: true 7 | :ssl_verify_mode: 0 8 | :verbose: true 9 | gem: --no-document --bindir /opt/homebrew/bin 10 | -------------------------------------------------------------------------------- /rc/zsh_alias: -------------------------------------------------------------------------------- 1 | alias hf='history | fzf' 2 | alias bc='bc -q -l' 3 | alias nvimconf='nvim ~/.config/nvim/init.lua' 4 | alias zshconf='nvim ~/.zshrc' 5 | 6 | alias -s md=nvim 7 | alias -s markdown=nvim 8 | alias -s bean=nvim 9 | alias -s beancount=nvim 10 | -------------------------------------------------------------------------------- /app/nvim/README.md: -------------------------------------------------------------------------------- 1 | # Neovim Setups 2 | 3 | ## Install Plugin 4 | 5 | ```sh 6 | :Lazy sync 7 | ``` 8 | 9 | ## Screenshots 10 | 11 | ![nvim-lsp](../../screenshots/v2-nvim-lsp.png) 12 | 13 | ![nvim-telescope](../../screenshots/v2-nvim-telescope.png) 14 | -------------------------------------------------------------------------------- /rc/bash_profile: -------------------------------------------------------------------------------- 1 | export CLICOLOR=1 2 | export LSCOLORS=gxfxaxdxcxegedabagacad 3 | 4 | gitPS1() { 5 | gitps1=$(git branch 2>/dev/null | grep '*') gitps1="${gitps1:+ (${gitps1/#\* /})}" 6 | echo "$gitps1" 7 | } 8 | 9 | export PS1="\033[1;34m\w$(gitPS1) $ \033[0m" 10 | -------------------------------------------------------------------------------- /rc/config/nvim/lua/terminal.lua: -------------------------------------------------------------------------------- 1 | require('toggleterm').setup({ 2 | size = 12, 3 | open_mapping = [[]], 4 | shade_filetypes = {}, 5 | shade_terminals = true, 6 | start_in_insert = true, 7 | persist_size = true, 8 | direction = 'horizontal', 9 | }) 10 | -------------------------------------------------------------------------------- /rc/config/nvim/lua/editor.lua: -------------------------------------------------------------------------------- 1 | require('gitsigns').setup({ 2 | signs = { 3 | add = { text = '+' }, 4 | change = { text = '~' }, 5 | delete = { text = '_' }, 6 | topdelete = { text = '‾' }, 7 | changedelete = { text = '~' }, 8 | }, 9 | }) 10 | -------------------------------------------------------------------------------- /app/nvim/init: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Run `nvim` to trigger plugin install. 4 | nvim --headless "+Lazy! sync" +qa 5 | 6 | # Install formatters & linters (language servers are ensured by mason-lspconfig). 7 | nvim --headless '+MasonInstall luacheck markdownlint revive stylua shfmt yamllint' +qa 8 | -------------------------------------------------------------------------------- /rc/config/nvim/lua/wiki.lua: -------------------------------------------------------------------------------- 1 | vim.g.vimwiki_list = { 2 | { 3 | path = '~/dev/wiki-base/wiki/', 4 | syntax = 'markdown', 5 | ext = '.md', 6 | }, 7 | } 8 | vim.g.vimwiki_global_ext = 0 9 | vim.g.vimwiki_key_mappings = { 10 | global = 0, 11 | links = 1, 12 | html = 0, 13 | } 14 | -------------------------------------------------------------------------------- /app/zsh/init: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | echo "Setup Zsh" 4 | ZSH_PATH="$(brew --prefix)/bin/zsh" 5 | sudo sh -c "echo $ZSH_PATH >> /etc/shells" 6 | sudo chsh -s "$ZSH_PATH" 7 | sh -c "$(curl -fsSL https://raw.githubusercontent.com/robbyrussell/oh-my-zsh/master/tools/install.sh)" 8 | cp ./app/zsh/crispy.zsh-theme ~/.oh-my-zsh/custom/themes/ 9 | -------------------------------------------------------------------------------- /test: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | 5 | echo "Test hostname" 6 | HOSTNAME=$(hostname) 7 | test "$HOSTNAME" = "david-macbook" 8 | 9 | echo "Test brews" 10 | test -x "$(which git)" 11 | test -x "$(which nvim)" 12 | 13 | echo "Test folders" 14 | test -d ~/dev 15 | test -d ~/work 16 | 17 | echo "Test RCM symlinks" 18 | test -s ~/.zshrc 19 | test -s ~/.gitconfig 20 | -------------------------------------------------------------------------------- /app/tmux/init: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # tpm 4 | git clone https://github.com/tmux-plugins/tpm ~/.tmux/plugins/tpm 5 | 6 | # plugins 7 | git clone https://github.com/arcticicestudio/nord-tmux ~/.tmux/themes/nord-tmux 8 | git clone https://github.com/tmux-plugins/tmux-resurrect ~/.tmux/plugins/tmux-resurrect 9 | 10 | # install plugins 11 | echo "Toggle \`prefix + I\` inside a tmux session." 12 | -------------------------------------------------------------------------------- /rc/config/nvim/lua/colorscheme.lua: -------------------------------------------------------------------------------- 1 | -- nord 2 | vim.g.nord_cursor_line_number_background = 1 3 | vim.g.nord_uniform_status_lines = 1 4 | vim.g.nord_bold_vertical_split_line = 1 5 | vim.g.nord_uniform_diff_background = 1 6 | vim.g.nord_underline = 1 7 | vim.g.nord_italic = 1 8 | vim.g.nord_italic_comments = 1 9 | 10 | vim.api.nvim_command('colorscheme nord') 11 | 12 | -- winbar 13 | vim.cmd('highlight WinBar guibg=NONE') 14 | -------------------------------------------------------------------------------- /check: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # check yourself at first 4 | shellcheck check 5 | 6 | shellcheck bootstrap 7 | shellcheck test 8 | shellcheck app/bootstrap 9 | 10 | apps=() 11 | while IFS='' read -r line; do apps+=("$line"); done < <(ls -d app/*) 12 | for app in "${apps[@]}"; do 13 | if [[ -f "./$app/init" ]]; then 14 | shellcheck "./$app/init" 15 | fi 16 | if [[ -f "./$app/test" ]]; then 17 | shellcheck "./$app/test" 18 | fi 19 | done 20 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: build 2 | on: 3 | push: 4 | branches: 5 | - main 6 | pull_request: 7 | jobs: 8 | ci: 9 | name: run 10 | runs-on: macos-latest 11 | if: "!contains(github.event.head_commit.message, '[ci skip]')" 12 | steps: 13 | - uses: actions/checkout@master 14 | - name: build 15 | run: bash ./bootstrap 16 | - name: Test 17 | run: bash ./test 18 | - name: ShellCheck 19 | run: bash ./check 20 | -------------------------------------------------------------------------------- /rc/config/ghostty/config: -------------------------------------------------------------------------------- 1 | theme = nord 2 | font-family = Iosevka Nerd Font 3 | font-size = 16 4 | font-feature = -calt, -liga, -dlig 5 | background-opacity = 0.90 6 | 7 | window-padding-x = 6,6 8 | window-padding-y = 6,6 9 | window-save-state = always 10 | 11 | link-url = true 12 | copy-on-select = false 13 | confirm-close-surface = false 14 | clipboard-trim-trailing-spaces = true 15 | auto-update = check 16 | keybind = global:cmd+shift+enter=toggle_quick_terminal 17 | 18 | macos-option-as-alt = true 19 | macos-titlebar-style = hidden 20 | -------------------------------------------------------------------------------- /app/bootstrap: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set +e 4 | 5 | if [[ -z "${CI}" ]]; then 6 | declare -a apps=("git" "zsh" "ruby" "go" "rust" "fzf" "tmux" "nvim" "VSCode") 7 | # Optional: bash 8 | else 9 | declare -a apps=("git" "ruby" "go") 10 | fi 11 | 12 | for app in "${apps[@]}"; do 13 | if [[ -f "./app/$app/init" ]]; then 14 | echo "Initializing $app" 15 | bash "./app/$app/init" 16 | fi 17 | if [[ -f "./app/$app/test" ]]; then 18 | echo "Testing $app" 19 | bash "./app/$app/test" 20 | fi 21 | done 22 | -------------------------------------------------------------------------------- /bootstrap: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | 5 | echo "Install Homebrew" 6 | if test ! "$(which brew)"; then 7 | echo "Installing homebrew..." 8 | /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" 9 | fi 10 | 11 | echo "Setup hostname" 12 | sudo scutil --set HostName david-macbook 13 | 14 | echo "Install with Brew Bundle" 15 | set +e 16 | export PATH=$PATH:/opt/homebrew/bin 17 | brew bundle 18 | set -e 19 | 20 | echo "Setup workspace" 21 | mkdir -p ~/dev 22 | mkdir -p ~/work 23 | 24 | echo "Install dotfiles" 25 | rcup -d ./rc -f 26 | 27 | echo "Application bootstrap" 28 | ./app/bootstrap 29 | 30 | echo "Final testing" 31 | ./test 32 | -------------------------------------------------------------------------------- /app/bash/motd: -------------------------------------------------------------------------------- 1 | 2 | ██╗ ███████╗████████╗███████╗ ██████╗ ██████╗ ██╗ ██╗ █████╗ ██████╗██╗ ██╗██╗███╗ ██╗ ██████╗ ██╗ 3 | ██║ ██╔════╝╚══██╔══╝██╔════╝ ██╔════╝ ██╔═══██╗ ██║ ██║██╔══██╗██╔════╝██║ ██╔╝██║████╗ ██║██╔════╝ ██║ 4 | ██║ █████╗ ██║ ███████╗ ██║ ███╗██║ ██║ ███████║███████║██║ █████╔╝ ██║██╔██╗ ██║██║ ███╗██║ 5 | ██║ ██╔══╝ ██║ ╚════██║ ██║ ██║██║ ██║ ██╔══██║██╔══██║██║ ██╔═██╗ ██║██║╚██╗██║██║ ██║╚═╝ 6 | ███████╗███████╗ ██║ ███████║ ╚██████╔╝╚██████╔╝ ██║ ██║██║ ██║╚██████╗██║ ██╗██║██║ ╚████║╚██████╔╝██╗ 7 | ╚══════╝╚══════╝ ╚═╝ ╚══════╝ ╚═════╝ ╚═════╝ ╚═╝ ╚═╝╚═╝ ╚═╝ ╚═════╝╚═╝ ╚═╝╚═╝╚═╝ ╚═══╝ ╚═════╝ ╚═╝ 8 | 9 | -------------------------------------------------------------------------------- /rc/config/nvim/lua/languages.lua: -------------------------------------------------------------------------------- 1 | vim.lsp.enable({ 2 | 'bashls', 3 | 'beancount', 4 | 'cssls', 5 | 'gopls', 6 | 'html', 7 | 'jsonls', 8 | 'lua_ls', 9 | 'pyright', 10 | 'ruby_lsp', 11 | 'rust_analyzer', 12 | 'sqlls', 13 | 'ts_ls', 14 | 'vimls', 15 | 'vue_ls', 16 | 'yamlls', 17 | }) 18 | 19 | -- html 20 | -- > emmet 21 | vim.g.user_emmet_install_global = 0 22 | vim.g.user_emmet_leader_key = '' 23 | vim.api.nvim_command('autocmd FileType html,css EmmetInstall') 24 | -- > prettier 25 | vim.g['prettier#autoformat'] = 1 26 | vim.g['prettier#autoformat_require_pragma'] = 0 27 | vim.g['prettier#exec_cmd_path'] = vim.fn.exepath('prettier') 28 | 29 | -- rust 30 | vim.g.rustfmt_autosave = 1 31 | -------------------------------------------------------------------------------- /rc/gitconfig: -------------------------------------------------------------------------------- 1 | [user] 2 | name = David Zhang 3 | email = crispgm@gmail.com 4 | [core] 5 | ignorecase = false 6 | editor = nvim 7 | [color] 8 | ui = true 9 | [pull] 10 | rebase = true 11 | [init] 12 | defaultBranch = main 13 | [alias] 14 | bd = "! git branch -D $(git branch | fzf -m)" 15 | sf = "! git switch $(git branch | fzf)" 16 | sc = "switch -c" 17 | sm = "! git switch main || git switch master" 18 | history = log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit 19 | hub = "!f() { \ 20 | open \"$(git ls-remote --get-url \ 21 | | sed 's|git@github.com:\\(.*\\)$|https://github.com/\\1|' \ 22 | | sed 's|\\.git$||'; \ 23 | )\"; \ 24 | }; f" 25 | rank = "shortlog -s -n --no-merges" 26 | [includeIf "gitdir:~/work/"] 27 | path = ~/work/.gitconfig 28 | -------------------------------------------------------------------------------- /rc/config/nvim/lua/formatter.lua: -------------------------------------------------------------------------------- 1 | local M = {} 2 | local f = vim.fn 3 | local a = vim.api 4 | 5 | function M.bean_format(opts) 6 | local view = f.winsaveview() 7 | f.execute(':silent !bean-format ' .. opts.file .. ' -o ' .. opts.file) 8 | a.nvim_exec2('edit', { output = true }) 9 | f.winrestview(view) 10 | end 11 | 12 | function M.lua_format(opts) 13 | local view = f.winsaveview() 14 | if f.executable('.stylua.toml') then 15 | f.execute( 16 | ':silent !stylua ' .. opts.file .. ' --config-path ./.stylua.toml' 17 | ) 18 | else 19 | f.execute(':silent !stylua ' .. opts.file) 20 | end 21 | a.nvim_exec2('edit', { output = true }) 22 | f.winrestview(view) 23 | end 24 | 25 | function M.shell_format(opts) 26 | local view = f.winsaveview() 27 | f.execute(':silent !shfmt -l -w ' .. opts.file) 28 | a.nvim_exec2('edit', { output = true }) 29 | f.winrestview(view) 30 | end 31 | 32 | return M 33 | -------------------------------------------------------------------------------- /rc/config/nvim/init.lua: -------------------------------------------------------------------------------- 1 | local try_require = require('common').try_require 2 | 3 | -- package manager 4 | local lazypath = vim.fn.stdpath('data') .. '/lazy/lazy.nvim' 5 | if not vim.loop.fs_stat(lazypath) then 6 | vim.fn.system({ 7 | 'git', 8 | 'clone', 9 | '--filter=blob:none', 10 | 'https://github.com/folke/lazy.nvim.git', 11 | '--branch=stable', -- latest stable release 12 | lazypath, 13 | }) 14 | end 15 | vim.opt.rtp:prepend(lazypath) 16 | 17 | -- pre hooks 18 | vim.g.vimwiki_ext2syntax = vim.empty_dict() 19 | 20 | -- options 21 | try_require('options') 22 | 23 | -- packages 24 | try_require('pack') 25 | 26 | -- mappings 27 | try_require('mappings') 28 | 29 | -- functions 30 | try_require('completion') 31 | try_require('colorscheme') 32 | try_require('editor') 33 | try_require('finder') 34 | try_require('languages') 35 | try_require('statusline') 36 | try_require('terminal') 37 | try_require('treesitter') 38 | try_require('wiki') 39 | 40 | -- autocmds 41 | try_require('autocmds') 42 | -------------------------------------------------------------------------------- /rc/config/nvim/lua/common.lua: -------------------------------------------------------------------------------- 1 | local M = {} 2 | 3 | --- try requiring a submodule and do not crash all the configs 4 | function M.try_require(name) 5 | local ok, _ = pcall(require, name) 6 | if not ok then 7 | local msg = string.format( 8 | 'The configuration is not fully loaded. Requiring `%s` failed. Check the path and syntax.', 9 | name 10 | ) 11 | vim.notify(msg, vim.log.levels.ERROR) 12 | end 13 | end 14 | 15 | function M.map(mode, lhs, rhs, opts) 16 | vim.keymap.set(mode, lhs, rhs, opts or {}) 17 | end 18 | 19 | function M.noremap(mode, lhs, rhs) 20 | local opts = { noremap = true } 21 | vim.keymap.set(mode, lhs, rhs, opts) 22 | end 23 | 24 | function M.nmap(lhs, rhs) 25 | vim.keymap.set('n', lhs, rhs) 26 | end 27 | 28 | function M.nnoremap(lhs, rhs) 29 | M.noremap('n', lhs, rhs) 30 | end 31 | 32 | function M.inoremap(lhs, rhs) 33 | M.noremap('i', lhs, rhs) 34 | end 35 | 36 | function M.vnoremap(lhs, rhs) 37 | M.noremap('v', lhs, rhs) 38 | end 39 | 40 | function M.cnoremap(lhs, rhs) 41 | M.noremap('c', lhs, rhs) 42 | end 43 | 44 | return M 45 | -------------------------------------------------------------------------------- /rc/config/nvim/lua/statusline.lua: -------------------------------------------------------------------------------- 1 | -- status line 2 | require('hardline').setup({ 3 | bufferline = false, 4 | theme = 'nord', 5 | sections = { 6 | { 7 | class = 'mode', 8 | item = require('hardline.parts.mode').get_item, 9 | }, 10 | { 11 | class = 'high', 12 | item = require('hardline.parts.git').get_item, 13 | hide = 80, 14 | }, 15 | '%<', 16 | { 17 | class = 'med', 18 | item = require('hardline.parts.filename').get_item, 19 | }, 20 | { 21 | class = 'med', 22 | item = '%=', 23 | }, 24 | { 25 | class = 'error', 26 | item = require('hardline.parts.lsp').get_error, 27 | }, 28 | { 29 | class = 'warning', 30 | item = require('hardline.parts.lsp').get_warning, 31 | }, 32 | { 33 | class = 'low', 34 | item = require('hardline.parts.wordcount').get_item, 35 | hide = 80, 36 | }, 37 | { 38 | class = 'warning', 39 | item = require('hardline.parts.whitespace').get_item, 40 | }, 41 | { 42 | class = 'high', 43 | item = require('hardline.parts.filetype').get_item, 44 | hide = 80, 45 | }, 46 | { 47 | class = 'mode', 48 | item = require('hardline.parts.line').get_item, 49 | }, 50 | }, 51 | }) 52 | -------------------------------------------------------------------------------- /rc/config/nvim/lua/finder.lua: -------------------------------------------------------------------------------- 1 | local nnoremap = require('common').nnoremap 2 | 3 | local actions = require('telescope.actions') 4 | require('telescope').setup({ 5 | defaults = require('telescope.themes').get_ivy({ 6 | mappings = { 7 | i = { 8 | [''] = actions.close, 9 | }, 10 | }, 11 | }), 12 | extensions = { 13 | heading = { 14 | treesitter = true, 15 | }, 16 | }, 17 | }) 18 | 19 | require('telescope').load_extension('session-lens') 20 | require('telescope').load_extension('heading') 21 | 22 | nnoremap( 23 | 'ff', 24 | 'Telescope find_files find_command=fd,--hidden,--exclude,*.git,--type,f' 25 | ) 26 | nnoremap( 27 | 'fF', 28 | 'Telescope find_files find_command=fd,--hidden,--no-ignore,--exclude,*.git,--type,f' 29 | ) 30 | nnoremap('fd', 'Telescope git_files') 31 | nnoremap( 32 | 'fg', 33 | "lua require('telescope.builtin').live_grep({default_text = vim.fn.expand(''), additional_args={'--sortr','modified'}})" 34 | ) 35 | nnoremap('fG', 'Telescope grep_string') 36 | nnoremap('fb', 'Telescope buffers') 37 | nnoremap('fh', 'Telescope help_tags') 38 | nnoremap('fl', 'Telescope lsp_document_symbols') 39 | nnoremap('fk', 'Telescope keymaps') 40 | nnoremap('fm', 'Telescope heading') 41 | nnoremap('fs', 'Telescope session-lens search_session') 42 | -------------------------------------------------------------------------------- /app/zsh/crispy.zsh-theme: -------------------------------------------------------------------------------- 1 | # Crispy.zsh-theme is a minimal theme for oh-my-zsh 2 | # Support exit code coloring and elapsed time. 3 | # It's based on gentoo.zsh-theme 4 | 5 | function preexec() { 6 | timer=$(($(print -P %D{%s%6.})/1000)) 7 | } 8 | 9 | function precmd() { 10 | if [ $timer ]; then 11 | now=$(($(print -P %D{%s%6.})/1000)) 12 | elapsed=$(($now-$timer)) 13 | unit="ms" 14 | if [[ $elapsed -ge 1000 ]]; then 15 | elapsed=$(($elapsed/1000)) 16 | unit="s" 17 | if [[ $elapsed -ge 60 ]]; then 18 | elapsed=$(($elapsed/60)) 19 | unit="m" 20 | if [[ $elapsed -ge 60 ]]; then 21 | elapsed=$(($elapsed/60)) 22 | unit="h" 23 | fi 24 | fi 25 | fi 26 | elapsed="$elapsed$unit" 27 | unset timer 28 | fi 29 | } 30 | 31 | function prompt_elapse { 32 | echo "%{$fg[cyan]%}${elapsed} %{$reset_color%}" 33 | } 34 | 35 | function prompt_char { 36 | if [ $UID -eq 0 ]; then CH=#; else CH=$; fi 37 | echo "%(?..%{$fg[red]%})$CH" 38 | } 39 | 40 | function prompt_exitcode { 41 | if [ $? -ne 0 ]; then 42 | echo "%{$fg[red]%}(%?) " 43 | fi 44 | } 45 | 46 | function prompt_arch { 47 | if [ "$ZSH_CRISPY_SHOW_ARCH" != "1" ]; then 48 | return 49 | fi 50 | MAC_ARCH=`arch` 51 | if [ "$MAC_ARCH" = "i386" ]; then 52 | echo "i " 53 | elif [ "$MAC_ARCH" = "arm64" ]; then 54 | echo "a " 55 | fi 56 | } 57 | 58 | PROMPT='%{$fg_bold[blue]%}$(prompt_arch)%(!.%1~.%~) $(git_prompt_info)$(prompt_char)%{$reset_color%} ' 59 | RPROMPT='$(prompt_exitcode)$(prompt_elapse)%{$fg[magenta]%}[%*]%{$reset_color%}' 60 | 61 | ZSH_THEME_GIT_PROMPT_PREFIX="(" 62 | ZSH_THEME_GIT_PROMPT_SUFFIX=") " 63 | -------------------------------------------------------------------------------- /macOS/settings: -------------------------------------------------------------------------------- 1 | # https://github.com/mathiasbynens/dotfiles/blob/master/.macos 2 | 3 | sudo -v 4 | 5 | # Disable Notification Center and remove the menu bar icon 6 | launchctl unload -w /System/Library/LaunchAgents/com.apple.notificationcenterui.plist 2> /dev/null 7 | 8 | # Trackpad: enable tap to click for this user and for the login screen 9 | defaults write com.apple.driver.AppleBluetoothMultitouch.trackpad "Clicking" -bool true 10 | defaults -currentHost write NSGlobalDomain "com.apple.mouse.tapBehavior" -int 1 11 | defaults write NSGlobalDomain "com.apple.mouse.tapBehavior" -int 1 12 | 13 | # Trackpad: map bottom right corner to right-click 14 | defaults write com.apple.driver.AppleBluetoothMultitouch.trackpad "TrackpadCornerSecondaryClick" -int 2 15 | defaults write com.apple.driver.AppleBluetoothMultitouch.trackpad "TrackpadRightClick" -bool true 16 | defaults -currentHost write NSGlobalDomain "com.apple.trackpad.trackpadCornerClickBehavior" -int 1 17 | defaults -currentHost write NSGlobalDomain "com.apple.trackpad.enableSecondaryClick" -bool true 18 | 19 | # Open Desktop 20 | defaults write com.apple.finder NewWindowTargetPath -string "file://${HOME}/Desktop/" 21 | defaults write com.apple.finder ShowPathbar -bool true 22 | 23 | # Dock 24 | defaults write com.apple.dock "tilesize" -int "36" 25 | defaults write com.apple.dock "show-recents" -bool "false" 26 | defaults write com.apple.dock "show-process-indicators" -bool "true" 27 | defaults write com.apple.dock "minimize-to-application" -bool "true" 28 | # Left corner to screensaver 29 | defaults write com.apple.dock wvous-bl-corner -int 5 30 | killall Dock 31 | 32 | # Terminal utf-8 33 | defaults write com.apple.terminal StringEncodings -array 4 34 | 35 | # Avoid create DS_Store to USB 36 | defaults write com.apple.desktopservices DSDontWriteNetworkStores -bool true 37 | defaults write com.apple.desktopservices DSDontWriteUSBStores -bool true 38 | -------------------------------------------------------------------------------- /Brewfile: -------------------------------------------------------------------------------- 1 | # primitives 2 | brew 'git' 3 | brew 'rcm' 4 | brew 'neovim' 5 | brew 'zsh' 6 | brew 'zsh-completions' 7 | brew 'tmux' 8 | brew 'fzf' 9 | 10 | # [brew] dev 11 | brew 'ruby' 12 | brew 'go' 13 | brew 'shellcheck' # for CI checks 14 | # dev: CI testing 15 | if ENV.key? 'CI' 16 | puts 'In CI mode, skip non-primitive brews' 17 | else 18 | # [brew] dev 19 | brew 'cmake' 20 | brew 'mysql' 21 | brew 'sqlite' 22 | brew 'postgresql' 23 | brew 'node' 24 | brew 'pnpm' 25 | brew 'luarocks' 26 | brew 'navi' 27 | brew 'tokei' 28 | 29 | # [brew] productivity 30 | brew 'wget' 31 | brew 'p7zip' 32 | brew 'dos2unix' 33 | brew 'mas' 34 | brew 'bat' 35 | brew 'eza' 36 | brew 'ripgrep' 37 | brew 'fd' 38 | brew 'zoxide' 39 | brew 'htop' 40 | brew 'jq' 41 | brew 'fx' 42 | brew 'qsv' 43 | brew 'pandoc' 44 | brew 'beancount' 45 | brew 'fava' 46 | brew 'yt-dlp' 47 | brew 'neofetch' 48 | brew 't-rec' 49 | 50 | # [brew] optional 51 | # brew 'hexyl' 52 | # brew 'onefetch' 53 | # brew 'glow' 54 | # brew 'mpv' 55 | 56 | # [font] for code editor 57 | cask 'font-menlo-for-powerline' 58 | cask 'font-iosevka-nerd-font' 59 | # [font] for web rendering 60 | cask 'font-fira-code' 61 | 62 | # [cask] dev 63 | cask 'visual-studio-code' 64 | cask 'ghostty' 65 | cask 'figma' 66 | 67 | # [cask] productivity 68 | cask '1password' 69 | cask 'alfred' 70 | cask 'google-chrome' 71 | cask 'dropbox' 72 | cask 'hiddenbar' 73 | cask 'rectangle' 74 | cask 'karabiner-elements' 75 | cask 'google-trends' 76 | cask 'rar' 77 | cask 'appcleaner' 78 | # cask 'qmk-toolbox' 79 | # cask 'via' 80 | 81 | # [cask] entertainment 82 | cask 'iina' 83 | cask 'neteasemusic' 84 | 85 | # mas app 86 | mas 'Unsplash Wallpapers', id: 1_284_863_847 87 | mas 'Microsoft ToDo', id: 1_274_495_053 88 | mas 'Microsoft OneNote', id: 784_801_555 89 | mas 'Bear', id: 1_091_189_122 90 | mas 'Lungo', id: 1_263_070_803 91 | mas 'Pages', id: 409_201_541 92 | mas 'Numbers', id: 409_203_825 93 | mas 'Keynote', id: 409_183_694 94 | mas 'WeChat', id: 836_500_024 95 | mas 'Command X', id: 6448461551 96 | end 97 | -------------------------------------------------------------------------------- /rc/config/nvim/lua/treesitter.lua: -------------------------------------------------------------------------------- 1 | require('nvim-treesitter.configs').setup({ 2 | ensure_installed = { 3 | 'bash', 4 | 'beancount', 5 | 'c', 6 | 'cmake', 7 | 'comment', 8 | 'cpp', 9 | 'css', 10 | 'dockerfile', 11 | 'dot', 12 | 'go', 13 | 'gomod', 14 | 'gowork', 15 | 'graphql', 16 | 'haskell', 17 | 'hcl', 18 | 'html', 19 | 'http', 20 | 'javascript', 21 | 'jsdoc', 22 | 'json', 23 | 'json5', 24 | 'jsonc', 25 | 'lua', 26 | 'make', 27 | 'markdown', 28 | 'php', 29 | 'pug', 30 | 'python', 31 | 'regex', 32 | 'rst', 33 | 'ruby', 34 | 'rust', 35 | 'scss', 36 | 'toml', 37 | 'tsx', 38 | 'typescript', 39 | 'vim', 40 | 'vimdoc', 41 | 'vue', 42 | 'yaml', 43 | }, 44 | highlight = { 45 | enable = true, 46 | }, 47 | indent = { 48 | enable = false, 49 | }, 50 | incremental_selection = { 51 | enable = true, 52 | keymaps = { 53 | init_selection = 'gnn', 54 | node_incremental = 'grn', 55 | scope_incremental = 'grc', 56 | node_decremental = 'grm', 57 | }, 58 | }, 59 | playground = { 60 | enable = true, 61 | disable = {}, 62 | updatetime = 25, -- Debounced time for highlighting nodes in the playground from source code 63 | persist_queries = false, -- Whether the query persists across vim sessions 64 | }, 65 | textobjects = { 66 | select = { 67 | enable = true, 68 | keymaps = { 69 | -- You can use the capture groups defined in textobjects.scm 70 | ['af'] = '@function.outer', 71 | ['if'] = '@function.inner', 72 | ['ac'] = '@class.outer', 73 | ['ic'] = '@class.inner', 74 | ['aP'] = '@parameter.outer', 75 | ['iP'] = '@parameter.inner', 76 | }, 77 | }, 78 | }, 79 | }) 80 | -------------------------------------------------------------------------------- /rc/config/nvim/lua/options.lua: -------------------------------------------------------------------------------- 1 | local cmd = vim.cmd 2 | local opt = vim.opt 3 | local has = vim.fn.has 4 | 5 | cmd('filetype plugin indent on') 6 | cmd('syntax enable') 7 | 8 | -- systematic 9 | opt.encoding = 'utf-8' 10 | opt.fileencoding = 'utf-8' 11 | opt.fileencodings = { 'utf-8' } 12 | opt.backup = false -- no .bak 13 | opt.swapfile = false -- no .swap 14 | opt.undofile = true -- use undo file 15 | opt.updatetime = 300 -- time (in ms) to write to swap file 16 | -- buffer 17 | opt.expandtab = true -- expand tab 18 | opt.tabstop = 4 -- tab stop 19 | opt.softtabstop = 4 -- soft tab stop 20 | opt.autoindent = true -- auto indent for new line 21 | opt.shiftwidth = 4 -- auto indent shift width 22 | -- window 23 | opt.number = true 24 | opt.relativenumber = true 25 | opt.foldmethod = 'marker' 26 | -- editing 27 | opt.whichwrap = 'b,s,<,>,[,]' -- cursor is able to move from end of line to next line 28 | opt.backspace = { 'indent', 'eol', 'start' } -- backspace behaviors 29 | opt.list = true -- show tabs with listchars 30 | opt.ignorecase = false -- search with no ignore case 31 | opt.hlsearch = true -- highlight search 32 | opt.incsearch = false -- no incremental search 33 | opt.inccommand = 'nosplit' -- live substitute preview 34 | opt.completeopt = { 'menuone', 'noselect' } 35 | opt.hidden = true 36 | opt.cursorline = true -- show cursor line 37 | opt.ruler = true -- show ruler line 38 | opt.colorcolumn = { 120 } -- display a color column when line is longer than 120 chars 39 | opt.signcolumn = 'yes' -- show sign column (column of the line number) 40 | opt.mouse = 'nv' -- enable mouse under normal and visual mode 41 | opt.showmatch = true -- show bracket match 42 | opt.cmdheight = 2 -- height of :command line 43 | opt.wildmenu = true -- wildmenu, auto complete for commands 44 | opt.wildmode = { 'longest', 'full' } 45 | opt.splitright = true -- split to right 46 | opt.splitbelow = true -- split to below 47 | opt.shortmess:append('c') -- status line e.g. CTRL+G 48 | opt.laststatus = 3 49 | 50 | if not has('gui_running') then 51 | opt.t_Co = 256 52 | end 53 | opt.background = 'dark' 54 | if has('termguicolors') then 55 | cmd('let &t_8f = "\\[38;2;%lu;%lu;%lum"') 56 | cmd('let &t_8b = "\\[48;2;%lu;%lu;%lum"') 57 | opt.termguicolors = true 58 | end 59 | -------------------------------------------------------------------------------- /rc/vimrc: -------------------------------------------------------------------------------- 1 | filetype plugin indent on 2 | syntax enable 3 | 4 | set encoding=utf-8 5 | set nobackup 6 | set noswapfile 7 | set undofile 8 | set expandtab 9 | set tabstop=4 10 | set softtabstop=4 11 | set autoindent 12 | set shiftwidth=4 13 | set number 14 | set whichwrap=b,s,<,>,[,] 15 | set backspace=indent,eol,start 16 | set ignorecase 17 | set hlsearch 18 | set noincsearch 19 | set hidden 20 | set cursorline 21 | set ruler 22 | set colorcolumn=120 23 | set signcolumn=yes 24 | set mouse=nv 25 | set showmatch 26 | set showtabline=2 27 | set cmdheight=2 28 | set wildmenu 29 | set wildmode=longest,full 30 | set splitright 31 | set splitbelow 32 | set shortmess+=c 33 | set t_Co=256 34 | set background=dark 35 | set termguicolors 36 | 37 | let mapleader="\\" 38 | nnoremap q q! 39 | nnoremap Q qa! 40 | nnoremap w wq! 41 | nnoremap e e! 42 | nnoremap r source ~/.vimrc 43 | inoremap I 44 | inoremap 45 | cnoremap 46 | cnoremap 47 | nnoremap k gk 48 | nnoremap j gj 49 | nnoremap C c$ 50 | nnoremap D d$ 51 | nnoremap Y y$ 52 | nnoremap pp "0p 53 | nnoremap m .-2== 54 | nnoremap m .+1== 55 | vnoremap :move '<-2gv=gv 56 | vnoremap :move '>+1gv=gv 57 | nnoremap ps :PlugInstall 58 | nnoremap s w 59 | nnoremap j j 60 | nnoremap k k 61 | nnoremap h h 62 | nnoremap l l 63 | nnoremap gT 64 | nnoremap gt 65 | nnoremap t[ tabmove -1 66 | nnoremap t] tabmove +1 67 | nnoremap 1 1gt 68 | nnoremap 2 2gt 69 | nnoremap 3 3gt 70 | nnoremap 4 4gt 71 | nnoremap 5 5gt 72 | nnoremap 6 6gt 73 | nnoremap 7 7gt 74 | nnoremap 8 8gt 75 | nnoremap 9 9gt 76 | nnoremap 0 tablast 77 | 78 | call plug#begin() 79 | Plug 'crispgm/nord-vim', { 'branch': 'develop' } 80 | Plug 'mkitt/tabline.vim' 81 | Plug 'google/vim-searchindex' 82 | Plug 'Yggdroot/indentLine' 83 | Plug 'RRethy/vim-illuminate' 84 | Plug 'christoomey/vim-system-copy' 85 | Plug 'tpope/vim-commentary' 86 | Plug 'tpope/vim-repeat' 87 | Plug 'tpope/vim-surround' 88 | Plug 'tpope/vim-abolish' 89 | Plug 'kana/vim-textobj-user' 90 | Plug 'haya14busa/vim-textobj-number' 91 | Plug 'AndrewRadev/splitjoin.vim' 92 | call plug#end() 93 | 94 | colorscheme nord 95 | -------------------------------------------------------------------------------- /rc/zshrc: -------------------------------------------------------------------------------- 1 | # Path to your oh-my-zsh installation. 2 | export ZSH=~/.oh-my-zsh 3 | 4 | # Set name of the theme to load. 5 | # Look in ~/.oh-my-zsh/themes/ 6 | # Optionally, if you set this to "random", it'll load a random theme each 7 | # time that oh-my-zsh is loaded. 8 | ZSH_THEME="crispy" 9 | 10 | # Uncomment the following line to use case-sensitive completion. 11 | CASE_SENSITIVE="true" 12 | 13 | # Uncomment the following line to use hyphen-insensitive completion. Case 14 | # sensitive completion must be off. _ and - will be interchangeable. 15 | # HYPHEN_INSENSITIVE="true" 16 | 17 | # Uncomment the following line to disable bi-weekly auto-update checks. 18 | # DISABLE_AUTO_UPDATE="true" 19 | 20 | # Uncomment the following line to change how often to auto-update (in days). 21 | export UPDATE_ZSH_DAYS=30 22 | 23 | # Uncomment the following line to disable colors in ls. 24 | # DISABLE_LS_COLORS="true" 25 | 26 | # Uncomment the following line to disable auto-setting terminal title. 27 | # DISABLE_AUTO_TITLE="true" 28 | 29 | # Uncomment the following line to enable command auto-correction. 30 | # ENABLE_CORRECTION="true" 31 | 32 | # Uncomment the following line to display red dots whilst waiting for completion. 33 | # COMPLETION_WAITING_DOTS="true" 34 | 35 | # Uncomment the following line if you want to disable marking untracked files 36 | # under VCS as dirty. This makes repository status check for large repositories 37 | # much, much faster. 38 | # DISABLE_UNTRACKED_FILES_DIRTY="true" 39 | 40 | # Uncomment the following line if you want to change the command execution time 41 | # stamp shown in the history command output. 42 | # The optional three formats: "mm/dd/yyyy"|"dd.mm.yyyy"|"yyyy-mm-dd" 43 | # HIST_STAMPS="mm/dd/yyyy" 44 | 45 | # Would you like to use another custom folder than $ZSH/custom? 46 | # ZSH_CUSTOM=/path/to/new-custom-folder 47 | 48 | plugins=(docker emoji eza golang macos redis-cli sudo) 49 | 50 | # User configuration 51 | source $ZSH/oh-my-zsh.sh 52 | export LANG=en_US.UTF-8 53 | export EDITOR='nvim' 54 | # allow the respect for LS_COLORS 55 | export LS_COLORS=gxfxaxdxcxegedabagacad 56 | 57 | # PATH 58 | export PATH=$GOPATH/bin:/opt/homebrew/bin:/opt/homebrew/opt/ruby/bin:$PATH 59 | 60 | # Go 61 | export GOROOT=`brew --prefix go`/libexec 62 | export GOPATH=~/go 63 | 64 | # Alias 65 | source ~/.zsh_alias 66 | 67 | # fzf 68 | [ -f ~/.fzf.zsh ] && source ~/.fzf.zsh 69 | 70 | # zoxide 71 | eval "$(zoxide init zsh)" 72 | 73 | # bat 74 | export BAT_THEME=Nord 75 | -------------------------------------------------------------------------------- /rc/config/nvim/lua/completion.lua: -------------------------------------------------------------------------------- 1 | local cmp = require('cmp') 2 | local ls = require('luasnip') 3 | 4 | require('luasnip.loaders.from_vscode').lazy_load({ paths = '~/dev/snippets' }) 5 | 6 | cmp.setup({ 7 | mapping = cmp.mapping.preset.insert({ 8 | [''] = cmp.mapping.scroll_docs(-4), 9 | [''] = cmp.mapping.scroll_docs(4), 10 | [''] = cmp.mapping.complete(), 11 | [''] = cmp.mapping.close(), 12 | [''] = cmp.mapping.confirm({ 13 | behavior = cmp.ConfirmBehavior.Insert, 14 | select = true, 15 | }), 16 | [''] = cmp.mapping(function(fallback) 17 | if ls.expand_or_jumpable() then 18 | ls.expand_or_jump() 19 | else 20 | fallback() 21 | end 22 | end, { 'i', 's' }), 23 | }), 24 | sources = cmp.config.sources({ 25 | -- { name = 'copilot' }, 26 | { name = 'nvim_lsp' }, 27 | { name = 'nvim_lsp_signature_help' }, 28 | { name = 'nvim_lua' }, 29 | { name = 'luasnip' }, 30 | { 31 | name = 'beancount', 32 | option = { account = '~/dev/ledger/beancounts/accounts.bean' }, 33 | }, 34 | { name = 'path' }, 35 | { name = 'calc' }, 36 | { name = 'emoji' }, 37 | { name = 'buffer' }, 38 | }), 39 | snippet = { 40 | expand = function(args) 41 | require('luasnip').lsp_expand(args.body) 42 | end, 43 | }, 44 | experimental = { 45 | native_menu = false, 46 | ghost_text = true, 47 | }, 48 | formatting = { 49 | format = function(entry, vim_item) 50 | vim_item.menu = ({ 51 | -- copilot = '[cop]', 52 | nvim_lsp = '[lsp]', 53 | nvim_lua = '[lua]', 54 | nvim_lsp_signature_help = '[sig]', 55 | bean_account = '[bean]', 56 | luasnip = '[snippet]', 57 | path = '[path]', 58 | calc = '[cal]', 59 | emoji = '[emo]', 60 | buffer = '[buf]', 61 | })[entry.source.name] 62 | return vim_item 63 | end, 64 | }, 65 | }) 66 | 67 | cmp.setup.cmdline(':', { 68 | mapping = cmp.mapping.preset.cmdline(), 69 | sources = { 70 | { name = 'cmdline', max_item_count = 30 }, 71 | }, 72 | }) 73 | 74 | cmp.setup.cmdline('/', { 75 | mapping = cmp.mapping.preset.cmdline(), 76 | sources = { 77 | { name = 'buffer' }, 78 | }, 79 | }) 80 | -------------------------------------------------------------------------------- /rc/config/nvim/lua/mappings.lua: -------------------------------------------------------------------------------- 1 | local map = require('common').map 2 | local nnoremap = require('common').nnoremap 3 | local inoremap = require('common').inoremap 4 | local vnoremap = require('common').vnoremap 5 | local cnoremap = require('common').cnoremap 6 | -- common 7 | nnoremap('#', 'let @/ = ""') 8 | nnoremap('n', 'nzzzv') 9 | nnoremap('N', 'Nzzzv') 10 | nnoremap('q', 'q!') 11 | nnoremap('e', 'e!') 12 | nnoremap('Q', 'qa!') 13 | nnoremap('w', 'wq!') 14 | nnoremap('n', 'set nonumber norelativenumber') 15 | nnoremap('N', 'set number') 16 | nnoremap('R', 'set relativenumber') 17 | -- moving 18 | inoremap('', 'I') 19 | inoremap('', '') 20 | nnoremap('k', 'gk') 21 | nnoremap('j', 'gj') 22 | -- editing 23 | nnoremap('Y', 'y$') 24 | nnoremap('cp', 'OSCYankOperator') 25 | vnoremap('cp', 'OSCYankVisual') 26 | inoremap('', 'ddi') 27 | nnoremap('pp', '"0p') 28 | nnoremap('', 'm .-2==') 29 | nnoremap('', 'm .+1==') 30 | vnoremap('', ":move '<-2gv=gv") 31 | vnoremap('', ":move '>+1gv=gv") 32 | -- splits 33 | nnoremap('s', 'w') 34 | nnoremap('j', 'j') 35 | nnoremap('k', 'k') 36 | nnoremap('h', 'h') 37 | nnoremap('l', 'l') 38 | -- buf 39 | nnoremap('bb', 'BufDel') 40 | nnoremap('', 'bprev') 41 | nnoremap('', 'bnext') 42 | -- tab 43 | nnoremap('[', 'gT') 44 | nnoremap(']', 'gt') 45 | nnoremap('t[', 'tabmove -1') 46 | nnoremap('t]', 'tabmove +1') 47 | nnoremap('1', '1gt') 48 | nnoremap('2', '2gt') 49 | nnoremap('3', '3gt') 50 | nnoremap('4', '4gt') 51 | nnoremap('5', '5gt') 52 | nnoremap('6', '6gt') 53 | nnoremap('7', '7gt') 54 | nnoremap('8', '8gt') 55 | nnoremap('9', '9gt') 56 | nnoremap('0', 'tablast') 57 | -- quickfix 58 | nnoremap('cc', 'cclose') 59 | -- command 60 | cnoremap('', '') 61 | cnoremap('', '') 62 | 63 | -- LSP 64 | nnoremap('ld', 'Telescope lsp_definitions') 65 | nnoremap('lD', 'lua vim.lsp.buf.declaration()') 66 | nnoremap('lt', 'Telescope lsp_type_definitions') 67 | nnoremap('li', 'Telescope lsp_implementations') 68 | nnoremap('K', 'lua vim.lsp.buf.hover()') 69 | nnoremap('U', 'lua vim.lsp.buf.signature_help()') 70 | nnoremap('lr', 'Telescope lsp_references') 71 | nnoremap('ls', 'Telescope lsp_document_symbols') 72 | nnoremap('lS', 'Telescope lsp_workspace_symbols') 73 | nnoremap('lR', 'lua vim.lsp.buf.rename()') 74 | nnoremap('lf', 'lua vim.lsp.buf.format({async=true})') 75 | 76 | -- dial.nvim 77 | map('n', '', '(dial-increment)') 78 | map('n', '', '(dial-decrement)') 79 | map('n', '', '(dial-increment)') 80 | map('n', '', '(dial-decrement)') 81 | map('n', 'g', '(dial-increment-additional)') 82 | map('n', 'g', '(dial-decrement-additional)') 83 | 84 | -- hop.nvim 85 | nnoremap('s', 'HopChar2') 86 | nnoremap('S', 'HopWord') 87 | nnoremap('', 'HopLine') 88 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # dotfiles 2 | 3 |

4 | 5 |

6 | 7 |

8 | GitHub CI 9 | platform 10 |

11 | 12 | ## Introduction 13 | 14 | This is a dotfiles project which may be used to provision a new macOS with cosy dev setups. 15 | And it is tested with GitHub Actions CI. The checkbox denotes whether it is done by `bootstrap`. 16 | More screenshots [here](screenshots). 17 | 18 | Inspired by [KrauseFx/new-mac](https://github.com/KrauseFx/new-mac). 19 | 20 | For Arch Linux, please refer to [crispgm/arch-linux-dotfiles](https://github.com/crispgm/arch-linux-dotfiles). 21 | 22 | ## Bootstrap 23 | 24 | ```shell 25 | $ xcode-select --install # or download here 26 | $ git clone --recursive https://github.com/crispgm/dotfiles.git 27 | # Login to AppStore with Apple ID, since there are MAS apps in Brewfile 28 | $ cd dotfiles 29 | $ ./bootstrap 30 | ``` 31 | 32 | ## Project Layout 33 | 34 | - `bootstrap`: entry point of dotfiles bootstrapping. 35 | - `Brewfile`: all Homebrew formulae and casks managed by Homebrew Bundle. 36 | - `rc`: dotfiles managed by [rcm](https://github.com/thoughtbot/rcm). 37 | - `app`: customized boostrapping scripts for applications. 38 | 39 | ## Dev Setups 40 | 41 | ### Terminal & Shell 42 | 43 | - [x] Install [Homebrew](https://brew.sh) 44 | - [x] Setup Hostname `sudo scutil --set HostName david-macbook` 45 | - [x] Install softwares and fonts from [Brewfile](https://github.com/crispgm/dotfiles/blob/master/Brewfile) with `brew bundle`. HINT: Login to AppStore at first. Some of the applications from Mac App Store may need purchase. 46 | - [x] Install `zsh`, `oh-my-zsh` and setup `.zshrc` 47 | - [x] Setup Alacritty 48 | - [x] Setup tmux 49 | - [x] Setup Neovim 50 | 51 | ### Git 52 | 53 | - [x] Git global config 54 | - [x] Git work config 55 | 56 | ### Ruby 57 | 58 | - [x] Setup `.gemrc` 59 | - [x] Setup bundler's mirror: `bundle config mirror.https://rubygems.org https://gems.ruby-china.com` if you locate in China mainland 60 | 61 | ### VSCode 62 | 63 | - [x] Create `code` SymLink: `sudo ln -s /Applications/Visual\ Studio\ Code.app/Contents/Resources/app/bin/code ~/Applications/code` 64 | - [x] Install `Setting Sync` extensions and then sync settings 65 | 66 | ### File Sync 67 | 68 | - [x] Install your favorite file sync service (e.g. Dropbox, Google Drive, One Drive ... I prefer Dropbox because it works with Alfred) 69 | - [ ] Setup syncing folder for apps (e.g. Alfred, Dash ...) 70 | 71 | ### Karabiner 72 | 73 | - [x] Setup `karabiner.json` 74 | 75 | ## macOS Setups 76 | 77 | ### Trackpad 78 | 79 | - [ ] Tap to click 80 | - [ ] Seconary click: Click in bottom right corner 81 | 82 | ### Control Center 83 | 84 | #### Battery 85 | 86 | - [ ] Show Battery in Control Center 87 | - [ ] Show percentage 88 | 89 | #### Time 90 | 91 | - [ ] Set time zone automatically using current location 92 | - [ ] Use a 24-hour clock and show date 93 | 94 | #### Siri 95 | 96 | - [ ] Disable Siri system wide and remove Siri button from Touch Bar 97 | 98 | ### Finder 99 | 100 | - [ ] New Finder show Desktop 101 | - [ ] Remove labels and clean up Sidebar 102 | 103 | ### Dock 104 | 105 | - [ ] Change to the size you like 106 | - [ ] Cancel: Show recent application in Dock 107 | - [ ] Downloads: View content as Grid 108 | - [ ] Add blank seperator: `defaults write com.apple.dock persistent-apps -array-add '{tile-type="spacer-tile";}'` 109 | 110 | ### Mission Control 111 | 112 | - [ ] Disable automatically rearrange Spaces based on most recent use 113 | 114 | ### Keyboard 115 | 116 | - [ ] Input Sources -> Automatically switch to a document's input source 117 | - [ ] Add more input sources that you like 118 | 119 | #### Keyboard Shortcuts 120 | 121 | - [ ] Show Launchpad: `F4` 122 | - [ ] Select the previous input source: `Option + Space` 123 | - [ ] Copy picture of selected area to clipboard: `Command + Shift + a` 124 | 125 | ## Optional Setups 126 | 127 | ### bash 128 | 129 | - [x] Setup shell login promtp with `motd`: ASCII art is generated with 130 | - [x] Setup `.bash_profile` `.bashrc` 131 | -------------------------------------------------------------------------------- /rc/config/nvim/lua/autocmds.lua: -------------------------------------------------------------------------------- 1 | local a = vim.api 2 | local f = vim.fn 3 | local formatter = require('formatter') 4 | 5 | local function trim_whitespace() 6 | local exclude_filetypes = { 'markdown', 'vimwiki' } 7 | local ft = vim.bo.filetype 8 | for _, ef in ipairs(exclude_filetypes) do 9 | if ft == ef then 10 | return 11 | end 12 | end 13 | local view = f.winsaveview() 14 | vim.cmd([[keeppatterns %s/\s\+$//e]]) 15 | vim.cmd([[silent! 0;/^\%(\n*.\)\@!/,$d]]) 16 | f.winrestview(view) 17 | end 18 | 19 | local editor = a.nvim_create_augroup('editor_options', { clear = true }) 20 | a.nvim_create_autocmd({ 'BufWritePre' }, { 21 | group = editor, 22 | pattern = { '*' }, 23 | callback = trim_whitespace, 24 | }) 25 | a.nvim_create_autocmd({ 'TextYankPost' }, { 26 | group = editor, 27 | pattern = { '*' }, 28 | callback = function() 29 | vim.highlight.on_yank({ timeout = 500 }) 30 | end, 31 | }) 32 | a.nvim_create_autocmd({ 'InsertEnter' }, { 33 | group = editor, 34 | pattern = { '*' }, 35 | callback = function() 36 | vim.wo.relativenumber = false 37 | end, 38 | }) 39 | a.nvim_create_autocmd({ 'InsertLeave' }, { 40 | group = editor, 41 | pattern = { '*' }, 42 | callback = function() 43 | vim.wo.relativenumber = true 44 | end, 45 | }) 46 | 47 | -- filetypes 48 | a.nvim_create_autocmd({ 'Filetype' }, { 49 | group = editor, 50 | pattern = { 51 | 'beancount', 52 | 'css', 53 | 'html', 54 | 'javascript', 55 | 'json', 56 | 'scss', 57 | 'typescript', 58 | 'yaml', 59 | 'vim', 60 | }, 61 | callback = function() 62 | vim.bo.tabstop = 2 63 | vim.bo.softtabstop = 2 64 | vim.bo.shiftwidth = 2 65 | vim.bo.expandtab = true 66 | end, 67 | }) 68 | a.nvim_create_autocmd({ 'Filetype' }, { 69 | group = editor, 70 | pattern = { 71 | 'go', 72 | }, 73 | callback = function() 74 | vim.bo.tabstop = 4 75 | vim.bo.softtabstop = 4 76 | vim.bo.shiftwidth = 4 77 | vim.bo.expandtab = false 78 | end, 79 | }) 80 | a.nvim_create_autocmd({ 'Filetype' }, { 81 | group = editor, 82 | pattern = { 83 | 'json', 84 | }, 85 | callback = function() 86 | vim.g['indentLine_conceallevel'] = 1 87 | end, 88 | }) 89 | a.nvim_create_autocmd({ 'BufRead', 'BufNewFile' }, { 90 | group = editor, 91 | pattern = { 92 | 'Brewfile', 93 | 'Gemfile', 94 | }, 95 | callback = function() 96 | vim.bo.filetype = 'ruby' 97 | end, 98 | }) 99 | 100 | -- quickfix 101 | local qf = a.nvim_create_augroup('qf_options', { clear = true }) 102 | a.nvim_create_autocmd({ 'WinEnter' }, { 103 | group = qf, 104 | pattern = { '*' }, 105 | callback = function() 106 | if vim.fn.winnr('$') == 1 and vim.bo.buftype == 'quickfix' then 107 | vim.cmd('q') 108 | end 109 | end, 110 | }) 111 | 112 | -- lsp 113 | local lsp = a.nvim_create_augroup('lsp_options', { clear = true }) 114 | a.nvim_create_autocmd({ 'CursorHold' }, { 115 | group = lsp, 116 | pattern = { '*' }, 117 | callback = function() 118 | vim.diagnostic.open_float(nil, { focusable = false, scope = 'cursor' }) 119 | end, 120 | }) 121 | 122 | -- formatter 123 | local format = a.nvim_create_augroup('formatter_options', { clear = true }) 124 | a.nvim_create_autocmd({ 'BufWritePost' }, { 125 | group = format, 126 | pattern = { '{*.bean,*.beancount}' }, 127 | callback = formatter.bean_format, 128 | }) 129 | a.nvim_create_autocmd({ 'BufWritePost' }, { 130 | group = format, 131 | pattern = { '{*.bean,*.beancount}' }, 132 | callback = function() 133 | vim.cmd('!bean-check ') 134 | end, 135 | }) 136 | a.nvim_create_autocmd({ 'BufWritePost' }, { 137 | group = format, 138 | pattern = { '*.lua' }, 139 | callback = formatter.lua_format, 140 | }) 141 | a.nvim_create_autocmd({ 'BufWritePost' }, { 142 | group = format, 143 | pattern = { '*.sh' }, 144 | callback = formatter.shell_format, 145 | }) 146 | 147 | -- nvim-go 148 | local nvim_go = a.nvim_create_augroup('nvim_go', { clear = true }) 149 | a.nvim_create_autocmd({ 'User' }, { 150 | group = nvim_go, 151 | pattern = { 'NvimGoLintPopupPost' }, 152 | command = 'wincmd p', 153 | }) 154 | -------------------------------------------------------------------------------- /rc/config/nvim/lua/pack.lua: -------------------------------------------------------------------------------- 1 | return require('lazy').setup({ 2 | -- {{{ lib 3 | 'nvim-lua/plenary.nvim', 4 | -- }}} 5 | 6 | -- {{{ colorscheme 7 | 'nordtheme/vim', 8 | -- }}} 9 | 10 | -- {{{ ui 11 | 'rcarriga/nvim-notify', 12 | 'nvim-tree/nvim-web-devicons', 13 | -- }}} 14 | 15 | -- {{{ file 16 | 'mhinz/vim-startify', -- startup page 17 | 'nvim-telescope/telescope.nvim', -- fuzzy picker 18 | { 19 | 'crispgm/telescope-heading.nvim', -- markdown heading 20 | -- dev = true, 21 | }, 22 | 'akinsho/toggleterm.nvim', -- terminal 23 | { 24 | 'rmagatti/auto-session', -- auto session 25 | opts = { 26 | suppressed_dirs = { '~/', '~/dev', '~/work', '/' }, 27 | }, 28 | }, 29 | 'rmagatti/session-lens', -- session lens for telescope 30 | 'ethanholz/nvim-lastplace', -- reopen files at your last edit position 31 | 'AndrewRadev/undoquit.vim', -- restore closed tabs 32 | 'ojroques/nvim-bufdel', -- delete buf without losing window layout 33 | 'ojroques/vim-oscyank', -- copy to system clipboard by OSC52 34 | -- }}} 35 | 36 | -- {{{ view 37 | 'ojroques/nvim-hardline', -- status line 38 | { 39 | 'crispgm/nvim-tabline', -- tab line 40 | -- dev = true, 41 | config = true, 42 | }, 43 | { 44 | 'SmiteshP/nvim-navic', -- LSP code context 45 | dependencies = { 'neovim/nvim-lspconfig' }, 46 | config = function() 47 | require('nvim-navic').setup({ lsp = { auto_attach = true } }) 48 | end, 49 | }, 50 | 'Bekaboo/dropbar.nvim', -- winbar 51 | 'dstein64/nvim-scrollview', -- scroll bar 52 | { 53 | 'declancm/cinnamon.nvim', -- smooth scrolling 54 | config = true, 55 | }, 56 | 'google/vim-searchindex', -- search index 57 | 'Yggdroot/indentLine', -- indent line 58 | { 59 | 'RRethy/vim-illuminate', -- highlight hover word 60 | config = function() 61 | require('illuminate').configure({ 62 | under_cursor = false, 63 | }) 64 | end, 65 | }, 66 | 'lewis6991/gitsigns.nvim', -- git signs 67 | 'rhysd/conflict-marker.vim', -- git conflict marker 68 | { 69 | 'norcalli/nvim-colorizer.lua', -- colorizer 70 | config = true, 71 | }, 72 | { 73 | 'winston0410/range-highlight.nvim', -- highlight range lines 74 | dependencies = { 'winston0410/cmd-parser.nvim' }, 75 | config = function() 76 | require('range-highlight').setup({ 77 | highlight = 'Visual', 78 | }) 79 | end, 80 | }, 81 | -- }}} 82 | 83 | -- {{{ edit 84 | { 85 | 'phaazon/hop.nvim', -- jump to anywhere within 2 strokes 86 | config = true, 87 | }, 88 | -- f/t enhancement 89 | 'tpope/vim-repeat', -- allow commands from plugin do repeat 90 | 'tpope/vim-surround', -- toggle surround 91 | 'tpope/vim-abolish', -- eh, hard to describe, see README 92 | { 93 | 'numToStr/Comment.nvim', -- toggle comment 94 | config = true, 95 | }, 96 | 'monaqa/dial.nvim', -- enhancement 97 | 'kana/vim-textobj-user', -- define textobj by user 98 | { 99 | 'haya14busa/vim-textobj-number', -- number textobj 100 | dependencies = { 'kana/vim-textobj-user' }, 101 | }, 102 | 'AndrewRadev/splitjoin.vim', -- split and join in vim 103 | 'wellle/targets.vim', -- various text objects 104 | { 105 | 'windwp/nvim-autopairs', -- auto pairs 106 | config = function() 107 | require('nvim-autopairs').setup({ 108 | disable_filetype = { 'TelescopePrompt' }, 109 | }) 110 | end, 111 | }, 112 | { 'chrisgrieser/nvim-spider', lazy = true }, 113 | { 114 | 'crispgm/nvim-auto-ime', 115 | -- dev = true, 116 | config = function() 117 | require('auto-ime').setup({ 118 | ime_source = 'com.apple.inputmethod.SCIM.ITABC', 119 | }) 120 | end, 121 | }, 122 | -- }}} 123 | 124 | -- {{{ language features 125 | { 126 | 'nvim-treesitter/nvim-treesitter', -- treesitter 127 | build = ':TSUpdate', 128 | }, 129 | { 130 | 'nvim-treesitter/playground', -- treesitter playground 131 | dependencies = { 'nvim-treesitter/nvim-treesitter' }, 132 | }, 133 | { 134 | 'nvim-treesitter/nvim-treesitter-textobjects', -- treesitter textobj e.g., class, function 135 | dependencies = { 'nvim-treesitter/nvim-treesitter' }, 136 | }, 137 | 'neovim/nvim-lspconfig', -- lsp client config 138 | { 139 | 'williamboman/mason.nvim', 140 | config = true, 141 | }, 142 | { 143 | 'williamboman/mason-lspconfig.nvim', 144 | dependencies = { 'williamboman/mason.nvim', 'neovim/nvim-lspconfig' }, 145 | config = function() 146 | require('mason-lspconfig').setup({ 147 | ensure_installed = { 148 | 'bashls', 149 | 'beancount', 150 | 'cssls', 151 | 'gopls', 152 | 'html', 153 | 'jsonls', 154 | 'lua_ls', 155 | 'pyright', 156 | 'rust_analyzer', 157 | 'ruby_lsp', 158 | 'sqlls', 159 | 'ts_ls', 160 | 'vimls', 161 | 'vuels', 162 | 'yamlls', 163 | }, 164 | }) 165 | end, 166 | }, 167 | { 168 | 'j-hui/fidget.nvim', -- lsp loading process 169 | config = true, 170 | tag = 'legacy', 171 | }, 172 | { 173 | 'hrsh7th/nvim-cmp', -- completion 174 | dependencies = { 175 | 'hrsh7th/cmp-nvim-lsp', -- cmp lsp 176 | 'hrsh7th/cmp-nvim-lsp-signature-help', -- cmp lsp signature help 177 | 'hrsh7th/cmp-nvim-lua', -- cmp lua vim api 178 | 'hrsh7th/cmp-buffer', 179 | 'hrsh7th/cmp-cmdline', 180 | 'hrsh7th/cmp-path', 181 | 'hrsh7th/cmp-calc', 182 | 'hrsh7th/cmp-emoji', 183 | { 184 | 'crispgm/cmp-beancount', 185 | -- dev = true, 186 | }, 187 | { 188 | 'saadparwaiz1/cmp_luasnip', 189 | dependencies = { 190 | 'L3MON4D3/LuaSnip', 191 | version = 'v1.*', 192 | build = 'make install_jsregexp', 193 | }, 194 | }, 195 | }, 196 | }, 197 | -- }}} 198 | 199 | -- {{{ language-specific 200 | { 201 | 'prettier/vim-prettier', -- prettier formatter 202 | build = 'yarn install', 203 | branch = 'release/0.x', 204 | }, 205 | 'mattn/emmet-vim', -- html/css snippets 206 | { 207 | 'crispgm/nvim-go', -- go dev 208 | -- dev = true, 209 | config = function() 210 | require('go').setup({ 211 | formatter = 'lsp', 212 | test_flags = { '-v', '-count=1' }, 213 | test_popup_width = 120, 214 | test_open_cmd = 'tabedit', 215 | }) 216 | end, 217 | }, 218 | 'rust-lang/rust.vim', -- rust lang support 219 | 'nathangrigg/vim-beancount', -- beancount ftplugin 220 | 'vimwiki/vimwiki', -- vimwiki 221 | { 222 | 'folke/neodev.nvim', 223 | config = true, 224 | }, 225 | 'rafcamlet/nvim-luapad', -- lua repl 226 | 'junegunn/vader.vim', -- vim plugin testing 227 | -- }}} 228 | }, { 229 | dev = { 230 | path = '~/dev', 231 | }, 232 | install = { colorscheme = { 'nord' } }, 233 | }) 234 | -------------------------------------------------------------------------------- /rc/tmux.conf: -------------------------------------------------------------------------------- 1 | # cat << EOF > /dev/null 2 | # https://github.com/gpakosz/.tmux 3 | # (‑●‑●)> dual licensed under the WTFPL v2 license and the MIT license, 4 | # without any warranty. 5 | # Copyright 2012— Gregory Pakosz (@gpakosz). 6 | # /!\ do not edit this file 7 | # instead, override settings in ~/.tmux.conf.local, see README.md 8 | 9 | # -- general ------------------------------------------------------------------- 10 | 11 | set -g default-terminal "screen-256color" 12 | if 'infocmp -x tmux-256color > /dev/null 2>&1' 'set -g default-terminal "tmux-256color"' 13 | set -sa terminal-overrides ',xterm-256color:RGB' 14 | set -s set-clipboard on 15 | 16 | setw -g xterm-keys on 17 | set -s escape-time 10 # faster command sequences 18 | set -sg repeat-time 600 # increase repeat timeout 19 | set -s focus-events on 20 | set -g mouse on 21 | bind -n WheelUpPane if-shell -F -t = "#{mouse_any_flag}" "send-keys -M" "if -Ft= '#{pane_in_mode}' 'send-keys -M' 'copy-mode -e'" 22 | 23 | set -q -g status-utf8 on # expect UTF-8 (tmux < 2.2) 24 | setw -q -g utf8 on 25 | 26 | set -g history-limit 5000 # boost history 27 | 28 | # edit configuration 29 | bind e new-window -n '~/.tmux.conf' "sh -c '\${EDITOR:-vim} ~/.tmux.conf && tmux source ~/.tmux.conf && tmux display \"~/.tmux.conf sourced\"'" 30 | bind E command-prompt -p "Command:" \ 31 | "run \"tmux list-panes -a -F '##{session_name}:##{window_index}.##{pane_index}' \ 32 | | xargs -I PANE tmux send-keys -t PANE '%1' Enter\"" 33 | 34 | # reload configuration 35 | bind r source-file ~/.tmux.conf \; display '~/.tmux.conf sourced' 36 | 37 | 38 | # -- display ------------------------------------------------------------------- 39 | 40 | set -g base-index 1 # start windows numbering at 1 41 | setw -g pane-base-index 1 # make pane numbering consistent with windows 42 | 43 | setw -g automatic-rename on # rename window to reflect current program 44 | set -g renumber-windows on # renumber windows when a window is closed 45 | 46 | set -g set-titles on # set terminal title 47 | 48 | set -g display-panes-time 800 # slightly longer pane indicators display time 49 | set -g display-time 1000 # slightly longer status messages display time 50 | 51 | set -g status-interval 10 # redraw status line every 10 seconds 52 | 53 | # clear both screen and history 54 | bind -n C-l send-keys C-l \; run 'sleep 0.1' \; clear-history 55 | 56 | # activity 57 | set -g monitor-activity on 58 | set -g visual-activity off 59 | 60 | 61 | # -- navigation ---------------------------------------------------------------- 62 | 63 | # find session 64 | bind C-f command-prompt -p find-session 'switch-client -t %%' 65 | # popup select session 66 | bind C-j display-popup -E "tmux list-sessions | sed -E 's/:.*$//' | grep -v \"^$(tmux display-message -p '#S')\$\" | fzf --reverse | xargs tmux switch-client -t" 67 | 68 | # split current window horizontally 69 | bind - split-window -v 70 | # split current window vertically 71 | bind _ split-window -h 72 | 73 | # pane navigation 74 | bind -r h select-pane -L # move left 75 | bind -r j select-pane -D # move down 76 | bind -r k select-pane -U # move up 77 | bind -r l select-pane -R # move right 78 | bind > swap-pane -D # swap current pane with the next one 79 | bind < swap-pane -U # swap current pane with the previous one 80 | 81 | # maximize current pane 82 | bind + run 'cut -c3- ~/.tmux.conf | sh -s _maximize_pane "#{session_name}" #D' 83 | 84 | # pane resizing 85 | bind -r H resize-pane -L 2 86 | bind -r J resize-pane -D 2 87 | bind -r K resize-pane -U 2 88 | bind -r L resize-pane -R 2 89 | 90 | # window navigation 91 | unbind n 92 | unbind p 93 | bind -r [ previous-window # select previous window 94 | bind -r ] next-window # select next window 95 | bind Tab last-window # move to last active window 96 | 97 | # toggle mouse 98 | bind m run "cut -c3- ~/.tmux.conf | sh -s _toggle_mouse" 99 | 100 | 101 | # -- urlview ------------------------------------------------------------------- 102 | 103 | bind U run "cut -c3- ~/.tmux.conf | sh -s _urlview #{pane_id}" 104 | 105 | 106 | # -- facebook pathpicker ------------------------------------------------------- 107 | 108 | bind F run "cut -c3- ~/.tmux.conf | sh -s _fpp #{pane_id}" 109 | 110 | 111 | # -- list choice (tmux < 2.4) -------------------------------------------------- 112 | 113 | # vi-choice is gone in tmux >= 2.4 114 | run -b 'tmux bind -t vi-choice h tree-collapse 2> /dev/null || true' 115 | run -b 'tmux bind -t vi-choice l tree-expand 2> /dev/null || true' 116 | run -b 'tmux bind -t vi-choice K start-of-list 2> /dev/null || true' 117 | run -b 'tmux bind -t vi-choice J end-of-list 2> /dev/null || true' 118 | run -b 'tmux bind -t vi-choice H tree-collapse-all 2> /dev/null || true' 119 | run -b 'tmux bind -t vi-choice L tree-expand-all 2> /dev/null || true' 120 | run -b 'tmux bind -t vi-choice Escape cancel 2> /dev/null || true' 121 | 122 | 123 | # -- edit mode (tmux < 2.4) ---------------------------------------------------- 124 | 125 | # vi-edit is gone in tmux >= 2.4 126 | run -b 'tmux bind -ct vi-edit H start-of-line 2> /dev/null || true' 127 | run -b 'tmux bind -ct vi-edit L end-of-line 2> /dev/null || true' 128 | run -b 'tmux bind -ct vi-edit q cancel 2> /dev/null || true' 129 | run -b 'tmux bind -ct vi-edit Escape cancel 2> /dev/null || true' 130 | 131 | 132 | # -- copy mode ----------------------------------------------------------------- 133 | 134 | bind Enter copy-mode # enter copy mode 135 | 136 | run -b 'tmux bind -t vi-copy v begin-selection 2> /dev/null || true' 137 | run -b 'tmux bind -T copy-mode-vi v send -X begin-selection 2> /dev/null || true' 138 | run -b 'tmux bind -t vi-copy C-v rectangle-toggle 2> /dev/null || true' 139 | run -b 'tmux bind -T copy-mode-vi C-v send -X rectangle-toggle 2> /dev/null || true' 140 | run -b 'tmux bind -t vi-copy y copy-selection 2> /dev/null || true' 141 | run -b 'tmux bind -T copy-mode-vi y send -X copy-selection-and-cancel 2> /dev/null || true' 142 | run -b 'tmux bind -t vi-copy Escape cancel 2> /dev/null || true' 143 | run -b 'tmux bind -T copy-mode-vi Escape send -X cancel 2> /dev/null || true' 144 | run -b 'tmux bind -t vi-copy H start-of-line 2> /dev/null || true' 145 | run -b 'tmux bind -T copy-mode-vi H send -X start-of-line 2> /dev/null || true' 146 | run -b 'tmux bind -t vi-copy L end-of-line 2> /dev/null || true' 147 | run -b 'tmux bind -T copy-mode-vi L send -X end-of-line 2> /dev/null || true' 148 | 149 | # copy to Mac OSX clipboard 150 | if -b 'command -v reattach-to-user-namespace > /dev/null 2>&1' 'bind y run -b "tmux save-buffer - | reattach-to-user-namespace pbcopy"' 151 | # copy to X11 clipboard 152 | if -b 'command -v xsel > /dev/null 2>&1' 'bind y run -b "tmux save-buffer - | xsel -i -b"' 153 | if -b '! command -v xsel > /dev/null 2>&1 && command -v xclip > /dev/null 2>&1' 'bind y run -b "tmux save-buffer - | xclip -i -selection clipboard >/dev/null 2>&1"' 154 | # copy to Windows clipboard 155 | if -b 'command -v clip.exe > /dev/null 2>&1' 'bind y run -b "tmux save-buffer - | clip.exe"' 156 | if -b '[ -c /dev/clipboard ]' 'bind y run -b "tmux save-buffer - > /dev/clipboard"' 157 | 158 | 159 | # -- buffers ------------------------------------------------------------------- 160 | 161 | bind b list-buffers # list paste buffers 162 | bind p paste-buffer # paste from the top paste buffer 163 | bind P choose-buffer # choose which buffer to paste from 164 | 165 | # -- 8< ------------------------------------------------------------------------ 166 | 167 | run 'cut -c3- ~/.tmux.conf | sh -s _apply_configuration' 168 | 169 | # -- plugins 170 | set -g @plugin "arcticicestudio/nord-tmux" 171 | set -g @plugin 'tmux-plugins/tmux-resurrect' 172 | 173 | # -- plugin: nord 174 | set -g @nord_tmux_no_patched_font "1" 175 | 176 | # -- run tpm 177 | run '~/.tmux/plugins/tpm/tpm' 178 | -------------------------------------------------------------------------------- /rc/config/alacritty/alacritty.toml: -------------------------------------------------------------------------------- 1 | 2 | [bell] 3 | animation = "EaseOutExpo" 4 | color = "0xffffff" 5 | duration = 0 6 | 7 | [colors] 8 | draw_bold_text_with_bright_colors = true 9 | indexed_colors = [] 10 | 11 | [colors.bright] 12 | black = "#4c566a" 13 | blue = "#81a1c1" 14 | cyan = "#8fbcbb" 15 | green = "#a3be8c" 16 | magenta = "#b48ead" 17 | red = "#bf616a" 18 | white = "#eceff4" 19 | yellow = "#ebcb8b" 20 | 21 | [colors.cursor] 22 | cursor = "#d8dee9" 23 | text = "#2e3440" 24 | 25 | [colors.dim] 26 | black = "#373e4d" 27 | blue = "#68809a" 28 | cyan = "#6d96a5" 29 | green = "#809575" 30 | magenta = "#8c738c" 31 | red = "#94545d" 32 | white = "#aeb3bb" 33 | yellow = "#b29e75" 34 | 35 | [colors.normal] 36 | black = "#3b4252" 37 | blue = "#81a1c1" 38 | cyan = "#88c0d0" 39 | green = "#a3be8c" 40 | magenta = "#b48ead" 41 | red = "#bf616a" 42 | white = "#e5e9f0" 43 | yellow = "#ebcb8b" 44 | 45 | [colors.primary] 46 | background = "#2e3440" 47 | dim_foreground = "#a5abb6" 48 | foreground = "#d8dee9" 49 | 50 | [colors.footer_bar] 51 | background = "#434c5e" 52 | foreground = "#d8dee9" 53 | 54 | [colors.search.matches] 55 | background = "#88c0d0" 56 | foreground = "CellBackground" 57 | 58 | [colors.selection] 59 | background = "#4c566a" 60 | text = "CellForeground" 61 | 62 | [colors.vi_mode_cursor] 63 | cursor = "#d8dee9" 64 | text = "#2e3440" 65 | 66 | [cursor] 67 | style = "Block" 68 | unfocused_hollow = true 69 | 70 | [debug] 71 | log_level = "Warn" 72 | persistent_logging = false 73 | print_events = false 74 | # ref_test = false 75 | render_timer = false 76 | 77 | [env] 78 | TERM = "xterm-256color" 79 | 80 | [font] 81 | size = 14.4 82 | 83 | [font.bold] 84 | family = "Iosevka Nerd Font" 85 | style = "Bold" 86 | 87 | [font.glyph_offset] 88 | x = 0 89 | y = 0 90 | 91 | [font.italic] 92 | family = "Iosevka Nerd Font" 93 | style = "Italic" 94 | 95 | [font.normal] 96 | family = "Iosevka Nerd Font" 97 | style = "Regular" 98 | 99 | [font.offset] 100 | x = 0 101 | y = 0 102 | 103 | [[keyboard.bindings]] 104 | action = "ResetFontSize" 105 | key = "Key0" 106 | mods = "Command" 107 | 108 | [[keyboard.bindings]] 109 | action = "IncreaseFontSize" 110 | key = "Equals" 111 | mods = "Command" 112 | 113 | [[keyboard.bindings]] 114 | action = "DecreaseFontSize" 115 | key = "Minus" 116 | mods = "Command" 117 | 118 | [[keyboard.bindings]] 119 | action = "ToggleFullscreen" 120 | key = "F" 121 | mods = "Command|Control" 122 | 123 | [[keyboard.bindings]] 124 | chars = "$EDITOR ~/.config/alacritty/alacritty.toml\r" 125 | key = "Comma" 126 | mods = "Command" 127 | 128 | [[keyboard.bindings]] 129 | action = "Paste" 130 | key = "Paste" 131 | 132 | [[keyboard.bindings]] 133 | action = "Copy" 134 | key = "Copy" 135 | 136 | [[keyboard.bindings]] 137 | action = "ClearLogNotice" 138 | key = "L" 139 | mods = "Control" 140 | 141 | [[keyboard.bindings]] 142 | chars = "\f" 143 | key = "L" 144 | mods = "Control" 145 | 146 | [[keyboard.bindings]] 147 | chars = "\u001B[1;3H" 148 | key = "Home" 149 | mods = "Alt" 150 | 151 | [[keyboard.bindings]] 152 | chars = "\u001BOH" 153 | key = "Home" 154 | mode = "AppCursor" 155 | 156 | [[keyboard.bindings]] 157 | chars = "\u001B[H" 158 | key = "Home" 159 | mode = "~AppCursor" 160 | 161 | [[keyboard.bindings]] 162 | chars = "\u001B[1;3F" 163 | key = "End" 164 | mods = "Alt" 165 | 166 | [[keyboard.bindings]] 167 | chars = "\u001BOF" 168 | key = "End" 169 | mode = "AppCursor" 170 | 171 | [[keyboard.bindings]] 172 | chars = "\u001B[F" 173 | key = "End" 174 | mode = "~AppCursor" 175 | 176 | [[keyboard.bindings]] 177 | action = "ScrollPageUp" 178 | key = "PageUp" 179 | mode = "~Alt" 180 | mods = "Shift" 181 | 182 | [[keyboard.bindings]] 183 | chars = "\u001B[5;2~" 184 | key = "PageUp" 185 | mode = "Alt" 186 | mods = "Shift" 187 | 188 | [[keyboard.bindings]] 189 | chars = "\u001B[5;5~" 190 | key = "PageUp" 191 | mods = "Control" 192 | 193 | [[keyboard.bindings]] 194 | chars = "\u001B[5;3~" 195 | key = "PageUp" 196 | mods = "Alt" 197 | 198 | [[keyboard.bindings]] 199 | chars = "\u001B[5~" 200 | key = "PageUp" 201 | 202 | [[keyboard.bindings]] 203 | action = "ScrollPageDown" 204 | key = "PageDown" 205 | mode = "~Alt" 206 | mods = "Shift" 207 | 208 | [[keyboard.bindings]] 209 | chars = "\u001B[6;2~" 210 | key = "PageDown" 211 | mode = "Alt" 212 | mods = "Shift" 213 | 214 | [[keyboard.bindings]] 215 | chars = "\u001B[6;5~" 216 | key = "PageDown" 217 | mods = "Control" 218 | 219 | [[keyboard.bindings]] 220 | chars = "\u001B[6;3~" 221 | key = "PageDown" 222 | mods = "Alt" 223 | 224 | [[keyboard.bindings]] 225 | chars = "\u001B[6~" 226 | key = "PageDown" 227 | 228 | [[keyboard.bindings]] 229 | chars = "\u001B[Z" 230 | key = "Tab" 231 | mods = "Shift" 232 | 233 | [[keyboard.bindings]] 234 | chars = "\u007F" 235 | key = "Back" 236 | 237 | [[keyboard.bindings]] 238 | chars = "\u001B\u007F" 239 | key = "Back" 240 | mods = "Alt" 241 | 242 | [[keyboard.bindings]] 243 | chars = "\u001B[2~" 244 | key = "Insert" 245 | 246 | [[keyboard.bindings]] 247 | chars = "\u001B[3~" 248 | key = "Delete" 249 | 250 | [[keyboard.bindings]] 251 | chars = "\u001B[1;2D" 252 | key = "Left" 253 | mods = "Shift" 254 | 255 | [[keyboard.bindings]] 256 | chars = "\u001B[1;5D" 257 | key = "Left" 258 | mods = "Control" 259 | 260 | [[keyboard.bindings]] 261 | chars = "\u001Bb" 262 | key = "Left" 263 | mods = "Alt" 264 | 265 | [[keyboard.bindings]] 266 | chars = "\u001Bf" 267 | key = "Right" 268 | mods = "Alt" 269 | 270 | [[keyboard.bindings]] 271 | chars = "\u001Bb" 272 | key = "B" 273 | mods = "Alt" 274 | 275 | [[keyboard.bindings]] 276 | chars = "\u001Bf" 277 | key = "F" 278 | mods = "Alt" 279 | 280 | [[keyboard.bindings]] 281 | chars = "\u001Bd" 282 | key = "D" 283 | mods = "Alt" 284 | 285 | [[keyboard.bindings]] 286 | chars = "\u001B[D" 287 | key = "Left" 288 | mode = "~AppCursor" 289 | 290 | [[keyboard.bindings]] 291 | chars = "\u001BOD" 292 | key = "Left" 293 | mode = "AppCursor" 294 | 295 | [[keyboard.bindings]] 296 | chars = "\u001B[1;2C" 297 | key = "Right" 298 | mods = "Shift" 299 | 300 | [[keyboard.bindings]] 301 | chars = "\u001B[1;5C" 302 | key = "Right" 303 | mods = "Control" 304 | 305 | [[keyboard.bindings]] 306 | chars = "\u001Bf" 307 | key = "Right" 308 | mods = "Alt" 309 | 310 | [[keyboard.bindings]] 311 | chars = "\u001B[C" 312 | key = "Right" 313 | mode = "~AppCursor" 314 | 315 | [[keyboard.bindings]] 316 | chars = "\u001BOC" 317 | key = "Right" 318 | mode = "AppCursor" 319 | 320 | [[keyboard.bindings]] 321 | chars = "\u001B[1;2A" 322 | key = "Up" 323 | mods = "Shift" 324 | 325 | [[keyboard.bindings]] 326 | chars = "\u001B[1;5A" 327 | key = "Up" 328 | mods = "Control" 329 | 330 | [[keyboard.bindings]] 331 | chars = "\u001B[1;3A" 332 | key = "Up" 333 | mods = "Alt" 334 | 335 | [[keyboard.bindings]] 336 | chars = "\u001B[A" 337 | key = "Up" 338 | mode = "~AppCursor" 339 | 340 | [[keyboard.bindings]] 341 | chars = "\u001BOA" 342 | key = "Up" 343 | mode = "AppCursor" 344 | 345 | [[keyboard.bindings]] 346 | chars = "\u001B[1;2B" 347 | key = "Down" 348 | mods = "Shift" 349 | 350 | [[keyboard.bindings]] 351 | chars = "\u001B[1;5B" 352 | key = "Down" 353 | mods = "Control" 354 | 355 | [[keyboard.bindings]] 356 | chars = "\u001B[1;3B" 357 | key = "Down" 358 | mods = "Alt" 359 | 360 | [[keyboard.bindings]] 361 | chars = "\u001B[B" 362 | key = "Down" 363 | mode = "~AppCursor" 364 | 365 | [[keyboard.bindings]] 366 | chars = "\u001BOB" 367 | key = "Down" 368 | mode = "AppCursor" 369 | 370 | [mouse] 371 | hide_when_typing = false 372 | 373 | [[mouse.bindings]] 374 | action = "PasteSelection" 375 | mouse = "Middle" 376 | 377 | [scrolling] 378 | history = 10000 379 | multiplier = 3 380 | 381 | [selection] 382 | save_to_clipboard = false 383 | semantic_escape_chars = ",│`|:\"' ()[]{}<>" 384 | 385 | [window] 386 | decorations = "buttonless" 387 | dynamic_padding = false 388 | dynamic_title = true 389 | opacity = 0.95 390 | option_as_alt = "OnlyLeft" 391 | startup_mode = "Windowed" 392 | 393 | [window.dimensions] 394 | columns = 240 395 | lines = 80 396 | 397 | [window.padding] 398 | x = 12 399 | y = 12 400 | 401 | [general] 402 | live_config_reload = true 403 | working_directory = "None" 404 | -------------------------------------------------------------------------------- /rc/config/karabiner/karabiner.json: -------------------------------------------------------------------------------- 1 | { 2 | "global": { 3 | "ask_for_confirmation_before_quitting": true, 4 | "check_for_updates_on_startup": false, 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": 100, 16 | "basic.to_if_held_down_threshold_milliseconds": 500, 17 | "mouse_motion_to_scroll.speed": 100 18 | }, 19 | "rules": [ 20 | { 21 | "description": "Change shift + delete to forward delete (rev 2)", 22 | "manipulators": [ 23 | { 24 | "from": { 25 | "key_code": "delete_or_backspace", 26 | "modifiers": { 27 | "mandatory": [ 28 | "shift" 29 | ], 30 | "optional": [ 31 | "caps_lock", 32 | "option" 33 | ] 34 | } 35 | }, 36 | "to": [ 37 | { 38 | "key_code": "delete_forward" 39 | } 40 | ], 41 | "type": "basic" 42 | } 43 | ] 44 | }, 45 | { 46 | "description": "Command + Esc to Command + `", 47 | "manipulators": [ 48 | { 49 | "from": { 50 | "key_code": "escape", 51 | "modifiers": { 52 | "mandatory": [ 53 | "left_command" 54 | ] 55 | } 56 | }, 57 | "to": [ 58 | { 59 | "key_code": "grave_accent_and_tilde", 60 | "modifiers": [ 61 | "left_command" 62 | ] 63 | } 64 | ], 65 | "type": "basic" 66 | } 67 | ] 68 | }, 69 | { 70 | "description": "Shift + Esc to Shift + `", 71 | "manipulators": [ 72 | { 73 | "from": { 74 | "key_code": "escape", 75 | "modifiers": { 76 | "mandatory": [ 77 | "left_shift" 78 | ] 79 | } 80 | }, 81 | "to": [ 82 | { 83 | "key_code": "grave_accent_and_tilde", 84 | "modifiers": [ 85 | "left_shift" 86 | ] 87 | } 88 | ], 89 | "type": "basic" 90 | } 91 | ] 92 | }, 93 | { 94 | "description": "Option + Esc to `", 95 | "manipulators": [ 96 | { 97 | "from": { 98 | "key_code": "escape", 99 | "modifiers": { 100 | "mandatory": [ 101 | "left_option" 102 | ] 103 | } 104 | }, 105 | "to": [ 106 | { 107 | "key_code": "grave_accent_and_tilde" 108 | } 109 | ], 110 | "type": "basic" 111 | } 112 | ] 113 | }, 114 | { 115 | "description": "Fn + Up Arrow to Vol+", 116 | "manipulators": [ 117 | { 118 | "from": { 119 | "key_code": "up_arrow", 120 | "modifiers": { 121 | "mandatory": [ 122 | "fn" 123 | ] 124 | } 125 | }, 126 | "to": [ 127 | { 128 | "key_code": "volume_increment" 129 | } 130 | ], 131 | "type": "basic" 132 | } 133 | ] 134 | }, 135 | { 136 | "description": "Fn + Down Arrow to Vol-", 137 | "manipulators": [ 138 | { 139 | "from": { 140 | "key_code": "down_arrow", 141 | "modifiers": { 142 | "mandatory": [ 143 | "fn" 144 | ] 145 | } 146 | }, 147 | "to": [ 148 | { 149 | "key_code": "volume_decrement" 150 | } 151 | ], 152 | "type": "basic" 153 | } 154 | ] 155 | }, 156 | { 157 | "description": "Fn + Left Arrow to Brightness-", 158 | "manipulators": [ 159 | { 160 | "from": { 161 | "key_code": "left_arrow", 162 | "modifiers": { 163 | "mandatory": [ 164 | "fn" 165 | ] 166 | } 167 | }, 168 | "to": [ 169 | { 170 | "key_code": "display_brightness_decrement" 171 | } 172 | ], 173 | "type": "basic" 174 | } 175 | ] 176 | }, 177 | { 178 | "description": "Fn + Right Arrow to Brightness+", 179 | "manipulators": [ 180 | { 181 | "from": { 182 | "key_code": "right_arrow", 183 | "modifiers": { 184 | "mandatory": [ 185 | "fn" 186 | ] 187 | } 188 | }, 189 | "to": [ 190 | { 191 | "key_code": "display_brightness_increment" 192 | } 193 | ], 194 | "type": "basic" 195 | } 196 | ] 197 | } 198 | ] 199 | }, 200 | "devices": [ 201 | { 202 | "disable_built_in_keyboard_if_exists": true, 203 | "fn_function_keys": [], 204 | "identifiers": { 205 | "is_keyboard": true, 206 | "is_pointing_device": false, 207 | "product_id": 256, 208 | "vendor_id": 2131 209 | }, 210 | "ignore": false, 211 | "manipulate_caps_lock_led": false, 212 | "simple_modifications": [ 213 | { 214 | "from": { 215 | "key_code": "backslash" 216 | }, 217 | "to": [ 218 | { 219 | "key_code": "grave_accent_and_tilde" 220 | } 221 | ] 222 | }, 223 | { 224 | "from": { 225 | "key_code": "delete_or_backspace" 226 | }, 227 | "to": [ 228 | { 229 | "key_code": "backslash" 230 | } 231 | ] 232 | }, 233 | { 234 | "from": { 235 | "key_code": "grave_accent_and_tilde" 236 | }, 237 | "to": [ 238 | { 239 | "key_code": "delete_or_backspace" 240 | } 241 | ] 242 | }, 243 | { 244 | "from": { 245 | "key_code": "left_control" 246 | }, 247 | "to": [ 248 | { 249 | "key_code": "left_option" 250 | } 251 | ] 252 | }, 253 | { 254 | "from": { 255 | "key_code": "left_option" 256 | }, 257 | "to": [ 258 | { 259 | "key_code": "left_control" 260 | } 261 | ] 262 | }, 263 | { 264 | "from": { 265 | "key_code": "right_option" 266 | }, 267 | "to": [ 268 | { 269 | "key_code": "escape" 270 | } 271 | ] 272 | } 273 | ], 274 | "treat_as_built_in_keyboard": false 275 | }, 276 | { 277 | "disable_built_in_keyboard_if_exists": false, 278 | "fn_function_keys": [], 279 | "identifiers": { 280 | "is_keyboard": true, 281 | "is_pointing_device": false, 282 | "product_id": 636, 283 | "vendor_id": 1452 284 | }, 285 | "ignore": false, 286 | "manipulate_caps_lock_led": true, 287 | "simple_modifications": [], 288 | "treat_as_built_in_keyboard": false 289 | }, 290 | { 291 | "disable_built_in_keyboard_if_exists": false, 292 | "fn_function_keys": [], 293 | "identifiers": { 294 | "is_keyboard": true, 295 | "is_pointing_device": false, 296 | "product_id": 641, 297 | "vendor_id": 1452 298 | }, 299 | "ignore": false, 300 | "manipulate_caps_lock_led": true, 301 | "simple_modifications": [], 302 | "treat_as_built_in_keyboard": false 303 | }, 304 | { 305 | "disable_built_in_keyboard_if_exists": false, 306 | "fn_function_keys": [], 307 | "identifiers": { 308 | "is_keyboard": true, 309 | "is_pointing_device": false, 310 | "product_id": 833, 311 | "vendor_id": 1452 312 | }, 313 | "ignore": false, 314 | "manipulate_caps_lock_led": true, 315 | "simple_modifications": [], 316 | "treat_as_built_in_keyboard": false 317 | }, 318 | { 319 | "disable_built_in_keyboard_if_exists": false, 320 | "fn_function_keys": [], 321 | "identifiers": { 322 | "is_keyboard": false, 323 | "is_pointing_device": true, 324 | "product_id": 833, 325 | "vendor_id": 1452 326 | }, 327 | "ignore": true, 328 | "manipulate_caps_lock_led": false, 329 | "simple_modifications": [], 330 | "treat_as_built_in_keyboard": false 331 | }, 332 | { 333 | "disable_built_in_keyboard_if_exists": false, 334 | "fn_function_keys": [], 335 | "identifiers": { 336 | "is_keyboard": true, 337 | "is_pointing_device": true, 338 | "product_id": 17031, 339 | "vendor_id": 16969 340 | }, 341 | "ignore": true, 342 | "manipulate_caps_lock_led": true, 343 | "simple_modifications": [], 344 | "treat_as_built_in_keyboard": false 345 | }, 346 | { 347 | "disable_built_in_keyboard_if_exists": false, 348 | "fn_function_keys": [], 349 | "identifiers": { 350 | "is_keyboard": true, 351 | "is_pointing_device": false, 352 | "product_id": 17031, 353 | "vendor_id": 16969 354 | }, 355 | "ignore": false, 356 | "manipulate_caps_lock_led": true, 357 | "simple_modifications": [], 358 | "treat_as_built_in_keyboard": false 359 | }, 360 | { 361 | "disable_built_in_keyboard_if_exists": false, 362 | "fn_function_keys": [], 363 | "identifiers": { 364 | "is_keyboard": false, 365 | "is_pointing_device": true, 366 | "product_id": 613, 367 | "vendor_id": 76 368 | }, 369 | "ignore": true, 370 | "manipulate_caps_lock_led": false, 371 | "simple_modifications": [], 372 | "treat_as_built_in_keyboard": false 373 | }, 374 | { 375 | "disable_built_in_keyboard_if_exists": false, 376 | "fn_function_keys": [], 377 | "identifiers": { 378 | "is_keyboard": true, 379 | "is_pointing_device": false, 380 | "product_id": 34304, 381 | "vendor_id": 1452 382 | }, 383 | "ignore": false, 384 | "manipulate_caps_lock_led": true, 385 | "simple_modifications": [], 386 | "treat_as_built_in_keyboard": false 387 | }, 388 | { 389 | "disable_built_in_keyboard_if_exists": false, 390 | "fn_function_keys": [], 391 | "identifiers": { 392 | "is_keyboard": true, 393 | "is_pointing_device": true, 394 | "product_id": 21, 395 | "vendor_id": 41219 396 | }, 397 | "ignore": true, 398 | "manipulate_caps_lock_led": true, 399 | "simple_modifications": [], 400 | "treat_as_built_in_keyboard": false 401 | }, 402 | { 403 | "disable_built_in_keyboard_if_exists": false, 404 | "fn_function_keys": [], 405 | "identifiers": { 406 | "is_keyboard": true, 407 | "is_pointing_device": false, 408 | "product_id": 21, 409 | "vendor_id": 41219 410 | }, 411 | "ignore": false, 412 | "manipulate_caps_lock_led": true, 413 | "simple_modifications": [], 414 | "treat_as_built_in_keyboard": false 415 | } 416 | ], 417 | "fn_function_keys": [ 418 | { 419 | "from": { 420 | "key_code": "f1" 421 | }, 422 | "to": [ 423 | { 424 | "consumer_key_code": "display_brightness_decrement" 425 | } 426 | ] 427 | }, 428 | { 429 | "from": { 430 | "key_code": "f2" 431 | }, 432 | "to": [ 433 | { 434 | "consumer_key_code": "display_brightness_increment" 435 | } 436 | ] 437 | }, 438 | { 439 | "from": { 440 | "key_code": "f3" 441 | }, 442 | "to": [ 443 | { 444 | "key_code": "mission_control" 445 | } 446 | ] 447 | }, 448 | { 449 | "from": { 450 | "key_code": "f4" 451 | }, 452 | "to": [ 453 | { 454 | "key_code": "launchpad" 455 | } 456 | ] 457 | }, 458 | { 459 | "from": { 460 | "key_code": "f5" 461 | }, 462 | "to": [ 463 | { 464 | "key_code": "illumination_decrement" 465 | } 466 | ] 467 | }, 468 | { 469 | "from": { 470 | "key_code": "f6" 471 | }, 472 | "to": [ 473 | { 474 | "key_code": "illumination_increment" 475 | } 476 | ] 477 | }, 478 | { 479 | "from": { 480 | "key_code": "f7" 481 | }, 482 | "to": [ 483 | { 484 | "consumer_key_code": "rewind" 485 | } 486 | ] 487 | }, 488 | { 489 | "from": { 490 | "key_code": "f8" 491 | }, 492 | "to": [ 493 | { 494 | "consumer_key_code": "play_or_pause" 495 | } 496 | ] 497 | }, 498 | { 499 | "from": { 500 | "key_code": "f9" 501 | }, 502 | "to": [ 503 | { 504 | "consumer_key_code": "fastforward" 505 | } 506 | ] 507 | }, 508 | { 509 | "from": { 510 | "key_code": "f10" 511 | }, 512 | "to": [ 513 | { 514 | "consumer_key_code": "mute" 515 | } 516 | ] 517 | }, 518 | { 519 | "from": { 520 | "key_code": "f11" 521 | }, 522 | "to": [ 523 | { 524 | "consumer_key_code": "volume_decrement" 525 | } 526 | ] 527 | }, 528 | { 529 | "from": { 530 | "key_code": "f12" 531 | }, 532 | "to": [ 533 | { 534 | "consumer_key_code": "volume_increment" 535 | } 536 | ] 537 | } 538 | ], 539 | "name": "David", 540 | "parameters": { 541 | "delay_milliseconds_before_open_device": 1000 542 | }, 543 | "selected": true, 544 | "simple_modifications": [], 545 | "virtual_hid_keyboard": { 546 | "country_code": 0, 547 | "indicate_sticky_modifier_keys_state": true, 548 | "mouse_key_xy_scale": 100 549 | } 550 | } 551 | ] 552 | } 553 | --------------------------------------------------------------------------------