Repository navigation
Screen Shield
Masking hides values one at a time. Sometimes the whole screen is the problem: you step away mid-share, or switch to another app while the editor is still in the shared area.
:CamouflageShield covers everything Neovim draws, the file, the statusline, the command line and other plugins' windows, with a camouflage pattern and a small card in the middle:
╭─── camouflage ───╮
│ │
│ screen hidden │
│ press any key │
│ │
╰──────────────────╯
The first key you press uncovers it, and that key never reaches the buffer underneath, so typing blind can't edit your file. The pattern is generated fresh every time, and follows the editor if the terminal is resized.
require('camouflage').setup({
shield = {
on_focus_lost = false, -- come down on its own
-- text = '...', -- the card, \n for a new line
},
})| Option | Type | Default | Description |
|---|---|---|---|
on_focus_lost |
boolean |
false |
Cover the editor when Neovim loses focus |
password_hash |
string |
nil |
Overrides the password saved by :CamouflageShieldPassword, see Password
|
text |
string |
'screen hidden\npress any key', or 'screen locked\nenter password' with a password |
Text on the card, \n for a new line |
Shield settings can only come from setup(). A .camouflage.yaml that sets shield is refused, so a cloned repository can't put a password on your editor and lock you out of it.
A keymap is up to you:
vim.keymap.set('n', '<leader>ms', '<cmd>CamouflageShield<cr>', { desc = 'Screen Shield' })With on_focus_lost = true the shield comes down when Neovim loses focus, when you switch to another window or app. Coming back does not lift it, a key does.
This relies on the terminal reporting focus changes to Neovim. Most terminals do (Ghostty, kitty, WezTerm, iTerm2, Alacritty).
Inside tmux, focus events are off by default. Without them Neovim never hears that it lost focus, and the shield never comes down. Add this to ~/.tmux.conf:
set -g focus-events onthen reload it with tmux source-file ~/.tmux.conf, or restart tmux.
By default any key lifts the shield. To require a password, run:
:CamouflageShieldPasswordIt asks for the password twice and applies right away, in every project and every session. There is nothing to add to your config. To remove it:
:CamouflageShieldPassword!The password itself is kept nowhere. What is kept is SHA-256 over a random salt, applied 50000 times, in stdpath('data')/camouflage/shield_password (usually ~/.local/share/nvim/camouflage/shield_password), readable by you only. Checking it takes less than a tenth of a second on a laptop when you unlock, and makes guessing a weak password slow.
If you'd rather keep it in your dotfiles, shield.password_hash in setup() overrides the saved one. Its value is the content of that file. A value that isn't in that form is ignored with a warning rather than used, since it would match nothing and lock the editor for good.
On the card the password shows as dots:
╭─── camouflage ────────╮
│ │
│ screen locked │
│ enter password │
│ │
│ ••••·············· │
│ wrong password │
│ │
╰───────────────────────╯
| Key | Does |
|---|---|
<CR> |
Check the password |
<BS> |
Delete the last character |
<C-u>, <Esc>
|
Clear the input |
<C-c> |
Nothing, it does not get past the password |
A wrong password pauses input for a moment.
This makes the shield a deterrent, not a lock. Whoever is at the keyboard can still close the terminal window (<C-z> doesn't help them, it is swallowed like any other key). For real protection, lock the machine. If you forget the password, close the terminal: unsaved changes are in the swap file.
| Group | Default | Purpose |
|---|---|---|
CamouflageShield1 to CamouflageShield4
|
woodland greens and brown | The four colors of the pattern |
CamouflageShieldCard |
Links to NormalFloat
|
Card background |
CamouflageShieldBorder |
Links to FloatBorder
|
Card border |
CamouflageShieldTitle |
Links to Title
|
camouflage in the border |
CamouflageShieldText |
Links to Comment
|
Card text |
CamouflageShieldInput |
Links to Normal
|
Password dots |
CamouflageShieldError |
Links to ErrorMsg
|
wrong password |
All are defined with default, so a colorscheme or your config can set them:
vim.api.nvim_set_hl(0, 'CamouflageShield3', { bg = '#7a5c3a' })It covers Neovim only. The terminal's title bar (which can show the file path when title is set), its scrollback and the tmux status line are outside its reach.
A window with a higher zindex than the shield would still draw on top. The shield sits at 30000, well above what pickers, notifiers and key hint popups use.
- Presentation Mode: mask everything and refuse reveals for a demo
-
Terminal Masking: masking values printed in
:terminal - Security Model: what visual masking does and does not protect