Multifunctional IDE using Neovim (3 of 3)
Tags: neovim, javascript, rust, code
Published: 2024-06-14 12:52:55

### 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.

```lua
--init.lua

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

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

---

})

```

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:

```lua
--init.lua

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

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

---

})
```

```lua
--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
]])
```

...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.

```lua
--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",
    },
  },

---

})
```

> 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.

```lua
--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
```

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

```lua
--init.lua

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

  {"nvimdev/lspsaga.nvim"},

---

})
```

And let's set it up accordingly.

```lua
--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,
})
```

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.

{% embed https://github.com/rebelot/heirline.nvim %}

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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/o8a548i68q3euh2imj4v.png)

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.

{% embed https://github.com/jesseduffield/lazygit#installation %}

After installation, install the plugin:

```lua
--init.lua

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

  { 'kdheepak/lazygit.nvim' },

---

})
```

for quick access you can set keymap:

```lua
--keymap.lua

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

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.


```lua
--init.lua

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

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

---

})
```

The configuration is appropriate:

```lua
--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.