2014-04-12 14:08:42 +08:00
<?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
2016-04-01 16:36:44 +08:00
<a href= "https://github.com/MarcWeber/vim-addon-manager/blob/master/doc/vim-addon-manager-additional-documentation.txt" > VAM documentation</a> for details).
2014-04-12 14:08:42 +08:00
</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>