Posts Contact

Using Vim

When you thought you got to a good programming level and started feeling more confident someone mentioned `vim` You wonder if moving to a new code editor is a good idea after mastering all the tricks and shortcuts of your current editor/ idea

 

That is what I went through.

 

What is vim
 

Vim is a terminal text editor When I first got introduced to it. It was when I was following a tutorial online for setting up a Linux server I
was shocked to find that Linux terminals didn't have a fully configured Intellji IDE. So I looked into other program

 

I know there are ways to use Intellji and VSCode to connect to server but I just wanted to edit a file quickly without going through ton of
menus

 

Going into vim is like having your first blue windows freeze screen. Nothing makes sense - First you try to scroll (may work depending on
what terminal you use) - Try to type something but end up just seeing random text come and go away as if some one is controlling your PC - 

Lastly try to exist x_x. This is where most people get turned off

 

,and sadly that was me at the start

 

Later on I learned to how to enter insert mode and then save and exist and never used it for anything else other than server configured 

Then I started seeing the vim users all over my YT homepage I thought I would give it a try at my job with some of our FE projects
 

Setting up NeoVim

 

NeoVim is a modern fork of vim with a number of features that makes it easier to use. NeoVim offers a Lua scripting API which makes it easier to configure. Each setup is different to suit your dev environment I will go over the main parts of my setup
Link to the configurations files below 

 

 

Plugin manager and plugins

 

In order to have be able to install plugins you need to setup a plugin manager for NeoVim. Packer is a Lua based plugin manager with a large number of plugins integrated into it You can checkout how to install packer in their official docs here
 

Linux
 

git clone --depth 1 https://github.com/wbthomason/packer.nvim\
 ~/.local/share/nvim/site/pack/packer/start/packer.nvim

 

Windows

 

git clone https://github.com/wbthomason/packer.nvim "$env:LOCALAPPDATA\nvim-data\site\pack\packer\start\packer.nvim"

 

Then create a folder with in your current NeoVim config directory
`lua/packer-plugins.lua` To find your config path run
`echo stdpath('config')` in command mode


 

vim.cmd.packadd("packer.nvim")
return require("packer").startup(
    function(use)
        use "wbthomason/packer.nvim"
        -- other plugins go here
    end
)

 

And add this to your init.lua file
 

require("packer-plugins")

 

Then restart NeoVim
 

File finder

 

use {
   "nvim-telescope/telescope.nvim",
   tag = "0.1.4",
   requires = {{"nvim-lua/plenary.nvim"}}
}

 

Custom key bindings for telescope in init.lua
 

local builtin = require("telescope.builtin")
local function get_visual_selections()
   vim.cmd('noau normal! "vy"')
   return vim.fn.getreg("v")
end
vim.keymap.set("n", "ff", builtin.find_files, {})
vim.keymap.set("n", "fg", builtin.live_grep, {})
vim.keymap.set("n", "fb", builtin.buffers, {})

 

in plugin/telescope.lua
 

local telescope = require("telescope")
telescope.setup {
   pickers = {
       find_files = {
           hidden = true,
           file_ignore_patterns = {"node_modules/.*", ".git/"}
       },
       live_grep = {
           additional_args = function(opts)
               return {"--hidden"}
           end,
           file_ignore_patterns = {"node_modules/.*", ".git/"}
       }
   }
}

 

LSP and code format

 

In lua/packer-plugins.lua

use {
   "VonHeikemen/lsp-zero.nvim",
   branch = "v1.x",
   requires = {
       -- LSP Support
       {"neovim/nvim-lspconfig"},
       {"williamboman/mason.nvim"},
       {"williamboman/mason-lspconfig.nvim"},
       -- Autocompletion
       {"hrsh7th/nvim-cmp"},
       {"hrsh7th/cmp-buffer"},
       {"hrsh7th/cmp-path"},
       {"saadparwaiz1/cmp_luasnip"},
       {"hrsh7th/cmp-nvim-lsp"},
       {"hrsh7th/cmp-nvim-lua"},
       -- Snippets
       {"L3MON4D3/LuaSnip"},
       {"rafamadriz/friendly-snippets"}
   }
}
use {"sbdchd/neoformat"}

 

In plugin/lsp.lua
 

local lsp = require("lsp-zero").preset({})
-- When you don't have mason.nvim installed
-- You'll need to list the servers installed in your system
lsp.preset("recommended")
-- (Optional) Configure lua language server for neovim
--
lsp.on_attach(
   function(client, bufnr)
       -- see :help lsp-zero-keybindings
       -- to learn the available actions
       lsp.default_keymaps({buffer = bufnr})
   end
)
-- add your required servers
lsp.setup_servers({"tsserver", "eslint", "intelephense", "pyright"})
lsp.setup()
vim.diagnostic.config(
   {
       virtual_text = true,
       signs = true,
       update_in_insert = false,
       underline = true,
       severity_sort = false,
       float = true
   }
)

 

In init.lua
 

vim.api.nvim_set_keymap("n", "<leader>f", ":Neoformat | update <CR>", {})

 

To format the files
 

Git signs
 

To show git changes
 

use "lewis6991/gitsigns.nvim"

 

Status bar
 

In lua/packer-plugins.lua
 

use {
   "nvim-lualine/lualine.nvim",
   requires = {"nvim-tree/nvim-web-devicons", opt = true}
}

 

Editor's theme
 

in plugin/statusline.lua
 

local custom_them = require "lualine.themes.dracula"
local sections = {
   lualine_a = {
       {
           "filename",
           file_status = true, -- Displays file status (readonly status, modified status)
           newfile_status = false, -- Display new file status (new file means no write after created)
           path = 1, -- 0: Just the filename
           -- 1: Relative path
           -- 2: Absolute path
           -- 3: Absolute path, with tilde as the home directory
           -- 4: Filename and parent dir, with tilde as the home directory
           shorting_target = 40, -- Shortens path to leave 40 spaces in the window
           -- for other components. (terrible name, any suggestions?)
           symbols = {
               modified = "[+]", -- Text to show when the file is modified.
               readonly = "[-]", -- Text to show when the file is non-modifiable or readonly.
               unnamed = "[No Name]", -- Text to show for unnamed buffers.
               newfile = "[New]" -- Text to show for newly created file before first write
           }
       }
   }
}
require("lualine").setup {
   options = {theme = custom_them},
   sections = sections
}

 

Tree file view
 

While I don't use a Tree file view all the time but it helps sometimes
show the file hierarchy In lua/packer-plugins.lua
 

use {
   "nvim-neo-tree/neo-tree.nvim",
   branch = "v3.x",
   requires = {
       "nvim-lua/plenary.nvim",
       "nvim-tree/nvim-web-devicons", -- not strictly required, but recommended
       "MunifTanjim/nui.nvim"
   }
}

 

Custom setup
 

Tabs

 

I have made a few custom key mappings to help me create and navigate
tabs in init.lua
 

vim.api.nvim_set_keymap("n", "<C-t>", ":tabnew <CR>", {})
vim.api.nvim_set_keymap("n", "<C-w>", ":tabclose <CR>", {})
vim.api.nvim_set_keymap("n", "<C-a>", ":tabnext <CR>", {})
vim.api.nvim_set_keymap("n", "<C-q>", ":tabprevious <CR>", {})

 

Copy current path
 

Another custom setup that is very convenient to me is copying current file with current line to share it with other people that work on the same code base.

 

vim.keymap.set(
   "n",
   "<leader>cf",
   function()
       local linenum = vim.api.nvim_win_get_cursor(0)[1]
       local relative_filepath =
           string.gsub(vim.api.nvim_buf_get_name(0), escape_lua_pattern(vim.api.nvim_command_output("pw")), "")
       vim.cmd('let @"="' .. relative_filepath .. ":" .. linenum .. '"')
       vim.cmd('let @+="' .. relative_filepath .. ":" .. linenum .. '"')
       vim.api.nvim_notify("Copied filename to clipboard", 0, {})
   end,
   {noremap = true, silent = true}
)

 

Copy keymap 

 

vim.api.nvim_set_keymap("v", "c", '"+y', {})

 

Telescope search for highlighted text

 

Setup for live grep selected text

 

vim.keymap.set(
   "v",
   "fg",
   function()
       local text = get_visual_selections()
       builtin.live_grep({default_text = text})
   end,
   {noremap = true, silent = true}
)