You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
412 lines
14 KiB
412 lines
14 KiB
<?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>
|
|
|