DEV Community

Alex Avetisov
Alex Avetisov

Posted on

Multifunctional IDE using Neovim (3 of 3)

God mode activation

Ok, here is the last section, let's summarize what we will do here. First, we will add a start page, just for beauty; if you use Obsidian, then it can be integrated into vim, this is also on our plan today; we will add a preview of .md files; cli for working with git; a very large and cool plugin for improving the UI, which combines a buffer, an integrated terminal, navigation tips, git integration and much more; and most importantly - where would we be without AI in 2024 (⌒ω⌒)

Let's start with something simpler, preview of md files, we will not configure it, as for me it is more convenient to launch it through the vim command, but if you want you can configure it for yourself.



--init.lua

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

  {
    "iamcco/markdown-preview.nvim",
    cmd = { "MarkdownPreviewToggle", "MarkdownPreview", "MarkdownPreviewStop" },
    ft = { "markdown" },
    build = function()
      vim.fn["mkdp#util#install"]()
    end,
  },

---

})



Enter fullscreen mode Exit fullscreen mode

Let's now create a start page, you can add an image in ASCII format to it, google the image to your taste, but for example I will choose this:



--init.lua

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

    {
    "goolord/alpha-nvim",
    config = function()
      require("alpha").setup(require("alpha.themes.dashboard").config)
    end,
    },

---

})


Enter fullscreen mode Exit fullscreen mode


--alpha_config.lua

local alpha = require("alpha")
local dashboard = require("alpha.themes.dashboard")

dashboard.section.header.val = {
    "⠄⠄⠄⢰⣧⣼⣯⠄⣸⣠⣶⣶⣦⣾⠄⠄⠄⠄⡀⠄⢀⣿⣿⠄⠄⠄⢸⡇⠄⠄",
    "⠄⠄⠄⣾⣿⠿⠿⠶⠿⢿⣿⣿⣿⣿⣦⣤⣄⢀⡅⢠⣾⣛⡉⠄⠄⠄⠸⢀⣿⠄",
    "⠄⠄⢀⡋⣡⣴⣶⣶⡀⠄⠄⠙⢿⣿⣿⣿⣿⣿⣴⣿⣿⣿⢃⣤⣄⣀⣥⣿⣿⠄",
    "⠄⠄⢸⣇⠻⣿⣿⣿⣧⣀⢀⣠⡌⢻⣿⣿⣿⣿⣿⣿⣿⣿⣿⠿⠿⠿⣿⣿⣿⠄",
    "⠄⢀⢸⣿⣷⣤⣤⣤⣬⣙⣛⢿⣿⣿⣿⣿⣿⣿⡿⣿⣿⡍⠄⠄⢀⣤⣄⠉⠋⣰",
    "⠄⣼⣖⣿⣿⣿⣿⣿⣿⣿⣿⣿⢿⣿⣿⣿⣿⣿⢇⣿⣿⡷⠶⠶⢿⣿⣿⠇⢀⣤",
    "⠘⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣽⣿⣿⣿⡇⣿⣿⣿⣿⣿⣿⣷⣶⣥⣴⣿⡗",
    "⢀⠈⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡟⠄",
    "⢸⣿⣦⣌⣛⣻⣿⣿⣧⠙⠛⠛⡭⠅⠒⠦⠭⣭⡻⣿⣿⣿⣿⣿⣿⣿⣿⡿⠃⠄",
    "⠘⣿⣿⣿⣿⣿⣿⣿⣿⡆⠄⠄⠄⠄⠄⠄⠄⠄⠹⠈⢋⣽⣿⣿⣿⣿⣵⣾⠃⠄",
    "⠄⠘⣿⣿⣿⣿⣿⣿⣿⣿⠄⣴⣿⣶⣄⠄⣴⣶⠄⢀⣾⣿⣿⣿⣿⣿⣿⠃⠄⠄",
    "⠄⠄⠈⠻⣿⣿⣿⣿⣿⣿⡄⢻⣿⣿⣿⠄⣿⣿⡀⣾⣿⣿⣿⣿⣛⠛⠁⠄⠄⠄",
    "⠄⠄⠄⠄⠈⠛⢿⣿⣿⣿⠁⠞⢿⣿⣿⡄⢿⣿⡇⣸⣿⣿⠿⠛⠁⠄⠄⠄⠄⠄",
    "⠄⠄⠄⠄⠄⠄⠄⠉⠻⣿⣿⣾⣦⡙⠻⣷⣾⣿⠃⠿⠋⠁⠄⠄⠄⠄⠄⢀⣠⣴",
    "⣿⣿⣿⣶⣶⣮⣥⣒⠲⢮⣝⡿⣿⣿⡆⣿⡿⠃⠄⠄⠄⠄⠄⠄⠄⣠⣴⣿⣿⣿",
}

dashboard.section.buttons.val = {
    dashboard.button("<leader> ft", "T  > Find Text", "<CMD> Telescope live_grep<CR>"),
    dashboard.button("<leader> ff", "  > Find File", "<CMD>Telescope find_files<CR>"),
    dashboard.button("<Leader> fr", "  > Recent", ":Telescope oldfiles<CR>"),
    dashboard.button("<leader>  q", "  > Quit NVIM", ":qa<CR>"),
}

alpha.setup(dashboard.opts)

vim.cmd([[
    autocmd FileType alpha setlocal nofoldenable
]])


Enter fullscreen mode Exit fullscreen mode

...I'm a terrible person, I know ( ̄□ ̄」)

I love Obsidian, it's a very handy management and note taking app, so to have quick access to it I decided to add it here.



--init.lua

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

{
    "epwalsh/obsidian.nvim",
    version = "*",
    lazy = true,
    ft = "markdown",

    keys = {
      { "<leader>on", "<cmd>ObsidianNew<cr>",         desc = "New Obsidian note",               mode = "n" },
      { "<leader>oo", "<cmd>ObsidianSearch<cr>",      desc = "Search Obsidian notes",           mode = "n" },
      { "<leader>os", "<cmd>ObsidianQuickSwitch<cr>", desc = "Quick Switch",                    mode = "n" },
      { "<leader>ob", "<cmd>ObsidianBacklinks<cr>",   desc = "Show location list of backlinks", mode = "n" },
      { "<leader>ot", "<cmd>ObsidianTemplate<cr>",    desc = "Follow link under cursor",        mode = "n" },
    },
    dependencies = {
      "nvim-lua/plenary.nvim",
    },
  },

---

})


Enter fullscreen mode Exit fullscreen mode

I will warn you in advance that you need to manually specify the path to the folder with all your files, I will highlight this line in the code, in it just write the path to your Obsidian folder.



--obsidian_config.lua

require("obsidian").setup({
  workspaces = {
    {
      --Specify the name that is convenient for you, and be sure to specify the path to your folder
      name = "Name",
      path = "Path",
    },
  },
  completion = {
    nvim_cmp = true,
    min_chars = 2,
  },
  new_notes_location = "current_dir",
  wiki_link_func = function(opts)
    if opts.id == nil then
      return string.format("[[%s]]", opts.label)
    elseif opts.label ~= opts.id then
      return string.format("[[%s|%s]]", opts.id, opts.label)
    else
      return string.format("[[%s]]", opts.id)
    end
  end,

  mappings = {
    -- "Obsidian follow"
    ["<leader>of"] = {
      action = function()
        return require("obsidian").util.gf_passthrough()
      end,
      opts = { noremap = false, expr = true, buffer = true },
    },
    -- Toggle check-boxes "obsidian done"
    ["<leader>od"] = {
      action = function()
        return require("obsidian").util.toggle_checkbox()
      end,
      opts = { buffer = true },
    },
    -- Create a new newsletter issue
    ["<leader>onn"] = {
      action = function()
        return require("obsidian").commands.new_note("Newsletter-Issue")
      end,
      opts = { buffer = true },
    },
    ["<leader>ont"] = {
      action = function()
        return require("obsidian").util.insert_template("Newsletter-Issue")
      end,
      opts = { buffer = true },
    },
  },

  note_frontmatter_func = function(note)
    local out = { Title = "None", Complete = false, tags = note.tags }

    if note.metadata ~= nil and not vim.tbl_isempty(note.metadata) then
      for k, v in pairs(note.metadata) do
        out[k] = v
      end
    end
    return out
  end,

  note_id_func = function(title)
    local suffix = ""
    if title ~= nil then
      suffix = title:gsub(" ", "-"):gsub("[^A-Za-z0-9-]", ""):lower()
    else
      for _ = 1, 4 do
        suffix = suffix .. string.char(math.random(65, 90))
      end
    end
    return tostring(os.time()) .. "-" .. suffix
  end,

  templates = {
    subdir = "Templates",
    date_format = "%Y-%m-%d-%a",
    time_format = "%H:%M",
    tags = "",
  },
})

vim.opt.conceallevel = 1


Enter fullscreen mode Exit fullscreen mode

The next step is to add one very powerful tool that will improve your vim experience.



--init.lua

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

  {"nvimdev/lspsaga.nvim"},

---

})


Enter fullscreen mode Exit fullscreen mode

And let's set it up accordingly.



--lsp_config.lua

require("lspsaga").setup({
  ui = {
    border = "rounded",
    code_action = "",
  },
})

vim.keymap.set("n", "[d", "<cmd>Lspsaga diagnostic_jump_prev<cr>")
vim.keymap.set("n", "]d", "<cmd>Lspsaga diagnostic_jump_next<cr>")
vim.keymap.set("n", "<leader>lo", "<cmd>Lspsaga outline<cr>")
vim.keymap.set("n", "<leader>k", "<cmd>Lspsaga hover_doc<cr>", { silent = true })
--this terminal is from the next plugin, it just won't work!!!
vim.keymap.set({ 'n', 't' }, [[<c-\>]], '<cmd>Lspsaga term_toggle<cr>')
vim.keymap.set('n', '<leader>lci', '<cmd>Lspsaga incoming_calls<cr>')
vim.keymap.set('n', '<leader>lco', '<cmd>Lspsaga outgoing_calls<cr>')
local builtin = require("telescope.builtin")

vim.api.nvim_create_autocmd("LspAttach", {
  group = vim.api.nvim_create_augroup("UserLspConfig", {}),
  callback = function(ev)
    vim.bo[ev.buf].omnifunc = "v:lua.vim.lsp.omnifunc"

    local opts = { buffer = ev.buf }
    vim.keymap.set("n", "gd", "<cmd>Lspsaga goto_definition<cr>", opts)
    vim.keymap.set("n", "<leader>lr", "<cmd>Lspsaga rename<cr>", opts)
    vim.keymap.set({ "n", "v" }, "<leader>la", "<cmd>Lspsaga code_action<cr>", opts)
    vim.keymap.set("n", "gr", builtin.lsp_references, opts)
  end,
})


Enter fullscreen mode Exit fullscreen mode

Now I want to clarify the situation a little, the next plugin has quite a large code, so I will not write it here, otherwise half of this article will be only for it. Therefore, I came to a consensus, I will just leave a link to this plugin and recommend that you figure it out yourself, it is not difficult, you just copy and paste the code from their manual to yourself. You can also configure it at your own discretion. I will only say that it has a buffer zone, you can improve the explorer we already have, install a git observer and many other informative things.

GitHub logo rebelot / heirline.nvim

Heirline.nvim is a no-nonsense Neovim Statusline plugin designed around recursive inheritance to be exceptionally fast and versatile.

heirline.nvim

The ultimate Neovim Statusline for tinkerers

About

Heirline.nvim is a no-nonsense Neovim plugin made for rendering statusline/winbar/tabline/statuscolumn format strings. It is designed around recursive inheritance to be exceptionally fast and versatile.

Heirline does not provide any defaults, in fact, heirline can be thought of as an API to generate Vim status format strings.

Why another statusline plugin?

Heirline picks up from other popular customizable statusline plugins like galaxyline and feline but removes all the hard-coded guides and offers you thousands times more freedom. But freedom has a price: responsibility. I don't get to tell you what your statusline should do. You're in charge! With Heirline, you have a framework to easily implement whatever you can imagine, from simple to complex rules!

heirline_prev

Features:

  • Conditionals: Build custom active/inactive and buftype/filetype/bufname statuslines or single components.
  • Highlight propagation: Seamlessly surround components within separators and/or set the (dynamic) coloring of a…




As a result, you should get something like this, when I was setting it up, I broke everything down into separate components, just to make it more convenient:

Neovim config

Let's integrate lazygit into our config, it provides a git interface to visualize your project. But first you need to install it on your device.

GitHub logo jesseduffield / lazygit

simple terminal UI for git commands

A simple terminal UI for git commands

GitHub Releases Go Report Card Codacy Badge Codacy Badge GolangCI GitHub tag homebrew

commit_and_push

Sponsors

Maintenance of this project is made possible by all the contributors and sponsors. If you'd like to sponsor this project and have your avatar or company logo appear below click here. 💙

Mark LussierDean HerbertPeter BjorklundReilly WoodOliver GüntherPawan DhananjayBartłomiej DachCarsten GehlingCEUKAkos PutzHolden LucasChau TranmatejciktheAverageDev (Luca Tumedei)Ivan ZaitsevNicholas CloudLightQuantumGabriel SaillardAliaksandr StelmachonakBurgy BenjaminJoe KlemmerTobias LütkeBen BeaumontHollyJeff ForcierMaciej T. NowakFarzad MajidfayyazYuryAndreas KurthBraden SteffaniakJordan GillardSebastianGeorge SpanosAndy SlezakMartin KockIllarion KoperskiJesse AlamaCodacyBrettJan HeijmansKevin Nowaldsem pruijsOmar Luq Nicholas MoenEthan LiBrian MacAskillMaxinbrMiguel IbarsJan ZenknerVictor AremuIgor RamazanovElliott Maguiren8n - Workflow AutomationJosh ThomasJJFrederick MorlockDarren CraineMaximilian LangenfeldNurzhanDavis BulsChris OlsenNeil LambertDavid Heinemeier HanssonMikhailMarco Aurelio Caldas MirandaEmmanuel NosakhareEthan FischerTerry TaiAdam RoesnerAndy HerdWassim MetallaouiTornike GomareliTim MorganMax ShypulniakMeshan Naidookyu08Felipe PiacsekdimaunxKovács Ádám叶博Dusan LesanIan TanMaulik KatariaChanhLyEnzo SterroThomas Feldmann

Elevator Pitch

Rant time: You've heard it before, git is powerful, but what good is that power when everything is so damn hard to do? Interactive rebasing requires you to edit a goddamn TODO file in your editor? Are you kidding me? To stage part of a file you need to use a command line program to step…




After installation, install the plugin:



--init.lua

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

  { 'kdheepak/lazygit.nvim' },

---

})


Enter fullscreen mode Exit fullscreen mode

for quick access you can set keymap:



--keymap.lua

---
kmap.set("n", "<leader>gg", "<cmd>lazyGit<cr>")


Enter fullscreen mode Exit fullscreen mode

The penultimate plugin will be the simplest, it will simply prompt you for key combinations, the combinations that you have written down yourself are duplicated here.



--init.lua

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

  {
    "folke/which-key.nvim",
    event = "VeryLazy",
    init = function()
      vim.o.timeout = true
      vim.o.timeoutlen = 300
    end,
  },

---

})


Enter fullscreen mode Exit fullscreen mode

The configuration is appropriate:



--whichkey_config.lua

require("which-key").setup({
  plugins = {
    marks = true,    -- shows a list of your marks on ' and `
    registers = true, -- shows your registers on " in NORMAL or <C-r> in INSERT mode
    spelling = {
      enabled = true, -- enabling this will show WhichKey when pressing z= to select spelling suggestions
      suggestions = 20, -- how many suggestions should be shown in the list?
    },
    presets = {
      operators = true, -- adds help for operators like d, y, ...
      motions = true,   -- adds help for motions
      text_objects = true, -- help for text objects triggered after entering an operator
      windows = true,   -- default bindings on <c-w>
      nav = true,       -- misc bindings to work with windows
      z = true,         -- bindings for folds, spelling and others prefixed with z
      g = true,         -- bindings for prefixed with g
    },
  },
  operators = { gc = "Comments" },
  motions = {
    count = true,
  },
  icons = {
    breadcrumb = "»", -- symbol used in the command line area that shows your active key combo
    separator = "➜", -- symbol used between a key and it's label
    group = "+", -- symbol prepended to a group
  },
  popup_mappings = {
    scroll_down = "<c-d>", -- binding to scroll down inside the popup
    scroll_up = "<c-u>", -- binding to scroll up inside the popup
  },
  window = {
    border = "single",      -- none, single, double, shadow
    position = "bottom",    -- bottom, top
    margin = { 2, 1, 2, 1 }, -- extra window margin [top, right, bottom, left]. When between 0 and 1, will be treated as a percentage of the screen size.
    padding = { 1, 2, 1, 2 }, -- extra window padding [top, right, bottom, left]
    winblend = 50,          -- value between 0-100 0 for fully opaque and 100 for fully transparent
    zindex = 1000,          -- positive value to position WhichKey above other floating windows.
  },
  layout = {
    height = { min = 4, max = 25 },                                                -- min and max height of the columns
    width = { min = 20, max = 50 },                                                -- min and max width of the columns
    spacing = 3,                                                                   -- spacing between columns
    align = "center",                                                              -- align columns left, center or right
  },
  ignore_missing = false,                                                          -- enable this to hide mappings for which you didn't specify a label
  hidden = { "<silent>", "<cmd>", "<Cmd>", "<CR>", "^:", "^ ", "^call ", "^lua " }, -- hide mapping boilerplate
  show_help = true,                                                                -- show a help message in the command line for using WhichKey
  show_keys = true,                                                                -- show the currently pressed key and its label as a message in the command line
  triggers = "auto",                                                               -- automatically setup triggers
  triggers_nowait = {
    "`",
    "'",
    "g`",
    "g'",
    '"',
    "<c-r>",
    "z=",
  },
  triggers_blacklist = {
    i = { "j", "k" },
    v = { "j", "k" },
  },
  disable = {
    buftypes = {},
    filetypes = {},
  },
})

require("which-key").register({
  f = {
    name = "File",
    f = { "<cmd>Telescope find_files<cr>", "Find File" },
    t = { "<cmd>Telescope live_grep<cr>", "Find Text" },
    r = { "<cmd>Telescope oldfiles<cr>", "Old Files" },
    b = { "<cmd>Telescope buffers<cr>", "Find Buffer" },
    h = { "<cmd>Telescope help_tags<cr>", "Open Help Page" },
  },
  b = {
    name = "Buffers",
    c = { "<cmd>bd<cr>", "Close Current Buffer" },
  },
  g = {
    name = "Git",
    g = { "<cmd>LazyGit<cr>", "LazyGit" },
  },
  t = {
    name = "TypeScript Tools",
  },
  e = { "Sidebar" },
  q = { "Quit" },
  w = { "Save" },
  h = { "No highlight" },
  k = { "LSP Saga Documentation" },
  o = {
    name = "Obsidian Tools",
  },
  l = {
    name = "LSPsaga",
    o = "LSP Outline",
    r = "LSP Rename",
    t = "Open Terminal",
    a = "Code Action",
    c = {
      name = "Call Hierachy",
      i = "Inconming Calls",
      o = "Outgoing Calss",
    },
  },
}, { prefix = "<leader>" })
```
Well, the last thing I would like to do is to run our vim through neovide, but this is optional. First, you need to download it from the [official site](https://neovide.dev/), then write a small config for it in init.lua and everything is ready:

```lua
--init.lua

if vim.g.neovide then
  --if you want transparency, add it
  vim.g.neovide_transparency = 0.9
  --Write your font and its size
  vim.opt.guifont = { "JetBrainsMono Nerd Font", ":h12" }
  --Fill in the remaining fields at your discretion, whatever you like best
end
```

And finally the final boss, it is not as difficult as all before, although I would even say that there is nothing to do here. And so, installing the AI, first download the AI ​​model itself, look at how to install it on your device on the official website, in my case it is `brew install tabbyml/tabby/tabby`
Next install the plugin in _vim_:

{% embed https://tabby.tabbyml.com/ %}


```lua
--init.lua

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

  { "TabbyML/vim-tabby" },

---

})
```

Launch our server through this command and everything is ready:
`tabby serve --device metal --model StarCoder-1B`

Here we come to the end, in the end I will say that it turned out quite interesting, the config turned out not ideal, because there is always something that can be improved or improved. I wrote all this for the first time, I just wanted to try, and therefore criticism is welcome <( ̄︶ ̄)>

All the best to you, dear programmers.
Enter fullscreen mode Exit fullscreen mode

Top comments (0)