| <?xml version = '1.0'?> | |
| <?xml-stylesheet type="text/xsl" href="styleguide.xsl"?> | |
| <GUIDE title="Google Vimscript Style Guide"> | |
| <p class="revision"> | |
| Revision 1.1 | |
| </p> | |
| <address> | |
| Nate Soares<br/> | |
| Artemis Sparks<br/> | |
| David Barnett<br/> | |
| </address> | |
| <OVERVIEW> | |
| <CATEGORY title="Background"> | |
| <p> | |
| This is a casual version of the vimscript style guide, because | |
| vimscript is a casual language. When submitting vim plugin code, you | |
| must adhere to these rules. For clarifications, justifications, and | |
| explanations about the finer points of vimscript, please refer to the | |
| <a href="vimscriptfull.xml">heavy guide</a>. | |
| </p> | |
| </CATEGORY> | |
| </OVERVIEW> | |
| <CATEGORY title="Portability"> | |
| <p> | |
| It's hard to get vimscript right. Many commands depend upon the user's | |
| settings. By following these guidelines, you can hope to make your | |
| scripts portable. | |
| </p> | |
| <STYLEPOINT title="Strings"> | |
| <SUMMARY>Prefer single quoted strings</SUMMARY> | |
| <BODY> | |
| <p> | |
| Double quoted strings are semantically different in vimscript, and | |
| you probably don't want them (they break regexes). | |
| </p> | |
| <p> | |
| Use double quoted strings when you need an escape sequence (such as | |
| <code>"\n"</code>) or if you know it doesn't matter and you need to | |
| embed single quotes. | |
| </p> | |
| </BODY> | |
| </STYLEPOINT> | |
| <STYLEPOINT title="Matching Strings"> | |
| <SUMMARY> | |
| Use the <code>=~#</code> or <code>=~?</code> operator families over the | |
| <code>=~</code> family. | |
| </SUMMARY> | |
| <BODY> | |
| <p> | |
| The matching behavior depends upon the user's ignorecase and smartcase | |
| settings and on whether you compare them with the <code>=~</code>, | |
| <code>=~#</code>, or <code>=~?</code> family of operators. Use the | |
| <code>=~#</code> and <code>=~?</code> operator families explicitly | |
| when comparing strings unless you explicitly need to honor the user's | |
| case sensitivity settings. | |
| </p> | |
| </BODY> | |
| </STYLEPOINT> | |
| <STYLEPOINT title="Regular Expressions"> | |
| <SUMMARY>Prefix all regexes with <code>\m\C</code>.</SUMMARY> | |
| <BODY> | |
| <p> | |
| In addition to the case sensitivity settings, regex behavior depends | |
| upon the user's nomagic setting. To make regexes act like nomagic and | |
| noignorecase are set, prepend all regexes with <code>\m\C</code>. | |
| </p> | |
| <p> | |
| You are welcome to use other magic levels (<code>\v</code>) and case | |
| sensitivities (<code>\c</code>) so long as they are intentional and | |
| explicit. | |
| </p> | |
| </BODY> | |
| </STYLEPOINT> | |
| <STYLEPOINT title="Dangerous commands"> | |
| <SUMMARY>Avoid commands with unintended side effects.</SUMMARY> | |
| <BODY> | |
| <p> | |
| Avoid using <code>:s[ubstitute]</code> as it moves the cursor and | |
| prints error messages. Prefer functions (such as | |
| <code>search()</code>) better suited to scripts. | |
| </p> | |
| <p> | |
| For many vim commands, functions exist that do the same thing with | |
| fewer side effects. See <code>:help functions()</code> for a list of | |
| built-in functions. | |
| </p> | |
| </BODY> | |
| </STYLEPOINT> | |
| <STYLEPOINT title="Fragile commands"> | |
| <SUMMARY>Avoid commands that rely on user settings.</SUMMARY> | |
| <BODY> | |
| <p> | |
| Always use <code>normal!</code> instead of <code>normal</code>. The | |
| latter depends upon the user's key mappings and could do anything. | |
| </p> | |
| <p> | |
| Avoid <code>:s[ubstitute]</code>, as its behavior depends upon a | |
| number of local settings. | |
| </p> | |
| <p> | |
| The same applies to other commands not listed here. | |
| </p> | |
| </BODY> | |
| </STYLEPOINT> | |
| <STYLEPOINT title="Catching Exceptions"> | |
| <SUMMARY>Match error codes, not error text.</SUMMARY> | |
| <BODY> | |
| <p>Error text may be locale dependent.</p> | |
| </BODY> | |
| </STYLEPOINT> | |
| </CATEGORY> | |
| <CATEGORY title="General Guidelines"> | |
| <STYLEPOINT title="Messaging"> | |
| <SUMMARY>Message the user infrequently.</SUMMARY> | |
| <BODY> | |
| <p> | |
| Loud scripts are annoying. Message the user only when: | |
| <ul> | |
| <li>A long-running process has kicked off.</li> | |
| <li>An error has occurred.</li> | |
| </ul> | |
| </p> | |
| </BODY> | |
| </STYLEPOINT> | |
| <STYLEPOINT title="Type checking"> | |
| <SUMMARY>Use strict and explicit checks where possible.</SUMMARY> | |
| <BODY> | |
| <p> | |
| Vimscript has unsafe, unintuitive behavior when dealing with some | |
| types. For instance, <code>0 == 'foo'</code> evaluates to true. | |
| </p> | |
| <p> | |
| Use strict comparison operators where possible. When comparing against | |
| a string literal, use the <code>is#</code> operator. Otherwise, prefer | |
| <code>maktaba#value#IsEqual</code> or check <code>type()</code> | |
| explicitly. | |
| </p> | |
| <p> | |
| Check variable types explicitly before using them. Use functions from | |
| <code>maktaba#ensure</code>, or check <code>maktaba#value</code> or | |
| <code>type()</code> and throw your own errors. | |
| </p> | |
| <p> | |
| Use <code>:unlet</code> for variables that may change types, | |
| particularly those assigned inside loops. | |
| </p> | |
| </BODY> | |
| </STYLEPOINT> | |
| <STYLEPOINT title="Python"> | |
| <SUMMARY>Use sparingly.</SUMMARY> | |
| <BODY> | |
| <p> | |
| Use python only when it provides critical functionality, for example | |
| when writing threaded code. | |
| </p> | |
| </BODY> | |
| </STYLEPOINT> | |
| <STYLEPOINT title="Other Languages"> | |
| <SUMMARY>Use vimscript instead.</SUMMARY> | |
| <BODY> | |
| <p> | |
| Avoid using other scripting languages such as ruby and lua. We can | |
| not guarantee that the end user's vim has been compiled with support | |
| for non-vimscript languages. | |
| </p> | |
| </BODY> | |
| </STYLEPOINT> | |
| <STYLEPOINT title="Boilerplate"> | |
| <SUMMARY> | |
| Use <a href="https://github.com/google/maktaba">maktaba</a>. | |
| </SUMMARY> | |
| <BODY> | |
| <p> | |
| maktaba removes boilerplate, including: | |
| <ul> | |
| <li>Plugin creation</li> | |
| <li>Error handling</li> | |
| <li>Dependency checking</li> | |
| </ul> | |
| </p> | |
| </BODY> | |
| </STYLEPOINT> | |
| <STYLEPOINT title="Plugin layout"> | |
| <SUMMARY>Organize functionality into modular plugins</SUMMARY> | |
| <BODY> | |
| <p> | |
| Group your functionality as a plugin, unified in one directory (or | |
| code repository) which shares your plugin's name (with a "vim-" prefix | |
| or ".vim" suffix if desired). It should be split into plugin/, | |
| autoload/, etc. subdirectories as necessary, and it should declare | |
| metadata in the addon-info.json format (see the | |
| <a href="https://github.com/MarcWeber/vim-addon-manager/blob/master/doc/vim-addon-manager-additional-documentation.txt">VAM documentation</a> for details). | |
| </p> | |
| </BODY> | |
| </STYLEPOINT> | |
| <STYLEPOINT title="Functions"> | |
| <SUMMARY> | |
| In the autoload/ directory, defined with <code>[!]</code> and | |
| <code>[abort]</code>. | |
| </SUMMARY> | |
| <BODY> | |
| <p> | |
| Autoloading allows functions to be loaded on demand, which makes | |
| startuptime faster and enforces function namespacing. | |
| </p> | |
| <p> | |
| Script-local functions are welcome, but should also live in autoload/ | |
| and be called by autoloaded functions. | |
| </p> | |
| <p> | |
| Non-library plugins should expose commands instead of functions. | |
| Command logic should be extracted into functions and autoloaded. | |
| </p> | |
| <p> | |
| <code>[!]</code> allows developers to reload their functions | |
| without complaint. | |
| </p> | |
| <p> | |
| <code>[abort]</code> forces the function to halt when it encounters | |
| an error. | |
| </p> | |
| </BODY> | |
| </STYLEPOINT> | |
| <STYLEPOINT title="Commands"> | |
| <SUMMARY> | |
| In the plugin/commands.vim or under the ftplugin/ directory, defined | |
| without <code>[!]</code>. | |
| </SUMMARY> | |
| <BODY> | |
| <p> | |
| General commands go in <code>plugin/commands.vim</code>. | |
| Filetype-specific commands go in <code>ftplugin/</code>. | |
| </p> | |
| <p> | |
| Excluding <code>[!]</code> prevents your plugin from silently | |
| clobbering existing commands. Command conflicts should be resolved by | |
| the user. | |
| </p> | |
| </BODY> | |
| </STYLEPOINT> | |
| <STYLEPOINT title="Autocommands"> | |
| <SUMMARY> | |
| Place them in plugin/autocmds.vim, within augroups. | |
| </SUMMARY> | |
| <BODY> | |
| <p> | |
| Place all autocommands in augroups. | |
| </p> | |
| <p> | |
| The augroup name should be unique. It should either be, or be prefixed | |
| with, the plugin name. | |
| </p> | |
| <p> | |
| Clear the augroup with <code>autocmd!</code> before defining new | |
| autocommands in the augroup. This makes your plugin re-entrable. | |
| </p> | |
| </BODY> | |
| </STYLEPOINT> | |
| <STYLEPOINT title="Mappings"> | |
| <SUMMARY> | |
| Place them in <code>plugin/mappings.vim</code>, using | |
| <code>maktaba#plugin#MapPrefix</code> to get a prefix. | |
| </SUMMARY> | |
| <BODY> | |
| <p> | |
| All key mappings should be defined in | |
| <code>plugin/mappings.vim</code>. | |
| </p> | |
| <p> | |
| Partial mappings (see :help using-<Plug>.) should be defined in | |
| <code>plugin/plugs.vim</code>. | |
| </p> | |
| </BODY> | |
| </STYLEPOINT> | |
| <STYLEPOINT title="Settings"> | |
| <SUMMARY>Change settings locally</SUMMARY> | |
| <BODY> | |
| <p> | |
| Use <code>:setlocal</code> and <code>&l:</code> instead of | |
| <code>:set</code> and <code>&</code> unless you have explicit | |
| reason to do otherwise. | |
| </p> | |
| </BODY> | |
| </STYLEPOINT> | |
| </CATEGORY> | |
| <CATEGORY title="Style"> | |
| <p> | |
| Follow google style conventions. When in doubt, treat vimscript style | |
| like python style. | |
| </p> | |
| <STYLEPOINT title="Whitespace"> | |
| <SUMMARY> | |
| Similar to python. | |
| <br/> | |
| <br/> | |
| </SUMMARY> | |
| <BODY> | |
| <ul> | |
| <li>Use two spaces for indents</li> | |
| <li>Do not use tabs</li> | |
| <li>Use spaces around operators | |
| <p>This does not apply to arguments to commands.</p> | |
| <CODE_SNIPPET> | |
| let s:variable = "concatenated " . "strings" | |
| command -range=% MyCommand | |
| </CODE_SNIPPET> | |
| </li> | |
| <li>Do not introduce trailing whitespace | |
| <p>You need not go out of your way to remove it.</p> | |
| <p> | |
| Trailing whitespace is allowed in mappings which prep commands | |
| for user input, such as | |
| "<code>noremap <leader>gf :grep -f </code>". | |
| </p> | |
| </li> | |
| <li>Restrict lines to 80 columns wide</li> | |
| <li>Indent continued lines by four spaces</li> | |
| <li>Do not align arguments of commands | |
| <BAD_CODE_SNIPPET> | |
| command -bang MyCommand call myplugin#foo() | |
| command MyCommand2 call myplugin#bar() | |
| </BAD_CODE_SNIPPET> | |
| <CODE_SNIPPET> | |
| command -bang MyCommand call myplugin#foo() | |
| command MyCommand2 call myplugin#bar() | |
| </CODE_SNIPPET> | |
| </li> | |
| </ul> | |
| </BODY> | |
| </STYLEPOINT> | |
| <STYLEPOINT title="Naming"> | |
| <SUMMARY> | |
| <p> | |
| In general, use | |
| <code>plugin-names-like-this</code>, | |
| <code>FunctionNamesLikeThis</code>, | |
| <code>CommandNamesLikeThis</code>, | |
| <code>augroup_names_like_this</code>, | |
| <code>variable_names_like_this</code>. | |
| </p> | |
| <p>Always prefix variables with their scope.</p> | |
| </SUMMARY> | |
| <BODY> | |
| <SUBSECTION title="plugin-names-like-this"> | |
| <p>Keep them short and sweet.</p> | |
| </SUBSECTION> | |
| <SUBSECTION title="FunctionNamesLikeThis"> | |
| <p>Prefix script-local functions with <code>s:</code></p> | |
| <p>Autoloaded functions may not have a scope prefix.</p> | |
| <p> | |
| Do not create global functions. Use autoloaded functions | |
| instead. | |
| </p> | |
| </SUBSECTION> | |
| <SUBSECTION title="CommandNamesLikeThis"> | |
| <p>Prefer succinct command names over common command prefixes.</p> | |
| </SUBSECTION> | |
| <SUBSECTION title="variable_names_like_this"> | |
| <p>Augroup names count as variables for naming purposes.</p> | |
| </SUBSECTION> | |
| <SUBSECTION title="Prefix all variables with their scope."> | |
| <ul> | |
| <li>Global variables with <code>g:</code></li> | |
| <li>Script-local variables with <code>s:</code></li> | |
| <li>Function arguments with <code>a:</code></li> | |
| <li>Function-local variables with <code>l:</code></li> | |
| <li>Vim-predefined variables with <code>v:</code></li> | |
| <li>Buffer-local variables with <code>b:</code></li> | |
| </ul> | |
| <p> | |
| <code>g:</code>, <code>s:</code>, and <code>a:</code> must always | |
| be used. | |
| </p> | |
| <p> | |
| <code>b:</code> changes the variable semantics; use it when you | |
| want buffer-local semantics. | |
| </p> | |
| <p> | |
| <code>l:</code> and <code>v:</code> should be used for consistency, | |
| future proofing, and to avoid subtle bugs. They are not strictly | |
| required. Add them in new code but don’t go out of your way to add | |
| them elsewhere. | |
| </p> | |
| </SUBSECTION> | |
| </BODY> | |
| </STYLEPOINT> | |
| </CATEGORY> | |
| <p align="right"> | |
| Revision 1.1 | |
| </p> | |
| <address> | |
| Nate Soares<br/> | |
| Artemis Sparks<br/> | |
| David Barnett<br/> | |
| </address> | |
| </GUIDE> |