Add configuration for vim
- Add ~/.config/vim/vimrc
+ Configure basic stuff
+ Activate spell checks
+ Activate syntax highlighting and ruler
+ Show whitespace characters
+ Add various snippets for mouse handling,
toggling line numbers, and search
+ Set `vim`-related directories inside
~/.config/vim and ~/.local/state/vim
- Integrate extra settings for Python files
in ~/.config/vim/after/ftplugin/python.vim
- Add `vim` artifacts in ~/.config/git/ignore
This commit is contained in:
parent
4d4da8263c
commit
a26c6e0263
9 changed files with 447 additions and 0 deletions
|
|
@ -4,3 +4,24 @@
|
|||
*.orig
|
||||
*.temp
|
||||
*.tmp
|
||||
|
||||
# Vim
|
||||
# Source: https://github.com/github/gitignore/blob/main/Global/Vim.gitignore
|
||||
#
|
||||
# Swap
|
||||
[._]*.s[a-v][a-z]
|
||||
!*.svg
|
||||
[._]*.sw[a-p]
|
||||
[._]s[a-rt-v][a-z]
|
||||
[._]ss[a-gi-z]
|
||||
[._]sw[a-p]
|
||||
# Session
|
||||
Session.vim
|
||||
Sessionx.vim
|
||||
# Temporary
|
||||
.netrwhist
|
||||
*~
|
||||
# Auto-generated tag files
|
||||
tags
|
||||
# Persistent undo
|
||||
[._]*.un~
|
||||
|
|
|
|||
|
|
@ -22,11 +22,14 @@ export DOTFILES_DIR="$XDG_DATA_HOME/dotfiles" # also set in ~/.local/bin/instal
|
|||
|
||||
# Generic shell configs
|
||||
|
||||
export EDITOR=vim
|
||||
export GPG_TTY=$(tty)
|
||||
export PAGER="less --chop-long-lines --ignore-case --LONG-PROMPT --no-init --status-column --quit-if-one-screen"
|
||||
export TZ="Europe/Berlin"
|
||||
export VISUAL=$EDITOR
|
||||
|
||||
|
||||
# Move common tools' config and cache files into XDG directories
|
||||
|
||||
export LESSHISTFILE="$XDG_STATE_HOME/less/history"
|
||||
export VIMINIT='let $MYVIMRC="'"$XDG_CONFIG_HOME"'/vim/vimrc" | source $MYVIMRC'
|
||||
|
|
|
|||
91
.config/vim/after/ftplugin/python.vim
Normal file
91
.config/vim/after/ftplugin/python.vim
Normal file
|
|
@ -0,0 +1,91 @@
|
|||
" Set the search path to the folder of the current file and its sub-folders
|
||||
setlocal path=.,**
|
||||
|
||||
" Exclude Python's compiled files from searches
|
||||
setlocal wildignore=*/__pycache__/*,*.pyc
|
||||
|
||||
|
||||
" Resolve Python imports to files,
|
||||
" so that `gf` jumps to the module under the cursor
|
||||
"
|
||||
" Examples, with the cursor on the marked word:
|
||||
" - `from lalib.elements import galois` => lalib/elements/galois.py
|
||||
" - `from lalib.elements import ...` => lalib/elements/__init__.py
|
||||
" - `import lalib.config` => lalib/config.py
|
||||
"
|
||||
if !exists('*s:PyGoToFile')
|
||||
|
||||
" Build the dotted module path for the word under the cursor
|
||||
function! s:PyModuleUnderCursor()
|
||||
let l:word = expand('<cword>')
|
||||
let l:from = matchstr(getline('.'), '^\s*from\s\+\zs[A-Za-z0-9_.]\+')
|
||||
let l:imp = matchstr(getline('.'), '^\s*import\s\+\zs[A-Za-z0-9_.]\+')
|
||||
let l:base = !empty(l:from) ? l:from : l:imp
|
||||
if empty(l:base)
|
||||
return ''
|
||||
endif
|
||||
let l:parts = split(l:base, '\.')
|
||||
let l:idx = index(l:parts, l:word)
|
||||
if l:idx >= 0 " Cursor within the dotted prefix => Truncate there
|
||||
return join(l:parts[0:l:idx], '/')
|
||||
elseif !empty(l:from) " Cursor on an imported name => Append it
|
||||
return join(l:parts, '/') . '/' . l:word
|
||||
endif
|
||||
return ''
|
||||
endfunction
|
||||
|
||||
function! s:PyFindFile(mod)
|
||||
for l:candidate in [a:mod . '.py', a:mod . '/__init__.py']
|
||||
let l:found = findfile(l:candidate) " search the `path`
|
||||
if !empty(l:found)
|
||||
return l:found
|
||||
endif
|
||||
endfor
|
||||
return ''
|
||||
endfunction
|
||||
|
||||
function! s:PyGoToFile()
|
||||
let l:mod = s:PyModuleUnderCursor()
|
||||
let l:file = empty(l:mod) ? '' : s:PyFindFile(l:mod)
|
||||
if empty(l:file)
|
||||
echohl ErrorMsg | echo 'No module file for: ' . l:mod | echohl NONE
|
||||
return
|
||||
endif
|
||||
execute 'edit ' . fnameescape(l:file)
|
||||
endfunction
|
||||
|
||||
endif
|
||||
|
||||
" <c-o> jumps back
|
||||
nnoremap <buffer><silent> gf :call <SID>PyGoToFile()<cr>
|
||||
|
||||
" Find `def`s and `class`es with [d and [D
|
||||
setlocal define=^\\s*\\<\\(def\\|class\\)\\>
|
||||
|
||||
|
||||
" Indentation settings come from ~/.config/vim/vimrc, and
|
||||
" `smartindent` is left off as it interferes with VIM's Python indent script
|
||||
|
||||
|
||||
" Auto-wrap lines after 88 characters, which is PEP8's limit plus 10%,
|
||||
" a more relaxed boundary which occasionally may be used
|
||||
setlocal textwidth=88
|
||||
|
||||
|
||||
" Make column 80 red to indicate PEP8's maximum allowed line length
|
||||
setlocal colorcolumn=80
|
||||
|
||||
" Additionally, give every character beyond 80 columns a red background
|
||||
" (matches are window-local, so re-apply them per buffer)
|
||||
highlight ColorColumn ctermbg=DarkRed
|
||||
augroup python_overlength
|
||||
autocmd! * <buffer>
|
||||
autocmd BufEnter <buffer> call matchadd('ErrorMsg', '\%>80v.\+', 100)
|
||||
autocmd BufLeave <buffer> call clearmatches()
|
||||
augroup END
|
||||
call matchadd('ErrorMsg', '\%>80v.\+', 100)
|
||||
|
||||
|
||||
" Show line numbers by default for .py files
|
||||
let g:show_numbers=1
|
||||
call ShowLineNumbers()
|
||||
0
.config/vim/spell/.gitkeep
Normal file
0
.config/vim/spell/.gitkeep
Normal file
318
.config/vim/vimrc
Normal file
318
.config/vim/vimrc
Normal file
|
|
@ -0,0 +1,318 @@
|
|||
" Use VIM improved mode
|
||||
set nocompatible
|
||||
|
||||
|
||||
" Disable VIM's startup message
|
||||
set shortmess+=I
|
||||
|
||||
" Number of remembered undo steps
|
||||
set undolevels=1000
|
||||
|
||||
|
||||
set runtimepath^=$XDG_CONFIG_HOME/vim
|
||||
set runtimepath+=$XDG_CONFIG_HOME/vim/after
|
||||
|
||||
" Set environment variables for convenient usage
|
||||
let $RC = expand('$XDG_CONFIG_HOME/vim/vimrc')
|
||||
let $RTP=split(&runtimepath, ',')[0]
|
||||
|
||||
|
||||
" Detect the file's type and load the corresponding plugin and indent files
|
||||
filetype plugin indent on
|
||||
|
||||
" Enable syntax highlighting
|
||||
syntax on
|
||||
|
||||
|
||||
" Configure tab behavior
|
||||
set expandtab " Insert spaces instead of tab characters
|
||||
set tabstop=4 " Width of an existing tab character
|
||||
set shiftwidth=4 " Width of one >> or << indent step
|
||||
set softtabstop=4 " Width inserted/removed by <tab> and <bs>
|
||||
set shiftround " Round indents to a multiple of shiftwidth
|
||||
set autoindent " Keep the previous line's indent on a new line
|
||||
vnoremap <tab> >gv
|
||||
vnoremap <s-tab> <gv
|
||||
|
||||
|
||||
" Allow backspace to delete characters in insert mode
|
||||
" beyond the start of the insertion and end of lines
|
||||
set backspace=start,eol,indent
|
||||
|
||||
|
||||
" Hide buffers instead of closing them, which means we can have
|
||||
" unwritten changes to a file and open a new one with :e,
|
||||
" without having to write the changes first
|
||||
set hidden
|
||||
|
||||
|
||||
" Set to the folder of the current file and its sub-folders
|
||||
" (this may need to be adapted for large project folders)
|
||||
set path=.,**
|
||||
|
||||
|
||||
" Store all vim-related working files in the ~/.local/state/vim folder
|
||||
set viminfo+=n$XDG_STATE_HOME/vim/viminfo
|
||||
" Use dedicated folders to store temporary backup, swap, and undo files
|
||||
" (the // means that VIM adapts names automatically to avoid duplicates)
|
||||
set backupdir=$XDG_STATE_HOME/vim/backup//
|
||||
set directory=$XDG_STATE_HOME/vim/swap//
|
||||
set undodir=$XDG_STATE_HOME/vim/undo//
|
||||
set undofile
|
||||
|
||||
" To disable any of the temporary files, uncomment one of the following
|
||||
" set nobackup
|
||||
" set nowritebackup
|
||||
" set noswapfile
|
||||
" set noundofile
|
||||
|
||||
|
||||
" Show the filename in the terminal window's title bar
|
||||
set title
|
||||
|
||||
|
||||
" Do not wrap lines when showing text
|
||||
set nowrap
|
||||
|
||||
" This avoids a problem of losing data upon insertion in old VIMs
|
||||
set wrapmargin=0
|
||||
|
||||
|
||||
" Show spelling mistakes in italics
|
||||
|
||||
augroup spelling
|
||||
autocmd!
|
||||
autocmd FileType markdown,text,gitcommit setlocal spell spelllang=en_us,de_de
|
||||
augroup END
|
||||
|
||||
augroup spell_highlight
|
||||
autocmd!
|
||||
autocmd ColorScheme * hi clear SpellBad | hi clear SpellCap
|
||||
\ | hi clear SpellRare | hi clear SpellLocal
|
||||
\ | hi SpellBad cterm=italic
|
||||
augroup END
|
||||
silent! doautocmd ColorScheme
|
||||
|
||||
|
||||
" Show whitespace characters
|
||||
set listchars=tab:»»,extends:›,precedes:‹,nbsp:·,trail:·
|
||||
set list
|
||||
|
||||
|
||||
" Highlight matching brackets
|
||||
set showmatch
|
||||
set matchpairs+=<:>
|
||||
|
||||
|
||||
" Always show the status bar at the bottom
|
||||
set laststatus=2
|
||||
|
||||
" Show current position in status bar
|
||||
set ruler
|
||||
set rulerformat=%=%l/%L\ %c\ (%P)
|
||||
|
||||
" Show commands in status bar
|
||||
set showcmd
|
||||
|
||||
" If in non-normal mode, show the mode in the status bar
|
||||
set showmode
|
||||
|
||||
" Show a dialog to save changes instead of an error message
|
||||
set confirm
|
||||
|
||||
" Auto-clear messages from the status bar
|
||||
augroup clear_messages
|
||||
autocmd!
|
||||
autocmd CursorHold * echo
|
||||
augroup END
|
||||
|
||||
|
||||
" Better copy and paste behavior (needs vim-gtk3 installed)
|
||||
if has('clipboard')
|
||||
set clipboard=unnamed,unnamedplus
|
||||
endif
|
||||
|
||||
|
||||
" Make : and ; synonyms
|
||||
nnoremap ; :
|
||||
|
||||
|
||||
" Use \ and <space> as the <leader> keys and lower time to enter key sequences
|
||||
let mapleader='\'
|
||||
set timeoutlen=750
|
||||
" Make <space> the <leader> in visual mode as well
|
||||
nmap <space> \
|
||||
vmap <space> \
|
||||
|
||||
|
||||
" Q normally goes into Ex mode
|
||||
nmap Q <Nop>
|
||||
|
||||
|
||||
" Get sudo rights when writing a buffer with w!!
|
||||
cnoremap w!! w !sudo tee % >/dev/null
|
||||
|
||||
|
||||
" Fix mouse issues with Alacritty terminal
|
||||
" Source: https://wiki.archlinux.org/title/Alacritty#Mouse_not_working_properly_in_Vim
|
||||
set ttymouse=sgr
|
||||
|
||||
|
||||
" Enable the mouse for selections, including a toggle for this mode
|
||||
set mouse=a
|
||||
let g:mouse_enabled=1
|
||||
function! ToggleMouse()
|
||||
if g:mouse_enabled == 1
|
||||
echo "Mouse OFF"
|
||||
set mouse=
|
||||
let g:mouse_enabled=0
|
||||
else
|
||||
echo "Mouse ON"
|
||||
set mouse=a
|
||||
let g:mouse_enabled=1
|
||||
endif
|
||||
endfunction
|
||||
noremap <silent><leader>m :call ToggleMouse()<cr>
|
||||
|
||||
|
||||
" Enable toggling between
|
||||
" - showing and hiding line numbers (<leader>l)
|
||||
" - absolute and relative numbers (<leader>a) in normal mode
|
||||
" (default: relative line numbering)
|
||||
let g:show_numbers=0
|
||||
let g:show_absolute_numbers=0
|
||||
function! ShowLineNumbers()
|
||||
if g:show_numbers == 1
|
||||
set number
|
||||
if g:show_absolute_numbers
|
||||
set norelativenumber
|
||||
else
|
||||
set relativenumber
|
||||
endif
|
||||
else
|
||||
set nonumber
|
||||
set norelativenumber
|
||||
endif
|
||||
endfunction
|
||||
function! ToggleLineNumbers()
|
||||
if g:show_numbers == 1
|
||||
let g:show_numbers=0
|
||||
else
|
||||
let g:show_numbers=1
|
||||
endif
|
||||
call ShowLineNumbers()
|
||||
endfunction
|
||||
function! ToggleAbsoluteAndRelativeLineNumbers()
|
||||
if g:show_absolute_numbers == 1
|
||||
let g:show_absolute_numbers=0
|
||||
else
|
||||
let g:show_absolute_numbers=1
|
||||
endif
|
||||
call ShowLineNumbers()
|
||||
endfunction
|
||||
" Auto-switch between absolute and relative numbering when switching modes
|
||||
" (insert mode always shows absolute numbers when numbers are shown)
|
||||
augroup numbertoggle
|
||||
autocmd!
|
||||
autocmd BufEnter,FocusGained,InsertLeave * call ShowLineNumbers()
|
||||
autocmd BufLeave,FocusLost,InsertEnter * if g:show_numbers == 1 | set number | set norelativenumber | endif
|
||||
augroup END
|
||||
" Key bindings
|
||||
nnoremap <silent><leader>l :call ToggleLineNumbers()<cr>
|
||||
nnoremap <silent><leader>a :call ToggleAbsoluteAndRelativeLineNumbers()<cr>
|
||||
|
||||
|
||||
" Show all possible matches above command-line when tab completing
|
||||
set wildmenu
|
||||
set wildmode=longest:full,full
|
||||
|
||||
|
||||
" Highlight search results
|
||||
set hlsearch
|
||||
|
||||
" Shortcut to remove current highlighting
|
||||
nnoremap <silent><leader>h :nohlsearch<cr>
|
||||
|
||||
" Move cursor to result while typing immediately
|
||||
set incsearch
|
||||
|
||||
" Ignore case when searching
|
||||
set ignorecase
|
||||
|
||||
" Upper case search term => case sensitive search
|
||||
set smartcase
|
||||
|
||||
" Highlight the next match in red for 0.25 seconds
|
||||
function! HighlightNext()
|
||||
let [bufnum, lnum, col, off] = getpos('.')
|
||||
let matchlen = strlen(matchstr(strpart(getline('.'),col-1),@/))
|
||||
let target_pat = '\c\%#\%('.@/.'\)'
|
||||
let ring = matchadd('ErrorMsg', target_pat, 101)
|
||||
redraw
|
||||
exec 'sleep ' . float2nr(250) . 'm'
|
||||
call matchdelete(ring)
|
||||
redraw
|
||||
endfunction
|
||||
nnoremap <silent>n n:call HighlightNext()<cr>
|
||||
nnoremap <silent>N N:call HighlightNext()<cr>
|
||||
|
||||
|
||||
" Make <leader>w save the buffer in normal mode
|
||||
" and <c-z> save the buffer in all modes
|
||||
" (the latter disables making VIM a background job;
|
||||
" <c-z> is useful to have as <leader>w does not work in INSERT mode)
|
||||
nnoremap <leader>w :update<cr>
|
||||
nnoremap <c-z> :update<cr>
|
||||
vnoremap <c-z> <c-c>:update<cr>
|
||||
inoremap <c-z> <c-o>:update<cr>
|
||||
|
||||
" <leader>q quits VIM
|
||||
nnoremap <leader>q :quit<cr>
|
||||
|
||||
" Easier switching between tabs
|
||||
noremap <leader>, <esc>:tabprevious<cr>
|
||||
noremap <leader>. <esc>:tabnext<cr>
|
||||
|
||||
" Arrow keys either (un)indent lines or move them up or down
|
||||
" (same for blocks of lines in visual mode)
|
||||
nnoremap <left> <<
|
||||
nnoremap <right> >>
|
||||
nnoremap <silent><up> :m-2<cr>
|
||||
nnoremap <silent><down> :m+<cr>
|
||||
vnoremap <left> <gv
|
||||
vnoremap <right> >gv
|
||||
vnoremap <up> :m'<-2<cr>gv=gv
|
||||
vnoremap <down> :m'>+1<cr>gv=gv
|
||||
|
||||
" Make Y yank the rest of a line, just like C or D work
|
||||
nnoremap Y y$
|
||||
|
||||
" Alphabetically sort a selection of lines
|
||||
vnoremap <leader>s :sort<cr>
|
||||
|
||||
" Switch two words, just like xp switches two characters
|
||||
nnoremap <leader>xp dwElp
|
||||
|
||||
|
||||
" Auto-reload a file that was changed by some other process
|
||||
" if the buffer has not yet been changed in the meantime
|
||||
set autoread
|
||||
set updatetime=1000
|
||||
augroup checktime
|
||||
autocmd!
|
||||
autocmd BufEnter * silent! checktime
|
||||
autocmd CursorHold * silent! checktime
|
||||
autocmd CursorHoldI * silent! checktime
|
||||
augroup END
|
||||
|
||||
|
||||
" Auto-reload ~/.config/vim/vimrc on write for a fast edit loop
|
||||
" => NOTE: This adds to state rather than replacing it,
|
||||
" so, for example, removed mappings and options persist
|
||||
" until VIM is restarted
|
||||
augroup vimrc
|
||||
autocmd!
|
||||
autocmd BufWritePost $MYVIMRC source % | redraw
|
||||
augroup END
|
||||
" Key binding to reload ~/.config/vim/vimrc manually
|
||||
nnoremap <silent><leader>rc :so $MYVIMRC<cr>
|
||||
14
.inputrc
Normal file
14
.inputrc
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
# Enable vi-style line editing for all readline apps
|
||||
set editing-mode vi
|
||||
|
||||
# Indicate the current mode via the cursor shape
|
||||
set show-mode-in-prompt on
|
||||
set vi-cmd-mode-string "\1\e[2 q\2" # steady block
|
||||
set vi-ins-mode-string "\1\e[5 q\2" # blinking beam
|
||||
|
||||
# Ctrl-L clears the screen in command mode only
|
||||
# => Bind in insert mode as well
|
||||
set keymap vi-insert
|
||||
"\C-l": clear-screen
|
||||
|
||||
set keymap vi
|
||||
0
.local/state/vim/backup/.gitkeep
Normal file
0
.local/state/vim/backup/.gitkeep
Normal file
0
.local/state/vim/swap/.gitkeep
Normal file
0
.local/state/vim/swap/.gitkeep
Normal file
0
.local/state/vim/undo/.gitkeep
Normal file
0
.local/state/vim/undo/.gitkeep
Normal file
Loading…
Reference in a new issue