DEV Community

Alex Avetisov
Alex Avetisov

Posted on

Multifunctional IDE using Neovim (2 of 3)

Let's make it better

We are done with the basic settings, now let's move on to improving our working environment. We will add convenient file navigation, a search engine and much more.

let's start with the explorer, everything is pretty standard here, we install the required plugin and write its configuration in a separate file.

GitHub logo nvim-tree / nvim-tree.lua

A file explorer tree for neovim written in lua

A File Explorer For Neovim Written In Lua

CI

Automatic updates

File type icons

Git integration

Diagnostics integration: LSP and COC

(Live) filtering

Cut, copy, paste, rename, delete, create

Highly customisable



Take a look at the wiki for Showcases, Tips, Recipes and more.

Questions and general support: Discussions

Requirements

neovim >=0.9.0

nvim-web-devicons is optional and used to display file icons. It requires a patched font. Your terminal emulator must be configured to use that font, usually "Hack Nerd Font"

Install

Please install via your preferred package manager. See Installation for specific package manager instructions.

nvim-tree/nvim-tree.lua

Major or minor versions may be specified via tags: v<MAJOR> e.g. v1 or v<MAJOR>.<MINOR> e.g. v1.23

nvim-tree/nvim-web-devicons optional, for file icons

Disabling netrw is strongly advised, see :help nvim-tree-netrw

Quick Start

Setup

Setup the plugin in your init.lua

-- disable netrw at the very start of your init.lua
vim.g.loaded_netrw = 1
Enter fullscreen mode Exit fullscreen mode

Adding a plugin to init.lua

--init.lua


require("lazy").setup({
---

  {
    "nvim-tree/nvim-tree.lua",
    dependencies = { "nvim-tree/nvim-web-devicons" },
  },

---

})
Enter fullscreen mode Exit fullscreen mode

Create a new file tree_config.lua and write all of this:

--tree_config.lua

vim.g.loaded_netrw = 1
vim.g.loaded_netrwPlugin = 1

vim.opt.termguicolors = true

require("nvim-tree").setup({
    sort = {
        sorter = "case_sensitive",
    },
    view = {
        width = 35,
    },
    renderer = {
        group_empty = true,
        icons = {
            glyphs = {
                git = {
                    unstaged = "",
                    staged = "S",
                    unmerged = "",
                    renamed = "",
                    untracked = "U",
                    deleted = "",
                    ignored = "◌",
                },
            },
        },
    },
    git = {
        enable = true,
        ignore = false,
        show_on_dirs = true,
        show_on_open_dirs = true,
    },
    filters = {
        dotfiles = false,
    },
    diagnostics = {
        enable = true,
        show_on_dirs = true,
        icons = {
            hint = "",
            info = "",
            warning = "",
            error = "",
        },
    },
})

--Open Expkorer
vim.keymap.set("n", "<leader>e", "<cmd>NvimTreeToggle<cr>")
--Change focus from code to Explorer
vim.keymap.set("n", "<C-h>", "<C-w>w")
Enter fullscreen mode Exit fullscreen mode

Now let's add a plugin for quick search of files or text in files, for this you need to install telescope.nvim. Everything is as always, we install via init.lua and create a new file.

GitHub logo nvim-telescope / telescope.nvim

Find, Filter, Preview, Pick. All lua, all the time.

telescope.nvim

Gitter LuaRocks

Gaze deeply into unknown regions using the power of the moon.

What Is Telescope?

telescope.nvim is a highly extendable fuzzy finder over lists. Built on the latest awesome features from neovim core. Telescope is centered around modularity, allowing for easy customization.

Community driven builtin pickers, sorters and previewers.

Preview For more showcases of Telescope, please visit the Showcase section in the Telescope Wiki

Telescope Table of Contents

Getting Started

This section should guide you to run your first builtin pickers.

Neovim (v0.9.0) or the latest neovim nightly commit is required for telescope.nvim to work. The neovim version also needs to be compiled with LuaJIT, we currently do not support Lua5.1 because of some ongoing issues.

Required dependencies

Suggested dependencies


--init.lua

require("lazy").setup({
---

  {
    "nvim-telescope/telescope.nvim",
    --The version is entered manually, so it may differ from the latest, so enter the version from the repository
    tag = "0.1.8",
    dependencies = { "nvim-lua/plenary.nvim" },
  },
---

})
Enter fullscreen mode Exit fullscreen mode

And now let's set up our plugin a little. Create a file telescope_config.lua

---telescope_config.lua

require("telescope").setup({
  defaults = {
    file_ignore_patterns = {
      "node_modules",
      "yarn.lock"
    },
    dynamic_preview_title = true,
    path_directory = "smart"
  }
})

local builtin = require("telescope.builtin")
vim.keymap.set("n", "<leader>ff", builtin.find_files, {})
vim.keymap.set("n", "<leader>fb", builtin.buffers, {})
vim.keymap.set("n", "<leader>fh", builtin.help_tags, {})
vim.keymap.set("n", "<leader>fr", builtin.oldfiles, {})
Enter fullscreen mode Exit fullscreen mode

Now let's add auto-completion to our config. For this we will use nvim-cmp install it in the way we are already familiar with.

GitHub logo hrsh7th / nvim-cmp

A completion plugin for neovim coded in Lua.

nvim-cmp

A completion engine plugin for neovim written in Lua Completion sources are installed from external repositories and "sourced".

demo.mp4

Readme!

  1. There is a GitHub issue that documents breaking changes for nvim-cmp. Subscribe to the issue to be notified of upcoming breaking changes.
  2. This is my hobby project. You can support me via GitHub sponsors.
  3. Bug reports are welcome, but don't expect a fix unless you provide minimal configuration and steps to reproduce your issue.
  4. The cmp.mapping.preset.* is pre-defined configuration that aims to mimic neovim's native like behavior. It can be changed without announcement. Please manage key-mapping by yourself.

Concept

  • Full support for LSP completion related capabilities
  • Powerful customizability via Lua functions
  • Smart handling of key mappings
  • No flicker

Setup

Recommended Configuration

This example configuration uses vim-plug as the plugin manager and vim-vsnip as a snippet plugin.

call plug#begin(s:plug_dir)
Plug 'neovim/nvim-lspconfig'
Enter fullscreen mode Exit fullscreen mode

--init.lua

require("lazy").setup({
---

  { "hrsh7th/cmp-nvim-lsp" },
  { "hrsh7th/cmp-buffer" },
  { "hrsh7th/cmp-path" },
  { "hrsh7th/cmp-cmdline" },
  { "hrsh7th/nvim-cmp" },
  { "hrsh7th/cmp-vsnip" },
  { "hrsh7th/vim-vsnip" },
  { "L3MON4D3/LuaSnip" },
  { "saadparwaiz1/cmp_luasnip" },
---

})
Enter fullscreen mode Exit fullscreen mode

Create a new file cmp_config.lua

--cmp_config.lua

local cmp = require('cmp')

local kind_icons = {
  Text = "",
  Method = "󰆧",
  Function = "󰊕",
  Constructor = "",
  Field = "󰇽",
  Variable = "󰂡",
  Class = "󰠱",
  Interface = "",
  Module = "",
  Property = "󰜢",
  Unit = "",
  Value = "󰎠",
  Enum = "",
  Keyword = "󰌋",
  Snippet = "",
  Color = "󰏘",
  File = "󰈙",
  Reference = "",
  Folder = "󰉋",
  EnumMember = "",
  Constant = "󰏿",
  Struct = "",
  Event = "",
  Operator = "󰆕",
  TypeParameter = "󰅲",
}


cmp.setup({
  formatting = {
    format = function(entry, vim_item)
      vim_item.kind = string.format('%s %s', kind_icons[vim_item.kind], vim_item.kind)
      vim_item.menu = ({
        buffer = "[Buffer]",
        nvim_lsp = "[LSP]",
        luasnip = "[LuaSnip]",
        nvim_lua = "[Lua]",
        latex_symbols = "[LaTeX]",
      })[entry.source.name]
      return vim_item
    end
  },
  snippet = {
    expand = function(args)
      vim.fn["vsnip#anonymous"](args.body)
    end,
  },
  mapping = cmp.mapping.preset.insert({
    ['<C-b>'] = cmp.mapping.scroll_docs(-4),
    ['<C-f>'] = cmp.mapping.scroll_docs(4),
    ['<C-Space>'] = cmp.mapping.complete(),
    ['<C-e>'] = cmp.mapping.abort(),
    ['<CR>'] = cmp.mapping.confirm({ select = true }),
  }),
  sources = cmp.config.sources({
    { name = 'nvim_lsp' },
    { name = 'luasnip' },
  }, {
    { name = 'buffer' },
  })
})

cmp.setup.filetype('gitcommit', {
  sources = cmp.config.sources({
    { name = 'git' },
  }, {
    { name = 'buffer' },
  })
})

cmp.setup.cmdline({ '/', '?' }, {
  mapping = cmp.mapping.preset.cmdline(),
  sources = {
    { name = 'buffer' }
  }
})

cmp.setup.cmdline(':', {
  mapping = cmp.mapping.preset.cmdline(),
  sources = cmp.config.sources({
    { name = 'path' }
  }, {
    { name = 'cmdline' }
  })
})
Enter fullscreen mode Exit fullscreen mode

Well, let's quickly write a config for treesitter. Nvim-treesitter is based on three interlocking features: language parsers, queries, and modules, where modules provide features – e.g., highlighting.

GitHub logo nvim-treesitter / nvim-treesitter

Nvim Treesitter configurations and abstraction layer

nvim-treesitter



Matrix Chat


Linting and Style


Syntax files


Logo

Treesitter configurations and abstraction layer for Neovim

Logo by @steelsojka

The goal of nvim-treesitter is both to provide a simple and easy way to use the interface for tree-sitter in Neovim and to provide some basic functionality such as highlighting based on it:

example-cpp

Traditional highlighting (left) vs Treesitter-based highlighting (right) More examples can be found in our gallery.

Warning: Treesitter and nvim-treesitter highlighting are an experimental feature of Neovim. Please consider the experience with this plug-in as experimental until Tree-Sitter support in Neovim is stable! We recommend using the nightly builds of Neovim if possible. You can find the current roadmap here. The roadmap and all features of this plugin are open to change, and any suggestion will be highly appreciated!

Nvim-treesitter is based on three interlocking features: language parsers, queries, and modules, where modules provide features – e.g., highlighting – based on…

To install, add it to lazy.nvim


require("lazy").setup({
---

  { "nvim-treesitter/nvim-treesitter" },

---

})
Enter fullscreen mode Exit fullscreen mode

And as always, we write the configuration in a separate file:

--treesitter_config.lua

require 'nvim-treesitter.configs'.setup {
  -- A list of parser names, or "all" (the five listed parsers should always be installed)
  ensure_installed = { "lua", "vim", "vimdoc", "query", "javascript", "typescript", "html", "css", "rust", "markdown", "json" },

  sync_install = false,
  auto_install = true,

  highlight = {
    enable = true,
    additional_vim_regex_highlighting = false,
  },
  autotag = {
    enable = true,
  }
}

vim.opt.foldmethod = "expr"
vim.opt.foldexpr = "nvim_treesitter#foldexpr()"
vim.opt.foldenable = false
Enter fullscreen mode Exit fullscreen mode

There is a small plugin that allows you to link brackets by color, let's add it.


require("lazy").setup({
---

  { "lukas-reineke/indent-blankline.nvim", main = "ibl", opts = {} },

---

})
Enter fullscreen mode Exit fullscreen mode

Create a new file indent_config.lua:

If you don't like the colorful theme, you can make the configuration more down to earth, but I like when the brackets are different colors.

--indent_config.lua

local highlight = {
  "RainbowRed",
  "RainbowYellow",
  "RainbowBlue",
  "RainbowOrange",
  "RainbowGreen",
  "RainbowViolet",
  "RainbowCyan",
}

local hooks = require "ibl.hooks"
hooks.register(hooks.type.HIGHLIGHT_SETUP, function()
  vim.api.nvim_set_hl(0, "RainbowRed", { fg = "#E06C75" })
  vim.api.nvim_set_hl(0, "RainbowYellow", { fg = "#E5C07B" })
  vim.api.nvim_set_hl(0, "RainbowBlue", { fg = "#61AFEF" })
  vim.api.nvim_set_hl(0, "RainbowOrange", { fg = "#D19A66" })
  vim.api.nvim_set_hl(0, "RainbowGreen", { fg = "#98C379" })
  vim.api.nvim_set_hl(0, "RainbowViolet", { fg = "#C678DD" })
  vim.api.nvim_set_hl(0, "RainbowCyan", { fg = "#56B6C2" })
end)

require("ibl").setup { indent = { highlight = highlight } }
Enter fullscreen mode Exit fullscreen mode

Let's add two small plugins to improve your comments in code right away. The first plugin allows you to quickly comment one or more lines with one key. The second plugin allows you to expand comments, leaving notes like in a to-do list.

--init.lua

require("lazy").setup({
---

  {
    "numToStr/Comment.nvim",
    lazy = false,
  },
  {
    "folke/todo-comments.nvim",
    dependencies = { "nvim-lua/plenary.nvim" },
  },

---

})
Enter fullscreen mode Exit fullscreen mode

And configure each of them in their own file, although for the comment switcher this is not really necessary, you can just call it in our init.lua file, but I'd rather separate it into a separate file.

--comment_config.lua

require('Comment').setup()
Enter fullscreen mode Exit fullscreen mode
--todo_config.lua

require("todo-comments").setup({
  signs = true,      
  sign_priority = 8, 

  keywords = {
    FIX = {
      icon = " ", 
      color = "error", 
      alt = { "FIXME", "BUG", "FIXIT", "ISSUE" }, 
    },
    TODO = { icon = " ", color = "info" },
    HACK = { icon = " ", color = "warning" },
    WARN = { icon = " ", color = "warning", alt = { "WARNING", "XXX" } },
    PERF = { icon = " ", alt = { "OPTIM", "PERFORMANCE", "OPTIMIZE" } },
    NOTE = { icon = " ", color = "hint", alt = { "INFO" } },
    TEST = { icon = "⏲ ", color = "test", alt = { "TESTING", "PASSED", "FAILED" } },
  },
  gui_style = {
    fg = "NONE",         
    bg = "BOLD",         
  },
  merge_keywords = true,
  highlight = {
    multiline = true,                
    multiline_pattern = "^.",        
    multiline_context = 10,          
    before = "",                     
    keyword = "wide",
    after = "fg",                    
    pattern = [[.*<(KEYWORDS)\s*:]], 
    comments_only = true,            
    max_line_len = 400,              
    exclude = {},                    
  },
  colors = {
    error = { "DiagnosticError", "ErrorMsg", "#DC2626" },
    warning = { "DiagnosticWarn", "WarningMsg", "#FBBF24" },
    info = { "DiagnosticInfo", "#2563EB" },
    hint = { "DiagnosticHint", "#10B981" },
    default = { "Identifier", "#7C3AED" },
    test = { "Identifier", "#FF00FF" }
  },
  search = {
    command = "rg",
    args = {
      "--color=never",
      "--no-heading",
      "--with-filename",
      "--line-number",
      "--column",
    },
    -- regex that will be used to match keywords.
    -- don't replace the (KEYWORDS) placeholder
    pattern = [[\b(KEYWORDS):]], -- ripgrep regex
    -- pattern = [[\b(KEYWORDS)\b]], -- match without the extra colon. You'll likely get false positives
  },
})

vim.keymap.set("n", "]t", function()
  require("todo-comments").jump_next()
end, { desc = "Next todo comment" })

vim.keymap.set("n", "[t", function()
  require("todo-comments").jump_prev()
end, { desc = "Previous todo comment" })

--to search by comments
vim.keymap.set("n", "<leader>ft", "<cmd>TodoTelescope<cr>")
Enter fullscreen mode Exit fullscreen mode

for css I use colorizer to immediately see what color palette I applied to a given class, installation and configuration is simple

--init.lua

require("lazy").setup({
---

  { "norcalli/nvim-colorizer.lua" },

---

})
Enter fullscreen mode Exit fullscreen mode
--conlorizer_config.lua

require("colorizer").setup({
    "*",
}, {
    names = true,
    rgb_fn = true,
    RGB = true,
    RRGGBB = true,
    RRGGBBAA = true,
    hsl_fn = true,
    css = true,
    css_fn = true,
    mode = "background",
})
Enter fullscreen mode Exit fullscreen mode

Now our vim looks much better, but it's not over yet, there's the last section left, in it we will integrate separate cli inside our vim, further improve the UI and add many new features

Top comments (0)