Google Style Guides

Google Vimscript Guide

Background

This is the in-depth vimscript guide. If you’re just a casual user looking to write a plugin, the abbreviated style guide is for you.

This rather rotund guide dives into justifications and clarifications. It provides an idealized set of rules that are rather too draconian to push on casual scripters.

It’s for users who want to know why certain decisions were made in the abbreviated guide and who want to learn a thing or two about using vimscript safely.

Fair warning: Vimscript is a maddening abyss. When you gaze into it, it gazes also into you. Proceed with caution.

Portability

Vim is highly configurable. Users can change many of the default settings, including the case sensitivity, the regular expression rules, the substitution rules, and more. In order for your vimscript to work for all users, follow these guidelines:

In general, guard all commands and functions against user settings.

Language Guide

All other language features are fair game.

Structure

Libraries vs. Functionality

Separate library-providing plugins from command-providing plugins.

Many plugins provide either user functionality (commands, autocommands, etc) or an API (of autoloaded functions) but not both. This separation is encouraged, as it allows other plugins to pull in a library without also pulling in commands, setting changes, and other plugin functionality that affects the end user.

Configuration

Don’t clobber user settings. Provide as much configurability as possible: that’s what Vim’s all about.

Style Guide

Follow google-wide style conventions. Mimic google python style when in doubt.

Documentation

Use vimdoc.

Provide help files generated by vimdoc. Write documentation in .vim files in conformance with the vimdoc standards and include fields like “description” and “author” in the addon-info.json file (see the VAM documentation).

Whitespace

Follow google-wide conventions.

Line Continuations

Comments

Variables

plugin-names-like-this, FunctionNamesLikeThis, CommandNamesLikeThis, augroup_names_like_this, variable_names_like_this. Prefix all variables with their scope.

Strings

Prefer single quotes.

Prefer single quoted strings. Specifically, in order of precedence:

Settings

Prefer long names. Set settings locally.

Usage Guide

Vim plugins should provide any or all of the following: Commands, Autocommands, Functions, Statusline Flags, and Mappings.

Commands

* Define in `plugin/commands.vim`. * CommandNamesLikeThis. * Prefer semantic names to a unified prefix. * Do not use `[!]` * Extract logic into functions.

Conventions

Autocommands

* Define in `plugin/autocmds.vim`. * Use augroups. * `augroup_names_like_this`. * Clear the augroup first. * Extract logic into functions.

Functions

* FunctionNamesLikeThis. * Autoload all functions. * Prefix script-local functions with `s:` * Use `[!]`. * Use `[abort]`.

Mappings

* Provide opt-in key mappings in `plugin/mappings.vim`. * `` mappings can be defined in `plugin/plugs.vim` (unlike mappings.vim, plugs.vim is opt-out). </div> * Define key mappings in `plugin/mappings.vim`, using `maktaba#plugin#MapPrefix` to get a prefix. * Mappings defined in the special `plugin/mappings.vim` file will be disabled by default (by the standard `maktaba#plugin#Enter()` boilerplate). * Users can enable key mappings with `Glaive myplugin plugin[mappings]`. * Make all mappings with ``. * This will inform the user when they have a mapping conflict instead of silently clobbering their existing mappings. * You may provide pseudo-mappings using `` and your plugin's name in `plugin/plugs.vim` (separate from standard key mappings). * `` is a sequence which can not be typed. * You can do something like `noremap namespace#MappingName some_key_sequence` and then users can do `noremap x namespace#MappingName` to take advantage of your pseudo-mapping. * Pseudo-mappings should **not** be in `plugin/mappings.vim` or they will be disabled by default. * Such pseudo-mappings should be named `` followed by your plugin name, a pound sign, and a unique mapping name (CamelCased like a function). * Always use the `noremap` family of commands. Never use the `map` family. * `map` depends upon the user's existing mappings, and could do anything. * Only use `noremap` for commands that both make a motion and take a range. * `noremap` makes mappings in normal, visual, and operator-pending modes. * If you don't want all these use `nnoremap` `onoremap` or `vnoremap` explicitly. * Always use `` in place of `s:` when accessing script locals in mappings. * Using `s:` will often fail as the mapping attempts to type a literal s and colon. ## Conventions ### Dependency Checking Declare dependencies in addon-info.json and use `maktaba`. Declaring dependencies in addon-info.json allows conformant plugin managers (like VAM) to ensure dependencies are installed. See the [VAM documentation](https://goo.gl/CUXJZC) for details. Calling `maktaba#library#Require` from dependent code at runtime ensures that dependencies have been installed and that they don't include unsafe non-library files. ### Statusline Flags Use `#status#Status()` or its finer-grained variants to provide statusline flags. Following is a convention for exposing statusline flags to the user. A plugin should never modify the user's statusline except for when that is the only purpose of the plugin (powerline, etc.). * Provide the `Info`, `Alert`, `Warning`, and `Error` functions under the `#status` namespace. * `Info`should provide information about the state of the buffer. * Example: The current git branch. * `Alert` should provide a quiet reminder that the buffer is non-standard. * Example: The readonly setting is on. * `Warning`should provide a warning about the current state of the buffer. * Example: The file has been edited elsewhere. * `Error` should bring to attention a loud issue with the buffer. * Example: The file does not pass the syntax checker. * By following these conventions, users can easily build up their own statusline customizing the verbosity and colors to their tastes. * All functions should take no arguments and should return either empty strings or strings enclosed by square brackets, e.g. `[Google]`. For example: * A trailing whitespace plugin might return `[$]` if the file contains trailing whitespace * A prose writing plugin might return `[write]` if vim is in writing mode. * Consider providing the `#status#Status` function. * It should return the first non-empty of `Error`, `Warning`, `Alert`, or `Info`. * This is useful for users who want only the most relevant flag and do not have a colored statusline. ## Forbidden Commands These are commands which can only be used by a limited number of plugins, and should not in general be used by yours. * Do not use `:match :2match` or `:3match` * These are reserved for the user and for vim itself. * Use `matchadd()` to create a matchlevel unique to your plugin. * Do not use `echoerr`. * `echoerr` does not print the red error message that you might think it does. * `echoerr` prints an error message as well as context about the code where `echoerr` was called. * `echoerr` is best suited for debugging. * Use `echohl` in tandem with `echomsg` if you want the red error bar. * Use `echomsg` instead of `echo`. * `echomsg` messages can be reviewed with the `:messages` command. * `echo` messages disappear permanently on redraw, which can be very annoying to users who failed to read the message in time. ## Layout Lay out `plugin/` files in the following sections, if applicable, separated by two blank lines: * Declaration of script constants * Declaration of configuration variables * Other declarations (commands in `commands.vim` file, autocommands in `autocmds.vim` file, etc.) Lay out `autoload/` files in the following sections, if applicable, separated by two blank lines: * `maktaba#library#Require` calls * Script-local variables * Script-local functions * Private autoloaded functions * Public autoloaded functions This is recommended convention and is not enforced. ## Recommended Shortcuts Use the following shortcuts: * `catch` over `catch /.*/` * `return` over `return 0` when the return value has no semantic purpose. ## Errata This section plumbs some of the darker corners of vimscript, explaining the language pathologies that you wish you didn't have to know. ### Compatibility Mode If you don't support vi-compatibility mode, fail gracefully. When `compatible` is set, many vim features are not available. The vim feature which most commonly affects vimscript authors is line continuations. If you want your plugin to work in vim with vi compatibility on, you will need to save the compatibility options at the beginning of each plugin file, clear them, and restore them at the end of each plugin file. See `:help use-cpo-save` for details. Plugins that depend on maktaba generally don't need to worry about compatible mode since maktaba currently just disables it, printing a warning.