tonybtw.com

tonybtw.com

https://git.tonybtw.com/tonybtw.com.git git://git.tonybtw.com/tonybtw.com.git
11,077 bytes raw
1
#+title: How to Customize Vim in 2026
2
#+author: Tony, btw
3
#+date: 2025-10-01
4
#+HUGO_TITLE: How to Customize Vim in 2026
5
#+HUGO_FRONT_MATTER_FORMAT: yaml
6
#+HUGO_CUSTOM_FRONT_MATTER: :image "/img/vim.png" :showTableOfContents true
7
#+HUGO_BASE_DIR: ~/repos/tonybtw.com
8
#+HUGO_SECTION: tutorial/vim
9
#+EXPORT_FILE_NAME: index
10
#+EXPORT_FILE_NAME: index
11
#+OPTIONS: toc:nil broken-links:mark
12
#+HUGO_AUTO_SET_HEADLINE_SECTION: nil
13
#+DESCRIPTION: This is a quick and painless tutorial on how to get vanilla vim up and running.
14
15
* Table of Contents :toc:
16
- [[#intro][Intro]]
17
- [[#install-dependencies-for-vim][Install Dependencies for Vim]]
18
  - [[#arch-linux][Arch Linux]]
19
  - [[#nixos][NixOS]]
20
  - [[#gentoo][Gentoo]]
21
- [[#create-config-file][Create config file]]
22
- [[#bare-minimum-what-i-use-on-servers][Bare minimum (what i use on servers)]]
23
- [[#modularize-options][Modularize options]]
24
- [[#keybinds][Keybinds!]]
25
- [[#plugins][Plugins]]
26
  - [[#colorsvim][Colors.vim]]
27
  - [[#fzf-file-searching][Fzf file searching]]
28
  - [[#lightline][Lightline]]
29
  - [[#lsp][LSP...]]
30
- [[#outro][Outro]]
31
32
* Intro
33
What's up guys, my name is Tony, and today, I'm going to give you a quick and painless guide on Vim.
34
35
Vim is a blazingly fast text editor that leverages different modes in order to facilitate a keyboard centric efficient experience.
36
37
I use neovim on my main machine, but I find myself on servers a lot, or inside of install iso images, where I only have access to vi, or vim if I'm lucky. That's why I always keep my vanilla vim config up to date.
38
39
* Install Dependencies for Vim
40
41
To get things started, we're gonna need some dependencies. I have a written article to accompany this tutorial in a link below the subscribe button that will show you how to install these on your favorite operating system, but for today's guide, we're going to be using Arch, btw, so heres what we need:
42
43
#+begin_src
44
yay -S git vim ripgrep fd fzf rust-analzyer
45
#+end_src
46
47
- git
48
- vim
49
- ripgrep
50
- fd
51
- fzf
52
- rust_analyzer
53
54
** Arch Linux
55
56
#+begin_src
57
sudo pacman -S git vim ripgrep fd fzf rust-analyzer
58
#+end_src
59
60
** NixOS
61
62
#+begin_src nix
63
# vim.nix
64
{ config, pkgs, lib, ...}
65
66
{
67
  # Install Vim and dependencies
68
  home.packages = with pkgs; [
69
    # Tools required for Telescope
70
    ripgrep
71
    fd
72
    fzf
73
    # Language Servers
74
    rust-analzyer
75
  ];
76
77
  programs.git.enable = true;
78
  programs.vim.enable = true;
79
80
}
81
#+end_src
82
83
** Gentoo
84
85
#+begin_src sh
86
sudo emerge -q \
87
  app-shells/fzf \
88
  sys-apps/ripgrep \
89
  sys-apps/fd \
90
  dev-util/rust-analyzer \
91
  app-editors/vim
92
#+end_src
93
94
* Create config file
95
ls .vim
96
mkdir .vim
97
vim .vimrc
98
99
#+begin_src vim
100
echom "hello world"
101
#+end_src
102
103
We can use `:so` to source this file immediately
104
and we see, 'hello world' in the console.
105
106
lets add a print statement to vimrc inside of our .vim folder, so its easier to modularize.
107
108
cd .vim
109
vim vimrc
110
111
#+begin_src vimrc
112
echom "subsrcibe to my channel"
113
#+end_src
114
115
now in our ~/.vimrc, lets source this file
116
117
#+begin_src vimrc
118
echom "hello world"
119
source ~/.vim/vimrc
120
#+end_src
121
122
Now vim will always load the ~/.vim/vimrc file when launched. we can test by running `vim`
123
124
125
* Bare minimum (what i use on servers)
126
127
this is my 8 line copy paste that i use on servers, or take with me in isos
128
129
#+begin_src vim
130
filetype plugin indent on
131
set expandtab
132
set shiftwidth=4
133
set softtabstop=4
134
set tabstop=4
135
set number
136
set relativenumber
137
set smartindent
138
set showmatch
139
set backspace=indent,eol,start
140
syntax on
141
#+end_src
142
143
This will get you by for like 90% of your needs, unless you are into lsps and programming. If you literally just tinker with config files, this is enough.
144
145
Let's go further though.
146
147
* Modularize options
148
149
Let's move these options over to an options file, and lets also add a keybinds file.
150
So, lets actually just yank this entire file, since its all options, and then lets press y to yank all of it. Now we can do :e options.vim, to create and open options.vim and just paste this here. we can save this new file with :w, and now if we hit control-o to get back to our vimrc, we can delete all of this by pressing shift v, shift g to highlight everything in visual mode, and press c to delete and enter insert mode, and lets just replace it with source options.vim. Now we can modularize everything and source it right in our vimrc.
151
152
#+begin_src
153
source ~/.vim/options.vim
154
#+end_src
155
156
* Keybinds!
157
158
for keybinds, lets create a keybinds.vim file. let's just presource it here, since we know its coming.
159
160
#+begin_src vim
161
source ~/.vim/options.vim
162
source ~/.vim/keybinds.vim
163
#+end_src
164
165
:e keybinds.vim
166
167
Lets start by adding a leader key, its going to be the key that we press before hitting a keycombo in order to bind stuff.
168
#+begin_src vim
169
" Set leader key
170
let mapleader = " "
171
172
" Open netrw with <leader>cd
173
nnoremap <leader>cd :Ex<CR>
174
#+end_src
175
176
Let's source this file with :so, and now we can test this bind here by pressing space cd (for change directory), and BOOM we're right in our netrw.
177
178
We'll certainly add more keybinds later. Let's move onto plugins.
179
180
* Plugins
181
182
There is a plugin manager called 'plug', but I just wrote my own 6 line function to handle plugins. its a glorified wrapper for `git clone`. You guys can just paste it in here, I'll share it in a link below the subscribe button.
183
184
#+begin_src vimscript
185
let s:plugin_dir = expand('~/.vim/plugged')
186
187
function! s:ensure(repo)
188
  let name = split(a:repo, '/')[-1]
189
  let path = s:plugin_dir . '/' . name
190
191
  if !isdirectory(path)
192
    if !isdirectory(s:plugin_dir)
193
      call mkdir(s:plugin_dir, 'p')
194
    endif
195
    execute '!git clone --depth=1 https://github.com/' . a:repo . ' ' . shellescape(path)
196
  endif
197
198
  execute 'set runtimepath+=' . fnameescape(path)
199
endfunction
200
#+end_src
201
202
We need to add this file to our vimrc like so:
203
204
#+begin_src vimrc
205
source ~/.vim/options.vim
206
source ~/.vim/keybinds.vim
207
source ~/.vim/plugins.vim
208
#+end_src
209
210
211
And to use this plugin script, all we need to do as add a plugin to the bottom like so:
212
213
** Colors.vim
214
215
First lets head over to this [[https://github.com/ghifarit53/tokyonight-vim][github link]] and take a look at this plugin. We have a simple colorscheme plugin here for the tokyonight flavor, we can yank this url here, and throw it in the bottom of our plugin.vim:
216
217
#+begin_src vim
218
call s:ensure('ghifarit53/tokyonight-vim')
219
#+end_src
220
221
And lets source this file, and we see that tokyonight starts to download. Now that its downloaded, we can see it worked by typing :colorscheme tokyonight.
222
223
But lets add a custom colors.vim file to handle some options related to this plugin.
224
225
:e colors.vim (or space cd, and %colors.vim)
226
227
** Fzf file searching
228
229
One of the best plugins for neovim besides treesitter is Telescope, but we can achieve the same thing in vanilla vim here with f (zed) f .vim
230
231
#+begin_src
232
call s:ensure('junegunn/fzf')
233
call s:ensure('junegunn/fzf.vim')
234
#+end_src
235
Source this file now to install these with :so
236
237
And let's create fzf.vim to setup some options and binds for it:
238
:e fzf.vim
239
240
#+begin_src
241
" FZF keymaps (requires Plug 'junegunn/fzf.vim')
242
243
" Files
244
nnoremap <leader>ff :Files<CR>
245
nnoremap <leader>fo :History<CR>
246
nnoremap <leader>fb :Buffers<CR>
247
nnoremap <leader>fq :CList<CR>    " For quickfix list
248
nnoremap <leader>fh :Helptags<CR>
249
250
" Grep current string
251
nnoremap <leader>fs :Rg <C-r><C-w><CR>
252
253
" Grep input string (fzf prompt)
254
nnoremap <leader>fg :Rg<Space>
255
256
" Grep for current file name (without extension)
257
nnoremap <leader>fc :execute 'Rg ' . expand('%:t:r')<CR>
258
259
" Find files in your Vim config
260
nnoremap <leader>fi :Files ~/.vim<CR>
261
#+end_src
262
263
so now we can type space ff and we see our files. let's clean this up though, this is way too many files by default
264
265
First lets change fzf to point to fd instead of find. This has to be done in our .bashrc, or .zshrc if you're into that
266
267
#+begin_src bash
268
export FZF_DEFAULT_COMMAND='fd --type f --hidden --follow'
269
#+end_src
270
271
Now we can create a file that tells fd what to ignore called `.fdignore` like so:
272
273
vim ~/.fdignore
274
275
And lets add these 3 folders to it:
276
#+begin_src
277
undodir/
278
plugged/
279
.git
280
#+end_src
281
282
Now lets source bash, and check it out, we only see our files in .vim that we want to see. We can do the same with rg... .rgignore
283
284
Let's test rg by typing space fg and searching for vim. nice, we see 19 entries here.
285
286
So this is pretty much my fzf.vim config
287
288
** Lightline
289
Let's get a powerline here:
290
#+begin_src
291
call s:ensure('itchyny/lightline.vim')
292
#+end_src
293
294
And lets import our lightline config like so:
295
296
:e lightline.vim
297
298
TODO Test minimalism
299
300
#+begin_src
301
set laststatus=2
302
let g:lightline = {
303
      \ 'colorscheme' : 'tokyonight',
304
      \ 'active': {
305
      \   'left': [ [ 'mode', 'paste' ],
306
      \             [ 'gitbranch', 'readonly', 'filename', 'modified' ] ],
307
      \   'right': [ [ 'lineinfo' ], [ 'fileformat', 'fileencoding', 'filetype' ] ]
308
      \ },
309
      \ 'component_function': {
310
      \   'gitbranch': 'FugitiveHead',
311
      \   'filename': 'LightlineFilename'
312
      \ }
313
      \ }
314
315
function! LightlineFilename()
316
  return expand('%:t') !=# '' ? expand('%:t') : '[No Name]'
317
endfunction
318
#+end_src
319
320
Now we just need to add lightline to our vimrc, and we're good to go.
321
322
#+begin_src
323
source ~/.vim/lightline.vim
324
#+end_src
325
** LSP...
326
Alright so this is the hard part. an lsp that works on vim!
327
I've tried to make this as simple as possible so let's roll with it. First lets download this plugin:
328
329
#+begin_src
330
call s:ensure('yegappan/lsp')
331
#+end_src
332
333
Lets create our lsp.vim file, and just paste this in there (my lsp config)
334
#+begin_src
335
" Enable diagnostics highlighting
336
let lspOpts = #{autoHighlightDiags: v:true}
337
autocmd User LspSetup call LspOptionsSet(lspOpts)
338
let lspServers = [
339
      \ #{
340
      \   name: 'rust-analyzer',
341
      \   filetype: ['rust'],
342
      \   path: 'rust-analyzer',
343
      \   args: []
344
      \ }
345
      \ ]
346
347
autocmd User LspSetup call LspAddServer(lspServers)
348
349
" Key mappings
350
nnoremap gd :LspGotoDefinition<CR>
351
nnoremap gr :LspShowReferences<CR>
352
nnoremap K  :LspHover<CR>
353
nnoremap gl :LspDiag current<CR>
354
nnoremap <leader>nd :LspDiag next \| LspDiag current<CR>
355
nnoremap <leader>pd :LspDiag prev \| LspDiag current<CR>
356
inoremap <silent> <C-Space> <C-x><C-o>
357
358
" Set omnifunc for completion
359
autocmd FileType php setlocal omnifunc=lsp#complete
360
361
" Custom diagnostic sign characters
362
autocmd User LspSetup call LspOptionsSet(#{
363
    \   diagSignErrorText: '✘',
364
    \   diagSignWarningText: '▲',
365
    \   diagSignInfoText: '»',
366
    \   diagSignHintText: '⚑',
367
    \ })
368
369
#+end_src
370
371
You have to install rust_analyzer, I already have it installed, but on arch, we can do it like so:
372
373
#+begin_src
374
npm install -g rust_analzyer
375
#+end_src
376
377
And we see we have rust analyzer here, so lets open a rust project and test if its working.
378
379
vim ~/repos/oxwm/src/main.rs
380
and we can test hover with shift k, and if we add bad code here we should see an error.
381
Bad Code
382
And go to definition works!
383
384
* Outro
385
386
Alright, thats gonna be it for todays video. If you have any questions or recommendations on any other linux related content, as usual just drop a comment.
387
388
It wouldn't be a proper video without an obligatory neofetch.