Post

My neovim markdown setup in 2025

Here I list all the plugins, tips and tricks I use for taking markdown notes in neovim as of January 2025

My neovim markdown setup in 2025

Contents

Table of contents

YouTube video

Disclaimer

  • I use the lazyvim.org distro, so my plugins and tips are optimized to be compatible with that the most, if using something different you might need to to a bit of tweaking, but you can grab the overall ideas and adapt them to your own config
  • I use macOS, so keep that in mind too
  • This is not a distribution, this is my personal setup, so one day I may use certain plugin, like neo-tree, and the following day I may completely disable it and instead switch to mini.files, in case you clone and pull, expect to see changes

Pre-requisites


  • If you don’t want to watch the video above, and you already have your own neovim config, and want to quickly get started and follow along in this tutorial
  • Run the commands below to clone my dotfiles in your .config directory and we will run my config below
1
2
mkdir -p ~/.config
git clone git@github.com:linkarzu/dotfiles-latest ~/.config/linkarzu/dotfiles-latest
  • Open the newly downloaded neobean config with:
1
NVIM_APPNAME=linkarzu/dotfiles-latest/neovim/neobean nvim
  • You can create an alias in your .bashrc or .zshrc file to run my config
1
alias neobean='NVIM_APPNAME=linkarzu/dotfiles-latest/neovim/neobean nvim'
  • Then to run this config, just run neobean

Last year video

If you like this, and want to support me

  • I create and edit my videos in an m1 mac mini, and it’s starting to stay behind in the editing side of things, tends to slow me down a bit, I’d like to upgrade the machine I use for all my videos to a mac mini with these specs:
    • Apple M4 Pro chip with 14‑core CPU, 20‑core GPU, 16-core Neural Engine
    • 24GB unified memory
    • 1TB SSD storage
    • 10 Gigabit Ethernet
  • If you want to help me reach my goal, you can donate here

Image

Discord server

  • After following this guide or even watching the related video, you:
    • Have questions related to one of the tools, configs or scripts that I use
    • Would like me to expand a bit more on how something is done
    • Or simply would like to talk and meet other community members that share your same interests
  • join the discord server in this link
  • Access to the discord server is only for YouTube community members

Image

Follow me on Twitter

  • All of the links will also be in my blogpost

The stuff you’ll see here, is the stuff that I use as of today

  • I may have way many additional keymaps in my ~/github/dotfiles-latest/neovim/neobean/lua/config/keymaps.lua file, some of which I don’t use often, I will only demo the stuff that I think is useful in this article

Where are all these files?

  • If you already downloaded my neobean config in the steps above, you’ll already have all these files
  • Otherwise, all of them are in my dotfiles
  • Remember to star my dotfiles
  • Any keymap you need to find, for example <leader>fD, is in my keymaps file:
    • ~/github/dotfiles-latest/neovim/neobean/lua/config/keymaps.lua
  • I’m not giving you a permalink, as my dotfiles change quite often

Markdown tips

  • These are sorted by my personal preference, most preferred ones at the top

Use snippets

  • Snippets is one of my favorite things
  • I use these in case I want to:
    • Add one of my YouTube videos
    • Add a code block
  • Create a link from a URL I have in the clipboard ;lincex
    • I’ll demo this later


Todo items (tasks)

  • I use the todo snippet to add it
  • <leader>td (todo done)
    • Configured in my keymaps
    • <leader>ta (todo all)
  • <leader>tl (todo list)
    • Configured these keymaps in the telescope plugin

  • I used to add todo items with a todo snippet
  • And toggle with <leader>td
  • I now manage tasks differently:
    • M-l - create new task
    • M-x - toggle task
    • <leader>tt - list uncompleted tasks
    • <leader>tc - list completed tasks
  • To create a task below I use the [[#bullets-vim/bullets.vim]] plugin

  • Here I’ll create some sample tasks and complete them in the video

skitty-notes

  • I like keeping track of the things that I have to do during the day, and the things I have done, I also like to have my video ideas stored and tracked in github, reminders, etc
  • I used the Apple reminder’s app in the past, but I’ve recently switched to skitty-notes, it’s basically this same neovim config running in kitty showing on the right hand side of my screen, always visible
  • I can switch to it by tapping the right arrow key, and I create and toggle tasks there
  • I have a video in which I explain it in detail:

Add images to assets dir

  • This is something really useful with my blogpost
  • <M-1> - paste the image on the clipboard to the assets directory
  • <M-a> - paste image normally using img-clip settings
  • <leader>id - deletes the image under the cursor
  • <leader>iR - renames the image and updates the references across the entire file
  • <leader>if - open image under cursor in finder
  • <leader>io - open image under cursor in preview

Create or jump daily note hyper+t+r

  • I use the daily note every day, usually for example if I need to upload a new video, I have a template in LuaSnip to get me started, and I do this in my daily note
  • I don’t keep a journal, like in The Princess Diaries movie, I just use my daily note as a temp location to edit stuff that needs to be placed somewhere else
  • When I press hyper+t+r it will:
    • Create a daily note with the date-day for example 2024-06-30-Sunday inside the obsidian_main/250-daily/2024/06-Jun directory
      • If the directories do not exist it will create them
      • If the daily note doesn’t exist it will create it
    • Create a new tmux session with the note name in detached mode and start neovim with the daily note
      • If a tmux session with that name already exists, just switch to it


Make sure that the ~/github/dotfiles-latest/scripts/macos/mac/300-dailyNote.sh script is executable

How do I do the hyper+t+r and hyper+t+j

  • In case you’re wondering, what is this hyper+t+r keymap, why does it have like a sub layer?
  • I have a lot of keymaps and several sub layers, for example:
    • The sub layer to switch to each one of my apps is a, so hyper+a+j takes me to my terminal application
    • The sub layer to switch to my tmux sessions is t, so hyper+t+r takes me to my daily note tmux session or hyper+t+u takes me to my obsidian tmux session
  • I explain everything in detail in the video:


Fold all level 2 or 3 headings

  • I know, these may conflict with default folding config but I don’t care, I don’t use the original keymaps for now
  • I created 4 keymaps to fold:
    • <leader>mfj zj (markdown fold 1)
    • <leader>mfk zk (markdown fold 2)
    • <leader>mfl zl (markdown fold 3)
    • <leader>mf; z; (markdown fold 4)
  • And to unfold:
    • <leader>mfu zu (markdown fold undo)
  • I created a new keymap:
    • zi moves to the heading above and folds it, useful if you don’t want to jump back to the heading above and fold it
  • See the Folding section in the keymaps file

DO NOT leave headings OF THE SAME LEVEL without any text between them or folding will not work properly

Folding basics

  • There are several fold options worth knowing about
  • opt.foldlevel = 99
    • (default LazyVim)
    • Sets the initial fold level when opening a file.
    • With a high value like 99, it ensures that almost all folds are open when a file is opened.
  • opt.foldmethod = "expr"
    • (default LazyVim 0.10)
    • Sets the method for defining folds
    • Uses the expression defined in foldexpr to create folds. This method allows for highly customizable folding behavior based on the evaluated expression.
  • opt.foldexpr = "v:lua.require'lazyvim.util'.ui.foldexpr()"
    • (default LazyVim 0.10)
    • Specifies the expression used to define folds
    • Uses a lazyvim Lua function to dynamically determine fold levels
  • opt.foldtext = ""
    • (default LazyVim 0.10)
    • Defines the text displayed for a closed fold
    • An empty string means foldtext is disabled, and the line is displayed normally with highlighting and no line wrapping.
1
2
3
4
5
6
:set foldlevel? | set foldexpr? | set foldmethod? | set foldtext?

:set foldlevel?
:set foldmethod?
:set foldexpr?
:set foldtext?
  • Regular link <leader>mll (markdown link)
  • Link that opens in new tab <leader>mlt (markdown link tab)
  • These weren’t as reliable, and the code was just farts and have been deprecated
  • I’ve replaced them with luasnip snippets ;linkc and ;linkcex
  • (You thought I wasn’t going to provide an alternative? 😉)
  • These 2 new snippets add the link that you have in your clipboard as a markdown link and put your cursor in the alternative text section
  • dotfiles
  • dotfiles ext

Copy current file path to clipboard

Open current file in Github on the browser

  • <leader>fG - file GitHub

Terminal toggle

  • Sometimes you’re working in a file, and you need to quickly toggle your terminal and do something in the command line
  • I created a keymap <M-t> that toggles the terminal and follows the directory I’m on
  • Full details for this can be found in the video:

Alternate file


Use the dictionary with blink.cmp

Spell checking (works in tmux)

  • To toggle spelling <Leader>us
  • Created keymaps to switch spelling languages because I write in español:
    • English <leader>msle
    • Spanish <leader>msls
    • Both languages <leader>mslb
    • You can see the language in lualine
  • To jump between misspelled words use [s and ]s
  • To correct a word <leader>mss (markdown spelling)
    • UPDATE: This keymap now accepts the 1st suggestion on the list, which is 99.99% of the times what I need


  • Same stuff I still use:
    • <leader>msg add word to spell (markdown good)
    • <leader>msu remove word added by mistake
    • Spell dictionary, I still don’t manually add entries

Fix undercurl in tmux

  • I recently switched from Kitty, to WezTerm and then to Ghostty
  • I’m not sure the config below is still needed in Ghostty when using Tmux, which was the case with Kitty
  • I removed the 2 terminal-overrides lines below, saved my tmux config, reloaded it and undercurl works in Ghostty
  • In case you’re using a different terminal, you also use tmux, and are having undercurl issues, try adding this to your tmux.conf file
1
2
3
4
5
6
7
8
9
10
11
# Undercurl support (works with kitty)
# Fix found below in Folke's tokyonight theme :heart:
# https://github.com/folke/tokyonight.nvim#fix-undercurls-in-tmux
#
# After reloading the configuration, you also have to kill the tmux session for
# these changes to take effect
set -g default-terminal "${TERM}"
# undercurl support
set -as terminal-overrides ',*:Smulx=\E[4::%p1%dm'
# underscore colours - needs tmux-3.0
set -as terminal-overrides ',*:Setulc=\E[58::2::%p1%{65536}%/%d::%p1%{256}%/%{255}%&%d::%p1%{255}%&%d%;m'
  • I change the undercurl color and style in my neovim colorscheme settings, every time you make a change there you have to reload the tmux config, but also kill the tmux session or it won’t work

Lazyvim spell defaults

  • There’s a default Auto Command (autocmd) in Folke’s lazyvim.org distro that is what enables spelling
  • Also the lazyvim.org comes preconfigured with the Option opt.spelllang = { "en" } (English) but remember I have keymaps to set that above
  • UPDATE:
    • Wrap is set to true by default on this autocmd and I don’t want that, so added the autocmd to my ~/github/dotfiles-latest/neovim/neobean/lua/config/autocmds.lua file and removed that
1
2
3
4
5
6
7
8
9
10
11
12
-- wrap and check for spell in text filetypes
vim.api.nvim_create_autocmd("FileType", {
  group = augroup("wrap_spell"),
  pattern = { "text", "plaintex", "typst", "gitcommit", "markdown" },
  callback = function()
    -- -- By default wrap is set to true regardless of what I chose in my options.lua file,
    -- -- This sets wrapping for my skitty-notes and I don't want to have
    -- -- wrapping there, I want to decide this in the options.lua file
    -- vim.opt_local.wrap = false
    vim.opt_local.spell = true
  end,
})

Use alt for keymaps

  • They keymaps that I use the most have been configured with alt, for example alt+g opens LazyGit
  • Before this, all my keymaps started with <leader>, and some of them with Ctrl but sometimes I need to start them when in insert mode and it’s also less keystrokes
  • I speak Spanish and sometimes write notes in Spanish, so the left alt key is used for something else, so I added this to my Ghostty config:
    • This config is also available for kitty and wezterm, see my config files
1
2
3
4
5
6
7
8
9
10
11
12
13
14
# If `true`, the *Option* key will be treated as *Alt*. This makes terminal
# sequences expecting *Alt* to work properly, but will break Unicode input
# sequences on macOS if you use them via the *Alt* key. You may set this to
# `false` to restore the macOS *Alt* key unicode sequences but this will break
# terminal sequences expecting *Alt* to work.
#
# The values `left` or `right` enable this for the left or right *Option*
# key, respectively.
#
# Note that if an *Option*-sequence doesn't produce a printable character, it
# will be treated as *Alt* regardless of this setting. (i.e. `alt+ctrl+a`).
#
# This does not work with GLFW builds.
macos-option-as-alt = right

I need help

  • My entire markdown config is a bit complex and will probably raise some questions that need to do some troubleshooting or hand holding
  • Remember to join the YouTube members only discord

Add markdown TOC

  • <leader>mt <leader>mtt (English) and <leader>mts (Spanish)
  • This is to create a Table Of Contents
  • UPDATE: Insert the TOC inside a H2 and H3 heading right below the main H1 at the top
  • If there is a TOC already, it will update it
  • It doesn’t matter if the file has front matter at the top or not, the keymap will detect it and not cause problems
  • To generate the TOC I use the markdown-toc plugin, and it’s installed as a LazyExtra
  • I have a video in which I go over this in detail:

Upload images to my own imgur account (authenticated)

  • Sometimes you need to share an image, but through a link
  • <M-i>
  • This script uploads images to Imgur using an access token, and refreshes the token if it’s expired. It reads environment variables from a specified file and updates them as needed.
  • I have a video in which all of this is explained in detail:

Delete newlines in between (markdown join)

  • Sometimes you have multiple separate bulletpoint lines, and they could even be paragraphs, like this first one which spans across more than one line
  • And you would like to keep them consistent
  • I created a keymap <leader>mj
  • There must be some default Vim command that takes care of it, but I don’t know it, still issue

Toggle bulletpoint

  • <leader>md - (d as in dash)
  • Sometimes you start writing a paragraph, but you forgot to start it as a bulletpoint, notice that I use bulletpoints for basically everything
  • So this allows me to turn those lines into bulletpoints, which I can then join with <leader>mj
  • Use it in normal mode at the top of the current paragraph

Delete current file

  • A lot of times, I want to remove the file I’m on without going out of neovim or without even opening my neovim file explorer
  • <leader>fD
  • This is for macOS and uses the trash app, if you’re on Linux, modify the keymap

See key maps

  • You will forget your keymaps, trust me
  • <leader>sk M-k

See messages history

  • This comes by default with lazyvim, but you will forget
  • These are the messages that show up with folke/noice.nvim
  • You’ll see the pop-up, but a lot of times you will want to see them again
  • There’s a default lazyvim keymap <leader>snh (search noice history)
    • I use <M-h>
    • Close the window that shows below with <leader>wd (window delete)
  • Or use the command :NoiceHistory

Accept completion with ctrl+y instead of enter

  • I really hated this behaviour, maybe skill issue, but every time I was at the end of a line and hit enter, it would autocomplete a word instead of moving to the line below
  • I change this in the keymap section of the blink-cmp.lua file

Bold easily

  • This is still relevant and I use it sometimes
  • If I’m on a word and press <leader>mb it will toggle bold on the single word
  • If try to bold on a * it will let me know that I need to move the cursor
  • Can bold a paragraph in visual mode
  • If in a bold area (paragraph) and run <leader>mb will unbold that section
    • need to be on the first line

  • It needs the mini.surround plugin
  • By default if you want to bold some text, you select it and do 2gsa* or if you want to “unbold” it I normally do gsd*.
  • I configured keymap <leader>mb

This is just a random paragraph with random text in it, it doesn’t serve any purpose but I just want to use it to demonstrate how multi line bold and unbold works

This is just a single line of text

Inline code

  • I have 2 keymaps, one for normal mode and 1 for visual mode
  • If I’m on a word in normal mode and type gss formats is as inline code
  • By default this is done with
1
2
3
4
5
# In visual mode
gsa`

# For the word you're in
gsaiw`
  • But notice all the characters you need to press, and I just use this way too much

Remember to star my dots

  • ⭐⭐⭐ If you like what you find in my dotfiles, including my neobean configuration and keymaps, star my dotfiles

Jump between markdown headings

  • Follow markdown convention and use a single H1 heading in your file for this to work
  • I tend to fold items and navigate that way, or use the outline plugin, but sometimes I do still use gj and gk when unfolded to navigate between headings

lazyvim already uses default gj and gk mappings

  • Remember that I use the lazyvim.org distro
  • That distro already comes with some Default keymaps configured that you can find here
  • Some of these default keymaps are the better up/down ones found below:
1
2
3
4
5
6
7
8
9
-- better up/down
-- If there is no count (v:count == 0), pressing j will execute gj
  -- Useful when dealing with wrapped lines in the buffer.
-- If there is a count (v:count != 0), pressing j will execute j.
  -- For example, if you press 3j to move down three lines
map({ "n", "x" }, "j", "v:count == 0 ? 'gj' : 'j'", { expr = true, silent = true })
map({ "n", "x" }, "<Down>", "v:count == 0 ? 'gj' : 'j'", { expr = true, silent = true })
map({ "n", "x" }, "k", "v:count == 0 ? 'gk' : 'k'", { expr = true, silent = true })
map({ "n", "x" }, "<Up>", "v:count == 0 ? 'gk' : 'k'", { expr = true, silent = true })
  • So by default my neovim “sends” gj when I press j and I can navigate through wrapped lines easily
  • You might think that gj and gk mappings I added would break the default keymaps, but for some reason it still keeps working
    • So with j and k I navigate through wrapped lines without issues

Fold with enter

  • Normally you fold with za but I changed it to use enter <CR>

Line wrapping at 80 characters

  • I don’t like my lines to be longer than 80 characters, helps me with readability and overall consistency of my files.
  • If I open an obsidian markdown file in neovim, line lengths are all over the place, so I prefer to follow the markdown guidelines.
  • To achieve this I do 2 things:

textwidth = 80

  • Set the option vim.opt.textwidth = 80 in lua/config/options.lua
    • When text reaches this limit, it automatically wraps to the next line.
    • This will automatically switch to the line below as you are typing and reach the 80 characters
    • This will NOT auto wrap:
      • Existing lines in a document after you enable the option
      • Long lines that you paste into a file

ProseWrap and .prettierrc.yaml

  • This requires the prettier plugin, we’ll install it later
  • Configure the proseWrap: "always" option in the .prettierrc.yaml file
    • This will autoformat existing lines over 80 characters and also long lines that you paste that exceed the 80 characters
    • You will see how to enable prettier in the LazyExtras section

  • I add the ~/github/dotfiles-latest/.prettierrc.yaml file, to my $HOME directory
  • I keep the file in my dotfiles and create a symlink in my home directory that points to the .prettierrc.yaml file

  • Source for the text below
  • The configuration file will be resolved starting from the location of the file being formatted, and searching up the file tree until a config file is (or isn’t) found.
  • Prettier intentionally doesn’t support any kind of global configuration. This is to make sure that when a project is copied to another computer, Prettier’s behavior stays the same. Otherwise, Prettier wouldn’t be able to guarantee that everybody in a team gets the same consistent results.

Disable autoformatting in certain sections

This is a message that renders correctly in the page because it’s not autoformatted

Add file path to current file

  • A lot of times I need the path of the current file to be added to the file itself as a comment
  • This does not only work for markdown, but for any file type
  • This uses gcc in the background, which is handled by the echasnovski/mini.comment
    • So make sure that plugin is installed, comes with lazyvim.org distro by default
  • <C-z> <M-z>
  • This hasn’t changed
  • If for example you’re setting up a keymap, or you want to understand what the commands on an existing keymap do, or basically, any command in neovim, use the help
  • <leader>sh
  • Then search for something pwd and navigate around “tags” with shift+k
  • To go back to where you were after navigating to a tag, use Ctrl-o
  • Close that pane with <leader>wd (window delete)

Paste with “p” in visual mode

  • This is not markdown specific, but overall neovim specific
  • DON’T use cmd+v (macOS) to paste or the line below will be deleted
  • Paste with p (lowercase) or P (uppercase)
1
2
3
4
5
6
7
8
Laborum aute consectetur sit reprehenderit.
Laborum aute consectetur sit reprehenderit.

Duis consectetur laborum deserunt.
Duis consectetur laborum deserunt.

Minim tempor ullamco do eu pariatur minim.
Minim tempor ullamco do eu pariatur minim.

Increase decrease all markdown headings

  • I have several old .md documents that do not follow markdown guidelines
  • Some have more than one H1 heading, so I want to add one more # to each heading
  • <leader>mhI and <leader>mhD
    • These 2 don’t ask for confirmation and just increase all the headings

Don’t indent with tab

  • Don’t try this, because if you use snippets, this will interfere with them and you won’t be able to jump to the next field using tab
  • If you use tab for something else, you’ll lose it
  • To indent use defaults:
    • In insert mode use <C-T> and <C-D>
    • In normal mode >> and <<

Open current file in finder

  • <leader>fO or <M-f> (uppercase O as in “Oscar”)
  • Update: I now open the file in ForkLift instead of finder
  • This is for macOS, not sure if works on Linux, but modify it

Dismiss all messages

  • If you open neovim on an old outdated machine, you will get hundreds of noice messages on the screen, sometimes occupying the entire screen and you won’t be able to read
  • Clear them all with <leader>snd <M-d> (search noice dismiss)
1
:lua local messages = {"System update available. System update available. System update available.","Backup completed successfully. Backup completed successfully. Backup completed successfully.","New email received. New email received. New email received.","Reminder: Meeting at 3 PM. Reminder: Meeting at 3 PM. Reminder: Meeting at 3 PM.","Low disk space on drive C:. Low disk space on drive C:. Low disk space on drive C:.","Software update installed. Software update installed. Software update installed.","Battery level critical. Battery level critical. Battery level critical.","File download completed. File download completed. File download completed.","New message from John. New message from John. New message from John.","Security scan completed. Security scan completed. Security scan completed.","Application crash detected. Application crash detected. Application crash detected.","Printer is out of paper. Printer is out of paper. Printer is out of paper.","Wi-Fi connection lost. Wi-Fi connection lost. Wi-Fi connection lost.","New friend request received. New friend request received. New friend request received.","Weather alert: Heavy rain expected. Weather alert: Heavy rain expected. Weather alert: Heavy rain expected.","VPN connection established. VPN connection established. VPN connection established.","System reboot required. System reboot required. System reboot required.","Bluetooth device connected. Bluetooth device connected. Bluetooth device connected.","Scheduled maintenance at midnight. Scheduled maintenance at midnight. Scheduled maintenance at midnight.","Password change reminder. Password change reminder. Password change reminder."} for _, message in ipairs(messages) do vim.api.nvim_echo(, false, {}) end
  • <C-g> M-; (since you run it with alt, can run it in insert mode)
  • Make sure you have the main github repo link in your clipboard first

Select text in a bullet point

  • Press ctrl+space
    • Keep pressing it to keep selecting
    • To go back use backspace

[!WARNING] I still don’t know why this breaks

  • This breaks if you have a markdown comment below in the file, it will jump there, not sure why
    • If you know why this is, let me know down in the comments

Create headings and daily note

  • This is a good practice, but I haven’t been following it, I don’t add to much stuff to my obsidian notes these days, I document stuff closer to the code, or i the code itself, if you look at my dotfiles, you’ll understand
  • I’m leaving this here, as it’s still valid

I use this in my Obsidian vault

  • This is useful in case I want to have stuff linked to my daily note
  • I use markdown headings with date on a specific note XOA for example
  • Then in obsidian I can go to a specific note, and see which headings are linked to that note, just so that I can keep track of what did each day, some sort of journal
  • These keymaps besides adding the heading, will also create the daily note if it does not exist:
    • If you don’t want to create the daily note, comment that line
  • <leader>jj, <leader>kk, <leader>ll, <leader>;;, <leader>uu,<leader>ii

Working with marks

  • I have not used marks in an entire year, but leaving this here as it’s relevant and useful to some
  • I’m not going to demo this, go to last years video
  • Leave a mark somewhere you need to come back to
  • While in normal mode, press m and then a letter a-z will create a mark
    • Lowercase letters (a to z) are for marks local to the current buffer
    • Uppercase letters (A to Z) create global marks that can be jumped to from any buffer
  • To jump to a mark
    • 'a - (single quote) jump to the line of the mark in the first character
    • `a - (backtick), jumps to character in which mark was set originally
  • To see all the marks use :marks
  • :delmarks a would remove the mark a
  • :delmarks a j k l m z n removes all the marks specified
  • I created a keymap to delete all marks
    • <leader>md (mark delete)

What plugins and tips do you use?

  • Let me know down below, there’s also cool recommendations that can help me improve my setup

What do you want to see next?

  • Let me know in the youtube comments, what you’d like to see next

What’s that keyboard?

Markdown plugins

  • These are sorted by my personal preference, most preferred ones at the top
  • Star the repos below if you like the plugins

MeanderingProgrammer/render-markdown.nvim

bullets-vim/bullets.vim

  • bullets-vim/bullets.vim
  • This is one of my favorite ones
  • I 100% love this plugin, and I still use it daily for bulletpoints
  • Currently I use it a lot with my tasks as well
  • M-l to add new task and press enter to keep creating them below

echasnovski/mini.files

echasnovski/mini.surround

  • echasnovski/mini.surround
  • Add a surrounding
    • If I want to surround a part of the text
    • I select it in visual mode, then press gsa"
      • I normally use “, `, ‘, (, [, {
  • Replace a surrounding
    • Let’s say I have this “surrounded text”
    • And I want to change it with ‘surrounded text’
    • Place the cursor anywhere inside the “ “
    • Then press gsr"'
      • goto, surround, replace, current surrounding, new surrounding
  • Remove a surround
    • If we have ‘this surrounded text’
      • Place cursor anywhere inside the surrounding and remove it with gsd'

echasnovski/mini.ai

  • echasnovski/mini.ai
  • This is a beauty, it comes installed with lazyvim.org by default, I think Folke disabled it once, and I almost died, so in case the following stop working, you know this is the plugin
  • viq or vaq select inside or around quotes
    • Text inside backticks
    • “Text inside double quotes”
    • ‘Text inside single quotes’
  • vig or yig select entire file
  • vio or vao
    • I select text inside code blocks A LOT, and I mean A LOT
    • So this is definitely one of my personal favorites
  • vi or va to see what other options are useful for you
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#!/usr/bin/env bash

# Filename: ~/github/scripts/macos/mac/300-dailyNote.sh

# Get current date components
current_year=$(date +"%Y")
current_month_num=$(date +"%m")
current_month_abbr=$(date +"%b")
current_day=$(date +"%d")
current_weekday=$(date +"%A")

# Construct the directory structure and filename
note_dir=~/github/obsidian_main/250-daily/${current_year}/${current_month_num}-${current_month_abbr}
note_name=${current_year}-${current_month_num}-${current_day}-${current_weekday}
full_path=${note_dir}/${note_name}.md
# Use note name as the session name
tmux_session_name=${note_name}

arnamak/stay-centered.nvim

hedyhli/outline.nvim

lukas-reineke/headlines.nvim

MagicDuck/grug-far.nvim

  • MagicDuck/grug-far.nvim
  • This is used for search and replace, it allows me to do magical stuff, like multi line search and replace
  • In-depth video on this plugin soon, so stay tuned and subscribe

nvim-pack/nvim-spectre

  • nvim-pack/nvim-spectre
  • Find and replace text <leader>sr
  • I normally do <leader>uw to wrap when in the plugin
  • I changed the highlight colors in eldritch.lua because I could barely see the default ones
  • I didn’t take this call, it was Folke and replaced the plugin with MagicDuck/grug-far.nvim

okuuva/auto-save.nvim

  • okuuva/auto-save.nvim
  • I still use this plugin every single day, still love it
  • UPDATES:
    • My auto-save plugin debounce_delay used to be set to 750ms but I felt it slowed me down, I had to wait a bit for auto-save to kick in, which also auto-formats my files, so if I needed to quickly change stuff between 2 lines and I got out of insert mode, auto-save kicked in, now I have more time to go out of insert mode, edit stuff, go somewhere else and enter insert mode without autosave not kicking in
    • It’s configured to auto save when I leave a buffer or the focus is lost, but only if I’m not on insert mode
    • Otherwise it would cause issues when switching to a tutorial in insert mode and coming back
    • debounce_delay currently set to 5s and if need to save for a strange reason, maybe to auto-format faster I run M-w

  • This is a really controversial plugin, some people love autosave, some other ones hate it
  • Personally I like autosaving, this plugin will auto save for you when you exit insert mode
    • Also if you focus another app or you leave the buffer, even if you’re on insert mode, it will autosave
  • I have a video about this plugin, you can find it here

iamcco/markdown-preview.nvim

  • iamcco/markdown-preview.nvim
  • This already comes installed with lazyvim.org by default, I just changed the mapping to open it with <leader>mp (markdown preview)
  • I really love to use it if I need to print a markdown file as PDF, looks quite nice and you can toggle dark light mode
  • If studying, your teachers will think to themselves, how did this guy print this PDF so beautifully?
    • Just careful with line wrapping and code blocks when converting to PDF

3rd/image.nvim

HakonHarnes/img-clip.nvim

jlanzarotta/bufexplorer


  • I navigate my buffers using telescope, they’re also sorted by MRU, I can close buffers from telescope with d and the best thing, is that I can get a preview of the buffers:
    • I can scroll up or down the preview with S-j and S-k
  • By default, in lazyvim with <S-h> and <S-l> you navigate between the prev and next buffers, but I changed both of those:
    • <S-h> opens telescope buffers
    • <S-l> opens snipe.nvim
  • I have a video in which I cover all of this:

  • If you’re a fan of harpoon, I’d recommend you to also check out the snipe plugin, I have a video for it:

nvim-telescope/telescope.nvim

nvim-treesitter/nvim-treesitter

  • nvim-treesitter/nvim-treesitter
  • I want the code blocks in my markdown files to have proper syntax highlighting
  • If one of your languages doesn’t show up properly, add it to treesitter, I statically configure it in the plugin file treesitter.lua
  • Use :checkhealth to see which ones are installed
1
2
3
4
SELECT id, name
FROM users
WHERE age > 18
ORDER BY name;
1
2
3
4
5
6
7
package main

import "fmt"

func main() {
    fmt.Println("Hello, Go!")
}
1
2
3
4
5
#!/bin/bash
echo "Hello, Bash!"
for i in {1..5}; do
    echo "Number $i"
done
1
2
3
4
5
6
version: "3"
services:
  web:
    image: nginx
    ports:
      - "80:80"
1
2
3
4
5
{
  "name": "John Doe",
  "age": 30,
  "city": "New York"
}
1
2
3
4
5
6
#include <iostream>

int main() {
    std::cout << "Hello, C++!" << std::endl;
    return 0;
}
name,age,city
John Doe,30,New York
Jane Smith,25,Los Angeles
Mike Johnson,40,Chicago
1
2
3
4
5
public class HelloWorld {
    public static void main(String[] args) {
        System.out.println("Hello, Java!");
    }
}
1
2
3
4
function greet() {
  console.log("Hello, JavaScript!");
}
greet();
1
2
3
4
def greet():
    print("Hello, Python!")

greet()
1
2
3
FROM ubuntu:latest
RUN apt-get update && apt-get install -y nginx
CMD ["nginx", "-g", "daemon off;"]
1
2
3
4
5
6
7
8
9
<!doctype html>
<html>
  <head>
    <title>Hello, HTML!</title>
  </head>
  <body>
    <h1>Hello, World!</h1>
  </body>
</html>
1
2
3
4
5
body {
  font-family: Arial, sans-serif;
  background-color: #f0f0f0;
  color: #333;
}

nvim-treesitter/nvim-treesitter-context

  • nvim-treesitter/nvim-treesitter-context
  • I’ve been asked what this plugin is a few times
  • If on a markdown file, and you’re inside a level 4 heading, this plugin shows you the level 2 and 3 heading that you’re under at the top of the screen Really useful to know where you’re at
  • This plugin used to be enabled by default in lazyvim, but it was moved to extras

mfussenegger/nvim-lint

LazyExtras

  • You can manage these in the lua/config/lazy.lua file or with :LazyExtras
    • I’m not sure if you can also manage them in the lazyvim.json file as well
  • I prefer to configure the extras in the lazy.lua file, because I want to have the settings on each machine, but if that’s not your case, you can enable the extras on each machine with :LazyExtras

lang.markdown

  • This includes:
  •  markdown-preview.nvim  mason.nvim  nvim-lspconfig  render-markdown.nvim  conform.nvim  none-ls.nvim  nvim-lint
  • If you go to the lazyvim.org website in the extras -> lang -> markdown section (notice it matches the Extra’s name)
    • You’ll be able to see which plugins Mason will install
      • Mason is a package manager for Neovim
    • In this case it will install markdownlint-cli2 and markdown-toc, it also installs marksman but not sure why it’s not shown on the page
markdownlint-cli2
markdown-toc
marksman
  • artempyanykh/marksman
  • Using LSP protocol it provides completion, goto definition, find references, rename refactoring, diagnostics, and more. In addition to regular Markdown, it also supports wiki-link-style references that enable Zettelkasten-like, note taking
  • Go to the obsidian XOA file under Create Windows 11 VM
    • K (uppercase k) over a link allow me to hover
      • KK (press it twice) and you can navigate that file in the hover menu
    • gd (go to definition) allows me to go the file that a link points to
  • In combination with blink.cmp this is quite useful for linking notes together

formatting.prettier

  • This includes:
    •  mason.nvim  conform.nvim  none-ls.nvim
  • If you go to the lazyvim.org website in the extras -> formatting -> prettier section (notice it matches the Extra’s name)
    • You’ll be able to see which plugins Mason will install, which is only prettier

  • Prettier is the one that automatically formats my markdown files
    • It removes extra blank lines
    • Removes blank spaces at the end of a line
    • But also messes up my chirpy tips because it format things
      • You can ignore some parts from formatting, will show you how below
  • I like following markdown guidelines, so I don’t like my lines to be longer than 80 characters, I like to enable wrapping for them

epwalsh/obsidian.nvim (uninstalled)

  • epwalsh/obsidian.nvim
  • I link notes with marksman and I format my files with meanderingprogrammerrender-markdownnvim, so I don’t see a use case for this plugin

Improve the video next year

  • I’ll make a follow up video next year with the things that changed between now and then
  • Share improvements and tips in the youtube comments of stuff that would make my markdown editing experience even better

Timeline

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
0:00 - intro
0:16 - disclaimer
0:29 - instal neobean
1:30 - pre-requisites images
1:56 - support and discord
3:00 - dotfiles
4:17 - snippets luasnip
6:03 - todo and tasks
8:40 - skitty notes
9:36 - image assets
12:30 - daily note
13:36 - hyper sublayers
14:39 - folds new mappings
15:57 - markdown link from clipboard
17:18 - file path to clipboard
19:02 - open file in github
19:30 - toggle terminal
20:37 - alternate file
21:40 - blink.cmp dictionary
22:07 - spell check
23:04 - alt for keymaps
23:47 - need help
24:02 - markdown TOC
24:55 - images to imgur
26:08 - delete newlines
26:35 - toggle bulletpoints
27:04 - delete current file
27:21 - list keymaps
27:43 - message history
28:07 - completion ctrl+y
28:33 - bold text
28:59 - inline code
29:32 - star
29:44 - jump headings
30:02 - fold with enter
30:11 - wrap at 80
30:23 - disable autoformat
31:14 - add file path as comment
31:38 - help pages
32:23 - dismiss notifications
32:39 - github repo as link
33:02 - select bulletpoint text
33:16 - headings linked to daily note
33:33 - marks
33:45 - plugin suggestions
34:04 - glove80
34:16 - plugins section
34:35 - render-markdown.nvim
35:03 - bullets.vim
35:22 - mini.files
35:59 - mini.surround
36:13 - mini.ai
36:34 - stay-centered.nvim
36:40 - outline.nvim
36:54 - headlines.nvim
37:09 - grug-far.nvim
37:29 - nvim-spectre
37:46 - auto-save.nvim
38:26 - markdown-preview.nvim
38:38 - image.nvim
38:48 - img-clip.nvim
39:02 - bufexplorer
39:45 - telescope-frecency.nvim
40:42 - nvim-treesitter
40:48 - nvim-treesitter-context
41:13 - nvim-lint
42:51 - markdownlint-cli2 markdown-toc marksman
43:06 - prettier
43:22 - obsidian.nvim
43:45 - see you next year

Completed tasks

  • done: 250111 task3
  • done: 250111 task2
  • done: 250111 task1
This post is licensed under CC BY 4.0 by the author.