Five lines I put in a blank .vimrc
swordandsignals.com
swordandsignals.com
That's a bit naughty but sometimes needed to prove something useful.
In that case you've got an effemeral file system, and probably had to install Vim in the first place, knowing that that when you close the container all will be forgotten.
Ofcourse in that situation you probably don't need to disable the Vim swap files, so that's one less thing to changet the defaults on.
I often use Busybox for that kind of thing as you're usually missing other useful OS stuff and its little Vi clone is usually enough.
It would log into the remote machine using Expect, then it would send a command to the remote end that tested whether a home directory already existed. If so, it spawned a new shell in it. Otherwise it created a "home directory" in /tmp, pulled a tarball from a server, and extracted it into the "home directory". Then it spawned a new shell there.
Depending on how often it happens, you could also have a separate command that does the initial setup, and then call that as required.
echo 'set keywordprg=:help' >> ~/.vimrc
:)And like u/strogonoff, I also disable line numbers, but that's just personal preference of course. For vim newbies, relative lines might also be worth checking out: "set relativenumber".
One thing that really annoys me is :Wq or :Q not being commands. Or typing only Q because you didn't hit the : and accidentally entering ex mode. Or hitting F1 instead of escape. I can recommend:
command Wq wq
command WQ wq
command W w
command Q q
nnoremap Q <nop>
map <F1> <Esc>
imap <F1> <Esc>
Or for the non-newbie that has the 'too many terminals' problem, "set title" will give your terminals more useful titles. There are a bunch more things, of course, but these are the lines in my vimrc that I think are useful to most people.I'm not certain this is different (because I don't use either deliberately) but I'm forever hitting q (not even trying to quit) and entering some kind of macro recording mode.
I think the only reason I haven't yet disabled it like you suggest (after doing it for years now) is that... Well 'some kind of macro recording' does sound like it might be pretty useful if I bothered to learn to use it!
For a quick demo, try it on this file:
hello world!
here's wolves
what's up with the hackers?
Go to the first line and do: 1. qq starts a macro named 'q'
2. $vbgUj select last word on line, uppercase it, go down one line
3. q to end macro recording
4. @q run the macro
4b. @@ repeats the last macro
4c. 100@q runs the macro 100 times
When you want to do multi-line edits and the columns are not aligned (so block mode, Ctrl+V, doesn't work), this works wonders. You just record whatever you would do on every line plus whatever motions you use to go to the next occurrence, using things like "f|" (find the next pipe symbol) or "/example<Esc>n" (find the next instance of "example"), and then run the macro however many times. If you specify a number of times greater than the file is large, it will automatically stop at end of file, and you can also cancel if it takes too long (Ctrl+C) and undo what it did so far (u).Alternatively, sed -i s/a/b/ my.txt is much much faster than macros, but macros can be more complex and are often easier to record (since you're just showing the computer what to do in a human way) than trying to regex the line.
I tried recording it for the lazy but asciinema is having issues (server error when uploading).
This happens just often enough that I have to regard it as useful, but it's also less common than crashes that leave me with swaps to contend with across a dozen files that really were pretty much fine. This is a frequent annoyance.
So: occasional big help vs frequent annoyance.
I don't think the problem is actually swap files themselves, though, but the user experience with them. What vim does is prompt you to choose what to do before you've even had a chance to compare the swap with what's saved, and provides no help with the comparison. What'd be nice is if it gave you some kind of visualization of a diff between the two and then prompted you for a choice.
For what it's worth, Vim never crashes on me. For me swap files are mostly helpful with broken connections, killed VMs that apparently still had a vim session open in a faraway terminal, or other such situations.
Agreed, the UX is 99% the reason of me hating swap files. More often than not I choose recover, only to discover the diff is literally null. Come on, you could not check for that before interrupting? And then in any case you have double the annoyance with that recovered buffer as the old swap remains and you have to delete it or you get the warning again on the next open.
It’s kind of like changing branches with git and then back again, vim notices the time stamp of an opened file changed vs the last buffer save, lets you change the file but complains on :w that the file “changed” outside, yet is unable to a) show you a diff of current buffer vs current file, nor b) realised that the filesystem state vs buffer state at last save (which vim fully knows about) produces a null diff, so the buffer changes are safe to write.
Note that you can save the trouble of running diff by watching for the message "Buffer contents equals file contents." Only when they're different, you'll want to write the file to another place and diff it.
What bugs me a lot is that, even if the contents are equal, it doesn't cleanup the swap file... is there maybe a command for that so I don't have to go back to my terminal, manually remove .<filename>.swp, and open up vim again?
nmap <leader>d :w !diff -u % -<CR>
It writes the buffer’s content to diff’s stdin, and diff gets passed the filename (hence the current on disk content) to compare vs stdin (hence the current buffer content).Only I wish it were run automatically by vim in aforementioned cases before whining (case a: recover, run the above, if no diff stop complaining; case b: rewind til last save, run the above, if no diff then replay and save without complaining)
[0]: https://github.com/lloeki/vimfiles/blob/9c50f3be60e536518beb...
I'm definitely one of those people too, and while I don't disable swap files I do depend heavily on `persistent-undo`. It literally changed the way I work when it was introduced. To some extent I treat it as an extension to swapfile functionality as it also operates across broken sessions(intentional or not).
> [...] the user experience with them
Christian Brabandt's Recover.vim¹ is a huge improvement for those few times when you do actually want to work with a swap file. General recommendation to poke around in his other repositories too, as he has written a heap of extremely useful vim things.
Edit: Especially unicode.vim² which improves `ga` no end, csv.vim³ which feels like magic, NrrwRgn⁴ for fellow emacs refugees, and ...
¹ https://github.com/chrisbra/Recover.vim
² https://github.com/chrisbra/unicode.vim
inoremap kj <Esc>
are essential to me... press both at the same time and you exit insert mode regardless of which one gets pressed slightly faster and you never leave the home row and if you press it when you are not in insert mode it's basically a nop unless you are at the start or end of the file. even if you are you might move down or up a line accidentally but i've never had that happen personally.
I really like the behaviour of `set number relativenumber`, where it shows me my actual line number of the current line and relative numbers on the lines I'm going to operate on.
It's one letter shorter and less likely to be confused.
set hls ic is nu noswf
On a serious note, personally disabling line numbers is the first thing I do in a new editor. Reduces visual noise—status line usually shows current line number anyway, jumping to a line might take a second and I found I don’t need to know my line numbers more frequently than once per month or so.What I do like to enable in an editor is visible whitespace characters (helps notice levels of indent, for example). In Vim that can be accomplished with:
set list listchars+=space:•
(Might take some tweaking to make whitespace appear subtly enough, depending on your color scheme.)Others just search for known text, which IMO is a habit I need to get into. I "got" hjkl after I disabled the cursor keys for a day, but I never followed up and disabled hjkl (or maybe even w and b!?) to get super efficient.
Also with the right setting(I think incsearch) Vim immediately jumps to the first result as you type, so I often use search to quickly peek at some code and then jump back with Esc when it doesn't warrant splitting the buffer.
But I do still struggle a bit with moving within the line - w and b tend to "get caught" in long series of different symbol categories that Vim will all see as separate words/tokens. At least I got my setup with the "camelcasemotion" plugin working, which is a great help with long identifier names.
The only time I find using :number is when I am exploring a codebase elsewhere, e.g. using GitHub’s web interface, and want to jump to a particular line in Vim to make edits—rarely happens.
It's not pretty, one could argue that the mouse is more efficient for such movements, but for me it's faster in practice than moving my hand to the mouse/trackpad, or than looking up a line number (either absolute or relative) and then typing it. And it has no mental burden.
I also find it especially useful in vi when working with config files. I’m sure you are aware of this feature but in case others aren’t, in vi if you type numbers before a command, it runs that commend n times. So you can quickly copy or delete multiple lines.
It just goes to show how deeply personal a preference a persons code editor is.
I use shift+v and a j/k relative jump to select a range of lines, then do the operation. Which is undeniably the slower way.
Didn’t know how dyslexia affects this, I will keep that in mind in case I happen to work with someone with it.
set list listchars+=space:•
This adds a lot of clutter! It's better to show only indentations (of course, using tabs): set listchars=tab:├─Sometimes also colors in general can get distracting and I just turn on grayscale system-wide, which also doesn’t play with syntax highlighting as text ends up being varying shades of gray with not enough contrast against the background.
Switching it off is the first I do.
There’s definitely something real about too much colours; the archetypal example of colouring our human language tokens by type (verbs, nouns, etc) making no sense sure rings home after a while.
But I found very much use of “colour”+ themeing for two things:
- comments vs code, one toned down vs the other, ideally swappable with a hotkey
- delimited content such as strings. It sure saves a lot of time when you get an imbalanced delimiter nested in a forest and the whole of your file changes colour starting near the imbalance.
I’m very much of the opinion that a lot of syntax highlighting is just dumbed down token matching and badly designed (if at all designed), when it should be much smarter in alerting you of inconsistencies, and putting relevant content forward.
+ by colour I don’t necessarily mean literally in colour, bold or italics can serve well.
Colouring human language by tokens is a very fitting analogy.
I am sure there are corner-cases where I would want to enable it, such as were someone has been in the habit of commenting-out parts of a line.
I don't know anyone who uses syntax highlighting for natural-language prose, though I suppose there are some who do.
I've always found syntax highlighting super distracting, but everyone i have met thinks im crazy.
Otoh i do love me line numbers.
Wow, don't ever use VSCode then! There are hovering diacritics and proofing marks everywhere!
It does real-time syntax checking and quick compilation to check interfaces (at least with TypeScript, JS, HTML, pug, css, Vue, and NodeJS).
I resisted fancy editors for years, as I found them crazy annoying, but over the past few months I've grown to adore VSCode because it has made me about 50% more efficient: I don't have to run the app to find errors, the IDE finds them for me, and it works on Win10, macOS and Linux. It is extremely context aware of my project.
It's like JetBrains but free (or Android Developer Studio, also made by JetBrains...).
:nmap <F12> :set invnumber<CR>
" mac clipboard {{
if has("clipboard")
set clipboard=unnamed
endif
" }} mac clipboardBut apparently according to peer comments, there are ways to yank into clipboards, which is pretty cool.
That works in tmux too. So you can have use the terminal but have it behave as a GUI app in most respects. For example being able to use a touchpad to quicly enlarge/resize splits or scroll a window can be quite useful.
As for showing line numbers, I'm often doing this to read logs on a remote VM. In those scenarios, having easy access to where you are in the file is really helpful.
set listchars=tab:>-
set listchars+=trail:⋄
This shows markers for tabs and trailing whitespaces.The latter will make you very sad when you browse other people's code.
view foo # opens read-only, no swap file
vi foo # opens read-write
Another benefit of this habit is, if you know you're not going to want to modify a file, you can protect yourself against errors like accidentally changing something and then absentmindedly saving the file. " check for and load file changes when a window is focused. Together with
" `noswapfile` this allows to edit the same file in multiple nvim instances and
" have the changes reloaded whenever the focus is changed.
autocmd WinEnter,BufWinEnter,FocusGained * checktimeSee [0] for something to try.
[0] https://vim.fandom.com/wiki/Auto_save_files_when_focus_is_lo...
in the few cases where i really need to open the file multiple times i use tmux to allow a shared view.
It's a bit crude but I really like how it results in a uniform way of working in the terminal. As opposed to handling different files and processes depending on what applications is currently running.
For me vim-sensible [1] has a more useful set of defaults (although more than five lines). Also, the readme of that project lists benefits of using a universal set of defaults.
set nocompatible hlsearch incsearch ignorecase number
then sane tabs set et sts=4 sw=4The nocompatible mode means adding some features to vim rendering it "incompatible" with the original vi. For example in the original vi you can only undo the last action, with compatible mode on vim will mimic this behavior.
set expandtab
set shiftwidth=4
set softtabstop=4
function Spaces(...)
if a:0 == 1
let l:width = a:1
else
let l:width = 4
endif
setlocal expandtab
let &l:shiftwidth = l:width
let &l:softtabstop = l:width
endfunction
command! T setlocal noexpandtab shiftwidth=8 softtabstop=0
command! -nargs=? S call Spaces(<args>)
autocmd BufNewFile,BufRead ~/src/linux/* T
autocmd BufNewFile,BufRead ~/src/git/* T
autocmd FileType html S 2
autocmd FileType tex S 2
This sets the default to 4-space indents, but lets me do :T to switch to tabs (and does so automatically for Linux and Git which use that style), or :S N to switch to N-space indents (and automatically switches HTML and TeX to 2-space indents).I find it odd, to compare Vim with VSCode and pretend that those 5 lines close the gap (especially when 3 of those lines are primarily about search). My own .vimrc has 166 lines (custom snippets, key bindings, plugin configurations (e.g. powerline, tmux navigator) and comments) and I try not to use more plugins than necessary.
I say that as someone who loves Vim. But not just for its features, but also for those that are not present (by default) and make it as fast as it is.
So for me, installing CtrP or FZF is pretty much mandatory (I've settled on FZF). I know this is about config options, and this is an extension, but for me, fuzzy search is pretty much essential for coding once you get to a moderate sized code-base.
set nobackup
set nowritebackup
set noundofile
set noswapfile
I explain why at https://lee-phillips.org/badvim/Also, it’s best to just have one instance of Vim running, in server mode, so you can send files to it from the command line.
Try this:
set backupdir=~/.vim/backups,.
set directory=~/.vim/swapfiles,.
It will only write in the current directory, if ~/.vim/backups does not exist, and the dot is just there for portability, so nothing breaks when using my vimrc on a new system.Edit: Upon actually reading your blog-post, I understand at least one reason - my options may not change the behaviour of a file not being written to the correct inode, so you have a point for some build systems.
I actually learned rather much reading this, thank you for sharing!
Edit: Hmmm. I’ll have to think some more about it. Anyway, glad you found my witeup useful.
set directory=~/.vim/swapfiles//,.
From the help text for "directory":> For Unix and Win32, if a directory ends in two path separators "//", the swap file name will be built from the complete path to the file with all path separators replaced by percent '%' signs (including the colon following the drive letter on Win32). This will ensure file name uniqueness in the preserve directory.
Truth
My undo files are in ~/.cache/
In retrospect, I probably should have just gotten used to whatever the default is, because using Vim without my .vimrc doesn't actually feel like Vim to me.
It might be more convenient to just do a one-time setup of something like "bring your .bashrc, .vimrc, etc. with you when you ssh" [0] (previously discussed on HN [1]).
Personally, I've got a shell script that I just scp over and execute to set up my dotfiles (in a git repo) if they aren't already present on a host, but that may not be an option for some (although I guess I could use sshrc to do that too).
--
[0]: https://github.com/danrabinowitz/sshrc (note: clone of the original repo, which now 404s).
map <F5> <Esc>:w<CR> :!"%:p"<CR>
Especially since I'm used to running my code with F5 since DelphiAnd you probably should, because vim is rightfully warning you, that you might lose changes made in the other instance.
With that said, thanks for the tips—`set noswapfile` definitely fits my workflow more than not.
Edit: fixed by removing "Apple Color Emoji" from the list. Thanks!
I wonder if there are more convenient ways to do this.
This is useful because sometimes you want to use the same configuration file on different systems and they usually need some customizations to adapt to each one, which can be done automatically by ansible based on jinja2 templates.
The idea is to make an alias that runs git so that it treats your home directory as a git repository and you can directly commit them.
I would recommend bypassing that article's `config config --local status.showUntrackedFiles no` setting and setting a `~/.gitignore`. This way, git will never tinker with your home directory if you accidentally run the wrong command.
So the complete list of setup commands is:
# Only needs to be done the first time
cat >~/.gitignore<<'EOF'
*
!/.bashrc
!/.zshrc
EOF
# On subsequent runs
git clone --bare ssh://git/cfg.git "${HOME}/.cfg"
function config() {
git --git-dir="${HOME}/.cfg/" --work-tree="${HOME}" "${@}"
}
config checkout -- ~/.gitignore
config reset ~
config checkout -- ~
config submodule update --init --recursive --remote
One caveat is adding files in subdirectories (`~/. config/...`), but just requires changes in your gitignoreWould be great if I could combine with a local secrets engine. Like Hashicorp Vault but local.
A few are in a git repo, such as my homedir's Makefile:
If I were on a fresh VM with an internet connection and wanted my vimrc, I would do
curl https://dotfilehub.com/knoebber/vimrc >> ~/.vimrc• 'directory' controls where swap files go, toggled by 'swapfile' (default on), filenames like […].swp; ~/.cache/vim/swap// is a good choice.
• 'undodir' controls where undo files go, toggled by 'undofile' (default off), filenames […].un~; ~/.cache/vim/undo// is a good choice.
• 'backupdir' controls where backup files go, toggled by 'backup' (default off), filename […]~; ~/.cache/vim/backup// is an interesting choice.
Arch Linux actually ships a runtime file that sets these paths, creating the directories if they don’t exist: https://github.com/archlinux/svntogit-packages/blob/packages....
(Note that the double trailing slashes are significant and necessary if you’re using a central location for these files. Refer to the help for explanation.)
set mouse=""
into all of my Debian server vimrc files so I can still use my middle-click paste buffer over ssh. :nnoremap : ;
:nnoremap ; :
:nnoremap Y y$
:vnoremap : ;
:vnoremap ; :
:vnoremap Y y$ inoremap jk <esc>
nnoremap <space> :There is no ignorecase option, `(?i)` is the way to enable that in a regex, you can `map global normal / /(?i)` to auto insert-it
incsearch is the same
`add-highlighter global/ number-lines` display line numbers for all buffers
There is no swap file in Kakoune.
No swap file is good though.