generate html for remaining XML guides

Since Chrome is dropping support for this completely this year,
generate HTML from all remaining XML guides.  These have largely
been migrated to other formats internally already too.
This commit is contained in:
Mike Frysinger authored and Mike Frysinger committed 2026-09-20 22:47:51 -04:00
1 parent fc855b4a94
commit 2b21895cd5
9 files changed
+5855 -5836

No files matched your search

+4
View File
@@ -15,11 +15,15 @@ window.onload = function() {
'cppguide.xml': 'cppguide.html',
'google-r-style.html': 'Rguide.html',
'htmlcssguide.xml': 'htmlcssguide.html',
'javascriptguide.xml': 'javascriptguide.html',
'jsoncstyleguide.html': 'jsoncguide.html',
'jsoncstyleguide.xml': 'jsoncguide.html',
'lispguide.xml': 'lispguide.html',
'objcguide.xml': 'objcguide.html',
'Rguide.xml': 'Rguide.html',
'shell.xml': 'shellguide.html',
'vimscriptfull.xml': 'vimscriptfull.html',
'vimscriptguide.xml': 'vimscriptguide.html',
};
const newPage = map[missingPage];
if (newPage) {
+2 -2
View File
@@ -92,8 +92,8 @@ primarily optimizing for Google's internal needs.
[markdown]: docguide/style.md
[ts]: https://google.github.io/styleguide/tsguide.html
[angular]: https://google.github.io/styleguide/angularjs-google-style.html
[cl]: https://google.github.io/styleguide/lispguide.xml
[vim]: https://google.github.io/styleguide/vimscriptguide.xml
[cl]: https://google.github.io/styleguide/lispguide.html
[vim]: https://google.github.io/styleguide/vimscriptguide.html
[emacs]: https://raw.githubusercontent.com/google/styleguide/gh-pages/google-c-style.el
[xml]: https://google.github.io/styleguide/xmlstyle.html
[dart]: https://www.dartlang.org/guides/language/effective-dart
+3691
View File
File diff suppressed because it is too large. Load diff
-3630
View File
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
-924
View File
@@ -1,924 +0,0 @@
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:dcq="http://purl.org/dc/qualifiers/1.0/"
xmlns:fo="http://www.w3.org/1999/XSL/Format"
xmlns:fn="http://www.w3.org/2005/xpath-functions">
<xsl:output method="html"/>
<!-- Set to 1 to show explanations by default. Set to 0 to hide them -->
<xsl:variable name="show_explanation_default" select="0" />
<!-- The characters within the Webdings font that show the triangles -->
<xsl:variable name="show_button_text" select="'&#x25B6;'" />
<xsl:variable name="hide_button_text" select="'&#x25BD;'" />
<!-- The suffix for names -->
<xsl:variable name="button_suffix" select="'__button'"/>
<xsl:variable name="body_suffix" select="'__body'"/>
<!-- For easy reference, the name of the button -->
<xsl:variable name="show_hide_all_button" select="'show_hide_all_button'"/>
<!-- The top-level element -->
<xsl:template match="GUIDE">
<HTML>
<HEAD>
<TITLE><xsl:value-of select="@title"/></TITLE>
<META http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<LINK HREF="/styleguide/favicon.ico" type="image/x-icon"
rel="shortcut icon"/>
<LINK HREF="styleguide.css"
type="text/css" rel="stylesheet"/>
<SCRIPT language="javascript" type="text/javascript">
function GetElementsByName(name) {
// Workaround a bug on old versions of opera.
if (document.getElementsByName) {
return document.getElementsByName(name);
} else {
return [document.getElementById(name)];
}
}
/**
* @param {string} namePrefix The prefix of the body name.
* @param {function(boolean): boolean} getVisibility Computes the new
* visibility state, given the current one.
*/
function ChangeVisibility(namePrefix, getVisibility) {
var bodyName = namePrefix + '<xsl:value-of select="$body_suffix"/>';
var buttonName = namePrefix + '<xsl:value-of select="$button_suffix"/>';
var bodyElements = GetElementsByName(bodyName);
var linkElement = GetElementsByName('link-' + buttonName)[0];
if (bodyElements.length != 1) {
throw Error('ShowHideByName() got the wrong number of bodyElements: ' +
bodyElements.length);
} else {
var bodyElement = bodyElements[0];
var buttonElement = GetElementsByName(buttonName)[0];
var isVisible = bodyElement.style.display != "none";
if (getVisibility(isVisible)) {
bodyElement.style.display = "inline";
linkElement.style.display = "block";
buttonElement.innerHTML = '<xsl:value-of select="$hide_button_text"/>';
} else {
bodyElement.style.display = "none";
linkElement.style.display = "none";
buttonElement.innerHTML = '<xsl:value-of select="$show_button_text"/>';
}
}
}
function ShowHideByName(namePrefix) {
ChangeVisibility(namePrefix, function(old) { return !old; });
}
function ShowByName(namePrefix) {
ChangeVisibility(namePrefix, function() { return true; });
}
function ShowHideAll() {
var allButton = GetElementsByName("show_hide_all_button")[0];
if (allButton.innerHTML == '<xsl:value-of select="$hide_button_text"/>') {
allButton.innerHTML = '<xsl:value-of select="$show_button_text"/>';
SetHiddenState(document.getElementsByTagName("body")[0].childNodes, "none", '<xsl:value-of select="$show_button_text"/>');
} else {
allButton.innerHTML = '<xsl:value-of select="$hide_button_text"/>';
SetHiddenState(document.getElementsByTagName("body")[0].childNodes, "inline", '<xsl:value-of select="$hide_button_text"/>');
}
}
// Recursively sets state of all children
// of a particular node.
function SetHiddenState(root, newState, newButton) {
for (var i = 0; i != root.length; i++) {
SetHiddenState(root[i].childNodes, newState, newButton);
if (root[i].className == 'showhide_button') {
root[i].innerHTML = newButton;
}
if (root[i].className == 'stylepoint_body' ||
root[i].className == 'link_button') {
root[i].style.display = newState;
}
}
}
function EndsWith(str, suffix) {
var l = str.length - suffix.length;
return l >= 0 &amp;&amp; str.indexOf(suffix, l) == l;
}
function RefreshVisibilityFromHashParam() {
var hashRegexp = new RegExp('#([^&amp;#]*)$');
var hashMatch = hashRegexp.exec(window.location.href);
var anchor = hashMatch &amp;&amp; GetElementsByName(hashMatch[1])[0];
var node = anchor;
var suffix = '<xsl:value-of select="$body_suffix"/>';
while (node) {
var id = node.id;
var matched = id &amp;&amp; EndsWith(id, suffix);
if (matched) {
var len = id.length - suffix.length;
ShowByName(id.substring(0, len));
if (anchor.scrollIntoView) {
anchor.scrollIntoView();
}
return;
}
node = node.parentNode;
}
}
window.onhashchange = RefreshVisibilityFromHashParam;
window.onload = function() {
// if the URL contains "?showall=y", expand the details of all children
var showHideAllRegex = new RegExp("[\\?&amp;](showall)=([^&amp;#]*)");
var showHideAllValue = showHideAllRegex.exec(window.location.href);
if (showHideAllValue != null) {
if (showHideAllValue[2] == "y") {
SetHiddenState(document.getElementsByTagName("body")[0].childNodes,
"inline", '<xsl:value-of select="$hide_button_text"/>');
} else {
SetHiddenState(document.getElementsByTagName("body")[0].childNodes,
"none", '<xsl:value-of select="$show_button_text"/>');
}
}
var showOneRegex = new RegExp("[\\?&amp;](showone)=([^&amp;#]*)");
var showOneValue = showOneRegex.exec(window.location.href);
if (showOneValue) {
ShowHideByName(showOneValue[2]);
}
RefreshVisibilityFromHashParam();
}
</SCRIPT>
</HEAD>
<BODY>
<H1><xsl:value-of select="@title"/></H1>
<xsl:apply-templates/>
</BODY>
</HTML>
</xsl:template>
<xsl:template match="OVERVIEW">
<xsl:variable name="button_text">
<xsl:choose>
<xsl:when test="$show_explanation_default">
<xsl:value-of select="$hide_button_text"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$show_button_text"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<DIV style="margin-left: 50%; font-size: 75%;">
<P>
Each style point has a summary for which additional information is available
by toggling the accompanying arrow button that looks this way:
<SPAN class="showhide_button" style="margin-left: 0; float: none">
<xsl:value-of select="$show_button_text"/></SPAN>.
You may toggle all summaries with the big arrow button:
</P>
<DIV style=" font-size: larger; margin-left: +2em;">
<SPAN class="showhide_button" style="font-size: 180%; float: none">
<xsl:attribute name="onclick"><xsl:value-of select="'javascript:ShowHideAll()'"/></xsl:attribute>
<xsl:attribute name="name"><xsl:value-of select="$show_hide_all_button"/></xsl:attribute>
<xsl:attribute name="id"><xsl:value-of select="$show_hide_all_button"/></xsl:attribute>
<xsl:value-of select="$button_text"/>
</SPAN>
Toggle all summaries
</DIV>
</DIV>
<xsl:call-template name="TOC">
<xsl:with-param name="root" select=".."/>
</xsl:call-template>
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="PARTING_WORDS">
<H2>Parting Words</H2>
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="CATEGORY">
<DIV>
<xsl:attribute name="class"><xsl:value-of select="@class"/></xsl:attribute>
<H2>
<xsl:variable name="category_name">
<xsl:call-template name="anchorname">
<xsl:with-param name="sectionname" select="@title"/>
</xsl:call-template>
</xsl:variable>
<xsl:attribute name="name"><xsl:value-of select="$category_name"/></xsl:attribute>
<xsl:attribute name="id"><xsl:value-of select="$category_name"/></xsl:attribute>
<xsl:value-of select="@title"/>
</H2>
<xsl:apply-templates/>
</DIV>
</xsl:template>
<xsl:template match="STYLEPOINT">
<DIV>
<xsl:attribute name="class"><xsl:value-of select="@class"/></xsl:attribute>
<xsl:variable name="stylepoint_name">
<xsl:call-template name="anchorname">
<xsl:with-param name="sectionname" select="@title"/>
</xsl:call-template>
</xsl:variable>
<xsl:variable name="button_text">
<xsl:choose>
<xsl:when test="$show_explanation_default">
<xsl:value-of select="$hide_button_text"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$show_button_text"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<H3>
<A>
<xsl:attribute name="name"><xsl:value-of select="$stylepoint_name"/></xsl:attribute>
<xsl:attribute name="id"><xsl:value-of select="$stylepoint_name"/></xsl:attribute>
<xsl:value-of select="@title"/>
</A>
</H3>
<xsl:variable name="buttonName">
<xsl:value-of select="$stylepoint_name"/><xsl:value-of select="$button_suffix"/>
</xsl:variable>
<xsl:variable name="onclick_definition">
<xsl:text>javascript:ShowHideByName('</xsl:text>
<xsl:value-of select="$stylepoint_name"/>
<xsl:text>')</xsl:text>
</xsl:variable>
<SPAN class="link_button" id="link-{$buttonName}" name="link-{$buttonName}">
<A>
<xsl:attribute name="href">?showone=<xsl:value-of select="$stylepoint_name"/>#<xsl:value-of select="$stylepoint_name"/></xsl:attribute>
link
</A>
</SPAN>
<SPAN class="showhide_button">
<xsl:attribute name="onclick"><xsl:value-of select="$onclick_definition"/></xsl:attribute>
<xsl:attribute name="name"><xsl:value-of select="$buttonName"/></xsl:attribute>
<xsl:attribute name="id"><xsl:value-of select="$buttonName"/></xsl:attribute>
<xsl:value-of select="$button_text"/>
</SPAN>
<xsl:apply-templates>
<xsl:with-param name="anchor_prefix" select="$stylepoint_name" />
</xsl:apply-templates>
</DIV>
</xsl:template>
<xsl:template match="SUMMARY">
<xsl:param name="anchor_prefix" />
<DIV style="display:inline;">
<xsl:attribute name="class"><xsl:value-of select="@class"/></xsl:attribute>
<xsl:apply-templates/>
</DIV>
</xsl:template>
<xsl:template match="BODY">
<xsl:param name="anchor_prefix" />
<DIV>
<xsl:attribute name="class"><xsl:value-of select="@class"/></xsl:attribute>
<DIV class="stylepoint_body">
<xsl:attribute name="name"><xsl:value-of select="$anchor_prefix"/><xsl:value-of select="$body_suffix"/></xsl:attribute>
<xsl:attribute name="id"><xsl:value-of select="$anchor_prefix"/><xsl:value-of select="$body_suffix"/></xsl:attribute>
<xsl:attribute name="style">
<xsl:choose>
<xsl:when test="$show_explanation_default">display: inline</xsl:when>
<xsl:otherwise>display: none</xsl:otherwise>
</xsl:choose>
</xsl:attribute>
<xsl:apply-templates/>
</DIV>
</DIV>
</xsl:template>
<xsl:template match="DEFINITION">
<P>
<xsl:attribute name="class"><xsl:value-of select="@class"/></xsl:attribute>
<SPAN class="stylepoint_section">Definition: </SPAN>
<xsl:apply-templates/>
</P>
</xsl:template>
<xsl:template match="PROS">
<P>
<xsl:attribute name="class"><xsl:value-of select="@class"/></xsl:attribute>
<SPAN class="stylepoint_section">Pros: </SPAN>
<xsl:apply-templates/>
</P>
</xsl:template>
<xsl:template match="CONS">
<P>
<xsl:attribute name="class"><xsl:value-of select="@class"/></xsl:attribute>
<SPAN class="stylepoint_section">Cons: </SPAN>
<xsl:apply-templates/>
</P>
</xsl:template>
<xsl:template match="DECISION">
<P>
<xsl:attribute name="class"><xsl:value-of select="@class"/></xsl:attribute>
<SPAN class="stylepoint_section">Decision: </SPAN>
<xsl:apply-templates/>
</P>
</xsl:template>
<xsl:template match="TODO">
<P>
<xsl:attribute name="class"><xsl:value-of select="@class"/></xsl:attribute>
<DIV style="font-size: 150%;">TODO:
<xsl:apply-templates/>
</DIV>
</P>
</xsl:template>
<xsl:template match="SUBSECTION">
<P>
<xsl:attribute name="class"><xsl:value-of select="@class"/></xsl:attribute>
<SPAN class="stylepoint_subsection"><xsl:value-of select="@title"/> </SPAN>
<xsl:apply-templates/>
</P>
</xsl:template>
<xsl:template match="SUBSUBSECTION">
<P>
<xsl:attribute name="class"><xsl:value-of select="@class"/></xsl:attribute>
<SPAN class="stylepoint_subsubsection"><xsl:value-of select="@title"/> </SPAN>
<xsl:apply-templates/>
</P>
</xsl:template>
<xsl:template match="CODE_SNIPPET">
<DIV>
<xsl:attribute name="class"><xsl:value-of select="@class"/></xsl:attribute>
<PRE><xsl:call-template name="print_without_leading_chars">
<xsl:with-param name="text" select="."/>
<xsl:with-param name="strip" select="1"/>
<xsl:with-param name="is_firstline" select="1"/>
<xsl:with-param name="trim_count">
<xsl:call-template name="num_leading_spaces">
<xsl:with-param name="text" select="."/>
<xsl:with-param name="max_so_far" select="1000"/>
</xsl:call-template>
</xsl:with-param>
</xsl:call-template></PRE>
</DIV>
</xsl:template>
<xsl:template match="BAD_CODE_SNIPPET">
<DIV>
<xsl:attribute name="class"><xsl:value-of select="@class"/></xsl:attribute>
<PRE class="badcode"><xsl:call-template name="print_without_leading_chars">
<xsl:with-param name="text" select="."/>
<xsl:with-param name="strip" select="1"/>
<xsl:with-param name="is_firstline" select="1"/>
<xsl:with-param name="trim_count">
<xsl:call-template name="num_leading_spaces">
<xsl:with-param name="text" select="."/>
<xsl:with-param name="max_so_far" select="1000"/>
</xsl:call-template>
</xsl:with-param>
</xsl:call-template></PRE>
</DIV>
</xsl:template>
<xsl:template match="PY_CODE_SNIPPET">
<DIV>
<xsl:attribute name="class"><xsl:value-of select="@class"/></xsl:attribute>
<PRE><xsl:call-template name="print_python_code">
<xsl:with-param name="text" select="."/>
</xsl:call-template></PRE>
</DIV>
</xsl:template>
<xsl:template match="BAD_PY_CODE_SNIPPET">
<DIV>
<xsl:attribute name="class"><xsl:value-of select="@class"/></xsl:attribute>
<PRE class="badcode"><xsl:call-template name="print_python_code">
<xsl:with-param name="text" select="."/>
</xsl:call-template></PRE>
</DIV>
</xsl:template>
<xsl:template match="FUNCTION">
<xsl:call-template name="print_function_name">
<xsl:with-param name="text" select="."/>
</xsl:call-template>
</xsl:template>
<xsl:template match="SYNTAX">
<I>
<xsl:attribute name="class"><xsl:value-of select="@class"/></xsl:attribute>
<xsl:apply-templates/>
</I>
</xsl:template>
<!-- This passes through any HTML elements that the
XML doc uses for minor formatting -->
<xsl:template match="a|address|blockquote|br|center|cite|code|dd|div|dl|dt|em|hr|i|img|li|ol|p|pre|span|table|td|th|tr|ul|var|A|ADDRESS|BLOCKQUOTE|BR|CENTER|CITE|CODE|DD|DIV|DL|DT|EM|HR|I|LI|OL|P|PRE|SPAN|TABLE|TD|TH|TR|UL|VAR">
<xsl:element name="{local-name()}">
<xsl:copy-of select="@*"/>
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
<!-- Builds the table of contents -->
<xsl:template name="TOC">
<xsl:param name="root"/>
<DIV class="toc">
<DIV class="toc_title">Table of Contents</DIV>
<TABLE>
<xsl:for-each select="$root/CATEGORY">
<TR valign="top">
<xsl:attribute name="class"><xsl:value-of select="@class"/></xsl:attribute>
<TD>
<DIV class="toc_category">
<A>
<xsl:attribute name="href">
<xsl:text>#</xsl:text>
<xsl:call-template name="anchorname">
<xsl:with-param name="sectionname" select="@title"/>
</xsl:call-template>
</xsl:attribute>
<xsl:value-of select="@title"/>
</A>
</DIV>
</TD><TD>
<DIV class="toc_stylepoint">
<xsl:for-each select="./STYLEPOINT">
<SPAN style="padding-right: 1em; white-space:nowrap;">
<xsl:attribute name="class"><xsl:value-of select="@class"/></xsl:attribute>
<A>
<xsl:attribute name="href">
<xsl:text>#</xsl:text>
<xsl:call-template name="anchorname">
<xsl:with-param name="sectionname" select="@title"/>
</xsl:call-template>
</xsl:attribute>
<xsl:value-of select="@title"/>
</A>
</SPAN>
<xsl:text> </xsl:text>
</xsl:for-each>
</DIV>
</TD>
</TR>
</xsl:for-each>
</TABLE>
</DIV>
</xsl:template>
<xsl:template name="TOC_one_stylepoint">
<xsl:param name="stylepoint"/>
</xsl:template>
<!-- Creates a standard anchor given any text.
Substitutes underscore for characters unsuitable for URLs -->
<xsl:template name="anchorname">
<xsl:param name="sectionname"/>
<!-- strange quoting necessary to strip apostrophes -->
<xsl:variable name="bad_characters" select="&quot; ()#'&quot;"/>
<xsl:value-of select="translate($sectionname,$bad_characters,'_____')"/>
</xsl:template>
<!-- Given text, evaluates to the number of leading spaces. -->
<!-- TODO(csilvers): deal well with leading tabs (treat as 8 spaces?) -->
<xsl:template name="num_leading_spaces_one_line">
<xsl:param name="text"/>
<xsl:param name="current_count"/>
<xsl:choose>
<xsl:when test="starts-with($text, ' ')">
<xsl:call-template name="num_leading_spaces_one_line">
<xsl:with-param name="text" select="substring($text, 2)"/>
<xsl:with-param name="current_count" select="$current_count + 1"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$current_count"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- Given a block of text, each line terminated by \n, evaluates to
the indentation-level of that text; that is, the largest number
n such that every non-blank line starts with at least n spaces. -->
<xsl:template name="num_leading_spaces">
<xsl:param name="text"/>
<xsl:param name="max_so_far"/>
<!-- TODO(csilvers): deal with case text doesn't end in a newline -->
<xsl:variable name="line" select="substring-before($text, '&#xA;')"/>
<xsl:variable name="rest" select="substring-after($text, '&#xA;')"/>
<xsl:variable name="num_spaces_this_line">
<xsl:choose>
<xsl:when test="$line=''">
<xsl:value-of select="$max_so_far"/>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="num_leading_spaces_one_line">
<xsl:with-param name="text" select="$line"/>
<xsl:with-param name="current_count" select="0"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name="new_max_so_far">
<xsl:choose>
<xsl:when test="$num_spaces_this_line &lt; $max_so_far">
<xsl:value-of select="$num_spaces_this_line"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$max_so_far"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<!-- now check if we're on the last line, and if not, recurse -->
<xsl:if test="$rest=''">
<xsl:value-of select="$new_max_so_far"/>
</xsl:if>
<xsl:if test="not($rest='')">
<xsl:call-template name="num_leading_spaces">
<xsl:with-param name="text" select="$rest"/>
<xsl:with-param name="max_so_far" select="$new_max_so_far"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
<!-- Given text, determine the starting position of code.
This similar to num_leading_spaces_one_line but treats "Yes:" and "No:"
as spaces. Also, if there is no code on the first line, it searches
subsequent lines until a non-empty line is found.
Used to find the start of code in snippets like:
Yes: if(foo):
No : if(foo):
As well as:
Yes:
if (foo):
-->
<xsl:template name="code_start_index">
<xsl:param name="text"/>
<xsl:param name="current_count"/>
<xsl:choose>
<xsl:when test="starts-with($text, ' ')">
<xsl:call-template name="code_start_index">
<xsl:with-param name="text" select="substring($text, 2)"/>
<xsl:with-param name="current_count" select="$current_count + 1"/>
</xsl:call-template>
</xsl:when>
<xsl:when test="starts-with($text, 'Yes:')">
<xsl:call-template name="code_start_index">
<xsl:with-param name="text" select="substring($text, 5)"/>
<xsl:with-param name="current_count" select="$current_count + 4"/>
</xsl:call-template>
</xsl:when>
<xsl:when test="starts-with($text, 'No:')">
<xsl:call-template name="code_start_index">
<xsl:with-param name="text" select="substring($text, 4)"/>
<xsl:with-param name="current_count" select="$current_count + 3"/>
</xsl:call-template>
</xsl:when>
<!-- This is only reached if the first line is entirely whitespace or
contains nothing but "Yes:" or "No:"-->
<xsl:when test="starts-with($text, '&#xA;')">
<xsl:call-template name="code_start_index">
<xsl:with-param name="text" select="substring($text, 2)"/>
<xsl:with-param name="current_count" select="0"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$current_count"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- Helper for ends_with_colon. Determine whether the given line is nothing
but spaces and python-style comments. -->
<xsl:template name="is_blank_or_comment">
<xsl:param name="line"/>
<xsl:choose>
<xsl:when test="$line = ''">
<xsl:value-of select="1"/>
</xsl:when>
<xsl:when test="starts-with($line, '&#xA;')">
<xsl:value-of select="1"/>
</xsl:when>
<xsl:when test="starts-with($line, '#')">
<xsl:value-of select="1"/>
</xsl:when>
<xsl:when test="starts-with($line, ' ')">
<xsl:call-template name="is_blank_or_comment">
<xsl:with-param name="line" select="substring($line, 2)"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="0"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- Determine whether the given line ends with a colon. Note that Python
style comments are ignored so the following lines return True:
- def foo():
- def foo(): # Bar
- if(foo):
But some code may confuse this function. For example the following are
also consider to "end_with_colon" even though they don't for Python
- foo(": #")
- foo() # No need for :
-->
<xsl:template name="ends_with_colon">
<xsl:param name="line"/>
<xsl:param name="found_colon"/>
<xsl:choose>
<xsl:when test="$line = ''">
<xsl:value-of select="$found_colon"/>
</xsl:when>
<xsl:when test="starts-with($line, '&#xA;')">
<xsl:value-of select="$found_colon"/>
</xsl:when>
<xsl:when test="starts-with($line, ' ')">
<xsl:call-template name="ends_with_colon">
<xsl:with-param name="line" select="substring($line, 2)"/>
<xsl:with-param name="found_colon" select="$found_colon"/>
</xsl:call-template>
</xsl:when>
<xsl:when test="starts-with($line, ':')">
<xsl:variable name="rest_is_comment">
<xsl:call-template name="is_blank_or_comment">
<xsl:with-param name="line" select="substring($line, 2)"/>
</xsl:call-template>
</xsl:variable>
<xsl:choose>
<xsl:when test="$rest_is_comment = '1'">
<xsl:value-of select="1"/>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="ends_with_colon">
<xsl:with-param name="line" select="substring($line, 2)"/>
<xsl:with-param name="found_colon" select="0"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="ends_with_colon">
<xsl:with-param name="line" select="substring($line, 2)"/>
<xsl:with-param name="found_colon" select="0"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- Prints one line of python code with proper indent and calls itself
recursively for the rest of the text.
This template uses "a", "b", "c" and "d" to refer to four key column
numbers. They are:
- a: the indentation common to all lines in a code snippet. This is
stripped out to allow for cleaner code in the xml.
- b: the indentation of the most out-dented line of code. This is
different from "a" when code is labelled with "Yes:" or "No:"
- c: the indentation of the current python block, in other words, the
indentation of the first line of this block, which is the
indentation of the last line we saw that ended with a colon.
- d: the "total" indentation of the line, ignoring possible "Yes:" or
"No:" text on the line.
For example, for the last line of the following code snippet, the
positions of a, b, c and d are indicated below:
Yes: def Foo():
if bar():
a += 1
baz()
a b c d
The algorithm is:
1) Split the text into first line and the rest. Note that the
substring-before function is supposed to handle the case where the
character is not present in the string but does not so we
automatically ignore the last line of the snippet which is always
empty (the closing snippet tag). This is consistent with the
behavior or print_without_leading_chars.
2) If the current is empty (only whitespace), print newline and call
itself recursively on the rest of the text with the rest of the
parameters unchanged.
3) Otherwise, measure "d"
4) Measure "c" by taking:
- the value of "d" if the previous line ended with a colon or the
current line is outdented compare to the previous line
- the indent of the previous line otherwise
5) Print line[a:c] (Note that we ignore line[0:a])
6) Print line[b:c] in an external span (in order to double the block
indent in external code).
7) Print line[c:<end>] with function names processed to produce both
internal and external names.
8) If there are more lines, recurse.
-->
<xsl:template name="print_python_line_recursively">
<xsl:param name="text"/>
<xsl:param name="a"/>
<xsl:param name="b"/>
<xsl:param name="previous_indent"/>
<xsl:param name="previous_ends_with_colon"/>
<xsl:param name="is_first_line"/>
<xsl:variable name="line" select="substring-before($text, '&#xA;')"/>
<xsl:variable name="rest" select="substring-after($text, '&#xA;')"/>
<xsl:choose>
<xsl:when test="substring($line, $b) = '' and not($rest = '')">
<xsl:if test="not($is_first_line = '1')">
<xsl:text>&#xA;</xsl:text>
</xsl:if>
<xsl:call-template name="print_python_line_recursively">
<xsl:with-param name="text" select="$rest"/>
<xsl:with-param name="a" select="$a"/>
<xsl:with-param name="b" select="$b"/>
<xsl:with-param name="previous_indent" select="$previous_indent"/>
<xsl:with-param name="previous_ends_with_colon"
select="$previous_ends_with_colon"/>
<xsl:with-param name="is_first_line" select="0"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:variable name="indent_after_b">
<xsl:call-template name="num_leading_spaces_one_line">
<xsl:with-param name="text" select="substring($line, $b + 1)"/>
<xsl:with-param name="current_count" select="0"/>
</xsl:call-template>
</xsl:variable>
<xsl:variable name="d" select="$b + $indent_after_b"/>
<xsl:variable name="c">
<xsl:choose>
<xsl:when test="$previous_ends_with_colon = '1' or
$previous_indent > $d">
<xsl:value-of select="$d"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$previous_indent"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:value-of select="substring($line, $a + 1, $c - $a)"/>
<span class="external">
<xsl:value-of select="substring($line, $b + 1, $c - $b)"/>
</span>
<xsl:call-template name="munge_function_names_in_text">
<xsl:with-param name="stripped_line"
select="substring($line, $c + 1)"/>
</xsl:call-template>
<xsl:if test="not(substring($rest, $a) = '')">
<xsl:text>&#xA;</xsl:text>
<xsl:call-template name="print_python_line_recursively">
<xsl:with-param name="text" select="$rest"/>
<xsl:with-param name="a" select="$a"/>
<xsl:with-param name="b" select="$b"/>
<xsl:with-param name="previous_indent" select="$c"/>
<xsl:with-param name="previous_ends_with_colon">
<xsl:call-template name="ends_with_colon">
<xsl:with-param name="line" select="$line"/>
<xsl:with-param name="found_colon" select="0"/>
</xsl:call-template>
</xsl:with-param>
<xsl:with-param name="is_first_line" select="0"/>
</xsl:call-template>
</xsl:if>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- Print python code with internal and external styles.
In order to conform with PEP-8 externally, we identify 2-space indents
and an external-only 4-space indent.
Function names that are marked with $$FunctionName/$$ have an external
lower_with_underscore version added. -->
<xsl:template name="print_python_code">
<xsl:param name="text"/>
<xsl:variable name="a">
<xsl:call-template name="num_leading_spaces">
<xsl:with-param name="text" select="."/>
<xsl:with-param name="max_so_far" select="1000"/>
</xsl:call-template>
</xsl:variable>
<xsl:variable name="b">
<xsl:call-template name="code_start_index">
<xsl:with-param name="text" select="$text"/>
<xsl:with-param name="current_count" select="0"/>
</xsl:call-template>
</xsl:variable>
<xsl:call-template name="print_python_line_recursively">
<xsl:with-param name="text" select="$text"/>
<xsl:with-param name="a" select="$a"/>
<xsl:with-param name="b" select="$b"/>
<xsl:with-param name="previous_indent" select="$b"/>
<xsl:with-param name="previous_ends_with_colon" select="0"/>
<xsl:with-param name="is_first_line" select="1"/>
</xsl:call-template>
</xsl:template>
<!-- Given a block of text, each line terminated by \n, and a number n,
emits the text with the first n characters of each line
deleted. If strip==1, then we omit blank lines at the beginning
and end of the text (but not the middle!) -->
<!-- TODO(csilvers): deal well with leading tabs (treat as 8 spaces?) -->
<xsl:template name="print_without_leading_chars">
<xsl:param name="text"/>
<xsl:param name="trim_count"/>
<xsl:param name="strip"/>
<xsl:param name="is_firstline"/>
<!-- TODO(csilvers): deal with case text doesn't end in a newline -->
<xsl:variable name="line" select="substring-before($text, '&#xA;')"/>
<xsl:variable name="rest" select="substring-after($text, '&#xA;')"/>
<xsl:variable name="stripped_line" select="substring($line, $trim_count+1)"/>
<xsl:choose>
<!-- $line (or $rest) is considered empty if we'd trim the entire line -->
<xsl:when test="($strip = '1') and ($is_firstline = '1') and
(string-length($line) &lt;= $trim_count)">
</xsl:when>
<xsl:when test="($strip = '1') and
(string-length($rest) &lt;= $trim_count)">
<xsl:value-of select="$stripped_line"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$stripped_line"/>
<xsl:text>&#xA;</xsl:text>
</xsl:otherwise>
</xsl:choose>
<xsl:if test="not($rest='')">
<xsl:call-template name="print_without_leading_chars">
<xsl:with-param name="text" select="$rest"/>
<xsl:with-param name="trim_count" select="$trim_count"/>
<xsl:with-param name="strip" select="$strip"/>
<xsl:with-param name="is_firstline" select="0"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
<!-- Given a line of code, find function names that are marked with $$ /$$ and
print out the line with the internal and external versions of the
function names.-->
<xsl:template name="munge_function_names_in_text">
<xsl:param name="stripped_line"/>
<xsl:choose>
<xsl:when test="contains($stripped_line, '$$')">
<xsl:value-of select="substring-before($stripped_line, '$$')"/>
<xsl:call-template name="print_function_name">
<xsl:with-param name="text" select="substring-after(substring-before($stripped_line, '/$$'), '$$')"/>
</xsl:call-template>
<xsl:call-template name="munge_function_names_in_text">
<xsl:with-param name="stripped_line" select="substring-after($stripped_line, '/$$')"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$stripped_line"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- Given a function name, print out both the internal and external version
of the function name in their respective spans.-->
<xsl:template name="print_function_name">
<xsl:param name="text"/>
<xsl:call-template name="convert_camel_case_to_lowercase_with_under">
<xsl:with-param name="text" select="$text"/>
</xsl:call-template>
</xsl:template>
<!-- Given a single word of text convert it from CamelCase to
lower_with_under.
This means replacing each uppercase character with _ followed by the
lowercase version except for the first character which is replaced
without adding the _.-->
<xsl:template name="convert_camel_case_to_lowercase_with_under">
<xsl:param name="text"/>
<xsl:param name="is_recursive_call"/>
<xsl:variable name="first_char" select="substring($text, 1, 1)"/>
<xsl:variable name="rest" select="substring($text, 2)"/>
<xsl:choose>
<xsl:when test="contains('ABCDEFGHIJKLMNOPQRSTUVWXYZ', $first_char)">
<xsl:if test="$is_recursive_call='1'">
<xsl:text>_</xsl:text>
</xsl:if>
<xsl:value-of select="translate($first_char, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz')"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$first_char" />
</xsl:otherwise>
</xsl:choose>
<xsl:if test="not($rest='')">
<xsl:call-template name="convert_camel_case_to_lowercase_with_under">
<xsl:with-param name="text" select="$rest"/>
<xsl:with-param name="is_recursive_call" select="1"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
+442 -201
View File
@@ -1,6 +1,139 @@
<?xml version = '1.0'?>
<?xml-stylesheet type="text/xsl" href="styleguide.xsl"?>
<GUIDE title="Google Vimscript Guide">
<HTML xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dcq="http://purl.org/dc/qualifiers/1.0/" xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:fn="http://www.w3.org/2005/xpath-functions">
<HEAD>
<TITLE>Google Vimscript Guide</TITLE>
<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
<LINK HREF="/styleguide/favicon.ico" type="image/x-icon" rel="shortcut icon">
<LINK HREF="styleguide.css" type="text/css" rel="stylesheet">
<SCRIPT language="javascript" type="text/javascript">
function GetElementsByName(name) {
// Workaround a bug on old versions of opera.
if (document.getElementsByName) {
return document.getElementsByName(name);
} else {
return [document.getElementById(name)];
}
}
/**
* @param {string} namePrefix The prefix of the body name.
* @param {function(boolean): boolean} getVisibility Computes the new
* visibility state, given the current one.
*/
function ChangeVisibility(namePrefix, getVisibility) {
var bodyName = namePrefix + '__body';
var buttonName = namePrefix + '__button';
var bodyElements = GetElementsByName(bodyName);
var linkElement = GetElementsByName('link-' + buttonName)[0];
if (bodyElements.length != 1) {
throw Error('ShowHideByName() got the wrong number of bodyElements: ' +
bodyElements.length);
} else {
var bodyElement = bodyElements[0];
var buttonElement = GetElementsByName(buttonName)[0];
var isVisible = bodyElement.style.display != "none";
if (getVisibility(isVisible)) {
bodyElement.style.display = "inline";
linkElement.style.display = "block";
buttonElement.innerHTML = '▽';
} else {
bodyElement.style.display = "none";
linkElement.style.display = "none";
buttonElement.innerHTML = '▶';
}
}
}
function ShowHideByName(namePrefix) {
ChangeVisibility(namePrefix, function(old) { return !old; });
}
function ShowByName(namePrefix) {
ChangeVisibility(namePrefix, function() { return true; });
}
function ShowHideAll() {
var allButton = GetElementsByName("show_hide_all_button")[0];
if (allButton.innerHTML == '▽') {
allButton.innerHTML = '▶';
SetHiddenState(document.getElementsByTagName("body")[0].childNodes, "none", '▶');
} else {
allButton.innerHTML = '▽';
SetHiddenState(document.getElementsByTagName("body")[0].childNodes, "inline", '▽');
}
}
// Recursively sets state of all children
// of a particular node.
function SetHiddenState(root, newState, newButton) {
for (var i = 0; i != root.length; i++) {
SetHiddenState(root[i].childNodes, newState, newButton);
if (root[i].className == 'showhide_button') {
root[i].innerHTML = newButton;
}
if (root[i].className == 'stylepoint_body' ||
root[i].className == 'link_button') {
root[i].style.display = newState;
}
}
}
function EndsWith(str, suffix) {
var l = str.length - suffix.length;
return l >= 0 && str.indexOf(suffix, l) == l;
}
function RefreshVisibilityFromHashParam() {
var hashRegexp = new RegExp('#([^&#]*)$');
var hashMatch = hashRegexp.exec(window.location.href);
var anchor = hashMatch && GetElementsByName(hashMatch[1])[0];
var node = anchor;
var suffix = '__body';
while (node) {
var id = node.id;
var matched = id && EndsWith(id, suffix);
if (matched) {
var len = id.length - suffix.length;
ShowByName(id.substring(0, len));
if (anchor.scrollIntoView) {
anchor.scrollIntoView();
}
return;
}
node = node.parentNode;
}
}
window.onhashchange = RefreshVisibilityFromHashParam;
window.onload = function() {
// if the URL contains "?showall=y", expand the details of all children
var showHideAllRegex = new RegExp("[\\?&](showall)=([^&#]*)");
var showHideAllValue = showHideAllRegex.exec(window.location.href);
if (showHideAllValue != null) {
if (showHideAllValue[2] == "y") {
SetHiddenState(document.getElementsByTagName("body")[0].childNodes,
"inline", '▽');
} else {
SetHiddenState(document.getElementsByTagName("body")[0].childNodes,
"none", '▶');
}
}
var showOneRegex = new RegExp("[\\?&](showone)=([^&#]*)");
var showOneValue = showOneRegex.exec(window.location.href);
if (showOneValue) {
ShowHideByName(showOneValue[2]);
}
RefreshVisibilityFromHashParam();
}
</SCRIPT>
</HEAD>
<BODY>
<H1>Google Vimscript Guide</H1>
<p class="revision">
Revision 1.1
@@ -8,13 +141,75 @@
<address>
Nate Soares<br/>
Artemis Sparks<br/>
David Barnett<br/>
Nate Soares<br>
Artemis Sparks<br>
David Barnett<br>
</address>
<OVERVIEW>
<CATEGORY title="Background">
<DIV style="margin-left: 50%; font-size: 75%;">
<P>
Each style point has a summary for which additional information is available
by toggling the accompanying arrow button that looks this way:
<SPAN class="showhide_button" style="margin-left: 0; float: none">▶</SPAN>.
You may toggle all summaries with the big arrow button:
</P>
<DIV style=" font-size: larger; margin-left: +2em;">
<SPAN class="showhide_button" style="font-size: 180%; float: none" onclick="javascript:ShowHideAll()" name="show_hide_all_button" id="show_hide_all_button">▶</SPAN>
Toggle all summaries
</DIV>
</DIV>
<DIV class="toc">
<DIV class="toc_title">Table of Contents</DIV>
<TABLE>
<TR valign="top" class="">
<TD><DIV class="toc_category"><A href="#Portability">Portability</A></DIV></TD>
<TD><DIV class="toc_stylepoint"></DIV></TD>
</TR>
<TR valign="top" class="">
<TD><DIV class="toc_category"><A href="#Language_Guide">Language Guide</A></DIV></TD>
<TD><DIV class="toc_stylepoint"></DIV></TD>
</TR>
<TR valign="top" class="">
<TD><DIV class="toc_category"><A href="#Structure">Structure</A></DIV></TD>
<TD><DIV class="toc_stylepoint">
<SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#Libraries_vs._Functionality">Libraries vs. Functionality</A></SPAN> <SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#Configuration">Configuration</A></SPAN> </DIV></TD>
</TR>
<TR valign="top" class="">
<TD><DIV class="toc_category"><A href="#Style_Guide">Style Guide</A></DIV></TD>
<TD><DIV class="toc_stylepoint">
<SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#Documentation">Documentation</A></SPAN> <SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#Whitespace">Whitespace</A></SPAN> <SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#Variables">Variables</A></SPAN> <SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#Strings">Strings</A></SPAN> <SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#Settings">Settings</A></SPAN> </DIV></TD>
</TR>
<TR valign="top" class="">
<TD><DIV class="toc_category"><A href="#Usage_Guide">Usage Guide</A></DIV></TD>
<TD><DIV class="toc_stylepoint">
<SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#Commands">Commands</A></SPAN> <SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#Autocommands">Autocommands</A></SPAN> <SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#Functions">Functions</A></SPAN> <SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#Mappings">Mappings</A></SPAN> </DIV></TD>
</TR>
<TR valign="top" class="">
<TD><DIV class="toc_category"><A href="#Conventions">Conventions</A></DIV></TD>
<TD><DIV class="toc_stylepoint">
<SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#Dependency_Checking">Dependency Checking</A></SPAN> <SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#Statusline_Flags">Statusline Flags</A></SPAN> </DIV></TD>
</TR>
<TR valign="top" class="">
<TD><DIV class="toc_category"><A href="#Forbidden_Commands">Forbidden Commands</A></DIV></TD>
<TD><DIV class="toc_stylepoint"></DIV></TD>
</TR>
<TR valign="top" class="">
<TD><DIV class="toc_category"><A href="#Layout">Layout</A></DIV></TD>
<TD><DIV class="toc_stylepoint"></DIV></TD>
</TR>
<TR valign="top" class="">
<TD><DIV class="toc_category"><A href="#Recommended_Shortcuts">Recommended Shortcuts</A></DIV></TD>
<TD><DIV class="toc_stylepoint"></DIV></TD>
</TR>
<TR valign="top" class="">
<TD><DIV class="toc_category"><A href="#Errata">Errata</A></DIV></TD>
<TD><DIV class="toc_stylepoint">
<SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#Compatibility_Mode">Compatibility Mode</A></SPAN> </DIV></TD>
</TR>
</TABLE>
</DIV>
<DIV class="">
<H2 name="Background" id="Background">Background</H2>
<p>
This is the in-depth vimscript guide. If you're just a casual user
looking to write a plugin, the
@@ -35,10 +230,11 @@
Fair warning: Vimscript is a maddening abyss. When you gaze into it, it
gazes also into you. Proceed with caution.
</p>
</CATEGORY>
</OVERVIEW>
</DIV>
<CATEGORY title="Portability">
<DIV class="">
<H2 name="Portability" id="Portability">Portability</H2>
<p>
Vim is highly configurable. Users can change many of the default
settings, including the case sensitivity, the regular expression rules,
@@ -181,24 +377,25 @@
In general, guard all commands and functions against user settings.
</p>
</CATEGORY>
<CATEGORY title="Language Guide">
</DIV>
<DIV class="">
<H2 name="Language_Guide" id="Language_Guide">Language Guide</H2>
<ul>
<li>
Line continuations: <strong>Yes</strong>
Line continuations: Yes
<ul>
<li>
Plugins that support vi compatibility mode must save and restore
compatibility options as described in the
<strong>Errata section</strong> so line continuations work properly.
Errata section so line continuations work properly.
</li>
</ul>
</li>
<li>
Exceptions: <strong>Yes, with caution</strong>
Exceptions: Yes, with caution
<ul>
<li>
Always use an error code in thrown exception messages.
@@ -218,7 +415,7 @@
</ul>
</li>
<li>
Global Variables: <strong>As configuration only</strong>
Global Variables: As configuration only
<ul>
<li>
See the plugin guide.
@@ -226,7 +423,7 @@
</ul>
</li>
<li>
Messaging: <strong>As little as possible.</strong>
Messaging: As little as possible.
<ul>
<li>
Loud scripts are annoying.
@@ -245,7 +442,7 @@
</li>
<li>
Type checking:
<strong>Use strict and explicit checks where possible.</strong>
Use strict and explicit checks where possible.
<ul>
<li>
Vimscript has unsafe, unintuitive behavior when dealing with some
@@ -270,7 +467,7 @@
</ul>
</li>
<li>
FuncRefs: <strong>No in most cases.</strong>
FuncRefs: No in most cases.
<ul>
<li>
FuncRefs have inconsistently enforced naming restrictions.
@@ -292,7 +489,7 @@
</ul>
</li>
<li>
Python: <strong>Sparingly</strong>
Python: Sparingly
<ul>
<li>
@@ -311,7 +508,7 @@
</ul>
</li>
<li>
Ruby: <strong>No</strong>
Ruby: No
<ul>
<li>
We can not assume ruby interoperability.
@@ -323,7 +520,7 @@
</ul>
</li>
<li>
Lua: <strong>No</strong>
Lua: No
<ul>
<li>
For the same reasons an Ruby.
@@ -331,7 +528,7 @@
</ul>
</li>
<li>
Dict Functions: <strong>Encouraged</strong>
Dict Functions: Encouraged
<ul>
<li>
Vimscript can attach functions to dictionaries. Such functions
@@ -351,8 +548,9 @@
<p>
All other language features are fair game.
</p>
</CATEGORY>
<CATEGORY title="Structure">
</DIV>
<DIV class="">
<H2 name="Structure" id="Structure">Structure</H2>
<ul>
<li>
Provided functionality should be packed into modular plugins.
@@ -404,12 +602,10 @@
<li>
Each file in the <code>plugin/</code> or <code>instant/</code> directory
should begin with the boilerplate
<CODE_SNIPPET>
let [s:plugin, s:enter] = maktaba#plugin#Enter(expand('&lt;sfile&gt;:p'))
if !s:enter
finish
endif
</CODE_SNIPPET>
<DIV class=""><PRE>let [s:plugin, s:enter] = maktaba#plugin#Enter(expand('&lt;sfile&gt;:p'))
if !s:enter
finish
endif</PRE></DIV>
(This prevents re-entry and allows users to selectively disable
functionality.)
</li>
@@ -465,11 +661,15 @@
</li>
</ul>
<STYLEPOINT title="Libraries vs. Functionality">
<SUMMARY>
<DIV class="">
<H3><A name="Libraries_vs._Functionality" id="Libraries_vs._Functionality">Libraries vs. Functionality</A></H3>
<SPAN class="link_button" id="link-Libraries_vs._Functionality__button" name="link-Libraries_vs._Functionality__button"><A href="?showone=Libraries_vs._Functionality#Libraries_vs._Functionality">
link
</A></SPAN><SPAN class="showhide_button" onclick="javascript:ShowHideByName('Libraries_vs._Functionality')" name="Libraries_vs._Functionality__button" id="Libraries_vs._Functionality__button">▶</SPAN>
<DIV style="display:inline;" class="">
Separate library-providing plugins from command-providing plugins.
</SUMMARY>
<BODY>
</DIV>
<DIV class=""><DIV class="stylepoint_body" name="Libraries_vs._Functionality__body" id="Libraries_vs._Functionality__body" style="display: none">
<p>
Many plugins provide either user functionality (commands,
autocommands, etc) or an API (of autoloaded functions) but not both.
@@ -477,15 +677,19 @@
library without also pulling in commands, setting changes, and other
plugin functionality that affects the end user.
</p>
</BODY>
</STYLEPOINT>
</DIV></DIV>
</DIV>
<STYLEPOINT title="Configuration">
<SUMMARY>
<DIV class="">
<H3><A name="Configuration" id="Configuration">Configuration</A></H3>
<SPAN class="link_button" id="link-Configuration__button" name="link-Configuration__button"><A href="?showone=Configuration#Configuration">
link
</A></SPAN><SPAN class="showhide_button" onclick="javascript:ShowHideByName('Configuration')" name="Configuration__button" id="Configuration__button">▶</SPAN>
<DIV style="display:inline;" class="">
Don't clobber user settings. Provide as much configurability as
possible: that's what Vim's all about.
</SUMMARY>
<BODY>
</DIV>
<DIV class=""><DIV class="stylepoint_body" name="Configuration__body" id="Configuration__body" style="display: none">
<ul>
<li>
Use maktaba flags for plugin configuration. Users can configure them
@@ -494,17 +698,16 @@
</li>
<li>
Check if configuration variables exist before setting them.
<CODE_SNIPPET>
if !exists('g:myplugin_option')
let g:myplugin_option = 1
endif
</CODE_SNIPPET>
<DIV class=""><PRE>if !exists('g:myplugin_option')
let g:myplugin_option = 1
endif</PRE></DIV>
</li>
</ul>
</BODY>
</STYLEPOINT>
</CATEGORY>
<CATEGORY title="Style Guide">
</DIV></DIV>
</DIV>
</DIV>
<DIV class="">
<H2 name="Style_Guide" id="Style_Guide">Style Guide</H2>
<p>
Follow google-wide style conventions. Mimic google python style when
in doubt.
@@ -512,11 +715,15 @@
<STYLEPOINT title="Documentation">
<SUMMARY>
<DIV class="">
<H3><A name="Documentation" id="Documentation">Documentation</A></H3>
<SPAN class="link_button" id="link-Documentation__button" name="link-Documentation__button"><A href="?showone=Documentation#Documentation">
link
</A></SPAN><SPAN class="showhide_button" onclick="javascript:ShowHideByName('Documentation')" name="Documentation__button" id="Documentation__button">▶</SPAN>
<DIV style="display:inline;" class="">
Use <a href="https://github.com/google/vimdoc">vimdoc</a>.
</SUMMARY>
<BODY>
</DIV>
<DIV class=""><DIV class="stylepoint_body" name="Documentation__body" id="Documentation__body" style="display: none">
<p>
Provide help files generated by
<a href="https://github.com/google/vimdoc">vimdoc</a>. Write
@@ -525,14 +732,18 @@
addon-info.json file (see the
<a href="https://github.com/MarcWeber/vim-addon-manager/blob/master/doc/vim-addon-manager-additional-documentation.txt">VAM documentation</a>).
</p>
</BODY>
</STYLEPOINT>
</DIV></DIV>
</DIV>
<STYLEPOINT title="Whitespace">
<SUMMARY>
<DIV class="">
<H3><A name="Whitespace" id="Whitespace">Whitespace</A></H3>
<SPAN class="link_button" id="link-Whitespace__button" name="link-Whitespace__button"><A href="?showone=Whitespace#Whitespace">
link
</A></SPAN><SPAN class="showhide_button" onclick="javascript:ShowHideByName('Whitespace')" name="Whitespace__button" id="Whitespace__button">▶</SPAN>
<DIV style="display:inline;" class="">
Follow google-wide conventions.
</SUMMARY>
<BODY>
</DIV>
<DIV class=""><DIV class="stylepoint_body" name="Whitespace__body" id="Whitespace__body" style="display: none">
<ul>
<li>
Use two spaces for indents.
@@ -549,14 +760,10 @@
safe, always omit whitespace around arguments to commands.
</li>
<li>
<CODE_SNIPPET>
let s:variable = "concatenated " . "strings"
command -range=% MyCommand
</CODE_SNIPPET>
<BAD_CODE_SNIPPET>
let s:variable="concatenated "."strings"
command -range = % MyCommand
</BAD_CODE_SNIPPET>
<DIV class=""><PRE>let s:variable = "concatenated " . "strings"
command -range=% MyCommand</PRE></DIV>
<DIV class=""><PRE class="badcode">let s:variable="concatenated "."strings"
command -range = % MyCommand</PRE></DIV>
</li>
</ul>
</li>
@@ -579,32 +786,25 @@
commands. It is both difficult and expensive to maintain.
<ul>
<li>
<CODE_SNIPPET>
command -bang MyCommand call myplugin#foo()
command MyCommand2 call myplugin#bar()
</CODE_SNIPPET>
<BAD_CODE_SNIPPET>
command -bang MyCommand call myplugin#foo()
command MyCommand2 call myplugin#bar()
</BAD_CODE_SNIPPET>
<DIV class=""><PRE>command -bang MyCommand call myplugin#foo()
command MyCommand2 call myplugin#bar()</PRE></DIV>
<DIV class=""><PRE class="badcode">command -bang MyCommand call myplugin#foo()
command MyCommand2 call myplugin#bar()</PRE></DIV>
</li>
</ul>
</li>
</ul>
<SUBSECTION title="Line Continuations">
<P class="">
<SPAN class="stylepoint_subsection">Line Continuations</SPAN>
<ul start="7">
<li>
Prefer line continuations on semantic boundaries.
<ul>
<li>
<CODE_SNIPPET>
command SomeLongCommand
\ call some#function()
</CODE_SNIPPET>
<BAD_CODE_SNIPPET>
command SomeLongCommand call
\ some#function()
</BAD_CODE_SNIPPET>
<DIV class=""><PRE>command SomeLongCommand
\ call some#function()</PRE></DIV>
<DIV class=""><PRE class="badcode">command SomeLongCommand call
\ some#function()</PRE></DIV>
</li>
<li>
Use your best judgement.
@@ -617,14 +817,12 @@
<li>
When continuing a multi-line command a pipe can be substituted
for this space as necessary, as follows:
<CODE_SNIPPET>
autocommand BufEnter &lt;buffer&gt;
\ if !empty(s:var)
\| call some#function()
\|else
\| call some#function(s:var)
\|endif
</CODE_SNIPPET>
<DIV class=""><PRE>autocommand BufEnter &lt;buffer&gt;
\ if !empty(s:var)
\| call some#function()
\|else
\| call some#function(s:var)
\|endif</PRE></DIV>
</li>
</ul>
</li>
@@ -633,17 +831,16 @@
function calls.
</li>
</ul>
</SUBSECTION>
<SUBSECTION title="Comments">
</P>
<P class="">
<SPAN class="stylepoint_subsection">Comments</SPAN>
<ul>
<li>
Place a space after the <code>"</code> before the comment text.
<ul>
<li>
<CODE_SNIPPET>
" I am a line comment.
call call(s:my_function)
</CODE_SNIPPET>
<DIV class=""><PRE>" I am a line comment.
call call(s:my_function)</PRE></DIV>
</li>
</ul>
</li>
@@ -666,21 +863,23 @@
blank line.
<ul>
<li>
<CODE_SNIPPET>
" I am one continuous
"
" comment block
</CODE_SNIPPET>
<DIV class=""><PRE>" I am one continuous
"
" comment block</PRE></DIV>
</li>
</ul>
</li>
</ul>
</SUBSECTION>
</BODY>
</STYLEPOINT>
</P>
</DIV></DIV>
</DIV>
<STYLEPOINT title="Variables">
<SUMMARY>
<DIV class="">
<H3><A name="Variables" id="Variables">Variables</A></H3>
<SPAN class="link_button" id="link-Variables__button" name="link-Variables__button"><A href="?showone=Variables#Variables">
link
</A></SPAN><SPAN class="showhide_button" onclick="javascript:ShowHideByName('Variables')" name="Variables__button" id="Variables__button">▶</SPAN>
<DIV style="display:inline;" class="">
<p>
<code>plugin-names-like-this</code>,
<code>FunctionNamesLikeThis</code>,
@@ -691,8 +890,8 @@
<p>
Prefix all variables with their scope.
</p>
</SUMMARY>
<BODY>
</DIV>
<DIV class=""><DIV class="stylepoint_body" name="Variables__body" id="Variables__body" style="display: none">
<ul>
<li>
<code>variable_names_like_this</code>
@@ -791,14 +990,18 @@
</ul>
</li>
</ul>
</BODY>
</STYLEPOINT>
</DIV></DIV>
</DIV>
<STYLEPOINT title="Strings">
<SUMMARY>
<DIV class="">
<H3><A name="Strings" id="Strings">Strings</A></H3>
<SPAN class="link_button" id="link-Strings__button" name="link-Strings__button"><A href="?showone=Strings#Strings">
link
</A></SPAN><SPAN class="showhide_button" onclick="javascript:ShowHideByName('Strings')" name="Strings__button" id="Strings__button">▶</SPAN>
<DIV style="display:inline;" class="">
Prefer single quotes.
</SUMMARY>
<BODY>
</DIV>
<DIV class=""><DIV class="stylepoint_body" name="Strings__body" id="Strings__body" style="display: none">
<p>
Prefer single quoted strings. Specifically, in order of precedence:
</p>
@@ -867,14 +1070,18 @@
</ul>
</li>
</ul>
</BODY>
</STYLEPOINT>
</DIV></DIV>
</DIV>
<STYLEPOINT title="Settings">
<SUMMARY>
<DIV class="">
<H3><A name="Settings" id="Settings">Settings</A></H3>
<SPAN class="link_button" id="link-Settings__button" name="link-Settings__button"><A href="?showone=Settings#Settings">
link
</A></SPAN><SPAN class="showhide_button" onclick="javascript:ShowHideByName('Settings')" name="Settings__button" id="Settings__button">▶</SPAN>
<DIV style="display:inline;" class="">
Prefer long names. Set settings locally.
</SUMMARY>
<BODY>
</DIV>
<DIV class=""><DIV class="stylepoint_body" name="Settings__body" id="Settings__body" style="display: none">
<ul start="6">
<li>
Prefer long names of built in settings (i.e. <code>tabstop</code>
@@ -892,28 +1099,34 @@
</ul>
</li>
</ul>
</BODY>
</STYLEPOINT>
</CATEGORY>
<CATEGORY title="Usage Guide">
</DIV></DIV>
</DIV>
</DIV>
<DIV class="">
<H2 name="Usage_Guide" id="Usage_Guide">Usage Guide</H2>
<p>
Vim plugins should provide any or all of the following:
<strong>Commands,</strong> <strong>Autocommands,</strong>
<strong>Functions,</strong> <strong>Statusline Flags, and</strong>
<strong>Mappings.</strong>
Commands, Autocommands,
Functions, Statusline Flags, and
Mappings.
</p>
<STYLEPOINT title="Commands">
<SUMMARY>
<DIV class="">
<H3><A name="Commands" id="Commands">Commands</A></H3>
<SPAN class="link_button" id="link-Commands__button" name="link-Commands__button"><A href="?showone=Commands#Commands">
link
</A></SPAN><SPAN class="showhide_button" onclick="javascript:ShowHideByName('Commands')" name="Commands__button" id="Commands__button">▶</SPAN>
<DIV style="display:inline;" class="">
<ul>
<li>Define in <code>plugin/commands.vim</code>.</li>
<li>CommandNamesLikeThis.</li>
<li>Prefer semantic names to a unified prefix.</li>
<li>Do not use <code>[!]</code></li>
<li>Do not use <code>[!]</code>
</li>
<li>Extract logic into functions.</li>
</ul>
</SUMMARY>
<BODY>
</DIV>
<DIV class=""><DIV class="stylepoint_body" name="Commands__body" id="Commands__body" style="display: none">
<ul>
<li>
<code>CommandNamesLikeThis</code>
@@ -926,14 +1139,10 @@
Name commands semantically at the expense of a common prefix.
</li>
<li>
<BAD_CODE_SNIPPET>
command WhitespaceFixTrailing
command WhitespaceFixIndentation
</BAD_CODE_SNIPPET>
<CODE_SNIPPET>
command FixTrailingWhitespace
command FixIndentation
</CODE_SNIPPET>
<DIV class=""><PRE class="badcode">command WhitespaceFixTrailing
command WhitespaceFixIndentation</PRE></DIV>
<DIV class=""><PRE>command FixTrailingWhitespace
command FixIndentation</PRE></DIV>
</li>
</ul>
</li>
@@ -987,7 +1196,8 @@
</ul>
</li>
</ul>
<SUBSECTION title="Conventions">
<P class="">
<SPAN class="stylepoint_subsection">Conventions</SPAN>
<ul>
<li>
Pass <code>&lt;bang&gt;</code> to functions with
@@ -999,12 +1209,16 @@
</ul>
</li>
</ul>
</SUBSECTION>
</BODY>
</STYLEPOINT>
</P>
</DIV></DIV>
</DIV>
<STYLEPOINT title="Autocommands">
<SUMMARY>
<DIV class="">
<H3><A name="Autocommands" id="Autocommands">Autocommands</A></H3>
<SPAN class="link_button" id="link-Autocommands__button" name="link-Autocommands__button"><A href="?showone=Autocommands#Autocommands">
link
</A></SPAN><SPAN class="showhide_button" onclick="javascript:ShowHideByName('Autocommands')" name="Autocommands__button" id="Autocommands__button">▶</SPAN>
<DIV style="display:inline;" class="">
<ul>
<li>Define in <code>plugin/autocmds.vim</code>.</li>
<li>Use augroups.</li>
@@ -1012,8 +1226,8 @@
<li>Clear the augroup first.</li>
<li>Extract logic into functions.</li>
</ul>
</SUMMARY>
<BODY>
</DIV>
<DIV class=""><DIV class="stylepoint_body" name="Autocommands__body" id="Autocommands__body" style="display: none">
<ul>
<li>
All autocommands should be defined in the
@@ -1061,20 +1275,25 @@
</ul>
</li>
</ul>
</BODY>
</STYLEPOINT>
</DIV></DIV>
</DIV>
<STYLEPOINT title="Functions">
<SUMMARY>
<DIV class="">
<H3><A name="Functions" id="Functions">Functions</A></H3>
<SPAN class="link_button" id="link-Functions__button" name="link-Functions__button"><A href="?showone=Functions#Functions">
link
</A></SPAN><SPAN class="showhide_button" onclick="javascript:ShowHideByName('Functions')" name="Functions__button" id="Functions__button">▶</SPAN>
<DIV style="display:inline;" class="">
<ul>
<li>FunctionNamesLikeThis.</li>
<li>Autoload all functions.</li>
<li>Prefix script-local functions with <code>s:</code></li>
<li>Prefix script-local functions with <code>s:</code>
</li>
<li>Use <code>[!]</code>.</li>
<li>Use <code>[abort]</code>.</li>
</ul>
</SUMMARY>
<BODY>
</DIV>
<DIV class=""><DIV class="stylepoint_body" name="Functions__body" id="Functions__body" style="display: none">
<ul>
<li>
<code>FunctionNamesLikeThis</code>
@@ -1155,11 +1374,15 @@
</ul>
</li>
</ul>
</BODY>
</STYLEPOINT>
</DIV></DIV>
</DIV>
<STYLEPOINT title="Mappings">
<SUMMARY>
<DIV class="">
<H3><A name="Mappings" id="Mappings">Mappings</A></H3>
<SPAN class="link_button" id="link-Mappings__button" name="link-Mappings__button"><A href="?showone=Mappings#Mappings">
link
</A></SPAN><SPAN class="showhide_button" onclick="javascript:ShowHideByName('Mappings')" name="Mappings__button" id="Mappings__button">▶</SPAN>
<DIV style="display:inline;" class="">
<ul>
<li>
Provide opt-in key mappings in <code>plugin/mappings.vim</code>.
@@ -1170,8 +1393,8 @@
opt-out).
</li>
</ul>
</SUMMARY>
<BODY>
</DIV>
<DIV class=""><DIV class="stylepoint_body" name="Mappings__body" id="Mappings__body" style="display: none">
<ul>
<li>
Define key mappings in <code>plugin/mappings.vim</code>, using
@@ -1215,7 +1438,7 @@
to take advantage of your pseudo-mapping.
</li>
<li>
Pseudo-mappings should <strong>not</strong> be in
Pseudo-mappings should not be in
<code>plugin/mappings.vim</code> or they will be disabled by
default.
</li>
@@ -1261,15 +1484,20 @@
</ul>
</li>
</ul>
</BODY>
</STYLEPOINT>
</CATEGORY>
<CATEGORY title="Conventions">
<STYLEPOINT title="Dependency Checking">
<SUMMARY>
</DIV></DIV>
</DIV>
</DIV>
<DIV class="">
<H2 name="Conventions" id="Conventions">Conventions</H2>
<DIV class="">
<H3><A name="Dependency_Checking" id="Dependency_Checking">Dependency Checking</A></H3>
<SPAN class="link_button" id="link-Dependency_Checking__button" name="link-Dependency_Checking__button"><A href="?showone=Dependency_Checking#Dependency_Checking">
link
</A></SPAN><SPAN class="showhide_button" onclick="javascript:ShowHideByName('Dependency_Checking')" name="Dependency_Checking__button" id="Dependency_Checking__button">▶</SPAN>
<DIV style="display:inline;" class="">
Declare dependencies in addon-info.json and use <code>maktaba</code>.
</SUMMARY>
<BODY>
</DIV>
<DIV class=""><DIV class="stylepoint_body" name="Dependency_Checking__body" id="Dependency_Checking__body" style="display: none">
<p>
Declaring dependencies in addon-info.json allows conformant plugin
managers (like VAM) to ensure dependencies are installed. See the
@@ -1280,15 +1508,19 @@
runtime ensures that dependencies have been installed and that they
don't include unsafe non-library files.
</p>
</BODY>
</STYLEPOINT>
</DIV></DIV>
</DIV>
<STYLEPOINT title="Statusline Flags">
<SUMMARY>
<DIV class="">
<H3><A name="Statusline_Flags" id="Statusline_Flags">Statusline Flags</A></H3>
<SPAN class="link_button" id="link-Statusline_Flags__button" name="link-Statusline_Flags__button"><A href="?showone=Statusline_Flags#Statusline_Flags">
link
</A></SPAN><SPAN class="showhide_button" onclick="javascript:ShowHideByName('Statusline_Flags')" name="Statusline_Flags__button" id="Statusline_Flags__button">▶</SPAN>
<DIV style="display:inline;" class="">
Use <code>&lt;plugin-name&gt;#status#Status()</code> or its
finer-grained variants to provide statusline flags.
</SUMMARY>
<BODY>
</DIV>
<DIV class=""><DIV class="stylepoint_body" name="Statusline_Flags__body" id="Statusline_Flags__body" style="display: none">
<p>
Following is a convention for exposing statusline flags to the user. A
plugin should never modify the user's statusline except for when that
@@ -1373,10 +1605,11 @@
</ul>
</li>
</ul>
</BODY>
</STYLEPOINT>
</CATEGORY>
<CATEGORY title="Forbidden Commands">
</DIV></DIV>
</DIV>
</DIV>
<DIV class="">
<H2 name="Forbidden_Commands" id="Forbidden_Commands">Forbidden Commands</H2>
<p>
These are commands which can only be used by a limited number of
plugins, and should not in general be used by yours.
@@ -1429,8 +1662,9 @@
</ul>
</li>
</ul>
</CATEGORY>
<CATEGORY title="Layout">
</DIV>
<DIV class="">
<H2 name="Layout" id="Layout">Layout</H2>
<p>
Lay out <code>plugin/</code> files in the following sections, if
applicable, separated by two blank lines:
@@ -1472,8 +1706,9 @@
This is recommended convention and is not enforced.
</p>
</CATEGORY>
<CATEGORY title="Recommended Shortcuts">
</DIV>
<DIV class="">
<H2 name="Recommended_Shortcuts" id="Recommended_Shortcuts">Recommended Shortcuts</H2>
<p>
Use the following shortcuts:
@@ -1488,19 +1723,24 @@
</li>
</ul>
</CATEGORY>
<CATEGORY title="Errata">
</DIV>
<DIV class="">
<H2 name="Errata" id="Errata">Errata</H2>
<p>
This section plumbs some of the darker corners of vimscript, explaining
the language pathologies that you wish you didn't have to know.
</p>
<STYLEPOINT title="Compatibility Mode">
<SUMMARY>
<DIV class="">
<H3><A name="Compatibility_Mode" id="Compatibility_Mode">Compatibility Mode</A></H3>
<SPAN class="link_button" id="link-Compatibility_Mode__button" name="link-Compatibility_Mode__button"><A href="?showone=Compatibility_Mode#Compatibility_Mode">
link
</A></SPAN><SPAN class="showhide_button" onclick="javascript:ShowHideByName('Compatibility_Mode')" name="Compatibility_Mode__button" id="Compatibility_Mode__button">▶</SPAN>
<DIV style="display:inline;" class="">
If you don't support vi-compatibility mode, fail gracefully.
</SUMMARY>
<BODY>
</DIV>
<DIV class=""><DIV class="stylepoint_body" name="Compatibility_Mode__body" id="Compatibility_Mode__body" style="display: none">
<p>
When <code>compatible</code> is set, many vim features are not
available. The vim feature which most commonly affects vimscript
@@ -1517,9 +1757,9 @@
compatible mode since maktaba currently just disables it, printing a
warning.
</p>
</BODY>
</STYLEPOINT>
</CATEGORY>
</DIV></DIV>
</DIV>
</DIV>
<p align="right">
Revision 1.1
@@ -1527,8 +1767,9 @@
<address>
Nate Soares<br/>
Artemis Sparks<br/>
David Barnett<br/>
Nate Soares<br>
Artemis Sparks<br>
David Barnett<br>
</address>
</GUIDE>
</BODY>
</HTML>
+662
View File
@@ -0,0 +1,662 @@
<HTML xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dcq="http://purl.org/dc/qualifiers/1.0/" xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:fn="http://www.w3.org/2005/xpath-functions">
<HEAD>
<TITLE>Google Vimscript Style Guide</TITLE>
<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
<LINK HREF="/styleguide/favicon.ico" type="image/x-icon" rel="shortcut icon">
<LINK HREF="styleguide.css" type="text/css" rel="stylesheet">
<SCRIPT language="javascript" type="text/javascript">
function GetElementsByName(name) {
// Workaround a bug on old versions of opera.
if (document.getElementsByName) {
return document.getElementsByName(name);
} else {
return [document.getElementById(name)];
}
}
/**
* @param {string} namePrefix The prefix of the body name.
* @param {function(boolean): boolean} getVisibility Computes the new
* visibility state, given the current one.
*/
function ChangeVisibility(namePrefix, getVisibility) {
var bodyName = namePrefix + '__body';
var buttonName = namePrefix + '__button';
var bodyElements = GetElementsByName(bodyName);
var linkElement = GetElementsByName('link-' + buttonName)[0];
if (bodyElements.length != 1) {
throw Error('ShowHideByName() got the wrong number of bodyElements: ' +
bodyElements.length);
} else {
var bodyElement = bodyElements[0];
var buttonElement = GetElementsByName(buttonName)[0];
var isVisible = bodyElement.style.display != "none";
if (getVisibility(isVisible)) {
bodyElement.style.display = "inline";
linkElement.style.display = "block";
buttonElement.innerHTML = '▽';
} else {
bodyElement.style.display = "none";
linkElement.style.display = "none";
buttonElement.innerHTML = '▶';
}
}
}
function ShowHideByName(namePrefix) {
ChangeVisibility(namePrefix, function(old) { return !old; });
}
function ShowByName(namePrefix) {
ChangeVisibility(namePrefix, function() { return true; });
}
function ShowHideAll() {
var allButton = GetElementsByName("show_hide_all_button")[0];
if (allButton.innerHTML == '▽') {
allButton.innerHTML = '▶';
SetHiddenState(document.getElementsByTagName("body")[0].childNodes, "none", '▶');
} else {
allButton.innerHTML = '▽';
SetHiddenState(document.getElementsByTagName("body")[0].childNodes, "inline", '▽');
}
}
// Recursively sets state of all children
// of a particular node.
function SetHiddenState(root, newState, newButton) {
for (var i = 0; i != root.length; i++) {
SetHiddenState(root[i].childNodes, newState, newButton);
if (root[i].className == 'showhide_button') {
root[i].innerHTML = newButton;
}
if (root[i].className == 'stylepoint_body' ||
root[i].className == 'link_button') {
root[i].style.display = newState;
}
}
}
function EndsWith(str, suffix) {
var l = str.length - suffix.length;
return l >= 0 && str.indexOf(suffix, l) == l;
}
function RefreshVisibilityFromHashParam() {
var hashRegexp = new RegExp('#([^&#]*)$');
var hashMatch = hashRegexp.exec(window.location.href);
var anchor = hashMatch && GetElementsByName(hashMatch[1])[0];
var node = anchor;
var suffix = '__body';
while (node) {
var id = node.id;
var matched = id && EndsWith(id, suffix);
if (matched) {
var len = id.length - suffix.length;
ShowByName(id.substring(0, len));
if (anchor.scrollIntoView) {
anchor.scrollIntoView();
}
return;
}
node = node.parentNode;
}
}
window.onhashchange = RefreshVisibilityFromHashParam;
window.onload = function() {
// if the URL contains "?showall=y", expand the details of all children
var showHideAllRegex = new RegExp("[\\?&](showall)=([^&#]*)");
var showHideAllValue = showHideAllRegex.exec(window.location.href);
if (showHideAllValue != null) {
if (showHideAllValue[2] == "y") {
SetHiddenState(document.getElementsByTagName("body")[0].childNodes,
"inline", '▽');
} else {
SetHiddenState(document.getElementsByTagName("body")[0].childNodes,
"none", '▶');
}
}
var showOneRegex = new RegExp("[\\?&](showone)=([^&#]*)");
var showOneValue = showOneRegex.exec(window.location.href);
if (showOneValue) {
ShowHideByName(showOneValue[2]);
}
RefreshVisibilityFromHashParam();
}
</SCRIPT>
</HEAD>
<BODY>
<H1>Google Vimscript Style Guide</H1>
<p class="revision">
Revision 1.1
</p>
<address>
Nate Soares<br>
Artemis Sparks<br>
David Barnett<br>
</address>
<DIV style="margin-left: 50%; font-size: 75%;">
<P>
Each style point has a summary for which additional information is available
by toggling the accompanying arrow button that looks this way:
<SPAN class="showhide_button" style="margin-left: 0; float: none">▶</SPAN>.
You may toggle all summaries with the big arrow button:
</P>
<DIV style=" font-size: larger; margin-left: +2em;">
<SPAN class="showhide_button" style="font-size: 180%; float: none" onclick="javascript:ShowHideAll()" name="show_hide_all_button" id="show_hide_all_button">▶</SPAN>
Toggle all summaries
</DIV>
</DIV>
<DIV class="toc">
<DIV class="toc_title">Table of Contents</DIV>
<TABLE>
<TR valign="top" class="">
<TD><DIV class="toc_category"><A href="#Portability">Portability</A></DIV></TD>
<TD><DIV class="toc_stylepoint">
<SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#Strings">Strings</A></SPAN> <SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#Matching_Strings">Matching Strings</A></SPAN> <SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#Regular_Expressions">Regular Expressions</A></SPAN> <SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#Dangerous_commands">Dangerous commands</A></SPAN> <SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#Fragile_commands">Fragile commands</A></SPAN> <SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#Catching_Exceptions">Catching Exceptions</A></SPAN> </DIV></TD>
</TR>
<TR valign="top" class="">
<TD><DIV class="toc_category"><A href="#General_Guidelines">General Guidelines</A></DIV></TD>
<TD><DIV class="toc_stylepoint">
<SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#Messaging">Messaging</A></SPAN> <SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#Type_checking">Type checking</A></SPAN> <SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#Python">Python</A></SPAN> <SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#Other_Languages">Other Languages</A></SPAN> <SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#Boilerplate">Boilerplate</A></SPAN> <SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#Plugin_layout">Plugin layout</A></SPAN> <SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#Functions">Functions</A></SPAN> <SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#Commands">Commands</A></SPAN> <SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#Autocommands">Autocommands</A></SPAN> <SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#Mappings">Mappings</A></SPAN> <SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#Settings">Settings</A></SPAN> </DIV></TD>
</TR>
<TR valign="top" class="">
<TD><DIV class="toc_category"><A href="#Style">Style</A></DIV></TD>
<TD><DIV class="toc_stylepoint">
<SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#Whitespace">Whitespace</A></SPAN> <SPAN style="padding-right: 1em; white-space:nowrap;" class=""><A href="#Naming">Naming</A></SPAN> </DIV></TD>
</TR>
</TABLE>
</DIV>
<DIV class="">
<H2 name="Background" id="Background">Background</H2>
<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>
</DIV>
<DIV class="">
<H2 name="Portability" id="Portability">Portability</H2>
<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>
<DIV class="">
<H3><A name="Strings" id="Strings">Strings</A></H3>
<SPAN class="link_button" id="link-Strings__button" name="link-Strings__button"><A href="?showone=Strings#Strings">
link
</A></SPAN><SPAN class="showhide_button" onclick="javascript:ShowHideByName('Strings')" name="Strings__button" id="Strings__button">▶</SPAN>
<DIV style="display:inline;" class="">Prefer single quoted strings</DIV>
<DIV class=""><DIV class="stylepoint_body" name="Strings__body" id="Strings__body" style="display: none">
<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>
</DIV></DIV>
</DIV>
<DIV class="">
<H3><A name="Matching_Strings" id="Matching_Strings">Matching Strings</A></H3>
<SPAN class="link_button" id="link-Matching_Strings__button" name="link-Matching_Strings__button"><A href="?showone=Matching_Strings#Matching_Strings">
link
</A></SPAN><SPAN class="showhide_button" onclick="javascript:ShowHideByName('Matching_Strings')" name="Matching_Strings__button" id="Matching_Strings__button">▶</SPAN>
<DIV style="display:inline;" class="">
Use the <code>=~#</code> or <code>=~?</code> operator families over the
<code>=~</code> family.
</DIV>
<DIV class=""><DIV class="stylepoint_body" name="Matching_Strings__body" id="Matching_Strings__body" style="display: none">
<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>
</DIV></DIV>
</DIV>
<DIV class="">
<H3><A name="Regular_Expressions" id="Regular_Expressions">Regular Expressions</A></H3>
<SPAN class="link_button" id="link-Regular_Expressions__button" name="link-Regular_Expressions__button"><A href="?showone=Regular_Expressions#Regular_Expressions">
link
</A></SPAN><SPAN class="showhide_button" onclick="javascript:ShowHideByName('Regular_Expressions')" name="Regular_Expressions__button" id="Regular_Expressions__button">▶</SPAN>
<DIV style="display:inline;" class="">Prefix all regexes with <code>\m\C</code>.</DIV>
<DIV class=""><DIV class="stylepoint_body" name="Regular_Expressions__body" id="Regular_Expressions__body" style="display: none">
<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>
</DIV></DIV>
</DIV>
<DIV class="">
<H3><A name="Dangerous_commands" id="Dangerous_commands">Dangerous commands</A></H3>
<SPAN class="link_button" id="link-Dangerous_commands__button" name="link-Dangerous_commands__button"><A href="?showone=Dangerous_commands#Dangerous_commands">
link
</A></SPAN><SPAN class="showhide_button" onclick="javascript:ShowHideByName('Dangerous_commands')" name="Dangerous_commands__button" id="Dangerous_commands__button">▶</SPAN>
<DIV style="display:inline;" class="">Avoid commands with unintended side effects.</DIV>
<DIV class=""><DIV class="stylepoint_body" name="Dangerous_commands__body" id="Dangerous_commands__body" style="display: none">
<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>
</DIV></DIV>
</DIV>
<DIV class="">
<H3><A name="Fragile_commands" id="Fragile_commands">Fragile commands</A></H3>
<SPAN class="link_button" id="link-Fragile_commands__button" name="link-Fragile_commands__button"><A href="?showone=Fragile_commands#Fragile_commands">
link
</A></SPAN><SPAN class="showhide_button" onclick="javascript:ShowHideByName('Fragile_commands')" name="Fragile_commands__button" id="Fragile_commands__button">▶</SPAN>
<DIV style="display:inline;" class="">Avoid commands that rely on user settings.</DIV>
<DIV class=""><DIV class="stylepoint_body" name="Fragile_commands__body" id="Fragile_commands__body" style="display: none">
<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>
</DIV></DIV>
</DIV>
<DIV class="">
<H3><A name="Catching_Exceptions" id="Catching_Exceptions">Catching Exceptions</A></H3>
<SPAN class="link_button" id="link-Catching_Exceptions__button" name="link-Catching_Exceptions__button"><A href="?showone=Catching_Exceptions#Catching_Exceptions">
link
</A></SPAN><SPAN class="showhide_button" onclick="javascript:ShowHideByName('Catching_Exceptions')" name="Catching_Exceptions__button" id="Catching_Exceptions__button">▶</SPAN>
<DIV style="display:inline;" class="">Match error codes, not error text.</DIV>
<DIV class=""><DIV class="stylepoint_body" name="Catching_Exceptions__body" id="Catching_Exceptions__body" style="display: none">
<p>Error text may be locale dependent.</p>
</DIV></DIV>
</DIV>
</DIV>
<DIV class="">
<H2 name="General_Guidelines" id="General_Guidelines">General Guidelines</H2>
<DIV class="">
<H3><A name="Messaging" id="Messaging">Messaging</A></H3>
<SPAN class="link_button" id="link-Messaging__button" name="link-Messaging__button"><A href="?showone=Messaging#Messaging">
link
</A></SPAN><SPAN class="showhide_button" onclick="javascript:ShowHideByName('Messaging')" name="Messaging__button" id="Messaging__button">▶</SPAN>
<DIV style="display:inline;" class="">Message the user infrequently.</DIV>
<DIV class=""><DIV class="stylepoint_body" name="Messaging__body" id="Messaging__body" style="display: none">
<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>
</DIV></DIV>
</DIV>
<DIV class="">
<H3><A name="Type_checking" id="Type_checking">Type checking</A></H3>
<SPAN class="link_button" id="link-Type_checking__button" name="link-Type_checking__button"><A href="?showone=Type_checking#Type_checking">
link
</A></SPAN><SPAN class="showhide_button" onclick="javascript:ShowHideByName('Type_checking')" name="Type_checking__button" id="Type_checking__button">▶</SPAN>
<DIV style="display:inline;" class="">Use strict and explicit checks where possible.</DIV>
<DIV class=""><DIV class="stylepoint_body" name="Type_checking__body" id="Type_checking__body" style="display: none">
<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>
</DIV></DIV>
</DIV>
<DIV class="">
<H3><A name="Python" id="Python">Python</A></H3>
<SPAN class="link_button" id="link-Python__button" name="link-Python__button"><A href="?showone=Python#Python">
link
</A></SPAN><SPAN class="showhide_button" onclick="javascript:ShowHideByName('Python')" name="Python__button" id="Python__button">▶</SPAN>
<DIV style="display:inline;" class="">Use sparingly.</DIV>
<DIV class=""><DIV class="stylepoint_body" name="Python__body" id="Python__body" style="display: none">
<p>
Use python only when it provides critical functionality, for example
when writing threaded code.
</p>
</DIV></DIV>
</DIV>
<DIV class="">
<H3><A name="Other_Languages" id="Other_Languages">Other Languages</A></H3>
<SPAN class="link_button" id="link-Other_Languages__button" name="link-Other_Languages__button"><A href="?showone=Other_Languages#Other_Languages">
link
</A></SPAN><SPAN class="showhide_button" onclick="javascript:ShowHideByName('Other_Languages')" name="Other_Languages__button" id="Other_Languages__button">▶</SPAN>
<DIV style="display:inline;" class="">Use vimscript instead.</DIV>
<DIV class=""><DIV class="stylepoint_body" name="Other_Languages__body" id="Other_Languages__body" style="display: none">
<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>
</DIV></DIV>
</DIV>
<DIV class="">
<H3><A name="Boilerplate" id="Boilerplate">Boilerplate</A></H3>
<SPAN class="link_button" id="link-Boilerplate__button" name="link-Boilerplate__button"><A href="?showone=Boilerplate#Boilerplate">
link
</A></SPAN><SPAN class="showhide_button" onclick="javascript:ShowHideByName('Boilerplate')" name="Boilerplate__button" id="Boilerplate__button">▶</SPAN>
<DIV style="display:inline;" class="">
Use <a href="https://github.com/google/maktaba">maktaba</a>.
</DIV>
<DIV class=""><DIV class="stylepoint_body" name="Boilerplate__body" id="Boilerplate__body" style="display: none">
<p>
maktaba removes boilerplate, including:
<ul>
<li>Plugin creation</li>
<li>Error handling</li>
<li>Dependency checking</li>
</ul>
</p>
</DIV></DIV>
</DIV>
<DIV class="">
<H3><A name="Plugin_layout" id="Plugin_layout">Plugin layout</A></H3>
<SPAN class="link_button" id="link-Plugin_layout__button" name="link-Plugin_layout__button"><A href="?showone=Plugin_layout#Plugin_layout">
link
</A></SPAN><SPAN class="showhide_button" onclick="javascript:ShowHideByName('Plugin_layout')" name="Plugin_layout__button" id="Plugin_layout__button">▶</SPAN>
<DIV style="display:inline;" class="">Organize functionality into modular plugins</DIV>
<DIV class=""><DIV class="stylepoint_body" name="Plugin_layout__body" id="Plugin_layout__body" style="display: none">
<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>
</DIV></DIV>
</DIV>
<DIV class="">
<H3><A name="Functions" id="Functions">Functions</A></H3>
<SPAN class="link_button" id="link-Functions__button" name="link-Functions__button"><A href="?showone=Functions#Functions">
link
</A></SPAN><SPAN class="showhide_button" onclick="javascript:ShowHideByName('Functions')" name="Functions__button" id="Functions__button">▶</SPAN>
<DIV style="display:inline;" class="">
In the autoload/ directory, defined with <code>[!]</code> and
<code>[abort]</code>.
</DIV>
<DIV class=""><DIV class="stylepoint_body" name="Functions__body" id="Functions__body" style="display: none">
<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>
</DIV></DIV>
</DIV>
<DIV class="">
<H3><A name="Commands" id="Commands">Commands</A></H3>
<SPAN class="link_button" id="link-Commands__button" name="link-Commands__button"><A href="?showone=Commands#Commands">
link
</A></SPAN><SPAN class="showhide_button" onclick="javascript:ShowHideByName('Commands')" name="Commands__button" id="Commands__button">▶</SPAN>
<DIV style="display:inline;" class="">
In the plugin/commands.vim or under the ftplugin/ directory, defined
without <code>[!]</code>.
</DIV>
<DIV class=""><DIV class="stylepoint_body" name="Commands__body" id="Commands__body" style="display: none">
<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>
</DIV></DIV>
</DIV>
<DIV class="">
<H3><A name="Autocommands" id="Autocommands">Autocommands</A></H3>
<SPAN class="link_button" id="link-Autocommands__button" name="link-Autocommands__button"><A href="?showone=Autocommands#Autocommands">
link
</A></SPAN><SPAN class="showhide_button" onclick="javascript:ShowHideByName('Autocommands')" name="Autocommands__button" id="Autocommands__button">▶</SPAN>
<DIV style="display:inline;" class="">
Place them in plugin/autocmds.vim, within augroups.
</DIV>
<DIV class=""><DIV class="stylepoint_body" name="Autocommands__body" id="Autocommands__body" style="display: none">
<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>
</DIV></DIV>
</DIV>
<DIV class="">
<H3><A name="Mappings" id="Mappings">Mappings</A></H3>
<SPAN class="link_button" id="link-Mappings__button" name="link-Mappings__button"><A href="?showone=Mappings#Mappings">
link
</A></SPAN><SPAN class="showhide_button" onclick="javascript:ShowHideByName('Mappings')" name="Mappings__button" id="Mappings__button">▶</SPAN>
<DIV style="display:inline;" class="">
Place them in <code>plugin/mappings.vim</code>, using
<code>maktaba#plugin#MapPrefix</code> to get a prefix.
</DIV>
<DIV class=""><DIV class="stylepoint_body" name="Mappings__body" id="Mappings__body" style="display: none">
<p>
All key mappings should be defined in
<code>plugin/mappings.vim</code>.
</p>
<p>
Partial mappings (see :help using-&lt;Plug&gt;.) should be defined in
<code>plugin/plugs.vim</code>.
</p>
</DIV></DIV>
</DIV>
<DIV class="">
<H3><A name="Settings" id="Settings">Settings</A></H3>
<SPAN class="link_button" id="link-Settings__button" name="link-Settings__button"><A href="?showone=Settings#Settings">
link
</A></SPAN><SPAN class="showhide_button" onclick="javascript:ShowHideByName('Settings')" name="Settings__button" id="Settings__button">▶</SPAN>
<DIV style="display:inline;" class="">Change settings locally</DIV>
<DIV class=""><DIV class="stylepoint_body" name="Settings__body" id="Settings__body" style="display: none">
<p>
Use <code>:setlocal</code> and <code>&amp;l:</code> instead of
<code>:set</code> and <code>&amp;</code> unless you have explicit
reason to do otherwise.
</p>
</DIV></DIV>
</DIV>
</DIV>
<DIV class="">
<H2 name="Style" id="Style">Style</H2>
<p>
Follow google style conventions. When in doubt, treat vimscript style
like python style.
</p>
<DIV class="">
<H3><A name="Whitespace" id="Whitespace">Whitespace</A></H3>
<SPAN class="link_button" id="link-Whitespace__button" name="link-Whitespace__button"><A href="?showone=Whitespace#Whitespace">
link
</A></SPAN><SPAN class="showhide_button" onclick="javascript:ShowHideByName('Whitespace')" name="Whitespace__button" id="Whitespace__button">▶</SPAN>
<DIV style="display:inline;" class="">
Similar to python.
<br>
<br>
</DIV>
<DIV class=""><DIV class="stylepoint_body" name="Whitespace__body" id="Whitespace__body" style="display: none">
<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>
<DIV class=""><PRE>let s:variable = "concatenated " . "strings"
command -range=% MyCommand</PRE></DIV>
</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 &lt;leader&gt;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
<DIV class=""><PRE class="badcode">command -bang MyCommand call myplugin#foo()
command MyCommand2 call myplugin#bar()</PRE></DIV>
<DIV class=""><PRE>command -bang MyCommand call myplugin#foo()
command MyCommand2 call myplugin#bar()</PRE></DIV>
</li>
</ul>
</DIV></DIV>
</DIV>
<DIV class="">
<H3><A name="Naming" id="Naming">Naming</A></H3>
<SPAN class="link_button" id="link-Naming__button" name="link-Naming__button"><A href="?showone=Naming#Naming">
link
</A></SPAN><SPAN class="showhide_button" onclick="javascript:ShowHideByName('Naming')" name="Naming__button" id="Naming__button">▶</SPAN>
<DIV style="display:inline;" class="">
<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>
</DIV>
<DIV class=""><DIV class="stylepoint_body" name="Naming__body" id="Naming__body" style="display: none">
<P class="">
<SPAN class="stylepoint_subsection">plugin-names-like-this</SPAN>
<p>Keep them short and sweet.</p>
</P>
<P class="">
<SPAN class="stylepoint_subsection">FunctionNamesLikeThis</SPAN>
<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>
</P>
<P class="">
<SPAN class="stylepoint_subsection">CommandNamesLikeThis</SPAN>
<p>Prefer succinct command names over common command prefixes.</p>
</P>
<P class="">
<SPAN class="stylepoint_subsection">variable_names_like_this</SPAN>
<p>Augroup names count as variables for naming purposes.</p>
</P>
<P class="">
<SPAN class="stylepoint_subsection">Prefix all variables with their scope.</SPAN>
<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>
</P>
</DIV></DIV>
</DIV>
</DIV>
<p align="right">
Revision 1.1
</p>
<address>
Nate Soares<br>
Artemis Sparks<br>
David Barnett<br>
</address>
</BODY>
</HTML>
-412
View File
@@ -1,412 +0,0 @@
<?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-&lt;Plug&gt;.) 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>&amp;l:</code> instead of
<code>:set</code> and <code>&amp;</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 &lt;leader&gt;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>