tonybtw.com

tonybtw.com

https://git.tonybtw.com/tonybtw.com.git git://git.tonybtw.com/tonybtw.com.git
10,638 bytes raw
1
#+TITLE: Neovim on Linux — Complete IDE Tutorial
2
#+AUTHOR: Tony, btw
3
#+DATE: 2025-05-10
4
#+HUGO_CUSTOM_FRONT_MATTER: :image "/img/neovim.png" :showTableOfContents true
5
#+HUGO_BASE_DIR: ~/www/tonybtw.com
6
#+HUGO_SECTION: tutorial/neovim
7
#+EXPORT_FILE_NAME: index
8
#+OPTIONS: toc:nil broken-links:mark
9
#+HUGO_AUTO_SET_HEADLINE_SECTION: nil
10
#+HUGO_TITLE: Neovim | Complete IDE Tutorial
11
#+DESCRIPTION: A quick and painless guide on installing and configuring Neovim, and how to use it as your full daily driver IDE, btw.
12
#+IMAGE: /img/neovim.png
13
14
* Intro
15
16
A clean and painless guide to turning Neovim into a modern IDE.
17
18
Neovim is a Vim-based text editor built for extensibility and usability. In this tutorial, you’ll learn how to set it up with plugins, keybinds, and full LSP support. This guide assumes you're using a Unix-like system and are comfortable with basic terminal commands.
19
20
* Install Neovim and dependencies
21
22
Use your system’s package manager to install Neovim, along with a few tools that will be required later (like npm and ripgrep).
23
24
#+begin_src sh
25
# Gentoo
26
sudo emerge app-editors/neovim
27
sudo emerge net-libs/nodejs
28
sudo emerge sys-apps/ripgrep
29
30
# Arch
31
sudo pacman -S neovim nodejs npm ripgrep
32
#+end_src
33
34
* Set up your Neovim config directory
35
36
Create your config folder and add the main config file.
37
38
#+begin_src sh
39
mkdir -p ~/.config/nvim
40
cd ~/.config/nvim
41
nvim .
42
#+end_src
43
44
In Neovim, press =%= to create a new file named =init.lua=:
45
46
#+begin_src lua
47
print("I use Neovim by the way")
48
#+end_src
49
50
Save and quit with =:wq=, then reopen Neovim.
51
52
* Create a Lua module for options
53
54
#+begin_src sh
55
mkdir -p ~/.config/nvim/lua/config
56
nvim lua/config/options.lua
57
#+end_src
58
59
#+begin_src lua
60
vim.opt.number = true
61
vim.opt.relativenumber = true
62
vim.opt.cursorline = true
63
vim.opt.shiftwidth = 4
64
#+end_src
65
66
Then in =init.lua=:
67
68
#+begin_src lua
69
require("config.options")
70
#+end_src
71
72
* Add keybindings
73
74
Here is how I set my leader key:
75
76
#+begin_src lua
77
vim.g.mapleader = " "
78
vim.keymap.set("n", "<leader>cd", vim.cmd.Ex)
79
#+end_src
80
81
In =init.lua=:
82
83
#+begin_src lua
84
require("config.keybinds")
85
#+end_src
86
87
* Install Lazy.nvim
88
89
Clone it into your runtime path.
90
91
#+begin_src lua
92
local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim"
93
if not vim.loop.fs_stat(lazypath) then
94
  vim.fn.system({
95
    "git",
96
    "clone",
97
    "--filter=blob:none",
98
    "https://github.com/folke/lazy.nvim.git",
99
    "--branch=stable",
100
    lazypath,
101
  })
102
end
103
vim.opt.rtp:prepend(lazypath)
104
105
require("lazy").setup({})
106
#+end_src
107
108
Then:
109
110
#+begin_src lua
111
require("config.lazy")
112
#+end_src
113
114
* Add a theme plugin
115
116
#+begin_src lua
117
return {
118
  "folke/tokyonight.nvim",
119
  config = function()
120
    vim.cmd.colorscheme("tokyonight")
121
  end,
122
}
123
#+end_src
124
125
* Add Telescope for fuzzy finding
126
127
#+begin_src lua
128
return {
129
  "nvim-telescope/telescope.nvim",
130
  dependencies = { "nvim-lua/plenary.nvim" },
131
  config = function()
132
    local builtin = require("telescope.builtin")
133
    vim.keymap.set("n", "<leader>ff", builtin.find_files)
134
    vim.keymap.set("n", "<leader>fg", builtin.live_grep)
135
    vim.keymap.set("n", "<leader>fb", builtin.buffers)
136
    vim.keymap.set("n", "<leader>fh", builtin.help_tags)
137
  end,
138
}
139
#+end_src
140
141
* Add Treesitter for syntax highlighting
142
143
#+begin_src lua
144
return {
145
  "nvim-treesitter/nvim-treesitter",
146
  build = ":TSUpdate",
147
  config = function()
148
    require("nvim-treesitter.configs").setup({
149
      highlight = { enable = true },
150
      indent = { enable = true },
151
      ensure_installed = { "lua" },
152
      auto_install = false,
153
    })
154
  end,
155
}
156
#+end_src
157
158
* Add Harpoon for file bookmarking
159
160
#+begin_src lua
161
return {
162
  "ThePrimeagen/harpoon",
163
  config = function()
164
    local harpoon = require("harpoon")
165
    vim.keymap.set("n", "<leader>a", function() harpoon:list():add() end)
166
    vim.keymap.set("n", "<C-e>", function() harpoon.ui:toggle_quick_menu(harpoon:list()) end)
167
  end,
168
}
169
#+end_src
170
171
* Add LSP, autocompletion, and snippets
172
173
#+begin_src lua
174
return {
175
  "neovim/nvim-lspconfig",
176
  dependencies = {
177
    "williamboman/mason.nvim",
178
    "hrsh7th/nvim-cmp",
179
    "L3MON4D3/LuaSnip",
180
  },
181
  config = function()
182
    require("mason").setup()
183
    require("mason-lspconfig").setup({ ensure_installed = { "lua_ls" } })
184
185
    local lspconfig = require("lspconfig")
186
    lspconfig.lua_ls.setup({})
187
188
    local cmp = require("cmp")
189
    cmp.setup({
190
      snippet = {
191
        expand = function(args)
192
          require("luasnip").lsp_expand(args.body)
193
        end,
194
      },
195
      mapping = cmp.mapping.preset.insert({
196
        ["<Tab>"] = cmp.mapping.select_next_item(),
197
        ["<S-Tab>"] = cmp.mapping.select_prev_item(),
198
      }),
199
      sources = { { name = "nvim_lsp" }, { name = "luasnip" } },
200
    })
201
  end,
202
}
203
#+end_src
204
205
* One-liner utility plugins
206
207
#+begin_src lua
208
return {
209
  { "tpope/vim-fugitive" },
210
  { "ojroques/nvim-osc52" },
211
  {
212
    "norcalli/nvim-colorizer.lua",
213
    config = function()
214
      require("colorizer").setup()
215
    end,
216
  },
217
}
218
#+end_src
219
220
* Final =init.lua= Example
221
222
#+begin_src lua
223
require("config.options")
224
require("config.keybinds")
225
require("config.lazy")
226
#+end_src
227
#+begin_src sh
228
/home/tony/.config/nvim
229
├── init.lua
230
├── lazy-lock.json
231
├── lua
232
│   ├── config
233
│   │   ├── keybinds.lua
234
│   │   ├── lazy.lua
235
│   │   └── options.lua
236
│   └── plugins
237
│       ├── colors.lua
238
│       ├── harpoon.lua
239
│       ├── init.lua
240
│       ├── lsp.lua
241
│       ├── lualine.lua
242
│       ├── one-liners.lua
243
│       ├── orgmode.lua
244
│       ├── telescope.lua
245
│       └── treesitter.lua
246
├── plugin
247
│   └── flterm.lua
248
└── README.md
249
250
5 directories, 16 files
251
252
#+end_src
253
254
* My keybinds
255
256
If you want to just copy my nvim config, my keybind documentation is here:
257
258
** General
259
260
| Mode | Key             | Action                                                 |
261
|------+-----------------+--------------------------------------------------------|
262
| n    | <leader>cd      | Open Ex mode (`:Ex`)                                   |
263
| n    | J               | Join lines while keeping the cursor in place           |
264
| n    | <C-d>           | Scroll half-page down and center cursor                |
265
| n    | <C-u>           | Scroll half-page up and center cursor                  |
266
| n    | n               | Next search result (centered)                          |
267
| n    | N               | Prev search result (centered)                          |
268
| n    | Q               | Disable Ex mode                                        |
269
| n    | <C-k>           | Next quickfix entry (centered)                         |
270
| n    | <C-j>           | Prev quickfix entry (centered)                         |
271
| n    | <leader>k       | Next location list entry (centered)                    |
272
| n    | <leader>j       | Prev location list entry (centered)                    |
273
| i    | <C-c>           | Exit insert mode                                       |
274
| n    | <leader>x       | Make current file executable                           |
275
| n    | <leader>u       | Toggle Undotree                                        |
276
| n    | <leader>rl      | Reload config                                          |
277
| n    | <leader><leader>| Source current file                                    |
278
279
** Visual Mode
280
281
| Mode | Key         | Action                                      |
282
|------+-------------+---------------------------------------------|
283
| v    | J           | Move block down                             |
284
| v    | K           | Move block up                               |
285
| x    | <leader>p   | Paste without overwriting clipboard         |
286
| v    | <leader>y   | Yank to system clipboard                    |
287
288
** Linting & Formatting
289
290
| Mode | Key      | Action                          |
291
|------+----------+---------------------------------|
292
| n    | <leader>cc | Run php-cs-fixer              |
293
| n    | <F3>     | Format (LSP)                    |
294
295
** Telescope
296
297
| Mode | Key         | Action                                  |
298
|------+-------------+-----------------------------------------|
299
| n    | <leader>ff  | Find files                              |
300
| n    | <leader>fg  | Git-tracked files                       |
301
| n    | <leader>fo  | Recent files                            |
302
| n    | <leader>fq  | Quickfix list                           |
303
| n    | <leader>fh  | Help tags                               |
304
| n    | <leader>fb  | Buffers                                 |
305
| n    | <leader>fs  | Grep string under cursor                |
306
| n    | <leader>fc  | Grep current filename (no extension)    |
307
| n    | <leader>fi  | Search in ~/.config/nvim                |
308
309
** Harpoon
310
311
| Mode | Key         | Action                           |
312
|------+-------------+----------------------------------|
313
| n    | <leader>a   | Add to Harpoon                   |
314
| n    | <C-e>       | Toggle Harpoon quick menu        |
315
| n    | <leader>fl  | Telescope Harpoon marks          |
316
| n    | <C-p>       | Prev Harpoon mark                |
317
| n    | <C-n>       | Next Harpoon mark                |
318
319
** LSP
320
321
| Mode     | Key     | Action                            |
322
|----------+---------+-----------------------------------|
323
| n        | K       | Hover docs                        |
324
| n        | gd      | Go to definition                  |
325
| n        | gD      | Go to declaration                 |
326
| n        | gi      | Go to implementation              |
327
| n        | go      | Go to type definition             |
328
| n        | gr      | List references                   |
329
| n        | gs      | Signature help                    |
330
| n        | gl      | Show diagnostics float            |
331
| n        | <F2>    | Rename symbol                     |
332
| n,x      | <F3>    | Format code                       |
333
| n        | <F4>    | Code actions                      |
334
335
** Misc
336
337
| Mode | Key         | Action                                     |
338
|------+-------------+--------------------------------------------|
339
| n    | <leader>dg  | Run DogeGenerate                           |
340
| n    | <leader>s   | Replace word on current line               |
341
342
343
* Final Thoughts
344
345
You're now ready to use Neovim as a modern, fast, and extensible code editor.
346
347
Thanks so much for checking out this tutorial. If you got value from it, and you want to find more tutorials like this, check out
348
my youtube channel here: [[https://youtube.com/@tony-btw][YouTube]], or my website here: [[https://www.tonybtw.com][tony,btw]]
349
350
You can support me here: [[https://ko-fi.com/tonybtw][kofi]]