| <?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/> |
| Joshua Hoak<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 dependant.</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/> |
| Joshua Hoak<br/> |
| David Barnett<br/> |
| </address> |
| </GUIDE> |