vim-script
Skill15 starsChanged 9 months agoMITView on GitHub
Google's official Vim script style guide. Covers plugin structure, naming conventions, variable scoping, error handling, portability, and Vimscript best practices.
In this repository17 other files it gives its agents.
- angularjsSkill
- common-lispSkill
- cppSkill
- csharpSkill
- goSkill
- html-cssSkill
- javascriptSkill
- javaSkill
- jsonSkill
- markdownSkill
- objective-cSkill
- pythonSkill
- rSkill
- shellSkill
- google-styleguides-skillsSkill
- swiftSkill
- typescriptSkill
The file
Files
Google Vim Script Style Guide
Official Google Vim script coding standards for consistent plugin development.
Golden Rules
- Use
scriptencoding utf-8— declare encoding at top of every file - Prefix plugin functions — avoid namespace collisions with other plugins
- Use
aborton functions — fail fast on errors instead of silently continuing - Check feature availability — use
has('feature')before using features - Avoid global variables — use script-local
s:instead ofg:internally - Document all commands — help users understand usage
- Test on multiple Vim versions — ensure broad compatibility
Quick Reference
Naming Conventions
| Element | Convention | Example |
| Plugin functions | prefix#FunctionName | myplugin#GetUser |
| Script-local functions | s:FunctionName | s:InternalHelper |
| Script-local variables | s:variable_name | s:internal_state |
| Local variables | l:variable_name | l:temp_value |
| Global variables | g:plugin_name | g:myplugin_enabled |
| Buffer variables | b:variable_name | b:current_mode |
| Autocommand groups | UpperCamelCase | MyPlugin |
File Structure
" ✓ CORRECT - file header and guard
" Plugin: MyPlugin
" Description: Does something useful
" Maintainer: Your Name <email@example.com>
" License: Apache 2.0
if exists('g:loaded_myplugin')
finish
endif
let g:loaded_myplugin = 1
scriptencoding utf-8
" Plugin code hereFunctions
" ✓ CORRECT - autoloaded function with abort
function! myplugin#ProcessBuffer() abort
let l:lines = getline(1, '$')
for l:line in l:lines
call s:ProcessLine(l:line)
endfor
endfunction
" ✓ CORRECT - script-local helper function
function! s:ProcessLine(line) abort
if empty(a:line)
return
endif
echo a:line
endfunction
" ✓ CORRECT - function with optional arguments
function! myplugin#Greet(...) abort
let l:name = a:0 >= 1 ? a:1 : 'World'
echo 'Hello, ' . l:name . '!'
endfunctionVariables and Scoping
" ✓ CORRECT - explicit scoping
function! myplugin#Example() abort
let l:local_var = 'local'
let s:script_var = 'script'
" Check before using global config
if exists('g:myplugin_config')
let l:config = g:myplugin_config
else
let l:config = {}
endif
echo l:local_var
endfunctionCommands
" ✓ CORRECT - custom commands
command! -nargs=0 MyPluginRun call myplugin#Run()
command! -nargs=1 MyPluginGreet call myplugin#Greet(<f-args>)
command! -range MyPluginProcess <line1>,<line2>call myplugin#ProcessRange()
command! -nargs=1 -complete=file MyPluginOpen call myplugin#Open(<f-args>)Mappings
" ✓ CORRECT - non-recursive mappings with <silent>
nnoremap <silent> <Leader>mp :call myplugin#Process()<CR>
vnoremap <silent> <Leader>ms :call myplugin#ProcessSelection()<CR>
inoremap <silent> <C-Space> <C-R>=myplugin#Complete()<CR>
" ✓ CORRECT - buffer-local mapping
nnoremap <buffer> <silent> <Leader>mp :call myplugin#ProcessBuffer()<CR>Autocommands
" ✓ CORRECT - always use augroup to avoid duplicate autocommands
augroup MyPlugin
autocmd!
autocmd BufRead,BufNewFile *.txt call myplugin#SetupTextFile()
autocmd FileType python call myplugin#SetupPython()
autocmd VimLeave * call myplugin#Cleanup()
augroup ENDError Handling
" ✓ CORRECT - try-catch for risky operations
function! myplugin#SafeOperation() abort
try
call myplugin#RiskyFunction()
catch /^Vim\%((\\a\+)\)\=:E/
echoerr 'Operation failed: ' . v:exception
finally
call myplugin#Cleanup()
endtry
endfunction
" ✓ CORRECT - checking for required executables
if !executable('git')
echoerr 'myplugin: git not found in PATH'
finish
endifFeature Detection
" ✓ CORRECT - check features before using them
if has('python3')
python3 import myplugin
elseif has('python')
python import myplugin
else
echoerr 'myplugin requires Python support'
finish
endif
" ✓ CORRECT - check Vim version
if v:version < 800
echoerr 'myplugin requires Vim 8.0+'
finish
endifString Operations
" ✓ CORRECT - case-sensitive comparison
if l:str ==# 'exact'
echo 'Case-sensitive match'
endif
" ✓ CORRECT - case-insensitive comparison
if l:str ==? 'case'
echo 'Case-insensitive match'
endif
" ✓ CORRECT - string concatenation
let l:message = 'Hello, ' . l:name . '!'Common Mistakes
| Mistake | Correct Approach |
Missing abort on functions | Always use function! Name() abort |
| No variable scoping | Use l:, s:, g: prefixes explicitly |
| Global namespace pollution | Prefix all functions with plugin name |
Missing g:loaded_plugin guard | Check at top to prevent double-loading |
No augroup for autocommands | Always wrap in augroup/autocmd! |
| Case-ambiguous comparisons | Use ==# (sensitive) or ==? (insensitive) |
Using map / noremap | Prefer nnoremap, vnoremap, etc. |
When to Use This Guide
- Writing Vim plugins
- Maintaining Vim configuration files
- Code reviews for Vimscript
- Onboarding new contributors to Vim plugin projects
Install
npx skills add testdino-hq/google-styleguides-skills/vim-scriptFull Guide
See vim-script.md for complete details, examples, and edge cases.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

