From 4bad81c4dd540b40af0db4db6a403f9e54481286 Mon Sep 17 00:00:00 2001 From: Alexander Hess <alexander@webartifex.biz> Date: Tue, 9 Aug 2022 01:16:07 +0200 Subject: [PATCH] Configure vim --- .config/git/ignore | 20 +++ .profile | 2 + .vim/after/ftplugin/python.vim | 65 +++++++ .vim/backup/.gitkeep | 0 .vim/swap/.gitkeep | 0 .vim/undo/.gitkeep | 0 .vim/vimrc | 303 +++++++++++++++++++++++++++++++++ 7 files changed, 390 insertions(+) create mode 100644 .vim/after/ftplugin/python.vim create mode 100644 .vim/backup/.gitkeep create mode 100644 .vim/swap/.gitkeep create mode 100644 .vim/undo/.gitkeep create mode 100644 .vim/vimrc diff --git a/.config/git/ignore b/.config/git/ignore index e69de29..c70f233 100644 --- a/.config/git/ignore +++ b/.config/git/ignore @@ -0,0 +1,20 @@ +# 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~ diff --git a/.profile b/.profile index 6514831..a5d4c1e 100644 --- a/.profile +++ b/.profile @@ -1,9 +1,11 @@ # Executed by a login shell (e.g., bash, sh, or zsh) during start-up +export EDITOR=vim export PAGER='less --chop-long-lines --ignore-case --LONG-PROMPT --no-init --status-column --quit-if-one-screen' export TERM=xterm-256color export TZ='Europe/Berlin' +export VISUAL=$EDITOR export REPOS="$HOME/repos" diff --git a/.vim/after/ftplugin/python.vim b/.vim/after/ftplugin/python.vim new file mode 100644 index 0000000..0bf9971 --- /dev/null +++ b/.vim/after/ftplugin/python.vim @@ -0,0 +1,65 @@ +" 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 + + +" TODO: This does not work, maybe because we spell out imports +" as project-local imports (e.g. from lalib.fields import base)? +" Include *.py files imported as modules when searching. +" Source: https://www.youtube.com/watch?v=Gs1VDYnS-Ac +set include=^\\s*\\(from\\\|import\\)\\s*\\zs\\(\\S\\+\\s\\{-}\\)*\\ze\\($\\\|\ as\\) +" 1) import foo.bar -> foo/bar.py +" 2) from foo import bar as var -> foo/bar.py or foo.py +function! PyInclude(fname) + let parts = split(a:fname, ' import ') " 1) [foo.bar] or 2) [foo, bar] + let left = parts[0] " 1) foo.bar or 2) foo + if len(parts) > 1 + let right = parts[1] " only 2) bar + let joined = join([left, right], '.') + let fpath = substitute(joined, '\.', '/', 'g') . '.py' + let found = glob(fpath, 1) + if len(found) + return found + endif + endif + return substitute(left, '\.', '/', 'g') . '.py' +endfunction +setlocal includeexpr=PyInclude(v:fname) +setlocal define=^\\s*\\<\\(def\\|class\\)\\> + + +" Number of spaces used for each step of auto-indent +set shiftwidth=4 + +" Number of spaces a <Tab> counts for in the file +set tabstop=4 + +" Number of spaces a <Tab> counts for in editing mode +set softtabstop=4 + +" Change <Tab>s into spaces +set expandtab + +" Copy indent from previous line when starting a new line +set autoindent + +" Use indent according to the syntax of the open file +set smartindent + +" Auto-wrap lines after 88 characters, which is PEP8's limit plus 10%, +" a more relaxed boundary which occasionally may be used +set textwidth=88 + + +" Make column 80 red to indicate PEP8's maximum allowed line length +set colorcolumn=80 + +" Additionally, give every character beyond 80 columns a red background +highlight ColorColumn ctermbg=DarkRed +call matchadd('ColorColumn', '\%80v', 100) +match ErrorMsg '\%>80v.\+' + + +" Show line numbers by default for .py files +let g:show_numbers=1 diff --git a/.vim/backup/.gitkeep b/.vim/backup/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/.vim/swap/.gitkeep b/.vim/swap/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/.vim/undo/.gitkeep b/.vim/undo/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/.vim/vimrc b/.vim/vimrc new file mode 100644 index 0000000..d880af5 --- /dev/null +++ b/.vim/vimrc @@ -0,0 +1,303 @@ +" Good sources on vimrc files: +" - https://www.youtube.com/watch?v=Gs1VDYnS-Ac + + +" Use VIM improved mode +set nocompatible + +" Set environment variables for convenient usage +let $RC="$HOME/.vim/vimrc" +let $RTP=split(&runtimepath, ',')[0] + +" Disable VIM's startup message +set shortmess+=I + +" Number of remembered undo steps +set undolevels=1000 + + +" Detect the file's type and load the corresponding plugin and indent files +filetype plugin indent on + +" Enable syntax highlighting +syntax on + + +" 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, wich 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 ~/.vim folder +set viminfo+=n~/.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=~/.vim/backup// +set directory=~/.vim/swap// +set undodir=~/.vim/undo// + +" 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 loosing data upon insertion in old VIMs +set wrapmargin=0 + + +" Show spelling mistakes (in English) in italics +set spelllang=en_us,de_de +set spell +hi clear SpellBad +hi clear SpellCap +hi clear SpellRare +hi clear SpellLocal +hi SpellBad cterm=italic + + +" 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 +autocmd CursorHold * :echo + + +" Better copy and paste behavior +set pastetoggle=<F2> +set clipboard=unnamed + + +" 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 + + +" 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 safe 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 and <c-h/j/k/l> 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> +nmap <c-h> <left> +nmap <c-j> <down> +nmap <c-k> <up> +nmap <c-l> <right> +vnoremap <left> <gv +vnoremap <right> >gv +vnoremap <up> :m'<-2<cr>gv=gv +vnoremap <down> :m'>+1<cr>gv=gv +vmap <c-h> <left> +vmap <c-j> <down> +vmap <c-k> <up> +vmap <c-l> <right> + +" Make <tab> (un)indent lines +nnoremap <tab> >> +nnoremap <s-tab> << +inoremap <tab> <esc>>> +inoremap <s-tab> <esc><< +vnoremap <tab> >gv +vnoremap <s-tab> <gv + +" Make Y yank the rest of a line, just like C or D work +noremap Y y$ + +" Alphabetically sort a selection of lines +vnoremap <leader>s :sort<cr> + +" Switch two words, just like xp switches two characters +noremap <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 +augroup checktime + autocmd! + autocmd BufEnter * silent! checktime + autocmd CursorHold * silent! checktime + autocmd CursorHoldI * silent! checktime + autocmd CursorMoved * silent! checktime + autocmd CursorMovedI * silent! checktime +augroup END + + +" Auto-reload ~/.vim/vimrc +augroup vimrc + autocmd! BufWritePost $RC source % | redraw +augroup END +" Key binding to reload ~/.vim/vimrc manually +nnoremap <silent><leader>rc :so $RC<cr>