Skip to content


Subversion checkout URL

You can clone with
Download ZIP
Fetching contributors…
Cannot retrieve contributors at this time
546 lines (440 sloc) 22.1 KB
*BellyButton.txt* For Vim version 7.3 Last change: 2011 March 17
0.- CONTENTS *BellyButton-contents*
1.- Introduction____________________________|BellyButtonIntro|
2.- Functionality___________________________|BellyButtonFunctionality|
3.- CUSTOMIZATION___________________________|BellyButtonOptions|
3.1 Configuration options______________________________|BellyButtonOptionConfigOpts|
3.1.1 Key mapings for BellyButton Commands
|BellyButtonExec| map option__________________|g:BellyButton_keymap_exec|
|BellyButtonLint| map option__________________|g:BellyButton_keymap_lint|
|BellyButtonExtra| map option_________________|g:BellyButton_keymap_extra|
3.2 Configuration option file__________________________|BellyButtonOptionFile|
4.- API_____________________________________|BellyButtonAPI|
4.0 TEMPLATE_______________________________|BellyButton_filetype_template|
4.1 load___________________________________|BellyButton_filetype_load|
4.2 init___________________________________|BellyButton_filetype_init|
4.3 clean__________________________________|BellyButton_filetype_clean|
4.4 lintRaw________________________________|BellyButton_filetype_lintRaw|
4.5 parseLintError_________________________|BellyButton_filetype_parseLintError|
4.6 exec___________________________________|BellyButton_filetype_exec|
4.7 parseExecError_________________________|BellyButton_filetype_parseExecError|
4.8 extra__________________________________|BellyButton_filetype_extra|
4.9 info___________________________________|BellyButton_filetype_info|
5.- File types_____________________________|BellyButtonFiletypes|
5.1 PHP____________________________________|BellyButtonFiletypesPHP|
5.2 JAVASCRIPT_____________________________|BellyButtonFiletypesJavascript|
5.3 PYTHON_________________________________|BellyButtonFiletypesPython|
5.4 C______________________________________|BellyButtonFiletypesC|
5.5 HTML___________________________________|BellyButtonFiletypesHTML|
5.6 CSS____________________________________|BellyButtonFiletypesCSS|
5.7 MARKDOWN_______________________________|BellyButtonFiletypesMarkdown|
6.- TODO list_______________________________|BellyButtonTodo|
7.- Maintainer______________________________|BellyButtonMaintainer|
9.- Credits_________________________________|BellyButtonCredits|
10.- History_________________________________|BellyButtonHistory|
1.- INTRODUCTION *BellyButtonIntro*
BellyButton is a plugin to make syntax checking and, in some cases, execution
or building of the contents of a buffer easy and consistent. The user interface of
BellyButton consists of three |commands|, Lint, Exec, and Extra. Lint will do
the syntax check. Exec will run the buffer as a program, script, etc. or even
attempt to build if appropriate. And Extra will vary by |filetype|. By default
these functions are mapped as:
Extra --> F3
Lint --> F4
Exec --> F5
Of course, the user can map those |commands| however they wish. In addition to
the three basic |commands| BellyButton will manage the error output of these
|commands| in a friendly Vim way by displaying the error output into Vim's
|quickfix| |window| so users can easily navigate through errors to make debugging
as efficient as possible.
2.- FUNCTIONALITY *BellyButtonFunctionality*
A core feature of BellyButton is to make it easy to implement Lint and Exec
|commands| on a per |filetype| basis. Where an Exec function doesn't make sense a
make or build function often does instead. In those cases BellyButton will
try to provide the appropriate build command functionality for the |filetype|.
3.- CUSTOMIZATION *BellyButtonOptions*
3.1 Configuration options *BellyButtonOptionConfigOpts*
3.1.1 Key mapings for BellyButton Commands
By default the |BellyButton| |commands| are mapped as such:
nmap <buffer> <silent> <F3> <ESC>:w<CR>:BellyButtonExtra<CR>
imap <buffer> <silent> <F3> <ESC>:w<CR>:BellyButtonExtra<CR>
nmap <buffer> <silent> <F4> <ESC>:w<CR>:BellyButtonLint<CR>
imap <buffer> <silent> <F4> <ESC>:w<CR>:BellyButtonLint<CR>
nmap <buffer> <silent> <F5> <ESC>:w<CR>:BellyButtonExec<CR>
imap <buffer> <silent> <F5> <ESC>:w<CR>:BellyButtonExec<CR>
The commands are mapped on a per buffer basis, and only if plugin for
the buffer's filetype exists.
You can easily override the default mappings by setting the
BellyButton keymap option variables in your .vimrc. The option
variable names are:
For example, to map the |BellyButtonExec| command to the F10 key you
would use this line in your .vimrc:
let g:BellyButton_keymap_exec = '<F10>'
This would cause the mapping command to be:
nmap <buffer> <silent> <F5> <ESC>:w<CR>:BellyButtonExec<CR>
imap <buffer> <silent> <F5> <ESC>:w<CR>:BellyButtonExec<CR>
3.2 Configuration option file *BellyButtonOptionFile*
Some of the external tools used by |BellyButton| have a very large array
of options available to them. It's also the case that you will often
want to set these options on a per project basis. This is where the
the |BellyButtonOptionFile| come into play. Every time you use a
|BellyButton| command |BellyButton| will first look in the current
directory for a file named .BellyButton_local_options.vim . If that
file exists it will be sourced into the current Vim session.
The Javascript BellyButton plugin is a great example of this. It uses jslint to analyze
javascript source code. Jslint is _very_ customizable and you'll
probably want some of the options to change on a per project level.
You can change the name of the option file that BellyButton will look
for by setting the g:BellyButton_local_option_file option.
To set the option file name that BellyButton will look for to
MyBBOptions.vim you would put the following line in your .vimrc:
let g:BellyButton_local_option_file = 'MyBBOptions.vim'
4.- API *BellyButtonAPI*
Make sure your hook implementation functions are declared with the bang!
function! funname
4.0 TEMPLATE *BellyButton_filetype_template*
Here is a template you can use to get started on on a BellyButton
|filetype| plugin. You don't have to use all of the functions in the
template. In fact you don't have to use any of them! But that would be
silly. It is important however, that if you don't implement a function
that you comment it out, or delete it all together. For further
explanation of each functions expected behavior, parameters, and
return value. Read the API details in the following sections.
function! BellyButton#<filetype>#load()
" Add any additional 'first time, one time' initializtion code here.
function! BellyButton#<filetype>#init()
" put any code down here that you want to run every time the
" #lintRaw, #exec, and #extra hooks are called, but right before they
" are caled. This can be a good place to setup options for external
" tools.
function! BellyButton#<filetype>#clean()
" put any code down here that you want to run every time the
" #lintRaw, #exec, and #extra hooks are called, but right _after_ they
" are caled. This hook is generally not needed. But for those that
" want or need it, it's available.
function! BellyButton#<filetype>#lintRaw()
" This is where you implement what's needed to perform the syntax
" checing on the buffer.
function! BellyButton#<filetype>#parseLintError( e_line )
" BellyButton will break the error string produced by the #lintRaw
" hook and iterate over the results for you. Each line in that error
" string will then be given as the parameter to the #parseLintError
" hook.
if no_errors
return {}
return { 'filename':'name of file the error came from',
\'lnum':'line number the error was found on',
\'char':'char column number the error is found at, optional',
\'errmsg':'the error message to display in the |quickfix| window' }
function! BellyButton#<filetype>#exec()
" This is where you put the code to execute or possibly make
" the current buffer. If the #exec hook doesn't make sense for your
" plugin, simple don't include it. If you implement the #exec hook
" you'll need to return a Dictionary as the result. See the API
" documentation BellyButton_filetype_exec for more details
return {'sysout':sysout,
function! BellyButton#<filetype>#parseExecError( e_line )
function! BellyButton#<filetype>#extra()
" Anything code you wish! See the API for further explanation of this
" hook
function! BellyButton#<filetype>#info()
return {'lint':"Short description of lint tool(s)",
\'exec':"Short description of exec command",
\'extra':"Short description of extra command",
\'author':"First Name Last Name",
\'author':"First Name Last Name",
\'externals':["External Tool One",
\"External Tool Two",
\"External Tool Three"],
\'desc':"Longer detailed description of this plugin."}
4.1- load *BellyButton_filetype_load*
Takes no parameters, returns nothing.
This function is required to exist, but does not have to do anything.
When a buffer is loaded BellyButton will call BellyButton#<filetype>#load to see if
it exists. If the function exists then BellyButton will setup the
command mappings to enable the BellyButton filetype plugin for the buffer.
BellyButton will remember that the function was found and not call it
again during the existing Vim session. Feel free to use this function
as a hook to run code that will only run once, the first time the
filetype plugin is checked against a matching buffer.
4.2- init *BellyButton_filetype_init*
Takes no parameters, returns nothing.
This will be called, if it
exists, right before the #lintRaw, #exec, and #extra hooks are
called. If you want any code that is only ran once, the first time the
script is used, you will want to put in the #lintRaw hook and use your
own logic to determine it's the first time its been called or not. The template
|BellyButton_filetype_template| has an example of that.
4.3- clean *BellyButton_filetype_clean*
Takes no parameters, returns nothing.
Very similar to the #init hook, except this is called _after_
#lintRaw, #exec, and #extra hooks have completed.
4.4- lintRaw *BellyButton_filetype_lintRaw*
Takes no parameters.
Returns: String
This is where you implement the syntax analysis of the current buffer.
Usually this means calling an external program to do the analysis of
the buffer for you. The string you return is expected to be the output
of the syntax analysis. Any errors are expected to be on one line and
be '\n' delimited within the string returned. All output must be in
one string, '\n' delimited. A simple example of an error string:
"error1\nerro2\nsome comment about something\nerror3\n"
4.5 parseLintError *BellyButton_filetype_parseLintError*
BellyButton#<filetype>#parseLintError( eline )
Params : String eline
Returns: |Dictionary|
This is where you will parse an error line that came from the #lintRaw
hook. The #lintRaw returned one string that possibly contained one or
more error lines from the syntax analysis tool that are newline, '\n',
delimited. This hook is where you analyze each piece of that string
and determine if it's an error string, and if so parse the error
string and return the error data in a |Dictionary.
The no error case is easy, simply return an empty |Dictionary|
if no_error
return {}
If the line is an error line, return the error information in a |Dictionary|
that contains the keys 'filename', 'lnum', 'char', and 'errmsg'. The
'char' is optional, but the other keys are required.
Key explanation:
'filename': The name of the file the error occurred in. Usually
this is the file that is open in the current buffer which easily
accessed with expand('%')
'lnum': The line number the error occurred on.
'errmsg': The human readable, hopefully, error message text that
will be the main body of the error line in the |quickfix|
'char': Optional. The column number the error occurred on. Some
tools will provide a character number for the offset in the
line the error happened at. If you have this information
please provide it. This will allow the user to easily jump not
only to the line the error is one, but also the column.
if error
return {'filename':expand('%'), 'lnum':69,
\'errmsg':'Your code exploded!'}
if charnum
return {'filename':expand('%'), 'lnum':69,
\'errmsg':'Your code exploded!', 'char':charnum}
4.6- exec *BellyButton_filetype_exec*
Takes no parameters.
Returns: |Dictionary|
This is where you put the code to execute or possible make
the current buffer. If the #exec hook doesn't make sense for your
plugin, simple don't include it. If you implement the #exec hook
you'll need to return a Dictionary as the result. The data in the
returned |Dictionary| is used to tell BellyButton if an error occurred
while executing/building the buffer and if so what to do about it. You
can safely return an empty |Dictionary| and BellyButton will assume
everything went fine. The return |Dictionary| should include four keys
with data. All of the keys are optional.
Key explanation:
'sysout': The raw output of the exec or build command.
'ecode' : The exit code of teh exec or build command.
'good_ecode': The value of a good exit code. Exit codes that are
not the same value as 'good_ecode' will be considered an error
'parse_error': If the an error is detected, 'ecode' does not match
'good_ecode', then parse each line of 'sysout' with the
#parseExecError hook and display the error results in the
</filetype>quickfix window.
sysout = system('exec_command '.expand('%'))
return {'sysout':sysout,
4.7- parseExecError *BellyButton_filetype_parseExecError*
BellyButton#<filetype>#parseExecError( eline )
Params : String eline
Returns: |Dictionary|
The function of this hook is nearly identical to the #parseLintError
hook. The only difference is this hook is used to parse error data as
result of executing or building a buffer instead of running a syntax
analysis tool. See |BellyButton_filetype_parseLintError| for
further explanation on how to implement this hook.
In some cases, the error output of executing or building a buffer is
the same format as produced by a lint tool. In that case, as is with
using php as both a lint tool and executable, you can simply run an
implemented #parseLintError hook and return it's results:
function BellyButton#<filetype>#parseExecError( e_line )
return BellyButton#<filetype>#parseLintError( a:e_line )
4.8- extra *BellyButton_filetype_extra*
Takes no parameters.
Returns nothing.
This is simple an easy way to add more |filetype| specific functionality
to a plugin. Certainly not required, but if there is an additional
command you think would help in the lint/exec/build process of a
|filetype|, feel free to implement the #extra() function hook. For
example, in the markdown(mkd) plugin the #extra() hook is used to
enable a one button render of the current buffer's markdown to a PDF
4.9- info *BellyButton_filetype_info*
Display information about the |filetype| plugin. This function is
expected to create and return a dictionary with the plugin's
information in it, indexed by the type of information. Below is a
description of each field of information.
lint: if lint is provided, give a brief description of how it is
exec: if an exec function is provided, give a brief description of how
it is implemented.
extra: if a #extra hook is implemented, give a brief description of
what it does.
author: "Author's Name"
author_email: "Author's e-mail address"
externals: A list of of external tools used by this plugin. Include a
URL to the tool if possible.
Here is an example from the javascript |fileytype| plugin. Information
fields that don't apply to the plugin are simply left blank. In this
case the javascript plugin does not provide an exec or extra command
so those dictionary entries are simply left out.
function! BellyButton#javascript#info()
return {'lint':"Lint: Uses jslint to analyze code",
\'author':"Jeff Buttars",
\'externals':["JSlint 2011-03-07 by Douglas Crockford:",
5.- FILE TYPES *BellyButtonFiletypes*
5.1- PHP *BellyButtonFiletypesPHP*
5.2- JAVASCRIPT *BellyButtonFiletypesJavascript*
Global Options
Enable/Disable highlighting of errors in source.
Default is Enable
To disable the highlighting put the line
in your .vimrc
Available JSLint options, override the defaults
with the var g:BellyButton_javascript_jslint_options = {}
adsafe true, if ADsafe rules should be enforced
bitwise true, if bitwise operators should not be allowed
browser true, if the standard browser globals should be predefined
cap true, if upper case HTML should be allowed
continue true, if the continuation statement should be tolerated
css true, if CSS workarounds should be tolerated
debug true, if debugger statements should be allowed
devel true, if logging should be allowed (console, alert, etc.)
es5 true, if ES5 syntax should be allowed
evil true, if eval should be allowed
forin true, if for in statements need not filter
fragment true, if HTML fragments should be allowed
indent the indentation factor
maxerr the maximum number of errors to allow
maxlen the maximum length of a source line
newcap true, if constructor names must be capitalized
nomen true, if names should be checked
on true, if HTML event handlers should be allowed
onevar true, if only one var statement per function should be allowed
passfail true, if the scan should stop on first error
plusplus true, if increment/decrement should not be allowed
regexp true, if the . should not be allowed in regexp literals
rhino true, if the Rhino environment globals should be predefined
undef true, if variables should be declared before used
safe true, if use of some browser features should be restricted
windows true, if MS Windows-specific globals should be predefined
strict true, require the "use strict"; pragma
sub true, if all forms of subscript notation are tolerated
white true, if strict whitespace rules apply
widget true if the Yahoo Widgets globals should be predefined
NOTE: This option is very handy!!!
predef [] an array of globals for jslint to not raise an error on
if it is not already defined. The value must be expressed as Javascript array
in a Vim string.
'predef':"['$', 'Ext', 'window', 'console', 'alert', 'confirm']"
5.3- PYTHON *BellyButtonFiletypesPython*
5.4- C *BellyButtonFiletypesC*
5.5- HTML *BellyButtonFiletypesHTML*
5.6- CSS *BellyButtonFiletypesCSS*
5.7- MARKDOWN *BellyButtonFiletypesMarkdown*
5.8- BASH *BellyButtonFiletypesBash*
6.- TODO list *BellyButtonTodo*
- Add exec output support.
Add the ability to display the raw output
of a |command| in a separate or split |buffer|. Also, the output |buffer|
should support "real-time" updating as well as not causing vim to
wait for the execution to finish before returning control to the
user. The execution should happen as a separate process.
- Add preprocessor support.
Make it easy for a user or |plugin| writer run a |buffer| through a
pre-process program before running a lint tool or executing the
|buffer|. We need to be able to analyze and execute buffers that have
been pre-processed in as easy a way as possible.
- Only map the |commands| if the current |buffer| supports it!
- Support for complex filetypes.
Example, a simple |filetype| is "javascript" but a complex filetype
could be "html.javascript" or even "html.javascript.css"
7.- Maintainer *BellyButtonMaintainer*
Jeff Buttars <>
9.- Credits *BellyButtonCredits*
Jeff Buttars <> Original u
10.- History *BellyButtonHistory*
Oh so young...
Jump to Line
Something went wrong with that request. Please try again.