Neovim Integration
One of Dockim's standout features is its seamless integration with Neovim. This chapter covers how to set up, configure, and optimize Neovim for use with your development containers.
Overview
Dockim's Neovim integration provides two main modes of operation:
- Remote UI Mode (default) - Neovim runs in the container while the UI runs on your host
- Direct Mode - Neovim runs entirely within the container
The remote UI mode is recommended as it provides the best of both worlds: your familiar host environment with access to the containerized development tools.
Quick Start
Basic Usage
Launch Neovim with automatic setup:
# Start Neovim with remote UI (recommended)
dockim neovim
# Short alias
dockim v
# Start directly in container (no remote UI)
dockim neovim --no-remote-ui
First Launch
On your first launch, Dockim will:
- Start the container if it's not running
- Launch Neovim server inside the container
- Find an available port for the connection
- Start your local Neovim client
- Establish the remote connection
Remote UI Mode
How It Works
Remote UI mode creates a client-server architecture:
Host Machine Container
┌─────────────────┐ ┌─────────────────┐
│ Neovim Client │ ◀────────▶ │ Neovim Server │
│ (Your UI) │ Network │ (LSP, Tools) │
└─────────────────┘ Connection└─────────────────┘
Benefits:
- Native performance on your host system
- Access to all container tools and LSPs
- Seamless file synchronization
- Clipboard integration
- Port forwarding handled automatically
Port Management
Dockim automatically manages ports for Neovim connections:
# View active Neovim connections
dockim port ls
# Specify a custom host port
dockim neovim --host-port 8080
Port Selection:
- Dockim automatically finds available ports
- Default range: 52000-53000
- You can specify a custom port if needed
- Multiple projects can run simultaneously
Client Configuration
Configure your Neovim client behavior:
# ~/.config/dockim/config.toml
[remote]
# Run client in background (don't block terminal)
background = false
# Enable clipboard synchronization
use_clipboard_server = true
# Custom client command
args = ["nvim", "--server", "{server}", "--remote-ui"]
Configuration Options:
background: Whether to run client in backgrounduse_clipboard_server: Enable clipboard sync between host/containerargs: Command template for launching the client
Server Configuration
Container Neovim Setup
Install and configure Neovim in your container:
# In your Dockerfile
FROM mcr.microsoft.com/devcontainers/base:ubuntu
# Install Neovim (latest stable)
RUN apt-get update && apt-get install -y software-properties-common \
&& add-apt-repository ppa:neovim-ppa/stable \
&& apt-get update && apt-get install -y neovim \
&& rm -rf /var/lib/apt/lists/*
# Or install from source for latest features
RUN curl -LO https://github.com/neovim/neovim/releases/latest/download/nvim-linux64.tar.gz \
&& tar -C /opt -xzf nvim-linux64.tar.gz \
&& ln -s /opt/nvim-linux64/bin/nvim /usr/local/bin/nvim
Building from Source
For the absolute latest Neovim features:
# Build with Neovim from source
dockim build --neovim-from-source
This option:
- Downloads and compiles the latest Neovim
- Takes longer but provides cutting-edge features
- Useful for plugin development or beta testing
Neovim Version Management
Configure the Neovim version to install:
# ~/.config/dockim/config.toml
neovim_version = "v0.11.0" # Specific version
# or
neovim_version = "stable" # Latest stable
# or
neovim_version = "nightly" # Latest nightly
Configuration Management
Dotfiles Integration
Automatically set up your Neovim configuration:
# ~/.config/dockim/config.toml
dotfiles_repository_name = "dotfiles"
dotfiles_install_command = "./install.sh nvim"
Dotfiles Workflow:
- Dockim clones your dotfiles repository
- Runs the specified install command
- Your Neovim configuration is available immediately
Configuration Mounting
Alternative approaches for configuration:
Mount local config:
# compose.yml
services:
dev:
volumes:
- ..:/workspace:cached
- ~/.config/nvim:/home/vscode/.config/nvim:ro
Copy during build:
# Dockerfile
COPY .config/nvim /home/vscode/.config/nvim
RUN chown -R vscode:vscode /home/vscode/.config
Language Server Protocol (LSP)
LSP in Containers
One major advantage of container-based development is consistent LSP setup:
Node.js/TypeScript:
# Install language servers in container
RUN npm install -g typescript-language-server typescript
RUN npm install -g @volar/vue-language-server
Python:
RUN pip install python-lsp-server[all] pylsp-mypy pylsp-rope
RUN pip install black isort flake8
Rust:
RUN rustup component add rust-analyzer
Go:
RUN go install golang.org/x/tools/gopls@latest
LSP Configuration
Example Neovim LSP setup for containers:
-- ~/.config/nvim/lua/lsp-config.lua
local lspconfig = require('lspconfig')
-- TypeScript
lspconfig.tsserver.setup({
root_dir = lspconfig.util.root_pattern("package.json", ".git"),
})
-- Python
lspconfig.pylsp.setup({
settings = {
pylsp = {
plugins = {
black = { enabled = true },
isort = { enabled = true },
}
}
}
})
-- Rust
lspconfig.rust_analyzer.setup({
settings = {
["rust-analyzer"] = {
cargo = { allFeatures = true },
checkOnSave = { command = "clippy" },
}
}
})
Debugging Integration
Debug Adapter Protocol (DAP)
Set up debugging within containers:
-- Debug configuration
local dap = require('dap')
-- Node.js debugging
dap.adapters.node2 = {
type = 'executable',
command = 'node',
args = {'/path/to/vscode-node-debug2/out/src/nodeDebug.js'},
}
dap.configurations.javascript = {
{
name = 'Launch',
type = 'node2',
request = 'launch',
program = '${workspaceFolder}/${file}',
cwd = vim.fn.getcwd(),
sourceMaps = true,
protocol = 'inspector',
console = 'integratedTerminal',
},
}
Port Forwarding for Debugging
# Forward debugger ports
dockim port add 9229 # Node.js debugger
dockim port add 5678 # Python debugger
# Launch with debugging
dockim exec node --inspect=0.0.0.0:9229 app.js
dockim exec python -m debugpy --listen 0.0.0.0:5678 --wait-for-client app.py
Plugin Management
Container-Specific Plugins
Useful plugins for container development:
-- Plugin configuration (using packer.nvim example)
return require('packer').startup(function(use)
-- Essential plugins for container dev
use 'neovim/nvim-lspconfig' -- LSP configuration
use 'hrsh7th/nvim-cmp' -- Completion
use 'nvim-treesitter/nvim-treesitter' -- Syntax highlighting
-- Container-specific utilities
use 'akinsho/toggleterm.nvim' -- Terminal integration
use 'nvim-telescope/telescope.nvim' -- File finding
use 'lewis6991/gitsigns.nvim' -- Git integration
-- Remote development helpers
use 'folke/which-key.nvim' -- Key binding help
use 'windwp/nvim-autopairs' -- Auto pairs
use 'numToStr/Comment.nvim' -- Easy commenting
end)
Plugin Synchronization
Ensure plugins work across host and container:
-- Conditional plugin loading
local in_container = vim.fn.getenv("CONTAINER") == "1"
if in_container then
-- Container-specific plugin config
require('lspconfig').tsserver.setup({})
else
-- Host-specific config (if needed)
end
Clipboard Integration
Automatic Clipboard Sync
Enable seamless clipboard sharing:
# ~/.config/dockim/config.toml
[remote]
use_clipboard_server = true
Manual Clipboard Setup
If automatic sync doesn't work:
-- Neovim clipboard configuration
if vim.fn.getenv("SSH_TTY") then
-- SSH/Remote environment
vim.g.clipboard = {
name = 'OSC 52',
copy = {
['+'] = require('vim.ui.clipboard.osc52').copy('+'),
['*'] = require('vim.ui.clipboard.osc52').copy('*'),
},
paste = {
['+'] = require('vim.ui.clipboard.osc52').paste('+'),
['*'] = require('vim.ui.clipboard.osc52').paste('*'),
},
}
end
Performance Optimization
Startup Time
Optimize Neovim startup in containers:
-- Lazy loading configuration
vim.loader.enable() -- Enable faster Lua module loading
-- Lazy load plugins
require('lazy').setup({
-- Plugin specifications with lazy loading
{
'nvim-treesitter/nvim-treesitter',
event = 'BufRead',
},
{
'hrsh7th/nvim-cmp',
event = 'InsertEnter',
},
})
File Watching
Configure file watching for better performance:
-- Optimize file watching in containers
vim.opt.updatetime = 100
vim.opt.timeoutlen = 500
-- Use polling for file changes (if needed)
if vim.fn.getenv("CONTAINER") == "1" then
vim.opt.backup = false
vim.opt.writebackup = false
vim.opt.swapfile = false
end
Troubleshooting
Connection Issues
Server won't start:
# Check if Neovim is installed in container
dockim exec nvim --version
# Check container is running
docker ps --filter "label=dockim"
# Restart container
dockim stop && dockim up
Client can't connect:
# Check port forwarding
dockim port ls
# Check if port is available on host
netstat -tuln | grep :52000
# Try with specific port
dockim neovim --host-port 8080
Performance Issues
Slow startup:
- Use lazy loading for plugins
- Minimize startup scripts
- Consider using Neovim nightly for performance improvements
Laggy editing:
- Check network latency between host and container
- Disable heavy plugins temporarily
- Use local file editing for large files
High memory usage:
- Monitor container resource limits
- Disable unnecessary language servers
- Use treesitter instead of regex-based syntax highlighting
Plugin Issues
LSP not working:
# Check if language server is installed
dockim exec which typescript-language-server
dockim exec which pylsp
# Check LSP status in Neovim
:LspInfo
Debugging not connecting:
# Verify debugger ports are forwarded
dockim port ls
# Check debugger is listening
dockim exec netstat -tuln | grep :9229
Advanced Workflows
Multiple Projects
Working with multiple projects simultaneously:
# Terminal 1: Project A
cd project-a
dockim neovim --host-port 8001
# Terminal 2: Project B
cd ../project-b
dockim neovim --host-port 8002
Session Management
Save and restore Neovim sessions:
-- Session management configuration
vim.opt.sessionoptions = 'blank,buffers,curdir,folds,help,tabpages,winsize,winpos,terminal'
-- Auto-save session on exit
vim.api.nvim_create_autocmd('VimLeavePre', {
callback = function()
vim.cmd('mksession! ~/.config/nvim/session.vim')
end,
})
Custom Keybindings
Container-specific keybindings:
-- Container development keybindings
local keymap = vim.keymap.set
-- Quick container commands
keymap('n', '<leader>ct', ':term dockim exec npm test<CR>')
keymap('n', '<leader>cb', ':term dockim exec npm run build<CR>')
keymap('n', '<leader>cs', ':term dockim shell<CR>')
-- Port management
keymap('n', '<leader>cp', ':term dockim port ls<CR>')
Next: Learn about Port Management for advanced networking configuration with your development containers.