😎 VSCode + Neovim Setup: keyboard-centric, powerful, reliable, clean, and aesthetic development environment. Tips and tricks
Here I will share my current development environment setup and the philosophy behind it. I’ll try to keep this article updated with my latest approaches and insights.
Productivity, power, reliability, cleanliness, aesthetics — it’s all about that.
Productivity
When I say “productivity”, I mean being able to edit your code and navigate through your editor blazingly fast. This very approach allows you to complete your tasks in an hour and spend the other seven hours debating the perfect programming language (DreamBerd) with your team lead at the bar. However, if your job involves spending seven hours on research and one hour writing 10 lines of code, this approach might not be your vibe. Anyways, I find it lit to advance efficiently in the coding part of a project and believe it’s natural to optimize your workflow, especially, in the case when you spend the lion’s share of time on implementation.
To edit code and move through an editor blazingly fast, I rely on this approach: everything that can be done using a keyboard should be done using a keyboard. After some training, it turns out that your fingers’ movements on a keyboard are faster than your attempts to wiggle a mouse.
Power
When I say “power”, I mean that your editor is packed with features that assist you throughout the development process. This includes code suggestions, autocompletion, quick fixes, go-to definition, syntax highlighting, community plugins, AI support, and more. All these features are designed to make your development process faster and more enjoyable.
It’s good to understand that fundamental features like code suggestions, autocompletion, quick fixes, and go-to definition are usually implemented by the specific language server. The code editor just communicates with this language server through the Language Server Protocol (LSP) and acts as an LSP client.
Reliability
When I say “reliability”, I mean that there is a large community behind your editor: if something goes wrong, you can expect issues to be fixed quickly; if new tools and approaches emerge, you can expect them to be implemented swiftly by the editor.
Cleanliness
When I say “cleanliness”, I mean that I’m not a big fan of having dozens of icons, buttons, and labels cluttering my workspace, especially if I don’t use or care about them. I prefer seeing only the essentials during the development process, such as the code itself and the current file with its path. If I need to see anything else occasionally, I navigate using shortcuts.
Aesthetics
When I say “aesthetics”, I mean that I’ve dedicated a lot of time to designing user interfaces and typography, so I notice every misalignment and any place that needs an extra 1px margin. Because of this, I find it more enjoyable to use an editor with a well-crafted UI.
Philosophy Implementation
Now that we have defined the philosophy behind the development environment, let’s move on to its implementation. My goal here is not to provide a complete setup, but rather to show you the framework, approaches, and opportunities that you can use as a foundation for building and evolving your personalized development environment.
So our implementation will be based on these four things: ten-fingers touch typing, VSCode, Neovim, and keyboard shortcuts.
Ten-fingers touch typing
The foundation of your coding productivity is your ability to type with all 10 fingers. If your typing speed is slow, it will significantly hinder your ability to code and navigate quickly. To avoid this bottleneck, it’s crucial to become proficient at touch typing. So if you’re not already in the league of touch typists, I highly recommend you join.
The early days of your switch may be challenging as your fingers get used to the new positions and movements. Initially, you will likely type even slower than with your previous approach, and it may drive you nuts. However, if you push through this period, you will undoubtedly see a gradual increase in typing speed, leading to a significant boost in the long term. I recommend finding an online training program that teaches ten-finger typing through specific exercises. Here is the resource I used when I was learning to type fast: https://www.typingstudy.com.
VSCode
According to the Stack Overflow Developer Survey 2023, Visual Studio Code (VSCode) turned out to be the most popular and preferred editor. This indicates that there is a large community supporting it, which usually means that the tool has everything we might need. Many people are working on polishing it, adding features, and creating plugins that enhance its capabilities. Also, VSCode is free, has a slick UI, and is quite lightweight, so it won’t eat up your RAM as heavily as Chrome or JetBrains IDEs do.
Step 1. Install Visual Studio Code
First, head over to the VSCode official website and download the editor for your operating system.
Step 2. Activate Zen Mode, uncheck Centered Layout
and Hide Line Numbers
options
After the installation, your VSCode will look something like this:
By default, it’s already pretty clean. But I prefer to make it spotless. To do this, first activate Zen Mode by pressing Cmd+K Z
(or by going to View
→ Appearance
and checking Zen Mode
). Now you get that:
I’m not a centered layout boy, and the lack of line numbers brings too much emptiness and sorrow here. Off we go fixing this. Hit cmd+shift+p
to open the command palette and start typing open user settings (json)
. When you see the corresponding item, hit enter
to navigate to it.
You can use
ctrl+n
andctrl+p
to move through the list of the command palette.
Now we have to set 2 options in the open settings.json file:
"zenMode.centerLayout": false,
"zenMode.hideLineNumbers": false
As a result, we have that:
Now it looks pretty neat. You can also toggle the primary side bar on the left with cmd + h
:
To focus between the Explorer and the Editor, hit
cmd+shift+e
multiple times.
If you see any other icons or panels that you find useless to display all the time, try to hide them as well.
Step 3. Find a dark theme of your preference
The main condition for a perfect color theme is that it should be dark, because Black Lives Matter and because a dark palette will save you from light bursts at night that can cause your eyes to become wide and almost closed.
The default VSCode dark theme is almost perfect. The only thing I don’t fancy is this accent color:
I don’t know why, but it reminds me of a morgue or at least a hospital, and it seems to be hinting, “to hell with this job”. Hence, I decided to switch over to the Github Dark Default, which looks like this:
This theme is even darker and looks like under the bed, and that’s how it should be.
Step 4. Set the JetBrains Mono font for the editor
As a former JetBrains user, I have a platonic relationship with the JetBrains Mono font, which is why I decided to bring it over to VSCode as well. To use this font in your editor, download it from the official website, install it, and set it in your settings.json
like this:
"editor.fontFamily": "JetBrains Mono"
I also recommend enabling font ligatures. This will make some symbol combinations look more attractive, like this arrow in the Rust codebase:
To enable ligatures in VSCode, head over to settings.json
and add this line:
"editor.fontLigatures": true
Step 5. Go wild with single tab mode and Harpoon
Effectively, there’s no need to see any tabs other than the current one. This isn’t what we want displayed at the top of our editor:
What we want is this:
To activate single tab mode, add this line to your settings.json
:
"zenMode.showTabs": "single"
Now the question is, how can you quickly switch between open files without the popular multi-tab panel? Here are some options at your disposal:
- You can navigate through open files using these two shortcuts:
cmd+shift+]
andcmd+shift+[
. However, without the multi-tab panel, this type of navigation feels more like a blindfolded trick. - You can use the quick open feature by pressing
cmd + p
, starting to type the file name, and then navigating to the desired file. - You can use Harpoon.
Let’s elaborate on the third option. Harpoon is a file navigation tool that lets you mark editors and quickly jump between them. The VSCode Harpoon extension is inspired by The Primeagen’s Harpoon plugin for neovim. It’s a great tool in case you find yourself frequenting a small set of files while working on a project.
With Harpoon, you can add certain files to a special list and quickly switch between them using shortcuts or by opening the list, typing the number corresponding to the file, and pressing enter
.
You can find my Harpoon keybindings in the section “Neovim — Step 4. Configure Neovim for VSCode”, which appears later in this article.
Step 6. Add the Project Manager extension
The Project Manger extension is like Harpoon, but for projects. You can add projects to a special list and quickly switch between them:
You can find my Project Manager keybindings in the section “Neovim — Step 4. Configure Neovim for VSCode”, which appears later in this article.
Neovim
Neovim is what makes you a Gigachad. It’s a tool that turns you into a Real Hacker from the movies. With Neovim, your development process becomes transcendent, and your editing speed is now unparalleled.
Step 1. Learn core vim keybindings
What most people love about Neovim are its core vim keybindings. With these commands, you can navigate through a codebase, edit, move, rearrange, and highlight code parts using only a keyboard, without needing to touch a mouse. If you’re new to Neovim, I highly recommend finding a tutorial, game, or cheat sheet to teach you these fundamental key combinations. There are many online resources that can guide you, so find one you like and start training. As with touch typing, you may not be fast at the beginning and may forget some keymaps, but over time, you’ll get used to these combinations, and they will become an extension of your hands.
Step 2. Install VSCode Neovim extension
Not vscodevim! But VSCode Neovim extension, install it from the VSCode marketplace, and complete the “Getting Started/Installation” part! The key selling point of this extension is that it uses a fully embedded Neovim instance, not a vim emulation. This means it supports custom init.lua
and many plugins. At the same time, the extension preserves VSCode’s native functionality for insert mode and editor commands, making the best use of both worlds. I highly recommend walking through the VSCode Neovim extension docs to familiarize yourself with all its features.
Step 3. Understand why I don’t advocate using ordinary terminal Neovim as your main editor
I made many attempts to create a custom terminal Neovim setup from scratch, but each time I encountered several unpleasant moments: I was either frustrated by the amount of time spent configuring basic features that the editor should rather have out of the box, faced issues with certain plugins or their interoperability that led to non-working functionality or noticeable lags, or found parts of the UI that I didn’t like and couldn’t modify.
All the unpleasant aspects of my attempts to use terminal Neovim as an editor led me to realize that I would rather prefer to use Neovim only as a back end. It’s better for me if the client part is a full-fledged editor that has at least the basic features out of the box, a slick UI, is easy to customize to my own needs without breaking things, and has a large plugin ecosystem where I can get plugin features working just by clicking the ‘install’ button. For now, I find VSCode well suited for this role as the client for Neovim, which is why we’ll proceed with it.
Step 4. Configure Neovim for VSCode
In this step, we’ll create a basic Neovim configuration, where we’ll define some custom basic keymaps along with some bindings that will call VSCode commands from Neovim using the vscode-neovim extension API.
First, head over to ~/.config/nvim
(or ~/AppData/Local/nvim
, if you’re on Windows) and create the following file structure:
In the init.lua
paste the following code:
if vim.g.vscode then
-- VSCode Neovim
require "user.vscode_keymaps"
else
-- Ordinary Neovim
end
It’s good to keep the VSCode-specific config separate from the ordinary one to have fine-grained control over each environment and avoid messing things up.
Now, let’s move to the vscode_keymaps.lua
file and define some basic keymaps. Here are the ones I have in my config:
local keymap = vim.keymap.set
local opts = { noremap = true, silent = true }
-- remap leader key
keymap("n", "<Space>", "", opts)
vim.g.mapleader = " "
vim.g.maplocalleader = " "
-- yank to system clipboard
keymap({"n", "v"}, "<leader>y", '"+y', opts)
-- paste from system clipboard
keymap({"n", "v"}, "<leader>p", '"+p', opts)
-- better indent handling
keymap("v", "<", "<gv", opts)
keymap("v", ">", ">gv", opts)
-- move text up and down
keymap("v", "J", ":m .+1<CR>==", opts)
keymap("v", "K", ":m .-2<CR>==", opts)
keymap("x", "J", ":move '>+1<CR>gv-gv", opts)
keymap("x", "K", ":move '<-2<CR>gv-gv", opts)
-- paste preserves primal yanked piece
keymap("v", "p", '"_dP', opts)
-- removes highlighting after escaping vim search
keymap("n", "<Esc>", "<Esc>:noh<CR>", opts)
Next, in the same file, let’s add a section with VSCode-specific keymaps that will trigger VSCode actions like toggling the built-in terminal, showing hover, displaying the quick fix list, toggling a breakpoint, etc. Here are the keybindings I currently have:
-- call vscode commands from neovim
-- general keymaps
keymap({"n", "v"}, "<leader>t", "<cmd>lua require('vscode').action('workbench.action.terminal.toggleTerminal')<CR>")
keymap({"n", "v"}, "<leader>b", "<cmd>lua require('vscode').action('editor.debug.action.toggleBreakpoint')<CR>")
keymap({"n", "v"}, "<leader>d", "<cmd>lua require('vscode').action('editor.action.showHover')<CR>")
keymap({"n", "v"}, "<leader>a", "<cmd>lua require('vscode').action('editor.action.quickFix')<CR>")
keymap({"n", "v"}, "<leader>sp", "<cmd>lua require('vscode').action('workbench.actions.view.problems')<CR>")
keymap({"n", "v"}, "<leader>cn", "<cmd>lua require('vscode').action('notifications.clearAll')<CR>")
keymap({"n", "v"}, "<leader>ff", "<cmd>lua require('vscode').action('workbench.action.quickOpen')<CR>")
keymap({"n", "v"}, "<leader>cp", "<cmd>lua require('vscode').action('workbench.action.showCommands')<CR>")
keymap({"n", "v"}, "<leader>pr", "<cmd>lua require('vscode').action('code-runner.run')<CR>")
keymap({"n", "v"}, "<leader>fd", "<cmd>lua require('vscode').action('editor.action.formatDocument')<CR>")
-- harpoon keymaps
keymap({"n", "v"}, "<leader>ha", "<cmd>lua require('vscode').action('vscode-harpoon.addEditor')<CR>")
keymap({"n", "v"}, "<leader>ho", "<cmd>lua require('vscode').action('vscode-harpoon.editorQuickPick')<CR>")
keymap({"n", "v"}, "<leader>he", "<cmd>lua require('vscode').action('vscode-harpoon.editEditors')<CR>")
keymap({"n", "v"}, "<leader>h1", "<cmd>lua require('vscode').action('vscode-harpoon.gotoEditor1')<CR>")
keymap({"n", "v"}, "<leader>h2", "<cmd>lua require('vscode').action('vscode-harpoon.gotoEditor2')<CR>")
keymap({"n", "v"}, "<leader>h3", "<cmd>lua require('vscode').action('vscode-harpoon.gotoEditor3')<CR>")
keymap({"n", "v"}, "<leader>h4", "<cmd>lua require('vscode').action('vscode-harpoon.gotoEditor4')<CR>")
keymap({"n", "v"}, "<leader>h5", "<cmd>lua require('vscode').action('vscode-harpoon.gotoEditor5')<CR>")
keymap({"n", "v"}, "<leader>h6", "<cmd>lua require('vscode').action('vscode-harpoon.gotoEditor6')<CR>")
keymap({"n", "v"}, "<leader>h7", "<cmd>lua require('vscode').action('vscode-harpoon.gotoEditor7')<CR>")
keymap({"n", "v"}, "<leader>h8", "<cmd>lua require('vscode').action('vscode-harpoon.gotoEditor8')<CR>")
keymap({"n", "v"}, "<leader>h9", "<cmd>lua require('vscode').action('vscode-harpoon.gotoEditor9')<CR>")
-- project manager keymaps
keymap({"n", "v"}, "<leader>pa", "<cmd>lua require('vscode').action('projectManager.saveProject')<CR>")
keymap({"n", "v"}, "<leader>po", "<cmd>lua require('vscode').action('projectManager.listProjectsNewWindow')<CR>")
keymap({"n", "v"}, "<leader>pe", "<cmd>lua require('vscode').action('projectManager.editProjects')<CR>")
An argument we pass to the action function is the VSCode’s Command ID. To retrieve the ID of a command, navigate to Keyboard Shortcuts by pressing cmd+k+s
, search for the command by name, then right-click on the found command and choose “Copy Command ID”:
With everything defined, once you restart VSCode, your custom keymaps should begin to work.
Step 5. Explore code navigation keybindings
In the corresponding section of the VSCode Neovim extension docs, you can find a list with all predefined keybindings for code navigation. Here, I will highlight the ones that I find the most significant and frequently used:
gd
— go to the definition;ctrl + o
— get back from the definition;space + d
— show the hover with details on the item where the cursor currently is (from our custom vscode_keymaps.lua);shift + k
— if the hover isn’t shown, it shows it. If the hover is already shown, it focuses on it, and then you can use vim motions likej
,k
,gg
,G
to scroll through it;space + a
— show the quick fix list (from our custom vscode_keymaps.lua). You can also usectrl + n
andctrl + p
to move through the list and hitenter
to choose the action to perform.
Step 6. Investigate explorer navigation and file manipulation keybindings
Once you focused on the explorer by hitting cmd + shift + e
, you can walk through it, expand and collapse folders, and select, create, rename, delete, copy, and move files and folders using specific keybindings as well.
In the explorer navigation section of the VSCode Neovim extension docs, you can find all predefined keymaps for moving through the VSCode explorer. And in the file manipulation section, you can find all bindings for performing actions on files and folders within the explorer. Here, I will highlight the most useful ones:
j
andk
— focus down and up between files and folders;h
andl
— collapse folders and select folders and files;enter
— select folders and files;gg
— focus on the first item of the explorer;G
— focus on the last item of the explorer;a
— create a new file;A
— create a new folder;r
— rename a file/folder;d
— delete a file/folder;y
— copy a file/folder;x
— cut a file/folder;p
— paste a file/folder.
You can also use
a
to create a folder, just terminate your input with/
. Additionally, you can create nested structures by hittinga
and entering input like this:new-folder/new-nested-folder/new-file.hs
.
Terminal
Now it’s time to make your terminal experience magnificent.
Step 1. Install and configure the Starship prompt
The Starship allows you to make your terminal prompt look more informative and appealing, for instance, like mine:
Also, the Starship is backed by Rust.
First, go through the installation steps.
By default, the Starship prompt displays a lot of information. However, I found that having only the current git branch and git status is enough for me, so I customized the Starship prompt accordingly.
To modify the prompt, create the following file: ~/.config/starship.toml
. If you want to have the Starship prompt set up like mine, define these options:
format = """
$directory\
$git_branch\
$git_status\
$line_break\
$shell\
$character
"""
[directory]
truncation_length = 10
truncate_to_repo = false
Step 2. Activate shell Vi Mode
With shell Vi Mode you can manipulate your prompt using familiar vi (vim, nvim) motions:
If you’re using the Z shell like I do, to activate Vi Mode, simply add this line to your ~/.zshrc
:
bindkey -v
Alternatively, you can use the zsh plugin that promotes itself as a better and friendly vi (vim) mode plugin for zsh. This is the option I chose.
If you’re using a different shell, simply google a way to activate Vi Mode for your case.
Step 3. Set up Tmux
If you believe Wikipedia, then “Tmux is an open-source terminal multiplexer for Unix-like operating systems”. The term “multiplexer” refers to a tool that allows you to manage multiple terminal sessions within a single terminal window.
In my setup, I primarily use Tmux for its Vi Copy Mode. This mode allows navigation through terminal history and copying text using vim motions.
Let’s integrate Tmux into our setup.
First, install Tmux.
To start a Tmux session, you can simply run the tmux
command in your terminal.
VSCode terminal with Tmux
To make things more convenient, let’s configure settings to automatically start a Tmux session when you open the VSCode terminal. To do this, we’ll create a new VSCode terminal profile for Tmux and set it as the default.
First, head over to settings.json
.
Then, under terminal.integrated.profiles.osx
or terminal.integrated.profiles.linux
, add:
"terminal.integrated.profiles.osx": {
//...existing profiles...
"tmux-shell": {
"path": "tmux",
"args": ["new-session", "-A", "-s", "vscode:${workspaceFolder}"]
}
}
This runs tmux new-session
on terminal startup, connecting to existing sessions named after the workspace folder. That way, if you've already created a terminal for this project, you'll automatically reconnect to it.
Finally, to set this profile as the default, add the following line to your settings.json
:
"terminal.integrated.defaultProfile.osx": "tmux-shell"
Now, every time you open the VSCode terminal, Tmux will start automatically.
Tmux config and Vi Copy Mode
To enable Vi Copy Mode, we need to modify the Tmux configuration. The Tmux config file is typically located at ~/.tmux.conf
. We'll also add custom keybindings to make things more memorable and Vi Copy Mode more intuitive. Add the following lines to your ~/.tmux.conf
:
# ctrl-b is the default Tmux prefix
# use ctrl-b + n to create a new window
bind n new-window
# -n stands for "no prefix", meaning you don't have to
# press the prefix key before using the binding
bind -n C-n next-window
bind -n C-p previous-window
# use ctrl-b + c instead of ctrl-b + [ to enter the copy mode
bind c copy-mode
# use v instead of Space to begin selection, like in vim
bind -T copy-mode-vi v send -X begin-selection
# use y instead of Enter to copy selection, like in vim
bind -T copy-mode-vi y send-keys -X copy-pipe-and-cancel "pbcopy"
# Use vi keybindings in copy mode
setw -g mode-keys vi
# Address vim mode switching delay
set -s escape-time 10
# enable mouse
set -g mouse on
To reload the config, run tmux source ~/.tmux.conf
.
Sometimes I encounter situations where things seem outdated or broken after reloading the config with
tmux source ~/.tmux.conf
. In such cases, I’ve found that terminating all Tmux sessions with the following command and then restarting Tmux resolves the issue:tmux kill-server
.
Now, to enter Vi Copy Mode press ctrl-b + c
. Then you can use regular vim motions to navigate terminal history. To begin highlighting, press v
, and to copy the highlighted section, press y
. The text will be saved to your clipboard, and you can paste it using the famous ctrl + v
. To exit Vi Copy Mode, press q
, y
, or enter
.
Refining the Tmux status bar
The default Tmux status bar looks something like this:
I prefer to set it up like this:
To customize our status bar, we’ll use the tmux-powerline plugin.
First, go through the plugin installation steps.
Next, create your own config file and theme.
To make the status bar look like mine, paste the following lines to your my-theme.sh
file:
if patched_font_in_use; then
TMUX_POWERLINE_SEPARATOR_LEFT_BOLD=""
TMUX_POWERLINE_SEPARATOR_LEFT_THIN=":"
TMUX_POWERLINE_SEPARATOR_RIGHT_BOLD=""
TMUX_POWERLINE_SEPARATOR_RIGHT_THIN=":"
else
TMUX_POWERLINE_SEPARATOR_LEFT_BOLD="◀"
TMUX_POWERLINE_SEPARATOR_LEFT_THIN="❮"
TMUX_POWERLINE_SEPARATOR_RIGHT_BOLD="▶"
TMUX_POWERLINE_SEPARATOR_RIGHT_THIN="❯"
fi
TMUX_POWERLINE_DEFAULT_BACKGROUND_COLOR=${TMUX_POWERLINE_DEFAULT_BACKGROUND_COLOR:-'235'}
TMUX_POWERLINE_DEFAULT_FOREGROUND_COLOR=${TMUX_POWERLINE_DEFAULT_FOREGROUND_COLOR:-'255'}
TMUX_POWERLINE_SEG_AIR_COLOR=$(air_color)
TMUX_POWERLINE_DEFAULT_LEFTSIDE_SEPARATOR=${TMUX_POWERLINE_DEFAULT_LEFTSIDE_SEPARATOR:-$TMUX_POWERLINE_SEPARATOR_RIGHT_BOLD}
TMUX_POWERLINE_DEFAULT_RIGHTSIDE_SEPARATOR=${TMUX_POWERLINE_DEFAULT_RIGHTSIDE_SEPARATOR:-$TMUX_POWERLINE_SEPARATOR_LEFT_BOLD}
if [ -z "$TMUX_POWERLINE_WINDOW_STATUS_CURRENT" ]; then
TMUX_POWERLINE_WINDOW_STATUS_CURRENT=(
"#[bg=#010408]"
"$TMUX_POWERLINE_DEFAULT_LEFTSIDE_SEPARATOR"
" #I"
"$TMUX_POWERLINE_SEPARATOR_RIGHT_THIN"
" #W "
"#[$(format regular)]"
"$TMUX_POWERLINE_DEFAULT_LEFTSIDE_SEPARATOR"
)
fi
if [ -z "$TMUX_POWERLINE_WINDOW_STATUS_STYLE" ]; then
TMUX_POWERLINE_WINDOW_STATUS_STYLE=(
"$(format regular)"
)
fi
if [ -z "$TMUX_POWERLINE_WINDOW_STATUS_FORMAT" ]; then
TMUX_POWERLINE_WINDOW_STATUS_FORMAT=(
"#[$(format regular)]"
" #I"
"$TMUX_POWERLINE_SEPARATOR_RIGHT_THIN"
" #W "
)
fi
TMUX_POWERLINE_LEFT_STATUS_SEGMENTS=()
TMUX_POWERLINE_RIGHT_STATUS_SEGMENTS=()
Now, your VSCode terminal should look like this:
Keyboard shortcuts
Let’s keep this as the final and one of the most significant takes.
Step 1 and the only 1. Make your world around your keyboard
If you need to navigate to a certain place in your workspace or perform some actions, don’t be quick to grab a mouse. Spend some time googling ways to achieve the desired result using keyboard combinations. As I mentioned previously, once you get used to the keybindings, you’ll accomplish tasks significantly faster than with a mouse.
And the final tip for today:
When defining your custom keymaps, don’t use random symbols. Instead, incorporate meaningful semantics to make it easier for you to remember the shortcuts. For instance, if you want to assign a keybinding to the “go to definition” action, don’t make it
pm
; make itgd
, whereg
stands for “go” andd
stands for “definition”.
If you want to see more of my content on software engineering topics and keep up with the latest updates, subscribe to my Telegram channel: https://t.me/nikmas_group.
And here is my Telegram channel for programming memes: https://t.me/nikmas_group_humor.