Multifunctional IDE using Neovim (3 of 3)

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,
},

})

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,
},

})

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

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

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

–init.lua

require(“lazy”).setup({

{“nvimdev/lspsaga.nvim”},

})

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

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.


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!

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:

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.


jesseduffield
/
lazygit

simple terminal UI for git commands

Special thanks to:

Warp is a modern, Rust-based terminal with AI built in so you and your team can build great software, faster.

Visit warp.dev to learn more.


I (Jesse) co-founded Subble to save your company time and money by helping you manage its software subscriptions. Check it out!

A simple terminal UI for git commands

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

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’ },

})

for quick access you can set keymap:

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

–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:

–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, then write a small config for it in init.lua and everything is ready:

–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:


Home | Tabby

Description will go into a meta tag in <head />

tabby.tabbyml.com

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