adding new stuff

This commit is contained in:
ViktorBarzin 2017-07-09 00:22:01 +03:00
parent f84d7183aa
commit 9ef8a96f9a
1580 changed files with 0 additions and 0 deletions

View file

@ -0,0 +1,722 @@
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
**Table of Contents** *generated with [DocToc](http://doctoc.herokuapp.com/)*
- [XPTemplate](#xptemplate)
- [Usage](#usage)
- [Browse and basic usage](#browse-and-basic-usage)
- [C skeleton](#c-skeleton)
- [C macro](#c-macro)
- [C for loop and wrapper](#c-for-loop-and-wrapper)
- [C if-else-else](#c-if-else-else)
- [Python option argument](#python-option-argument)
- [Python def and def in class](#python-def-and-def-in-class)
- [Python inline completion](#python-inline-completion)
- [Python try-except can be a wrapper](#python-try-except-can-be-a-wrapper)
- [Python quickly add snippet](#python-quickly-add-snippet)
- [Video tutorial](#video-tutorial)
- [Stay up-to-date](#stay-up-to-date)
- [About branches](#about-branches)
- [Features](#features)
- [FAQ](#faq)
- [Trouble Shooting. Why not work?](#trouble-shooting-why-not-work)
- [What else does xptemlate required to work](#what-else-does-xptemlate-required-to-work)
- [How to install](#how-to-install)
- [Customizing snippet loading](#customizing-snippet-loading)
- [How to reload snippets, after I changes snippet definition files(*.xpt.vim)?](#how-to-reload-snippets-after-i-changes-snippet-definition-filesxptvim)
- [Do NOT like spaces in auto-completed brackets/braces](#do-not-like-spaces-in-auto-completed-bracketsbraces)
- [I need spaces in brackets/braces only for this language, not that](#i-need-spaces-in-bracketsbraces-only-for-this-language-not-that)
- [I do not want XPTemplate to auto-complete braces](#i-do-not-want-xptemplate-to-auto-complete-braces)
- [Adjust space and line-break](#adjust-space-and-line-break)
- [Adjust format style of c functions, such as `main()`](#adjust-format-style-of-c-functions-such-as-main)
- [Supertab support](#supertab-support)
- [With popup menu opened, `<TAB>` doesn't trigger Snippe](#with-popup-menu-opened-tab-doesnt-trigger-snippe)
- [Set up personal info. XPTemplate complains: "author is not set .."](#set-up-personal-info-xptemplate-complains-author-is-not-set-)
- [Browse snippets: Pop up menu, Drop down list](#browse-snippets-pop-up-menu-drop-down-list)
- [Extend XPTemplate. Write new snippets](#extend-xptemplate-write-new-snippets)
- [Example of repetition snippet.](#example-of-repetition-snippet)
- [Define repetition trigger place holder](#define-repetition-trigger-place-holder)
- [Known Issues](#known-issues)
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
# XPTemplate
Code snippets engine for Vim, And snippets library.
Write codes in a smooth, quick and comfortable way.
[xptemplate-vim.org][xpt-vim]
<iframe src="http://ghbtns.com/github-btn.html?user=drmingdrmer&repo=xptemplate&type=watch&count=true"
allowtransparency="true" frameborder="0" scrolling="0" width="110" height="20"></iframe>
## Usage
>vim xpt.c
for<C-\>
generates:
for (i = 0; i < len; ++i){
/* cursor */
}
Press `<tab>`,`<tab>`.. to navigate through "i", "0", "len" and finally stop at "`/* cursor */`"
### Browse and basic usage
![](readme-img/600x/browse-and-basic.gif)
### C skeleton
![](readme-img/600x/c-outline.gif)
### C macro
![](readme-img/600x/c-macro.gif)
### C for loop and wrapper
![](readme-img/600x/c-loop-and-wrapper.gif)
### C if-else-else
![](readme-img/600x/c-ifee.gif)
### Python option argument
![](readme-img/600x/py-optional-ph.gif)
### Python def and def in class
![](readme-img/600x/py-class-def.gif)
### Python inline completion
![](readme-img/600x/py-for-inline-cmpl.gif)
### Python try-except can be a wrapper
![](readme-img/600x/py-try.gif)
### Python quickly add snippet
![](readme-img/600x/py-quick-add.gif)
### Video tutorial
Tutorial by Derek Wyatt :
<http://vimeo.com/4449258>
## Stay up-to-date
There are two major branches: "master" and "dev".
* "master" is compacted, logging-removed version.
Always use branch "master" unless you know what you are doing.
* "dev" is for development, that it contains debug statements thus it is a bit slow.
Before 2014-06-01, The two major branches are: "master" and "dist":
* "master" is for developing purpose.
* "dist" is for end user.
## About branches
* Branch `master` is the branch for end user.
* Branch `dev` is for doing further developing on top of
XPTemplate.
* Branches that starts with `f.` are feature branches for different sub system
of XPTemplate.
* Branches that starts with `fd.` are feature breanches that has not yet been
merged into `dev` and `master`, which are NOT considered stable.
* Branches that starts with `snp.` are snippet branches.
## Features
* Live update while typing.
* Navigate forward and backward with `<Tab>` and `<S-Tab>`.
* Support embedded language like JAVASCRIPT in HTML. Or HTML in PHP.
* Wrapper snippet.
* Inclusion.
* Generate dynamic content with variables/functions.
* code style customization: line break before "{".
* Filters.
# FAQ
## Trouble Shooting. Why not work?
First of all, Enter VIM.
* Check setting "compatible". In VIM, type:
:set compatible?
Make sure you get *"nocompatible"*. Or you need the following statement in your .vimrc:
set nocompatible
* Check setting "filetype". In VIM, type:
:filetype
Make sure you get *"filetype detection:ON plugin:ON ..."*. Or you need
the following statement in you .vimrc:
filetype plugin on
* Check if XPTemplate is loaded. In VIM, type:
:scriptnames
You will get a list of scripts VIM has loaded. There should be some files
with name started with "xpt", like this:
97: /data/.../dist/plugin/xptemplate.vim
98: /data/.../dist/plugin/xptemplate.conf.vim
99: /data/.../dist/plugin/xptemplate.util.vim
If not, you should check if you have XPTemplate installed correctly.
You should see files with name started with "xpt.." in folder ~/.vim/
(Unix-like OS) or in $VIMH/vimfiles/ (Windows). Like this:
|-- plugin
...
| |-- xpopup.vim
| |-- xpreplace.vim
| |-- xptemplate.conf.vim
...
Reference:
:help 'runtimepath'
* Check key binding. Make sure you have a clear environment:
none of XPTemplate settings like *"let g:xpt..."* in you .vimrc file.
In VIM, type:
:imap <C-\>
You will get something like this:
i <C-\> * <C-R>=XPTemplateStart(0,{'k':'<C-\++'})<CR>
This means your XPTemplate should work well.
Or check if some other plugin has conflicting key-binding.
If so, solve it by adding the following statement into you .vimrc file to
change XPTemplate key-binding:
let g:xptemplate_key = '<Tab>'
* Now type in *insert-mode*:
Date<C-\>
You will get current date.
## What else does xptemlate required to work
VIM and nothing else!
XPTemplate is implemented purely with VIM script.
Nothing else(like python) is required but a single VIM( at least 7.2 ).
XPTemplate works also in VIM 7.0 too. But it's no as good as in VIM 7.2.
## How to install
Copy all folders in to your ~/.vim folder(on unix-like OS)
Or add path to XPTemplate to VIM setting 'runtimepath'.
## Customizing snippet loading
To load your own snippets and *NOT* to load snippets supplied by XPTemplate,
add this line to your `.vimrc`:
```
let g:xptemplate_lib_filter = '/my_snippets/'
```
Snippets from folder `~/xpt/` that does not match `g:xptemplate_lib_filter`
will not be loaded.
```
~/xpt/ftplugin/c/c.xpt.vim
...
~/my_snippets/ftplugin/c/c.xpt.vim
...
```
## How to reload snippets, after I changes snippet definition files(*.xpt.vim)?
:XPTreload
## Do NOT like spaces in auto-completed brackets/braces
Spaces inside auto-completed brackets are controlled by XPTemplate variable $SParg.
The Simplest way to disable spaces globally is to add following statements to .vimrc:
let g:xptemplate_vars = "SParg="
With this setting, `"("` results in `"()"` but not `"( )"` by default.
## I need spaces in brackets/braces only for this language, not that
Assume you do need spaces in brackets for java( that you want `"()"` but not `"( )"`).
Create a snippet file to defines your own preference:
.vim/ftplugin/java/mine.xpt.vim
Add add following contents to this file:
XPTemplate priority=personal
XPTvar $SParg ''
## I do not want XPTemplate to auto-complete braces
I want XPTemplate to complete `(`, `[`, but not `{`.
Add this to .vimrc:
let g:xptemplate_brace_complete = '(['
Or you may just want to disable brackets complete:
let g:xptemplate_brace_complete = ''
## Adjust space and line-break
Spaces and line-breaks are defined by some *variable*.
Instead of rewrite snippet in your own coding style, modifying these
*variable* is the easiest way.
For example by default "for" loop snippet in C lang is like:
for ( i = 0; i < len; i++ ) {
/* cursor */
}
As snippet "for" defined as:
for`$SPcmd^(`$SParg^`$FOR_SCOPE^`$VAR_PRE`i^`$SPop^=`$SPop^`0^; `i^`$SPop^<`$SPop^`len^; `i^++`$SParg^)`$BRloop^{
`cursor^
}
If you want to remove space after "for" and create a line-break before "{":
for( i = 0; i < len; i++ )
{
/* cursor */
}
Just add two variables into your *.vimrc* file:
let g:xptemplate_vars = "SPcmd=&BRloop=\n"
## Adjust format style of c functions, such as `main()`
Default c function indent is like this:
int
main( int argc, char **argv )
{
return 0;
}
This is controlled by variable `$BRfun`, if you prefer the single line style:
int main( int argc, char **argv ) {
return 0;
}
Add variable into your *.vimrc* file, to make ***ALL*** function snippets to
use single line style:
let g:xptemplate_vars = "BRfun= "
Or redefine `$BRfun` in higher priority snippet file to modify only c
functions:
XPTemplate priority=personal
XPTvar $BRfun ' '
Add the above lines into `ftplugin/c/foobar.xpt.vim`.
## Supertab support
Let XPTemplate try to match any snippet,
then let supertab try to complete,
and then fall back to literal input.
Put following lines into `~/.vimrc`:
```vim
" Prevent supertab from mapping <tab> to anything.
let g:SuperTabMappingForward = '<Plug>xpt_void'
" Tell XPTemplate what to fall back to, if nothing matches.
" Original SuperTab() yields nothing if g:SuperTabMappingForward was set to
" something it does not know.
let g:xptemplate_fallback = '<C-r>=XPTwrapSuperTab("n")<CR>'
fun! XPTwrapSuperTab(command) "{{{
let v = SuperTab(a:command)
if v == ''
" Change \<Tab> to whatever you want, when neither XPTemplate or
" supertab needs to do anything.
return "\<Tab>"
else
return v
end
endfunction "}}}
```
## With popup menu opened, `<TAB>` doesn't trigger Snippet
By default if popup menu is opened and `<TAB>` is used as trigger key, a
`<TAB>` key press does not trigger a snippet, according to convention in many
other application user use `<TAB>`.
If you always want to trigger snippet with `<TAB>` no matter popup menu opened
or not, add these lines to your .vimrc:
let g:xptemplate_key = '<Plug>triggerxpt'
inoremap <Plug>closePUM <C-v><C-v><BS>
imap <TAB> <Plug>closePUM<Plug>triggerxpt
" " Optional. Use this only when you have no other plugin like SuperTab to
" " handle <TAB>.
" let g:xptemplate_fallback = 'nore:<TAB>'
It first forces popup menu to close and then trigger snippet.
This fix issue that some plugin like AutoComplPop opens popup menu
automatically.
## Set up personal info. XPTemplate complains: "author is not set .."
You can set up your name and email for just one time, and use them everywhere,
like that in a document comment block the name of the author(you) will be
filled in.
Set up variable $author and $email in your .vimrc:
let g:xptemplate_vars = "author=your_name&email=drdr.xp@gmail.com&..."
Thus "filehead" snippet of C language should result in:
...
* @author : your_name | drdr.xp@gmail.com
...
## Browse snippets: Pop up menu, Drop down list
By default, to list snippets whose name starts with "i", Press:
i<C-r><C-\>
By default, when pressing `<C-\>`
there must be at least one letter before cursor
so that XPTemplate triggers any snippet.
* If there is only one snippet matching the preceding letters:
XPTemplate expands it.
* If there are multiple matching:
XPTemplate shows up a drop down menu to let user to browse and select
snippet.
![c-pum-starts-with-f](readme-img/c-pum-starts-with-f.png)
* In order to always show drop down menu even when there is no preceding
letters before cursor, add `g:xptemplate_minimal_prefix = 0` to `.vimrc`:
```vim
let g:xptemplate_minimal_prefix = 0
```
See also:
```vim
:help g:xptemplate_minimal_prefix
:help g:xptemplate_key_force_pum
```
## Extend XPTemplate. Write new snippets
Do *NOT* modify snippets supplied by XPTemplate.
***Where***:
Add your own snippets into folder **personal** :
<path_to_xpt>/personal/ftplugins/
It is meant for user-defined snippets.
It shares the same directory-structure with the xpt-snippet-folder.
Example personal-snippet-folder:
|~personal/
| |~ftplugin/
| | |+_common/
| | `~c/
| | |-c_ext.xpt.vim
| | `-c_new.xpt.vim
...
***How***:
***NOTE: File names does not matter except it must ends with '.xpt.vim'.***
* To create new snippet: Create *c_new.xpt.vim*. Add new snippets in it.
* To override existing ones, Create *c_ext.xpte.vim* with *higher priority*.
Put modified snippets into this file.
For example an extended "*for*" snippet looks like:
XPTemplate priority=lang-1
XPTinclude
\ _common/common
XPTemplate for " tips
for (
`i^ = 0;
`i^ < `len^;
++`i^
)
The header line declares a higher priority than priority "*lang*"(
lower number means higher priority ):
XPTemplate priority=lang-1
All snippets in this file override snippets in
*xpt-snippet-folder/ftplugin/c/c.xpt.vim* which declares with priority "*lang*".
Except that this file is with higher **priority**, **Personal-snippet-folder**
has no differences from **xpt-snippet-folder**.
***If you use GIT to sync vim plugins and your own snippets,
it's a good idea to place your snippet GIT folder somewhere outside XPTemplate
folder and add snippet folder path to `runtimepath`.***
References:
:help xpt-write-snippet
:help xpt-snippet-priority
## Example of repetition snippet.
Repetition snippet generates repeating contents such as multiple `else if` or
multiple `case `.
The following example is c struct snippet:
```vim
XPT struct
struct `a^ {
`data_type^ `member^;
` `more...`
{{^ `data_type^ `member^;
` `more...`
^`}}^};
```
It generates:
```
struct a {
data_type member;
data_type member;
data_type member;
more...
}
```
The last `more...` is trigger place holder for next repetitive part.
Pressing `<Tab>` on `more...` generates another `data_type member;`.
Pressing `<CR>` on `more...` quits applying repetition.
One of the problems with repetition is controlling line breaks.
XPTemplate accepts space and line-break as part of placeholder.
When trigger place holder is removed by pressing `<CR>`,
line break `\n` should also be removed togeter.
Thus space and line break should be part of place holder.
To do this, use the complete-form of placeholder:
```vim
`left-edge`placeholder_name`right-edge^
```
`left-edge` and `right-edge` can be space char or non-space char.
Thus in this c struct snippet:
![screen shot 2014-05-10 at 5 09 21 pm](https://cloud.githubusercontent.com/assets/44069/2935685/c9c9dfac-d822-11e3-8fda-ef428576bfee.png)
The repetition trigger is `more...` in cyan.
4 spaces on the left to `more...` and 1 line break on the right to `more...`.
Repetition body is the text in green.
Trigger for next repetition is the text in red.
***These two triggers(cyan and red) must be the same to generate consistent copies***.
Thus there will always be correct indent and a line break around trigger.
![screen shot 2014-05-10 at 5 13 44 pm](https://cloud.githubusercontent.com/assets/44069/2935690/63288d6a-d823-11e3-978a-734e7451df9d.png)
When trigger of repetition is removed,
4 space indent and line break is also removed all together with trigger,
![screen shot 2014-05-10 at 5 15 32 pm](https://cloud.githubusercontent.com/assets/44069/2935691/a1f1e17c-d823-11e3-97fe-9f1af63cdec3.png)
## Define repetition trigger place holder
Indent and line breaks are a bit complicated in repetition snippet.
This section describes how to define repetition correctly and clearly.
You may expect repetition `struct` in c to be like:
```c
struct a { //
int a; //
more... // focused here
} //
struct a { //
int a; //
int name; // when triggered, repetitive content generated.
more... // focused here
} //
struct a { //
int a; //
int name; // when repetition canceled.
} //
```
General rule is:
* Think of snippet as a single string.
* The text of place holder is actually the change from text with place holder
not removed to the text with place holder removed.
The following three examples show what repetition trigger is, with:
* only content before repetitions
* only content after repetitions
* both before and after
( `*` = space)
With only content ***BEFORE*** repetition:
```
| | what on screen | plain string | trigger |
|---------------------------------------------------------------------
| repetition | before | before\n****ph... | |
| | ****ph... | | |
|------------------------------------------------------| |
| after canceling | before | before | \n****ph... |
| repetition | | | |
|---------------------------------------------------------------------
XPT rep_before
before`
`ph...`{{^repetitive-content`
`ph...`^`}}^
```
With only content ***AFTER*** repetition:
```
| | what on screen | plain string | trigger |
|---------------------------------------------------------------------
| repetition | ****ph... | ****ph...\nafter | |
| | after | | |
|------------------------------------------------------| |
| after canceling | after | after | ****ph...\n |
| repetition | | | |
|---------------------------------------------------------------------
XPT rep_after
` `ph...`
{{^repetitive-content
` `ph...`
^`}}^after
```
Both before and after:
```
| | what on screen | what happened | trigger |
|----------------------------------------------------------------------------
| repetition | before | before\n****ph...\nafter | |
| place holder | ****ph... | | |
| | after | | |
|-------------------------------------------------------------| |
| after canceling | before | before\nafter | \n****ph... |
| repetition | after | | or |
| | | | ****ph...\n |
|----------------------------------------------------------------------------
```
Either of rep_before and rep_after is OK in this case.
# Known Issues
- Key mapping can not be saved/restored correctly.
Before VIM 7.4, during applying snippet, key-mapping saving/restoring does
not support `<expr>` mapping well.
[#43](../../issues/43) Solution: upgrade to VIM 7.4
- Mapping of `CTRL-L` does not work with popup menu opened.
Before VIM 7.4.653 mapping of `CTRL-L` does not work with xpt-pum opened.
`complete()` opens pum in `compl-whole-line` mode and it handles `CTRL-L`
in its own way without considering any mapping binded to it.
Fixed in
[vim-7.4-patch-653](https://github.com/vim/vim/commit/cd2c1cda5803f5ef7bb71a4034d393b4872a019f)
[xpt-github]: https://github.com/drmingdrmer/xptemplate
[xpt-vim]: http://www.vim.org/scripts/script.php?script_id=2611

View file

@ -0,0 +1,173 @@
if exists("g:__XPT_VIM__")
finish
endif
let g:__XPT_VIM__ = 1
let s:oldcpo = &cpo
set cpo-=< cpo+=B
let XPT#ver = 2
let XPT#let_sid = 'map <Plug>xsid <SID>|let s:sid=matchstr(maparg("<Plug>xsid"), "\\d\\+_")|unmap <Plug>xsid'
let XPT#nullDict = {}
let XPT#nullList = []
let XPT#escapeHead = '\v(\\*)\V'
let XPT#unescapeHead = '\v(\\*)\1\\?\V'
let XPT#nonEscaped = '\%(' . '\%(\[^\\]\|\^\)' . '\%(\\\\\)\*' . '\)' . '\@<='
let XPT#regEval = '\V\w(\|$\w'
let XPT#nonsafe = '{$( '
let XPT#nonsafeHint = '$('
let XPT#item_var = '\V' . '$\w\+'
let XPT#item_qvar = '\V' . '{$\w\+}'
let XPT#item_func = '\V' . '\w\+(\.\*)'
let XPT#item_qfunc = '\V' . '{\w\+(\.\*)}'
let XPT#ptnIncFull = '\V' . '\^Include:' . '\zs' . '\(\.\{-}\)\$'
let XPT#ptnIncSimp = '\V' . '\^:' . '\zs' . '\(\.\{-}\)' . '\ze' . ':\$'
let XPT#ptnRepetition = '\V'. '\^\w\*...\w\*\$'
let XPT#ptnPreEvalFunc = '\v^%(Inc|Inline|ResetIndent|Pre)\('
let XPT#NONE = 0x000
let XPT#BUILT = 0x001
let XPT#NOTBUILT = 0x002
let XPT#DONE = 0x100
let XPT#UNDONE = 0x200
let XPT#GOON = 0x300
let XPT#AGAIN = 0x400
let XPT#BROKEN = -1
let XPT#importConst = '' . 'let s:escapeHead = XPT#escapeHead | ' . 'let s:unescapeHead = XPT#unescapeHead | ' . 'let s:nonEscaped = XPT#nonEscaped | ' . 'let s:regEval = XPT#regEval | ' . 'let s:nonsafe = XPT#nonsafe | ' . 'let s:nonsafeHint = XPT#nonsafeHint | ' . 'let s:nullDict = XPT#nullDict | ' . 'let s:nullList = XPT#nullList | ' . 'let s:item_var = XPT#item_var | ' . 'let s:item_qvar = XPT#item_qvar | ' . 'let s:item_func = XPT#item_func | ' . 'let s:item_qfunc = XPT#item_qfunc | ' . 'let s:ptnIncFull = XPT#ptnIncFull | ' . 'let s:ptnIncSimp = XPT#ptnIncSimp | ' . 'let s:ptnRepetition = XPT#ptnRepetition | ' . 'let s:ptnPreEvalFunc = XPT#ptnPreEvalFunc | ' . 'let s:NONE = XPT#NONE | ' . 'let s:DONE = XPT#DONE | ' . 'let s:UNDONE = XPT#UNDONE | ' . 'let s:GOON = XPT#GOON | ' . 'let s:AGAIN = XPT#AGAIN | ' . 'let s:BROKEN = XPT#BROKEN | ' . 'let s:BUILT = XPT#BUILT | ' . 'let s:NOTBUILT = XPT#NOTBUILT | ' . 'let s:R_NEXT = 0x008 | ' . 'let s:R_OUT = 0x009 | ' . 'let s:R_ = 0x00A | ' . 'let s:R_FOO = 0x00B | ' . 'let s:G_CRESTED = 0x010 | ' . 'let s:G_INITED = 0x020 | ' . 'let s:G_PROCESSED = 0x030 | ' . 'let s:G_REFOCUSED = 0x040 | '
let XPT#priorities = {'all' : 192, 'spec' : 160, 'like' : 128, 'lang' : 96, 'sub' : 64, 'personal' : 32}
let XPT#skipPattern = 'synIDattr(synID(line("."), col("."), 0), "name") =~? "\\vstring|comment"'
fun! XPT#warn(msg)
echohl WarningMsg
echom a:msg
echohl
endfunction
fun! XPT#info(msg)
echom a:msg
endfunction
fun! XPT#error(msg)
echohl ErrorMsg
echom a:msg
echohl
endfunction
fun! XPT#fallback(fbs)
let fbs = a:fbs
if len(fbs) > 0
let [key,flag] = fbs[0]
call remove(fbs,0)
if flag == 'feed'
call feedkeys( key, 'mt' )
return ''
else
return key
endif
else
return ''
endif
endfunction
fun! XPT#softTabStop()
let ts = &l:tabstop
return &l:softtabstop == 0 ? ts : &l:softtabstop
endfunction
fun! XPT#getIndentNr(ln,col)
let line = matchstr( getline(a:ln), '\V\^\s\*' )
let line = ( a:col == 1 ) ? '' : line[ 0 : a:col - 1 - 1 ]
let tabspaces = repeat( ' ', &l:tabstop )
return len( substitute( line, ' ', tabspaces, 'g' ) )
endfunction
fun! XPT#getPreferedIndentNr(ln)
if &indentexpr != ''
let indentexpr = substitute( &indentexpr, '\Vv:lnum', a:ln, '' )
try
return eval(indentexpr)
catch /.*/
return -1
endtry
elseif &cindent
return cindent(a:ln)
else
return -1
endif
endfunction
fun! XPT#getCmdOutput(cmd)
let l:a = ""
redir => l:a
exe a:cmd
redir END
return l:a
endfunction
fun! XPT#convertSpaceToTab(text)
if ( "\n" . a:text ) !~ '\V\n ' || &expandtab
return a:text
else
let tabspaces = repeat( ' ', &tabstop )
let lines = split( a:text, '\V\n', 1 )
let newlines = []
for line in lines
let newline = join( split( line, '\V\^\%(' . tabspaces . '\)', 1 ), ' ' )
let newlines += [newline]
endfor
return join( newlines, "\n" )
endif
endfunction
fun! XPT#SpaceToTab(lines)
if ! &expandtab && match( a:lines, '\v^ ' ) > -1
let cmd = 'join( split( v:val, ''\v^%('' . repeat( '' '', &tabstop ) . '')'', 1 ), '' '' )'
call map(a:lines,cmd)
endif
return a:lines
endfunction
fun! XPT#SpaceToTabExceptFirstLine(lines)
if ! &expandtab && len( a:lines ) > 1 && match( a:lines, '\v^ ', 1 ) > -1
let line0 = a:lines[0]
let cmd = 'join( split( v:val, ''\v^%('' . repeat( '' '', &tabstop ) . '')'', 1 ), '' '' )'
call map(a:lines,cmd)
let a:lines[0] = line0
endif
return a:lines
endfunction
fun! XPT#TextBetween(posList)
return join(XPT#LinesBetween( a:posList ), "\n")
endfunction
fun! XPT#TextInLine(ln,s,e)
if a:s >= a:e
return ""
endif
return getline(a:ln)[a:s - 1 : a:e - 2]
endfunction
fun! XPT#LinesBetween(posList)
let [s,e] = a:posList
if s[0] > e[0]
return ""
endif
if s[0] == e[0]
if s[1] == e[1]
return ""
else
return getline(s[0])[s[1] - 1 : e[1] - 2]
endif
endif
let r = [getline(s[0])[s[1] - 1:]] + getline(s[0]+1,e[0]-1)
if e[1] > 1
let r += [getline(e[0])[:e[1] - 2]]
else
let r += ['']
endif
return r
endfunction
fun! XPT#default(k,v)
if !exists(a:k)
exe "let" a:k "=" string( a:v )
endif
endfunction
fun! XPT#Strlen(s)
return strlen(substitute(a:s, ".", "x", "g"))
endfunction
fun! XPT#Assert(toBeTrue,msg)
if !a:toBeTrue
call XPT#warn(a:msg)
if g:xpt_test_on_error == 'stop'
throw "XPT_TEST: fail: " . a:msg
endif
endi
endfunction
fun! XPT#AssertEq(a,b,msg)
call XPT#Assert( a:a == a:b, 'expect:' . string( a:a ) . ' but:' . string( a:b ) . ' message:' . a:msg )
endfunction
let &cpo = s:oldcpo

View file

@ -0,0 +1,42 @@
if exists("g:__XPPUM_VIM__")
finish
endif
let g:__XPPUM_VIM__ = 1
let s:oldcpo = &cpo
set cpo-=< cpo+=B
exe XPT#let_sid
fun! XPpum#completeFunc(first,base)
if !exists( 'b:__xppum' . s:sid )
if a:first
return col( "." )
else
return []
endif
endif
if a:first
return b:__xppum{s:sid}.col - 1
else
let &completefunc = b:__xppum{s:sid}.oldcfu
call b:__xppum{s:sid}.onShow()
let list = b:__xppum{s:sid}.list
unlet b:__xppum{s:sid}
return list
endif
endfunction
fun! XPpum#complete(col,list,onShow)
let b:__xppum{s:sid} = { 'col' : a:col, 'list' : a:list, 'oldcfu' : &completefunc, 'onShow' : a:onShow }
set completefunc=XPpum#completeFunc
let keyTriggerUserDefinedPum = "\<C-x>\<C-u>"
let keyCleanupPumSetting = "\<C-r>=<SNR>" . s:sid . "RestoreCommpletefunc()\<CR>"
let keyForceRefresh = "\<C-n>\<C-p>"
return keyTriggerUserDefinedPum
endfunction
fun! s:RestoreCommpletefunc()
if !exists( 'b:__xppum' . s:sid )
return ''
endif
let &completefunc = b:__xppum{s:sid}.oldcfu
unlet b:__xppum{s:sid}
return ''
endfunction
let &cpo = s:oldcpo

View file

@ -0,0 +1,21 @@
exec xpt#once#init
let s:oldcpo = &cpo
set cpo-=< cpo+=B
fun! xpt#buf#New()
if exists( 'b:xptemplateData' )
return b:xptemplateData
endif
let b:xptemplateData = { 'filetypes':{}, 'wrapStartPos':0, 'wrap':'', 'savedReg':'', 'snippetToParse':[], 'abbrPrefix':{}, 'fallbacks':[], 'posStack':[], 'stack':[], 'snipFileScope':{'inheritFT':0}, 'snipFileScopeStack':[], }
let b:xptemplateData.renderContext = xpt#rctx#New(b:xptemplateData)
return b:xptemplateData
endfunction
fun! xpt#buf#Pushrctx()
let x = b:xptemplateData
call add(x.stack,x.renderContext)
let x.renderContext = xpt#rctx#New(x)
endfunction
fun! xpt#buf#Poprctx()
let x = b:xptemplateData
let x.renderContext = remove(x.stack,-1)
endfunction
let &cpo = s:oldcpo

View file

@ -0,0 +1,31 @@
if exists( "g:__AUTOLOAD__XPT__CWC__SNPT_VIM__" )
finish
endif
let g:__AUTOLOAD__XPT__CWC__SNPT_VIM__ = 1
let s:oldcpo = &cpo
set cpo-=< cpo+=B
fun! xpt#cwd#snpt#load()
if exists( 'b:xptemplate_cwd_snpt_loaded' )
return
endif
call XPTemplateInit()
for fn in split(globpath('.', '.xpt.vim'), '\n')
exec 'so ' fn
endfor
for fn in split(globpath('.', '.' . &filetype . '.xpt.vim'), '\n')
exec 'so ' fn
endfor
let b:xptemplate_cwd_snpt_loaded = 1
endfunction
fun! xpt#cwd#snpt#reload()
if exists( 'b:xptemplate_cwd_snpt_loaded' )
unlet b:xptemplate_cwd_snpt_loaded
endif
return xpt#cwd#snpt#load()
endfunction
fun! xpt#cwd#snpt#clearFlag()
if exists( 'b:xptemplate_cwd_snpt_loaded' )
unlet b:xptemplate_cwd_snpt_loaded
endif
endfunction
let &cpo = s:oldcpo

View file

@ -0,0 +1,159 @@
if exists( "g:__XPT_DEBUG_VIM__" ) && g:__XPT_DEBUG_VIM__ >= XPT#ver
finish
endif
let g:__XPT_DEBUG_VIM__ = XPT#ver
let s:oldcpo = &cpo
set cpo-=<
set cpo+=B
exe XPT#let_sid
let s:globalLogLevel = 'debug'
let s:logLevels = {
\ 'fatal' : 1,
\ 'error' : 2,
\ 'warn' : 3,
\ 'info' : 4,
\ 'log' : 5,
\ 'debug' : 6,
\ }
fun! xpt#debug#Logger( level ) "{{{
let level = s:logLevels[ a:level ]
let level = min( [ level, s:logLevels[ s:globalLogLevel ] ] )
let logger = copy( s:loggerPrototype )
if level < s:logLevels.fatal | let logger.Fatal = s:loggerPrototype.LogNothing | endif
if level < s:logLevels.error | let logger.Error = s:loggerPrototype.LogNothing | endif
if level < s:logLevels.warn | let logger.Warn = s:loggerPrototype.LogNothing | endif
if level < s:logLevels.info | let logger.Info = s:loggerPrototype.LogNothing | endif
if level < s:logLevels.log | let logger.Log = s:loggerPrototype.LogNothing | endif
if level < s:logLevels.debug | let logger.Debug = s:loggerPrototype.LogNothing | endif
return logger
endfunction "}}}
fun! xpt#debug#Assert( shouldBeTrue, msg ) "{{{
if !a:shouldBeTrue
throw a:msg
end
endfunction "}}}
fun! xpt#debug#List( l ) "{{{
let rst = '[' . "\n"
for e in a:l
let rst .= '--- ' . string( e ) . "\n"
unlet e
endfor
return rst . "\n" . ']'
endfunction "}}}
fun! xpt#debug#EchoList( l ) "{{{
echom '['
for e in a:l
echom '--- ' . string( e ) . "\n"
unlet e
endfor
echom ']'
endfunction "}}}
fun! s:Fatal(...) dict "{{{
return call('Log_core', ['Fatal'] + a:000)
endfunction "}}}
fun! s:Error(...) dict "{{{
return call('Log_core', ['Error'] + a:000)
endfunction "}}}
fun! s:Warn(...) dict "{{{
return call('Log_core', ['Warn'] + a:000)
endfunction "}}}
fun! s:Info(...) dict "{{{
return call('Log_core', ['Info'] + a:000)
endfunction "}}}
fun! s:Log(...) dict "{{{
return call('Log_core', ['Log'] + a:000)
endfunction "}}}
fun! s:Debug(...) dict "{{{
return call('Log_core', ['Debug'] + a:000)
endfunction "}}}
fun! s:LogNothing(...) "{{{
endfunction "}}}
fun! Log_core(level, ...) "{{{
if s:logLocation == ''
return
end
" call stack printing
try
throw ''
catch /.*/
let stack = matchstr( v:throwpoint, 'function\s\+\zs.\{-}\ze\.\.\%(Fatal\|Error\|Warn\|Info\|Log\|Debug\).*' )
let stack = substitute( stack, '<SNR>\d\+_', '', 'g' )
endtry
exe 'redir! >> '.s:logLocation
silent echom a:level . ':::' . stack . ' cursor at=' . string( [ line("."), col(".") ] )
for msg in a:000
let l = split(';' . msg . ';', "\n")
let l[0] = l[0][1:]
let l[ -1 ] = l[ -1 ][ :-2 ]
for v in l
silent! echom v
endfor
endfor
redir END
if a:level =~ 'Fatal\|Error\|Warn'
echoerr string( a:000 )
endif
endfunction "}}}
" define script-private functions first and then make reference to them. Thus
" in traceback function name can be shown.
let s:loggerPrototype = {}
let s:loggerPrototype.Fatal = function( "<SNR>" . s:sid . "Fatal" )
let s:loggerPrototype.Error = function( "<SNR>" . s:sid . "Error" )
let s:loggerPrototype.Warn = function( "<SNR>" . s:sid . "Warn" )
let s:loggerPrototype.Info = function( "<SNR>" . s:sid . "Info" )
let s:loggerPrototype.Log = function( "<SNR>" . s:sid . "Log" )
let s:loggerPrototype.Debug = function( "<SNR>" . s:sid . "Debug" )
let s:loggerPrototype.LogNothing = function( "<SNR>" . s:sid . "LogNothing" )
fun! s:MakeLogPath() "{{{
let path = g:xptemplate_debug_log
if path == ''
let s:logLocation = ''
else
let path = substitute( path, '\V\^~/', $HOME . '/', '' )
let s:logLocation = path
call delete(s:logLocation)
endif
endfunction "}}}
call s:MakeLogPath()
let &cpo = s:oldcpo

View file

@ -0,0 +1,75 @@
exec xpt#once#init
let s:oldcpo = &cpo
set cpo-=< cpo+=B
fun! xpt#diff#Diff(a,b)
let [a,b] = [a:a,a:b]
let [astart,aend,bstart,bend] = [0,len(a),0,len(b)]
let [i,lmin] = [0,min([aend,bend])]
while i < lmin && a[i] == b[i] | let i += 1 | endwhile
let [astart,bstart] = [i,i]
let m = min([aend - astart,bend - bstart])
let i = 1
while i <= m && a[aend-i] == b[bend-i]
let i += 1
endwhile
let [aend,bend] = [aend-i+1,bend-i+1]
if type(a) == type('')
let [a,b] = [strpart(a,astart,aend-astart),strpart(b,bstart,bend-bstart)]
else
let [a,b] = [a[astart :],b[bstart :]]
if len(a) > aend - astart
call remove(a,aend-astart,-1)
endif
if len(b) > bend - bstart
call remove(b,bend-bstart,-1)
endif
endif
let [la,lb] = [len(a),len(b)]
let matrix = []
let i = 0
while i < la + 1
let s = []
let j = 0
while j < lb + 1
let s += [[0,0,0]]
let j += 1
endwhile
let matrix += [s]
let i += 1
endwhile
let [i] = [1]
while i < la + 1
let matrix[i][0] = [i-1,0,0]
let i += 1
endwhile
let [j] = [1]
while j < lb + 1
let matrix[0][j] = [0,j-1,0]
let j += 1
endwhile
let [i,j] = [0,0]
while i < la
let j = 0
while j < lb
let matrix[i+1][j+1] = a[i] == b[j] ? [i,j,matrix[i][j][2] + 1] : (matrix[i][j+1][2] > matrix[i+1][j][2] ? [i,j+1,matrix[i][j+1][2]] : [i+1,j,matrix[i+1][j][2]])
let j += 1
endwhile
let i += 1
endwhile
let lst = []
let [i,j] = [la,lb]
while i > 0 || j > 0
while (i > 0 || j > 0) && matrix[i][j][0] < i && matrix[i][j][1] < j
let [i,j] = matrix[i][j][: 1]
endwhile
let [ii,jj] = [i,j]
while (ii > 0 || jj > 0) && (matrix[ii][jj][0] == ii || matrix[ii][jj][1] == jj)
let [ii,jj] = matrix[ii][jj][: 1]
endwhile
let chg = [[astart+ii,astart+i],[bstart+jj,bstart+j]]
let lst = [chg] + lst
let [i,j] = [ii,jj]
endwhile
return lst
endfunction
let &cpo = s:oldcpo

View file

@ -0,0 +1,145 @@
if exists( "g:__AL_XPT_EVAL_VIM__" ) && g:__AL_XPT_EVAL_VIM__ >= XPT#ver
finish
endif
let g:__AL_XPT_EVAL_VIM__ = XPT#ver
let s:oldcpo = &cpo
set cpo-=< cpo+=B
let s:log = xpt#debug#Logger( 'warn' )
let s:log = xpt#debug#Logger( 'debug' )
exe XPT#importConst
let s:_evalCache = { 'strMask' : {}, 'compiledExpr' : {} }
fun! xpt#eval#Eval(str,closures)
if a:str == ''
return ''
endif
let globals = a:closures[0]
let x = b:xptemplateData
let expr = xpt#eval#Compile(a:str)
let globals._ctx = { 'closures':a:closures, 'renderContext':x.renderContext, }
let xfunc = globals
try
let r = eval(expr)
return r
catch /.*/
call XPT#warn(v:throwpoint)
call XPT#warn(v:exception)
call XPT#warn(expr)
return ''
endtry
endfunction
fun! xpt#eval#Compile(s)
if a:s is ''
return ''
endif
let expr = get(s:_evalCache.compiledExpr,a:s,0)
if expr is 0
if a:s !~ s:item_var . '\|' . s:item_func
let expr = string(xpt#util#UnescapeChar(a:s,s:nonsafe))
elseif a:s =~ '\V\^$\w\+\$'
let expr = 'xfunc.GetVar(' . string( a:s ) . ')'
else
let expr = s:DoCompile(a:s)
endif
let s:_evalCache.compiledExpr[a:s] = expr
endif
return expr
endfunction
fun! s:DoCompile(s)
let fptn = '\V' . '\w\+(\[^($]\{-})' . '\|' . s:nonEscaped . '{\w\+(\[^($]\{-})}'
let vptn = '\V' . s:nonEscaped . '$\w\+' . '\|' . s:nonEscaped . '{$\w\+}'
let sptn = '\V' . s:nonEscaped . '(\[^($]\{-})'
let patternVarOrFunc = fptn . '\|' . vptn . '\|' . sptn
if a:s !~ s:regEval
return string(xpt#util#UnescapeChar(a:s,s:nonsafe))
endif
let stringMask = s:CreateStringMask(a:s)
if stringMask !~ patternVarOrFunc
return string(xpt#util#UnescapeChar(a:s,s:nonsafe))
endif
let str = a:s
let evalMask = repeat('-', len(stringMask))
while 1
let matchedIndex = match(stringMask,patternVarOrFunc)
if matchedIndex == -1
break
endif
let matchedLen = len(matchstr(stringMask,patternVarOrFunc))
let matched = str[matchedIndex : matchedIndex + matchedLen - 1]
if matched =~ '^{.*}$'
let matched = matched[1:-2]
endif
if matched[0:0] == '(' && matched[-1:-1] == ')'
let contextedMatchedLen = len(matched)
let spaces = repeat(' ', contextedMatchedLen)
let stringMask = (matchedIndex == 0 ? "" : stringMask[:matchedIndex-1]) . spaces . stringMask[matchedIndex + matchedLen :]
continue
elseif matched[-1:] == ')'
let funcname = matchstr(matched, '^\w\+')
let args = matched[len(funcname) + 1 : -2]
let matched = "xfunc.Call('" . funcname . "',[" . args . '])'
elseif matched[0:0] == '$'
let matched = 'xfunc.GetVar(' . string( matched ) . ')'
endif
let contextedMatchedLen = len(matched)
let spaces = repeat(' ', contextedMatchedLen)
let evalMask = (matchedIndex == 0 ? "" : evalMask[:matchedIndex-1]) . '+' . spaces[1:] . evalMask[matchedIndex + matchedLen :]
let stringMask = (matchedIndex == 0 ? "" : stringMask[:matchedIndex-1]) . spaces . stringMask[matchedIndex + matchedLen :]
let str = (matchedIndex == 0 ? "" : str[:matchedIndex-1]) . matched . str[matchedIndex + matchedLen :]
endwhile
let idx = 0
let expr = ''
while 1
let matches = matchlist( evalMask, '\V\(-\*\)\(+ \*\)\?', idx )
if '' == matches[0]
break
endif
if '' != matches[1]
let part = str[idx : idx + len(matches[1]) - 1]
if matches[2] != ''
let part = xpt#util#UnescapeChar(part . '$', '{$( ')
let part = strpart(part,0,strlen(part) - 1)
else
let part = xpt#util#UnescapeChar(part, '{$( ')
endif
let expr .= ',' . string(part)
endif
if '' != matches[2]
let expr .= ',' . str[ idx + len(matches[1]) : idx + len(matches[0]) - 1 ]
endif
let idx += len(matches[0])
endwhile
let expr = "xfunc.Concat(" . expr[ 1: ] . ')'
return expr
endfunction
fun! s:CreateStringMask(str)
if a:str == ''
return ''
endif
if has_key(s:_evalCache.strMask,a:str)
return s:_evalCache.strMask[a:str]
endif
let dqe = '\V\('. s:nonEscaped . '"\)'
let sqe = '\V\('. s:nonEscaped . "'\\)"
let dptn = dqe.'\_.\{-}\1'
let sptn = sqe.'\%(\_[^'']\)\{-}'''
let mask = substitute(a:str, '[ *]', '+', 'g')
while 1
let d = match(mask,dptn)
let s = match(mask,sptn)
if d == -1 && s == -1
break
endif
if d > -1 && (d < s || s == -1)
let sub = matchstr(mask,dptn)
let sub = repeat(' ', len(sub))
let mask = substitute(mask, dptn, sub, '')
elseif s > -1
let sub = matchstr(mask,sptn)
let sub = repeat(' ', len(sub))
let mask = substitute(mask, sptn, sub, '')
endif
endwhile
let s:_evalCache.strMask[a:str] = mask
return mask
endfunction
let &cpo = s:oldcpo

View file

@ -0,0 +1,88 @@
exec xpt#once#init
let s:oldcpo = &cpo
set cpo-=< cpo+=B
let s:log = xpt#debug#Logger( 'warn' )
let s:log = xpt#debug#Logger( 'debug' )
let g:EmptyFilter = {}
let s:proto = { 'force':0, }
fun! xpt#flt#New(nIndent,text,...)
let flt = deepcopy(s:proto)
call extend(flt,{ 'nIndent':a:nIndent, 'text':a:text, 'force':a:0 == 1 && a:1, }, 'force' )
return flt
endfunction
fun! xpt#flt#NewSimple(nIndent,text,...)
let flt = { 'nIndent' : a:nIndent, 'text' : a:text, }
if a:0 == 1 && a:1
let flt.force = 1
endif
return flt
endfunction
fun! xpt#flt#Extend(flt)
call extend( a:flt, s:proto, 'keep' )
endfunction
fun! xpt#flt#Simplify(flt)
call filter( a:flt, 'v:val!=get(s:proto,v:key,-987654)' )
endfunction
fun! xpt#flt#Eval(snip,flt,closures)
let snipptn = a:snip.ptn
let r = { 'rc' : 1, 'parseIndent' : 1, 'nav' : 'stay' }
let rst = xpt#eval#Eval(a:flt.text,a:closures)
if type(rst) == type(0)
let r.rc = 0
return r
endif
if type( rst ) == type( '' )
if rst =~ snipptn.lft
let r.action = 'build'
else
let r.action = 'text'
endif
let r.text = rst
return r
endif
if type(rst) == type([])
let r.action = 'pum'
let r.pum = rst
return r
endif
call extend( r, rst, 'force' )
if ! has_key( r, 'action' ) && has_key( r, 'text' )
if r.text =~ snipptn.lft
let r.action = 'build'
else
let r.action = 'text'
endif
endif
let r.action = get( r, 'action', '' )
if r.action ==# 'embed'
let r.action = 'build'
endif
if has_key( r, 'cursor' )
call xpt#flt#ParseCursorSpec(r)
endif
return r
endfunction
fun! xpt#flt#ParseCursorSpec(flt_rst)
let rst = a:flt_rst
if type(rst.cursor) == type([]) && type( rst.cursor[ 0 ] ) == type( '' )
let rst.cursor = { 'rel' : 1, 'where':rst.cursor[ 0 ], 'offset':get( rst.cursor, 1, [ 0, 0 ] ) }
endif
let rst.isCursorRel = type(rst.cursor) == type({})
endfunction
fun! s:AddIndentToPHs(flt)
if a:flt.rst.nIndent == 0
return
endif
let nIndent = a:flt.rst.nIndent
let rst = []
for ph in a:flt.rst.phs
if type( ph ) == type( '' )
call add(rst,xpt#util#AddIndent(ph,nIndent))
else
call add(rst,ph)
endif
unlet ph
endfor
let a:flt.rst.phs = rst
endfunction
let &cpo = s:oldcpo

View file

@ -0,0 +1,49 @@
if exists( "g:__AL_XPT_FTSCP_VIM__" ) && g:__AL_XPT_FTSCP_VIM__ >= XPT#ver
finish
endif
let g:__AL_XPT_FTSCP_VIM__ = XPT#ver
let s:oldcpo = &cpo
set cpo-=< cpo+=B
fun! xpt#ftscope#New()
let inst = { 'filetype':'', 'allTemplates':{}, 'ftkeyword':{ 'regexp' : '\w', 'list' : [] }, 'funcs':{ '$CURSOR_PH' : 'CURSOR' }, 'inited':0, 'varPriority':{}, 'loadedSnipFiles':{}, 'extensionTable':{}, 'snipPieces':[], }
return inst
endfunction
fun! xpt#ftscope#Init(ftscope)
if a:ftscope.inited
return
endif
let l = a:ftscope.funcs.GetVar( '$CL' )
let m = a:ftscope.funcs.GetVar( '$CM' )
if len(l) <= len(m)
let a:ftscope.funcs[ '$CM_OFFSET' ] = ''
let a:ftscope.funcs[ '$CL_STRIP' ] = l
else
let a:ftscope.funcs[ '$CM_OFFSET' ] = repeat( ' ', len( l ) - len( m ) )
let a:ftscope.funcs[ '$CL_STRIP' ] = l[ : -len( m ) -1 ]
endif
let a:ftscope.inited = 1
endfunction
fun! xpt#ftscope#IsSnippetLoaded(inst,filename)
return has_key(a:inst.loadedSnipFiles,a:filename)
endfunction
fun! xpt#ftscope#SetSnippetLoaded(inst,filename)
let a:inst.loadedSnipFiles[a:filename] = 1
let fn = substitute(a:filename, '\\', '/', 'g')
let shortname = matchstr(fn, '\Vftplugin\/\zs\[^/]\+\/\.\*\ze.xpt.vim')
if shortname != ''
let a:inst.loadedSnipFiles[shortname] = 1
endif
endfunction
fun! xpt#ftscope#CheckAndSetSnippetLoaded(inst,filename)
let loaded = has_key(a:inst.loadedSnipFiles,a:filename)
call xpt#ftscope#SetSnippetLoaded(a:inst,a:filename)
return loaded
endfunction
fun! xpt#ftscope#PushPHPieces(ftscope,phs)
call add(a:ftscope.snipPieces,a:phs)
return len(a:ftscope.snipPieces) - 1
endfunction
fun! xpt#ftscope#GetPHPieces(ftscope,phsID)
return a:ftscope.snipPieces[a:phsID]
endfunction
let &cpo = s:oldcpo

View file

@ -0,0 +1,20 @@
let s:oldcpo = &cpo
set cpo-=< cpo+=B
let s:log = xpt#debug#Logger( 'warn' )
exe XPT#importConst
fun! xpt#group#New(name,sessid)
let g = { 'name' : a:name, 'fullname':a:name, 'initValue':a:name, 'phase':'created', 'processed':0, 'placeHolders':[], 'keyPH':s:nullDict, 'behavior':{}, 'sessid':a:sessid, }
return g
endfunction
fun! xpt#group#InsertPH(g,ph,where)
if has_key( a:ph, 'isKey' ) && a:g.keyPH != s:nullDict
unlet a:ph.isKey
endif
if has_key( a:ph, 'isKey' )
let a:g.keyPH = a:ph
let a:g.fullname = a:ph.fullname
else
call insert(a:g.placeHolders,a:ph,a:where)
endif
endfunction
let &cpo = s:oldcpo

View file

@ -0,0 +1,85 @@
exec xpt#once#init
let s:oldcpo = &cpo
set cpo-=< cpo+=B
let s:log = xpt#debug#Logger( 'warn' )
exe XPT#importConst
let s:indent_convert_cmd = 'substitute(v:val, ''\v(^\s*)@<= '', '' '', "g" )'
fun! xpt#indent#ParseStr(text,first_line_shift)
let text = xpt#indent#IndentToTabStr(a:text)
return xpt#indent#ToActualIndentStr(text,a:first_line_shift)
endfunction
fun! xpt#indent#IndentToTabStr(text)
let lines = split( a:text, '\n', 1 )
call xpt#indent#IndentToTab(lines)
return join(lines, "\n")
endfunction
fun! xpt#indent#ToActualIndentStr(text,first_line_shift)
let lines = split( a:text, '\n', 1 )
call xpt#indent#ToActualIndent(lines,a:first_line_shift)
return join(lines, "\n")
endfunction
fun! xpt#indent#IndentToTab(lines)
call map(a:lines,s:indent_convert_cmd)
endfunction
fun! xpt#indent#ToActualIndent(lines,first_line_shift)
let indent_spaces = repeat(' ', &shiftwidth)
let cmd = 'substitute(v:val, ''\v(^ *)@<= '', ''' . indent_spaces . ''', "g" )'
call map(a:lines,cmd)
if a:first_line_shift != 0
let shift_spaces = repeat(' ', a:first_line_shift)
let i = 1
while i < len(a:lines)
if a:lines[i] != '' || i == len(a:lines)-1
let a:lines[i] = shift_spaces . a:lines[i]
endif
let i += 1
endwhile
endif
if &expandtab
return
endif
let tabspaces = repeat( ' ', &tabstop )
let cmd = 'substitute(v:val, ''\v(^\s*)@<=' . tabspaces . ''', '' '', "g" )'
call map(a:lines,cmd)
endfunction
fun! xpt#indent#IndentBefore(pos)
let [ln,col] = a:pos
let line = matchstr( getline(ln), '\V\^\s\*' )
let line = ( col == 1 ) ? '' : line[ 0 : col - 1 - 1 ]
let tabspaces = repeat( ' ', &tabstop )
return len( substitute( line, ' ', tabspaces, 'g' ) )
endfunction
fun! xpt#indent#RemoveIndentStr(text,nIndent)
let reg = '\V\n \{,' . a:nIndent . '\}'
let text = substitute(a:text, reg, '\n', 'g')
return text
endfunction
fun! xpt#indent#ToSpace(text)
if stridx( a:text, " " ) < 0
return a:text
endif
let tabspaces = repeat( ' ', &tabstop )
let reg = '\v' . tabspaces . '| {0,' . (&tabstop-1) . '} '
let rst = []
let lines = split( a:text, '\n', 1 )
for line in lines
let leading_space = matchstr( line, '\v\s*' )
let left = line[len(leading_space) :]
let l = substitute( leading_space, reg, tabspaces, 'g' )
call add(rst,l . left)
endfor
return join(rst, "\n")
endfunction
fun! xpt#indent#SpaceToTab(text)
let indent_spaces = repeat(' ', &shiftwidth)
let reg = 'substitute(v:val, ''\v(^\s*)@<='.indent_spaces.''', " ", "g" )'
let lines = split( a:text, '\n', 1 )
call map(lines,reg)
return join(lines, "\n")
endfunction
fun! xpt#indent#ActualToSnippetNr(n)
let n_one_indent = &shiftwidth
let n_indent = a:n / n_one_indent
return n_indent * 4 + a:n % n_one_indent
endfunction
let &cpo = s:oldcpo

View file

@ -0,0 +1,118 @@
exec xpt#once#init
let s:oldcpo = &cpo
set cpo-=< cpo+=B
fun! xpt#mark#InitBuf()
if ! exists('b:_xpt_snapshot')
let b:_xpt_snapshot = {'lines': getline(1, "$"), 'marks': []}
endif
return b:_xpt_snapshot
endfunction
fun! xpt#mark#Add(positions,opt)
let snp = xpt#mark#InitBuf()
let snp.marks += a:positions
endfunction
fun! xpt#mark#Update()
let snp = xpt#mark#InitBuf()
let lines_b = getline(1, "$")
let marks = snp.marks
let marks = xpt#mark#UpdateMarks(snp.lines,lines_b,marks)
let snp.lines = lines_b
let snp.marks = marks
return marks
endfunction
fun! xpt#mark#UpdateMarks(lines_a,lines_b,marks)
let n_lines_a = len(a:lines_a)
let marks = a:marks[:]
call filter(marks, 'v:val[0]<n_lines_a')
call map(marks, 'v:val[:]')
let changes = xpt#diff#Diff(a:lines_a,a:lines_b)
let [i,j,li,lj,line_offset] = [0,0,len(marks),len(changes),0]
while i < li && j < lj
let [m,c] = [marks[i],changes[j]]
let [ca,cb] = c
let [linenr,colnr] = m
let [cstart,cend] = ca
if linenr < cstart || (linenr == cstart && colnr == 0)
let m[0] += line_offset
let i += 1
elseif linenr >= cend
let line_offset += (cb[1] - cb[0]) - (cend - cstart)
let j += 1
else
if cb[0] == cb[1]
let ii = i
while ii < li && marks[ii][0] < cend
let marks[ii] = [cstart[0] + line_offset,0]
let ii += 1
endwhile
else
let ii = i
while ii < li && marks[ii][0] < cend
let ii += 1
endwhile
let changed_marks = marks[i : ii - 1]
call map(changed_marks, '[v:val[0]-cstart, v:val[1]]')
let changed_2 = xpt#mark#UpdateLineChange(a:lines_a[cstart : cend-1],a:lines_b[cb[0] : cb[1] - 1],changed_marks)
call map(changed_2, '[v:val[0]+cstart+line_offset, v:val[1]]')
let marks = marks[: i][: -2] + changed_2 + marks[ii :]
let i += len(changed_2)
let li = len(marks)
endif
endif
endwhile
while i < li
let marks[i][0] += line_offset
let i += 1
endwhile
return marks
endfunction
fun! xpt#mark#UpdateLineChange(lines_a,lines_b,marks)
let joined_offset = []
let offset = 0
for l in a:lines_a
let joined_offset += [offset]
let offset += len(l) + 1
endfor
let n_lines_a = len(a:lines_a)
let marks = a:marks[:]
call filter(marks, 'v:val[0]<n_lines_a')
call map(marks, 'joined_offset[v:val[0]] + v:val[1]')
let changes = xpt#diff#Diff(join(a:lines_a, "\n"), join(a:lines_b, "\n"))
let [i,j,li,lj,offset] = [0,0,len(marks),len(changes),0]
while i < li && j < lj
let [m,c] = [marks[i],changes[j]]
let [ca,cb] = c
if m <= ca[0] || m < ca[1]
let marks[i] = min([m,ca[0]]) + offset
let i += 1
else
let offset += (cb[1] - cb[0]) - (ca[1] - ca[0])
let j += 1
endif
endwhile
while i < li
let marks[i] += offset
let i += 1
endwhile
let lb_ranges = []
let offset = 0
for l in a:lines_b
let lb_ranges += [[offset,offset + len(l) + 1]]
let offset = lb_ranges[-1][1]
endfor
let [i,j] = [0,0]
let [li,lj] = [len(marks),len(lb_ranges)]
let splitted = []
while i < li && j < lj
let m = marks[i]
let [_start,_end] = lb_ranges[j]
if m < _end
let splitted += [[j,m - _start]]
let i += 1
else
let j += 1
endif
endwhile
return splitted
endfunction
let &cpo = s:oldcpo

View file

@ -0,0 +1,156 @@
if exists( "g:__AL_XPT_MSVR_VIM__" ) && g:__AL_XPT_MSVR_VIM__ >= XPT#ver
finish
endif
let g:__AL_XPT_MSVR_VIM__ = XPT#ver
let s:oldcpo = &cpo
set cpo-=< cpo+=B
let s:log = xpt#debug#Logger( 'warn' )
snoremap <Plug>selectToInsert d<BS>
let g:globalStack = []
fun! s:_GetAlighWidth()
nmap <buffer> 1 2
let line = xpt#util#getCmdOutput("silent nmap <buffer> 1")
nunmap <buffer> 1
let line = split(line, "\n")[0]
return len(matchstr(line, '^n.*\ze2$'))
endfunction
let s:alignWidth = s:_GetAlighWidth()
delfunction s:_GetAlighWidth
fun! xpt#msvr#New(isLocal)
return { 'keys':[], 'saved':[], }
endfunction
fun! xpt#msvr#Add(inst,mode,key)
if a:inst.saved != []
throw "keys are already saved and can not be added"
endif
let a:inst.keys += [[a:mode,a:key]]
endfunction
fun! xpt#msvr#AddList(inst,...)
if a:0 > 0 && type(a:1) == type([])
let list = a:1
else
let list = a:000
endif
for item in list
let [ mode, key ] = split( item, '^\w\zs_' )
call xpt#msvr#Add(a:inst,mode,key)
endfor
endfunction
fun! xpt#msvr#UnmapAll(inst)
if a:inst.saved == []
throw "keys are not saved, can not unmap all"
endif
let localStr = '<buffer> '
for [mode,key] in a:inst.keys
exe 'silent! ' . mode . 'unmap ' . localStr . key
endfor
endfunction
fun! xpt#msvr#Save(inst)
if a:inst.saved != []
return
endif
for [mode,key] in a:inst.keys
call insert(a:inst.saved,xpt#msvr#MapInfo(key,mode))
endfor
let stack = s:GetStack()
call add(stack,a:inst)
endfunction
fun! xpt#msvr#Literalize(inst,...)
if a:inst.saved == []
throw "keys are not saved yet, can not literalize"
endif
let option = a:0 == 1 ? a:1 : {}
let insertAsSelect = get(option, 'insertAsSelect', 0)
let localStr = '<buffer> '
let nowait = v:version >= 704 ? '<nowait>' : ''
for [mode,key] in a:inst.keys
if mode == 's' && insertAsSelect
exe 'silent! ' . mode . 'map ' . nowait . localStr . key . ' <Plug>selectToInsert' . key
else
exe 'silent! ' . mode . 'noremap ' . nowait . localStr . key . ' ' . key
endif
endfor
endfunction
fun! xpt#msvr#Restore(inst)
if a:inst.saved == []
return
endif
let stack = s:GetStack()
if empty(stack) || stack[-1] != a:inst
throw "MapSaver: Incorrect Restore of MapSaver:" . s:String( stack ) . ' but ' . string( a:inst.keys )
endif
for info in a:inst.saved
call s:MappingPop(info)
endfor
let a:inst.saved = []
call remove(stack,-1)
endfunction
fun! s:GetStack()
if !exists( 'b:__map_saver_stack__' )
let b:__map_saver_stack__ = []
endif
return b:__map_saver_stack__
endfunction
if v:version >= 704
fun! xpt#msvr#MapInfo(key,mode)
let arg = maparg(a:key,a:mode,0,1)
if arg == {} || arg.buffer == 0
return { 'mode' : a:mode, 'key':a:key, 'nore':'', 'isexpr':'', 'isscript':'', 'isbuf':' <buffer> ', 'cont':''}
endif
let rhs = substitute( arg.rhs, '\V\C<SID>', '<SNR>' . arg.sid . '_', 'g' )
let line = s:GetMappingLine(a:key,a:mode)
let flag = line[0 : 1]
return { 'mode' : a:mode, 'key':a:key, 'nore':arg.noremap ? 'nore' : '', 'isexpr':arg.expr ? '<expr>' : '', 'isscript':flag[0] == '&' ? ' <script> ' : '', 'isbuf':arg.buffer ? '<buffer>' : '', 'cont':rhs }
endfunction
else
fun! xpt#msvr#MapInfo(key,mode)
let line = s:GetMappingLine(a:key,a:mode)
if line == ''
return { 'mode' : a:mode, 'key':a:key, 'nore':'', 'isexpr':'', 'isscript':'', 'isbuf':' <buffer> ', 'cont':''}
endif
let item = line[0:1] " the first 2 characters
let isexpr = ''
if a:mode == 'i' && line[2:] =~ '\V\w(\.\*)' && line[2:] !~? '\V<c-r>' || a:mode != 'i' && line[2:] =~ '\V\w(\.\*)' || a:mode == 'i' && line[2:] =~ '\V\.\*?\.\*:\.\*'
let isexpr = '<expr> '
endif
let info = {'mode' : a:mode, 'key':a:key, 'nore':item =~ '*' ? 'nore' : '', 'isexpr':isexpr, 'isscript':item[0] == '&' ? ' <script> ' : '', 'isbuf':' <buffer> ', 'cont':line[2:]}
return info
endfunction
endif
fun! xpt#msvr#MapCommand(info)
let i = a:info
if i.cont == ''
let cmd = i.mode . 'unmap <silent> ' . i.isbuf . i.key
else
let cmd = i.mode . i['nore'] . 'map <silent> ' . i.isscript . i.isexpr . i.isbuf . i.key . ' ' . i.cont
endif
return "silent! " . cmd
endfunction
fun! s:GetMappingLine(key,mode)
let mcmd = "silent ".a:mode."map <buffer> ".a:key
let str = xpt#util#getCmdOutput(mcmd)
let lines = split(str, "\n")
let localmark = '@'
let ptn = '\V\c' . a:mode . ' ' . escape(a:key, '\') . '\s\{-}' . '\zs\[*& ]' . localmark . '\%>' . s:alignWidth . 'c\S\.\{-}\$'
for line in lines
if line =~? ptn
return matchstr(line,ptn)
endif
endfor
return ""
endfunction
fun! s:MappingPop(info)
let cmd = xpt#msvr#MapCommand(a:info)
try
exe cmd
catch /.*/
endtry
endfunction
fun! s:String(stack)
let rst = ''
for ms in a:stack
let rst .= " **** " . string( ms.keys )
endfor
return rst
endfunction
let &cpo = s:oldcpo

View file

@ -0,0 +1,18 @@
if exists( "g:__AL_XPT_NG_VIM__" ) && g:__AL_XPT_NG_VIM__ >= XPT#ver
finish
endif
let g:__AL_XPT_NG_VIM__ = XPT#ver
let s:oldcpo = &cpo
set cpo-=< cpo+=B
let s:priorities = XPT#priorities
fun! xpt#ng#SetFiletypeDetector(funName)
if !exists("b:xptemplateData")
call XPTemplateInit()
endif
let x = b:xptemplateData
let prio = get( x.snipFileScope, 'priority', s:priorities.lang )
if prio <= x.ftdetector.priority
let x.ftdetector = { 'priority' : prio, 'func':function( a:funName ) }
endif
endfunction
let &cpo = s:oldcpo

View file

@ -0,0 +1,46 @@
let xpt#once#init = 'if xpt#once#SetAndGetLoaded(expand("<sfile>")) | finish | endif'
fun! xpt#once#SetAndGetLoaded(fn)
if ! exists('g:xptemplate_loaded')
let g:xptemplate_loaded = {}
endif
let fn = resolve(fnamemodify( a:fn, ':p' ))
let fn = s:Norm(fn)
let _rtps = split(&runtimepath, ',')
let rtps = []
for p in _rtps
let p = resolve(fnamemodify( p, ':p' ))
let p = s:Norm(p) . '/'
let rtps += [p]
endfor
call sort(rtps)
call reverse(rtps)
for p in rtps
let pref = fn[0 : len(p) - 1]
if pref == p
let relpath = fn[len(pref) :]
if has_key(g:xptemplate_loaded,relpath)
return 1
else
let g:xptemplate_loaded[relpath] = 1
return 0
endif
endif
endfor
echoerr a:fn . ' not found in any one of &runtimepath'
return 0
endfunction
fun! s:Norm(path)
let path = a:path
let path = substitute(path, '\V\\', '/', 'g')
let path = substitute( path, '\V/\*\$', '', 'g' )
let path = substitute( path, '\V//\*', '/', 'g' )
while 1
let p0 = path
let path = substitute( path, '\V/\[^/]\+/..', '', 'g' )
if p0 == path
break
endif
endwhile
return path
endfunction
exec xpt#once#init

View file

@ -0,0 +1,13 @@
exec xpt#once#init
let s:oldcpo = &cpo
set cpo-=< cpo+=B
call XPT#default('g:xptemplate_cwd_snippet', 0)
augroup XPT_CWD_SNIPPET
au!
if g:xptemplate_cwd_snippet == 1
au BufEnter * call xpt#cwd#snpt#load()
au FileType * call xpt#cwd#snpt#reload()
au BufUnload * call xpt#cwd#snpt#clearFlag()
endif
augroup END
let &cpo = s:oldcpo

View file

@ -0,0 +1,22 @@
exec xpt#once#init
let s:oldcpo = &cpo
set cpo-=< cpo+=B
call XPT#default('g:xptemplate_lib_filter', '\v.')
fun! xpt#option#lib_filter#Match(fn)
if a:fn =~ '\V\<_\w\+\[/\\]\[^/\\]\+' || a:fn =~ '\V~~/xpt/pseudo/ftplugin/'
return 1
end
let regs = []
if type(g:xptemplate_lib_filter) == type('')
let regs = [g:xptemplate_lib_filter]
else
let regs = g:xptemplate_lib_filter
endif
for r in regs
if a:fn =~# r
return 1
endif
endfor
return 0
endfunction
let &cpo = s:oldcpo

View file

@ -0,0 +1,582 @@
exec xpt#once#init
let s:oldcpo = &cpo
set cpo-=< cpo+=B
let s:log = xpt#debug#Logger( 'debug' )
exe XPT#importConst
let s:KEYTYPE_MAP = { '.':'onfocus', '.def':'onfocus', '.ontype':'live', '.onchange':'live', }
let s:KEYTYPE_TO_DICT = { 'pre':'preValues', 'live':'liveFilters', 'onfocus':'onfocusFilters', }
runtime plugin/xptemplate.vim
fun s:CompileSnippetFile(fn)
if a:fn =~ '\V.xpt.vimc\$' || !filereadable( a:fn )
return
endif
let lines = readfile(a:fn)
let lines = xpt#parser#Compact(lines)
let lines = xpt#parser#CompileCompacted(lines)
call writefile( lines, a:fn . 'c' )
endfunction
fun! xpt#parser#Compile(fn)
let compiledFn = a:fn . 'c'
let ctime = getftime(a:fn)
if !filereadable(compiledFn) || getftime(compiledFn) < ctime || g:xptemplate_always_compile
call s:CompileSnippetFile(a:fn)
else
endif
endfunction
fun! xpt#parser#Compact(lines)
let compacted = []
let iSnipPart = match( a:lines, '\V\^XPT\s' )
if iSnipPart < 0
let iSnipPart = len(a:lines)
endif
let [i,len] = [0 - 1,iSnipPart - 1]
while i < len | let i += 1
let l = a:lines[i]
if l != '' && l !~ '\v^"[^"]*$'
call add(compacted,l)
endif
endwhile
let [s,e,lastNonblank] = [-1,-1,100000]
let [i,len] = [iSnipPart - 1,len(a:lines) - 1]
while i < len | let i += 1
let l = a:lines[i]
if l == '' || l =~ '\v^"[^"]*$'
let lastNonblank = min([lastNonblank,i - 1])
continue
endif
if l =~# '\V\^..XPT\>'
if s == -1
let [s,e,lastNonblank] = [-1,-1,100000]
continue
else
let compacted += a:lines[s : i - 1]
let [s,e,lastNonblank] = [-1,-1,100000]
endif
elseif l =~# '\V\^XPT\>'
if s == -1
let [s,lastNonblank] = [i,i]
else
let e = min([i - 1,lastNonblank])
let compacted += a:lines[s : e]
let [s,e,lastNonblank] = [i,-1,100000]
endif
else
let lastNonblank = i
endif
endwhile
if s != -1
let compacted += a:lines[s : min([lastNonblank,i])]
endif
return compacted
endfunction
fun! xpt#parser#CompileCompacted(lines)
let rst = []
let lines = a:lines
let iSnipPart = match( lines, '\V\^XPT\s' )
if iSnipPart < 0
return lines
endif
if iSnipPart > 0
let rst += lines[: iSnipPart - 1]
let lines = lines[iSnipPart :]
endif
let [i,len] = [0,len(lines)]
call xpt#indent#IndentToTab(lines)
let s = i
while i < len-1 | let i += 1
let v = lines[i]
if v =~# '\V\^XPT\>'
let ll = xpt#parser#CompileSnippet(lines[s : i - 1])
let rst += [ll]
let s = i
elseif v =~# '\V\^\\XPT'
let lines[i] = v[1 :]
endif
endwhile
if i >= s
let ll = xpt#parser#CompileSnippet(lines[s : i])
let rst += [ll]
endif
return rst
endfunction
fun! xpt#parser#CompileSnippet(lines)
let lines = a:lines
let snippetLines = []
let setting = xpt#st#New()
let l0 = lines[0]
let pos = match( l0, '\VXPT\s\+\S\+\.\{-}\zs\s' . s:nonEscaped . '"' )
if pos >= 0
let [setting.rawHint, lines[0]] = [ matchstr( l0[ pos + 1 + 1 : ], '\v\S.*' ), l0[ : pos ] ]
endif
let [ x, snippetName; snippetParameters ] = split(lines[0], '\V'.s:nonEscaped.'\s\+')
for pair in snippetParameters
let name = matchstr(pair, '\V\^\[^=]\*')
let value = pair[len(name) :]
let value = value[0:0] == '=' ? xpt#util#UnescapeChar(value[1:], ' ') : 1
let setting[name] = value
endfor
let start = 1
let len = len(lines)
while start < len
let command = matchstr( lines[ start ], '\V\^XSETm\?\ze\s' )
if command != ''
let [key,val,start] = s:GetXSETkeyAndValue(lines,start)
if key == ''
let start += 1
continue
endif
let [keyname,keytype] = xpt#parser#GetKeyType(key)
call s:HandleXSETcommand(setting,command,[keyname,keytype,val])
elseif lines[start] =~# '^\\XSET' " escaped XSET or XSETm
let snippetLines += [lines[start][1:]]
else
call add(snippetLines,lines[start])
endif
let start += 1
endwhile
call xpt#st#Simplify(setting)
if has_key( setting, 'alias' )
return printf( 'call XPTemplateAlias(%s,%s,%s)', string(snippetName),string(setting.alias),string(setting))
else
return printf( 'call XPTdefineSnippet(%s,%s,%s)', string(snippetName),string(setting),string(snippetLines))
endif
endfunction
fun! xpt#parser#Include(...)
call xpt#parser#Load(a:000,1)
endfunction
fun! xpt#parser#Embed(...)
call xpt#parser#Load(a:000,0)
endfunction
fun! xpt#parser#Load(fns,inherit)
let scope = b:xptemplateData.snipFileScope
let ftscope = b:xptemplateData.filetypes[scope.filetype]
let saved_inherit = scope.inheritFT
let scope.inheritFT = a:inherit
let fns = xpt#util#Flatten(a:fns)
for f in fns
if a:inherit && xpt#ftscope#IsSnippetLoaded(ftscope,f)
continue
endif
call xpt#snipfile#Push()
exe 'runtime! ftplugin/' . f . '.xpt.vim'
call xpt#snipfile#Pop()
endfor
let scope.inheritFT = saved_inherit
endfunction
fun! xpt#parser#SetVar(nameSpaceValue)
let x = b:xptemplateData
let ftScope = x.filetypes[x.snipFileScope.filetype]
let name = matchstr(a:nameSpaceValue, '^\S\+\ze')
if name == ''
return
endif
let val = matchstr(a:nameSpaceValue, '\s\+\zs.*')
if val =~ '^''.*''$'
let val = val[1:-2]
else
let val = substitute( val, '\\ ', " ", 'g' )
endif
let val = substitute( val, '\\n', "\n", 'g' )
let priority = x.snipFileScope.priority
if !has_key(ftScope.varPriority,name) || priority <= ftScope.varPriority[name]
let [ftScope.funcs[name],ftScope.varPriority[name]] = [val,priority]
endif
endfunction
fun! xpt#parser#SnipSet(dictNameValue)
let x = b:xptemplateData
let snipScope = x.snipFileScope
let [ dict, nameValue ] = split( a:dictNameValue, '\V.', 1 )
let name = matchstr( nameValue, '^.\{-}\ze=' )
let value = nameValue[len(name) + 1 :]
let snipScope[dict][name] = value
endfunction
fun! xpt#parser#loadSpecialFiletype(ft)
let x = b:xptemplateData
let ft = a:ft
if has_key(x.filetypes,ft)
return
endif
if ft == 'unknown'
call xpt#parser#loadSnippetFile( 'unknown/unknown' )
else
call xpt#parser#InitSnippetFile( '~~/xpt/pseudo/ftplugin/' . ft . '/' . ft . '.xpt.vim' )
call XPTinclude( '_common/common' )
call XPTfiletypeInit()
endif
call XPTparseSnippets()
endfunction
fun! xpt#parser#loadSnippetFile(rel_snip)
exe 'runtime! ftplugin/' . a:rel_snip . '.xpt.vim'
call XPTfiletypeInit()
endfunction
fun! s:AssignSnipFT(filename)
let x = b:xptemplateData
let filename = substitute( a:filename, '\\', '/', 'g' )
if filename =~ 'unknown.xpt.vim$'
return 'unknown'
endif
let ftFolder = matchstr( filename, '\V/ftplugin/\zs\[^\\]\+\ze/' )
if empty(x.snipFileScopeStack)
if filename =~ '\V\<pseudo\>/'
return ftFolder
endif
if &filetype =~ '\<' . ftFolder . '\>' " sub type like 'xpt.vim'
let ft = &filetype
else
let ft = 'not allowed'
endif
else
if x.snipFileScopeStack[-1].inheritFT || ftFolder =~ '\V\^_'
if !has_key( x.snipFileScopeStack[ -1 ], 'filetype' )
throw 'parent may has no XPTemplate command called :' . a:filename
endif
let ft = x.snipFileScopeStack[-1].filetype
else
let ft = ftFolder
endif
endif
return ft
endfunction
fun! xpt#parser#InitSnippetFile(filename,...)
if ! xpt#option#lib_filter#Match(a:filename)
return 'finish'
endif
if !exists("b:xptemplateData")
call XPTemplateInit()
endif
let x = b:xptemplateData
let filetypes = x.filetypes
let snipScope = xpt#snipfile#New(a:filename)
let snipScope.filetype = s:AssignSnipFT(a:filename)
let x.snipFileScope = snipScope
let ft = snipScope.filetype
if ft == 'not allowed'
call s:log.Info( "not allowed:" . a:filename )
return 'finish'
endif
if ! has_key(filetypes,ft)
let filetypes[ft] = xpt#ftscope#New()
endif
let ftScope = filetypes[ft]
if xpt#ftscope#CheckAndSetSnippetLoaded(ftScope,a:filename)
return 'finish'
endif
for pair in a:000
let kv = split( pair, '=', 1 )
let key = kv[0]
let val = join( kv[ 1 : ], '=' )
if key =~ 'prio\%[rity]'
call XPTemplatePriority(val)
elseif key =~ 'mark'
call XPTemplateMark(val[0 : 0],val[1 : 1])
elseif key =~ 'key\%[word]'
call XPTemplateKeyword(val)
endif
endfor
return 'doit'
endfunction
fun! xpt#parser#SnippetFileInit_for_compiled(filename,...)
if !filereadable(a:filename)
return call( function( 'xpt#parser#InitSnippetFile' ), [ a:filename ] + a:000 )
endif
if a:filename =~ '\V.xpt.vim\$'
call xpt#parser#Compile(a:filename)
exe 'so' a:filename . 'c'
return 'finish'
else
return call( function( 'xpt#parser#InitSnippetFile' ), [ a:filename ] + a:000 )
endif
endfunction
fun! xpt#parser#LoadSnippets()
let fts = split( &filetype, '\V.', 1 )
call filter( fts, 'v:val!=""' )
for ft in fts
call xpt#parser#LoadFTSnippets(ft)
endfor
endfunction
fun! s:RTP()
let rtps = split( &runtimepath, ',' )
call filter( rtps, 'v:val!=""' )
let rtps += [ g:XPT_PATH . '/xptsnippets', g:XPT_PATH . '/personal' ]
let rtpath = join( rtps, ',' )
return rtpath
endfunction
fun! xpt#parser#LoadFtDetectors(ft)
let namePattern = a:ft =~ '/' ? a:ft : a:ft . '/*'
let rtpath = s:RTP()
let ftdetectfiles = split( globpath( rtpath, 'ftplugin/' . namePattern . '.ftdetect.vim' ), "\n" )
for fn in ftdetectfiles
exe 'so' fn
endfor
endfunction
fun! xpt#parser#LoadFTSnippets(ft)
let namePattern = a:ft =~ '/' ? a:ft : a:ft . '/*'
let rtpath = s:RTP()
let ftdetectfiles = split( globpath( rtpath, 'ftplugin/' . namePattern . '.ftdetect.vim' ), "\n" )
for fn in ftdetectfiles
exe 'so' fn
endfor
let snipfiles = split( globpath( rtpath, 'ftplugin/' . namePattern . '.xpt.vim' ), "\n" )
for fn in snipfiles
let compiled = fn . 'c'
if !filereadable(compiled) || getftime(compiled) < getftime(fn) || g:xptemplate_always_compile
call xpt#parser#Compile(fn)
exe 'so' compiled
endif
endfor
endfunction
fun! xpt#parser#GetKeyType(rawKey)
let keytype = matchstr(a:rawKey, '\V'.s:nonEscaped.'|\zs\.\{-}\$')
if keytype == ""
let keytype = matchstr(a:rawKey, '\V'.s:nonEscaped.'.\zs\.\{-}\$')
endif
let keyname = keytype == "" ? a:rawKey : a:rawKey[ 0 : - len(keytype) - 2 ]
let keyname = substitute(keyname, '\V\\\(\[.|\\]\)', '\1', 'g')
return [keyname,keytype]
endfunction
let s:KEY_NAME = 0
let s:KEY_TYPE = 1
let s:VALUE = 2
let s:stHandler = {}
fun! s:stHandler.ComeFirst(setting,cmdArgs)
let a:setting.comeFirst = xpt#util#SplitWith( a:cmdArgs[ s:VALUE ], ' ' )
endfunction
fun! s:stHandler.ComeLast(setting,cmdArgs)
let a:setting.comeLast = xpt#util#SplitWith( a:cmdArgs[ s:VALUE ], ' ' )
endfunction
fun! s:stHandler.postQuoter(setting,cmdArgs)
let pq = split( a:cmdArgs[ s:VALUE ], ',' )
let a:setting.postQuoter = { 'start' : pq[0], 'end' : pq[1] }
endfunction
let s:stHandler.PostQuoter = s:stHandler.postQuoter
let s:keytypeHandler = {}
fun! s:keytypeHandler.repl(setting,cmdArgs)
let a:setting.replacements[a:cmdArgs[s:KEY_NAME]] = a:cmdArgs[s:VALUE]
endfunction
fun! s:keytypeHandler.map(setting,cmdArgs)
let [kn,kt,val] = a:cmdArgs
let mp = a:setting.mappings
if !has_key(mp,kn)
let mp[ kn ] = { 'saver' : xpt#msvr#New( 1 ), 'keys' : {} }
endif
let key = matchstr( val, '\V\^\S\+\ze\s' )
let mapping = matchstr( val, '\V\s\+\zs\.\*' )
call xpt#msvr#Add( mp[ kn ].saver, 'i', key )
let mp[kn].keys[key] = xpt#flt#NewSimple(0,mapping)
endfunction
fun! s:keytypeHandler.post(setting,cmdArgs)
let [kn,kt,val] = a:cmdArgs
let val = xpt#ph#AlterFilterByPHName(kn,val)
let a:setting.postFilters[kn] = xpt#flt#NewSimple(0,val)
endfunction
fun! s:HandleXSETcommand(setting,command,cmdArgs)
let [kn,kt,val] = a:cmdArgs
let kt = get( s:KEYTYPE_MAP, '.' . kt, kt )
let fcon = {}
if has_key(s:stHandler,kn)
let fcon.f = s:stHandler[kn]
call fcon.f(a:setting,[kn,kt,val])
elseif has_key(s:KEYTYPE_TO_DICT,kt)
let dicName = s:KEYTYPE_TO_DICT[kt]
let a:setting[dicName][kn] = xpt#flt#NewSimple(0,val)
elseif kn =~ '\V\^$'
let a:setting.variables[kn] = val
elseif has_key(s:keytypeHandler,kt)
let fcon.f = s:keytypeHandler[kt]
call fcon.f(a:setting,[kn,kt,val])
else
throw "unknown key name or type:" . kn . ' ' . kt
endif
endfunction
fun! xpt#parser#LoadSnippetToParseList(fn)
let lines = readfile(a:fn)
let i = match( lines, '\V\^XPTemplateDef' )
if i == -1
let i = match( lines, '\V\^XPT\s' ) - 1
endif
if i < 0
return
endif
let lines = lines[i :]
let x = b:xptemplateData
let x.snippetToParse += [ { 'snipFileScope' : x.snipFileScope, 'lines' : lines } ]
endfunction
fun! xpt#parser#ParseSnippet(p)
call xpt#snipfile#Push()
let x = b:xptemplateData
let x.snipFileScope = a:p.snipFileScope
let lines = a:p.lines
let [i,len] = [0,len(lines)]
let [s,e,blk] = [-1,-1,10000]
while i < len-1 | let i += 1
let v = lines[i]
if v =~ '^\s*$' || v =~ '^"[^"]*$'
let blk = min([blk,i - 1])
continue
endif
if v =~# '^\.\.XPT'
let e = i - 1
call s:XPTemplateParseSnippet(lines[s : e])
let [s,e,blk] = [-1,-1,10000]
elseif v =~# '^XPT\>'
if s != -1
let e = min([i - 1,blk])
call s:XPTemplateParseSnippet(lines[s : e])
let [s,e,blk] = [i,-1,10000]
else
let s = i
let blk = i
endif
elseif v =~# '^\\XPT'
let lines[i] = v[1 :]
else
let blk = i
endif
endwhile
if s != -1
call s:XPTemplateParseSnippet(lines[s : min([blk,i])])
endif
call xpt#snipfile#Pop()
endfunction
fun! s:XPTemplateParseSnippet(lines)
let lines = a:lines
let snipScope = XPTsnipScope()
let snipScope.loadedSnip = get( snipScope, 'loadedSnip', {} )
let snippetLines = []
let setting = deepcopy(g:XPTemplateSettingPrototype)
let [hint,lines[0]] = s:GetSnipCommentHint(lines[0])
if hint != ''
let setting.rawHint = hint
endif
let snippetParameters = split(lines[0], '\V'.s:nonEscaped.'\s\+')
let snippetName = snippetParameters[1]
let snippetParameters = snippetParameters[2:]
for pair in snippetParameters
let name = matchstr(pair, '\V\^\[^=]\*')
let value = pair[len(name) :]
let value = value[0:0] == '=' ? xpt#util#UnescapeChar(value[1:], ' ') : 1
let setting[name] = value
endfor
let start = 1
let len = len(lines)
while start < len
let command = matchstr( lines[ start ], '\V\^XSETm\?\ze\s' )
if command != ''
let [key,val,start] = s:GetXSETkeyAndValue(lines,start)
if key == ''
let start += 1
continue
endif
let [keyname,keytype] = xpt#parser#GetKeyType(key)
call s:HandleXSETcommandOld(setting,command,keyname,keytype,val)
elseif lines[start] =~# '^\\XSET' " escaped XSET or XSETm
let snippetLines += [lines[start][1:]]
else
let snippetLines += [lines[start]]
endif
let start += 1
endwhile
let setting.fromXPT = 1
if has_key( setting, 'alias' )
call XPTemplateAlias(snippetName,setting.alias,setting)
else
call XPTdefineSnippet(snippetName,setting,snippetLines)
endif
if has_key(snipScope.loadedSnip,snippetName)
call XPT#info( "XPT: warn : duplicate snippet:" . snippetName . ' in file:' . snipScope.filename )
endif
let snipScope.loadedSnip[snippetName] = 1
if has_key( setting, 'synonym' )
let synonyms = split( setting.synonym, '|' )
for synonym in synonyms
call XPTemplateAlias(synonym,snippetName,{})
if has_key(snipScope.loadedSnip,synonym)
call XPT#warn( "XPT: warn : duplicate synonym:" . synonym . ' in file:' . snipScope.filename )
endif
let snipScope.loadedSnip[synonym] = 1
endfor
endif
endfunction
fun! s:GetSnipCommentHint(str)
let pos = match(a:str, '\V' . s:nonEscaped . '\shint=')
if pos != -1
return [a:str[pos + 6 :],a:str[: pos - 1]]
endif
let pos = match( a:str, '\VXPT\s\+\S\+\.\{-}\zs\s' . s:nonEscaped . '"' )
if pos == -1
return [ '', a:str ]
else
return [ matchstr( a:str[ pos + 1 + 1 : ], '\S.*' ), a:str[ : pos ] ]
endif
endfunction
fun! s:GetXSETkeyAndValue(lines,start)
let start = a:start
let XSETparam = matchstr(a:lines[start], '\V\^XSET\%[m]\s\+\zs\.\*')
let isMultiLine = a:lines[ start ] =~# '\V\^XSETm'
if isMultiLine
let key = XSETparam
let [start,val] = s:ParseMultiLineValues(a:lines,start)
else
let key = matchstr(XSETparam, '\V\[^=]\*\ze=')
if key == ''
return [ '', '', start + 1 ]
endif
let val = matchstr(XSETparam, '\V=\s\*\zs\.\*')
let val = substitute(val, '\\n', "\n", 'g')
endif
return [key,val,start]
endfunction
fun! s:ParseMultiLineValues(lines,start)
let lines = a:lines
let start = a:start
let endPattern = '\V\^XSETm\s\+END\$'
let start += 1
let multiLineValues = []
while start < len(lines)
let line = lines[start]
if line =~# endPattern
break
endif
if line =~# '^\V\\\+XSET\%[m]'
let slashes = matchstr( line, '^\\\+' )
let nrSlashes = len(slashes + 1) / 2
let line = line[nrSlashes :]
endif
let multiLineValues += [line]
let start += 1
endwhile
let val = join(multiLineValues, "\n")
return [start,val]
endfunction
fun! s:HandleXSETcommandOld(setting,command,keyname,keytype,value)
if a:keyname ==# 'ComeFirst'
let a:setting.comeFirst = xpt#util#SplitWith( a:value, ' ' )
elseif a:keyname ==# 'ComeLast'
let a:setting.comeLast = xpt#util#SplitWith( a:value, ' ' )
elseif a:keyname ==# 'postQuoter'
let a:setting.postQuoter = a:value
elseif a:keyname =~ '\V\^$'
let a:setting.variables[a:keyname] = a:value
elseif a:keytype == "" || a:keytype ==# 'def'
let a:setting.defaultValues[a:keyname] = xpt#flt#New(0,a:value)
elseif a:keytype ==# 'map'
let a:setting.mappings[a:keyname] = get( a:setting.mappings, a:keyname, { 'saver' : xpt#msvr#New(1), 'keys' : {} } )
let key = matchstr( a:value, '\V\^\S\+\ze\s' )
let mapping = matchstr( a:value, '\V\s\+\zs\.\*' )
call xpt#msvr#Add( a:setting.mappings[ a:keyname ].saver, 'i', key )
let a:setting.mappings[a:keyname].keys[key] = xpt#flt#New(0,mapping)
elseif a:keytype ==# 'pre'
let a:setting.preValues[a:keyname] = xpt#flt#New(0,a:value)
elseif a:keytype ==# 'ontype'
let a:setting.ontypeFilters[a:keyname] = xpt#flt#New(0,a:value)
elseif a:keytype ==# 'post'
if a:keyname =~ '\V...'
let a:setting.postFilters[a:keyname] = xpt#flt#New( 0, 'BuildIfNoChange(' . string(a:value) . ')' )
else
let a:setting.postFilters[a:keyname] = xpt#flt#New(0,a:value)
endif
else
throw "unknown key name or type:" . a:keyname . ' ' . a:keytype
endif
endfunction
let &cpo = s:oldcpo

View file

@ -0,0 +1,122 @@
exec xpt#once#init
let s:oldcpo = &cpo
set cpo-=< cpo+=B
let s:log = xpt#debug#Logger( 'warn' )
exe XPT#importConst
fun! xpt#ph#CreateFromScreen(snipObject,nameInfo,valueInfo)
let xp = a:snipObject.ptn
let toescape = xp.l . xp.r
let leftEdge = xpt#util#TextBetween(a:nameInfo[0 : 1])
let name = xpt#util#TextBetween(a:nameInfo[1 : 2])
let rightEdge = xpt#util#TextBetween(a:nameInfo[2 : 3])
let [leftEdge,name,rightEdge] = [leftEdge[1 :],name[1 :],rightEdge[1 :]]
let leftEdge = xpt#util#UnescapeChar(leftEdge,toescape)
let name = xpt#util#UnescapeChar(name,toescape)
let rightEdge = xpt#util#UnescapeChar(rightEdge,toescape)
if a:valueInfo[1] != a:valueInfo[0]
let posList = [a:valueInfo[0],a:valueInfo[2]]
let val = xpt#util#TextBetween(posList)
let val = val[1:]
let nIndent = indent(a:valueInfo[0][0])
let phFilter = { 'text' : val, 'indent' : nIndent, }
else
let phFilter = 0
endif
return xpt#ph#New(a:snipObject, { 'leftEdge' : leftEdge, 'name':name, 'rightEdge':rightEdge, 'isKey':a:nameInfo[0] != a:nameInfo[1], }, phFilter )
endfunction
fun! xpt#ph#New(snipObject,pieces)
let phptns = a:snipObject.ptn
let textPieces = deepcopy(a:pieces)
call map( textPieces, 'v:val.text' )
let iFilter = match( textPieces, '\V\^' . a:snipObject.ptn.r )
if iFilter > 1
let ph ={ 'leftEdge':a:pieces[ 0 ], 'name':a:pieces[ 1 ].text, 'displayText':a:pieces[ 1 ], 'rightEdge':iFilter > 2 ? a:pieces[2] : { 'nIndent' : a:pieces[ 1 ].nIndent, 'text' : '' }, 'isKey':1 }
let ph.fullname = ph.leftEdge.text . ph.name . ph.rightEdge.text
for key in [ 'leftEdge', 'displayText', 'rightEdge' ]
call xpt#ph#CreateEvaluatablePHElt(a:snipObject,ph,key)
endfor
else
let ph ={ 'name':a:pieces[ 0 ].text, 'displayText':a:pieces[ 0 ], 'fullname':a:pieces[ 0 ].text }
call xpt#ph#CreateEvaluatablePHElt( a:snipObject, ph, 'displayText' )
endif
let spec = xpt#ph#CreateSpecial(a:snipObject,ph)
if spec isnot 0
return spec
endif
if len(a:pieces) - iFilter == 1
return ph
endif
let ftype = len( a:pieces ) - iFilter > 2 ? 'postFilter' : 'liveFilter'
let fltPart = copy(a:pieces[iFilter])
let fltPart.text = fltPart.text[1:]
let fltPart.text = xpt#ph#AlterFilterByPHName(ph.name,fltPart.text)
let flt = xpt#ph#CreatePHEltFilter(a:snipObject,fltPart)
if has_key( ph, 'isKey' ) && ph.name != ''
let a:snipObject.setting[ ftype . 's' ][ ph.name ] = flt
else
let ph[ftype] = flt
endif
return ph
endfunction
fun! xpt#ph#CreateEvaluatablePHElt(snipObject,ph,key)
let phptns = a:snipObject.ptn
if a:ph[ a:key ].text =~ '\V' . phptns.item_var . '\|' . phptns.item_func . '\|\n'
let a:ph[a:key] = xpt#ph#CreatePHEltFilter(a:snipObject,a:ph[a:key])
elseif a:ph[ a:key ].text =~ '\V' . s:ptnIncFull . '\|' . s:ptnIncSimp
let a:ph[a:key] = xpt#ph#CreatePHEltFilter(a:snipObject,a:ph[a:key])
else
let a:ph[a:key] = xpt#util#UnescapeChar(a:ph[a:key].text,a:snipObject.ptn.lr)
endif
endfunction
fun! xpt#ph#CreateSpecial(snipObject,ph)
let phptns = a:snipObject.ptn
if type(a:ph.displayText) == type({})
if a:ph.displayText[ 'text' ] =~ s:ptnIncFull
let params = matchstr( a:ph.displayText[ 'text' ], s:ptnIncFull )
let [name,args] = xpt#snip#ParseInclusionStatement(a:snipObject,params)
let a:ph.displayText[ 'text' ] = 'Inc(' . string( name ) . ', 1, ' . string( args ) .')'
return a:ph
elseif a:ph.displayText[ 'text' ] =~ s:ptnIncSimp
let params = matchstr( a:ph.displayText[ 'text' ], s:ptnIncSimp )
let [name,args] = xpt#snip#ParseInclusionStatement(a:snipObject,params)
let a:ph.displayText[ 'text' ] = 'Inc(' . string( name ) . ', 0, ' . string( args ) .')'
return a:ph
endif
let a:ph.value = 1
return a:ph
endif
return 0
endfunction
fun! xpt#ph#FilterEltKeys(ph)
let phKeys = [ 'leftEdge', 'displayText', 'rightEdge' ]
call filter( phKeys, 'type( get( a:ph, v:val, 0 ) ) is ' . string( type( {} ) ) )
return phKeys
endfunction
fun! xpt#ph#GetPresetFilter(ph,setting)
let phLive = get( a:ph, 'liveFilter', g:EmptyFilter )
if a:ph.name != ''
let pre = get(a:setting.preValues,a:ph.name,g:EmptyFilter)
if get( pre, 'force' )
return pre
endif
let live = get(a:setting.liveFilters,a:ph.name,g:EmptyFilter)
if get( live, 'force' )
return live
endif
let phLive = phLive is g:EmptyFilter || get( pre, 'force' ) ? pre : phLive
let phLive = phLive is g:EmptyFilter || get( live, 'force' ) ? live : phLive
endif
return phLive
endfunction
fun! xpt#ph#CreatePHEltFilter(snipObject,elt)
let val = xpt#util#UnescapeChar(a:elt.text,a:snipObject.ptn.lr)
return xpt#flt#New(-a:elt.nIndent,val)
endfunction
fun! xpt#ph#AlterFilterByPHName(phname,fltText)
if a:phname =~ '\V...\$'
let a:fltText = xpt#util#UnescapeChar( a:fltText, '$({' )
return 'BuildIfNoChange(' . string( a:fltText ) . ')'
endif
return a:fltText
endfunction
let &cpo = s:oldcpo

View file

@ -0,0 +1,223 @@
if exists( "g:__AL_XPT_PHFILTER_VIM__" ) && g:__AL_XPT_PHFILTER_VIM__ >= XPT#ver
finish
endif
let g:__AL_XPT_PHFILTER_VIM__ = XPT#ver
let s:oldcpo = &cpo
set cpo-=< cpo+=B
let s:log = xpt#debug#Logger( 'warn' )
let s:log = xpt#debug#Logger( 'debug' )
exe XPT#importConst
fun! xpt#phfilter#Filter(so,PHFilterName,extContext)
let fctx = { 'snipObject':a:so, 'snipSetting':a:so.setting, 'phptns':a:so.ptn, 'phEvalContext':{ 'variables':a:so.setting.variables, 'pos':[ 0, 0 ], 'nIndAdd':0 }, 'srcPHs':a:so.parsedSnip, 'rstPHs':[], 'skip':'\v[^]', 'forceNotSkip':'\v.', }
call extend( fctx, a:extContext, 'force' )
call extend( fctx.phEvalContext, { 'pos' : [ 0, 0 ], 'nIndAdd' : 0 }, 'force' )
let fctx.srcPHs = deepcopy(fctx.srcPHs)
if len(fctx.srcPHs) == 0
return []
endif
call add(b:xptemplateData.phFilterContexts,fctx)
call add( fctx.rstPHs, "\n" )
try
while !empty(fctx.srcPHs)
let fctx.ph = remove(fctx.srcPHs,0)
let r = {a:PHFilterName}(fctx)
endwhile
finally
call remove(b:xptemplateData.phFilterContexts,-1)
endtry
let rst = fctx.rstPHs
if !empty(rst)
let rst[0] = rst[0][1 :]
endif
call filter( rst, 'len(v:val) > 0' )
return rst
endfunction
fun! xpt#phfilter#EvalInstantFilters(fctx)
if type(a:fctx.ph) == type({})
for a:fctx.key in [ 'leftEdge', 'displayText', 'rightEdge' ]
if s:EvalPHElt(a:fctx) isnot s:GOON
return
endif
endfor
endif
call xpt#phfilter#FeedPH(a:fctx)
endfunction
fun! xpt#phfilter#EvalPresetFilters(fctx)
if type(a:fctx.ph) == type({})
if type( a:fctx.ph[ 'displayText' ] ) == type( '' )
let flt = xpt#ph#GetPresetFilter(a:fctx.ph,a:fctx.snipSetting)
if flt isnot g:EmptyFilter
let a:fctx.ph[ 'displayText' ] = flt
endif
endif
for a:fctx.key in [ 'leftEdge', 'displayText', 'rightEdge' ]
if s:EvalPHElt(a:fctx) isnot s:GOON
return
endif
endfor
endif
call xpt#phfilter#FeedPH(a:fctx)
endfunction
fun! s:EvalPHElt(fctx,...)
let a:fctx.key = a:0 > 0 ? a:1 : a:fctx.key
let [ph,key] = [a:fctx.ph,a:fctx.key]
if has_key(ph,key) && type(ph[key]) == type({})
let flt = ph[key]
if flt.text =~# a:fctx.forceNotSkip || flt.text !~# a:fctx.skip
call xpt#flt#Eval(flt, a:fctx.snipObject.ftScope.funcs, a:fctx.phEvalContext)
return xpt#phfilter#HandleEltFilterRst(a:fctx,flt)
endif
endif
return s:GOON
endfunction
fun! xpt#phfilter#HandleEltFilterRst(fctx,flt)
let frst = a:flt.rst
if frst.rc > 0
if has_key( frst, 'action' )
let rc = s:HandleAction(a:fctx,a:flt)
if rc is s:DONE
return rc
endif
endif
if has_key( frst, 'text' )
let a:fctx.ph[a:fctx.key] = frst.text
return s:GOON
else
call XPT#info( 'Failed to pre-eval filter: ' . string( frst ) . ' filter=' . string( a:flt.text ) )
return s:UNDONE
endif
endif
return s:GOON
endfunction
fun! s:HandleAction(fctx,flt)
let frst = a:flt.rst
if frst.action == 'embed'
call extend(a:fctx.srcPHs,frst.phs,0)
else
return s:UNDONE
endif
return s:DONE
endfunction
fun! xpt#phfilter#ReplacePH(fctx)
let ph = a:fctx.ph
let phptns = a:fctx.phptns
let params = a:fctx.replParams
let rst = a:fctx.rstPHs
if type( ph ) == type( '' ) || !has_key(params,ph.name)
call xpt#phfilter#FeedPH(a:fctx)
else
let rep = params[ph.name]
if rep =~ phptns.lft
if rep !~ phptns.rt . '\$'
let rep = phptns.l . rep . phptns.r
endif
let slaveSnip = xpt#snip#NewSlave(a:fctx.snipObject,rep)
call xpt#snip#CompileAndParse(slaveSnip)
for a:fctx.ph in slaveSnip.parsedSnip
call xpt#phfilter#FeedPH(a:fctx)
endfor
let a:fctx.ph = ph
else
let ph.name = rep
let ph.displayText = rep
if ph.displayText =~ '\V' . phptns.item_var . '\|' . phptns.item_func . '\|\n'
let filterText = xpt#util#UnescapeChar(ph.displayText,phptns.lr)
let ph.displayText = xpt#flt#New(-a:fctx.phEvalContext.nIndAdd,filterText)
endif
call xpt#phfilter#FeedPH(a:fctx)
endif
endif
endfunction
fun! xpt#phfilter#PostQuote(fctx)
let ph = a:fctx.ph
let quoter = a:fctx.snipObject.setting.postQuoter
if type( ph ) == type( '' )
call xpt#phfilter#AppendRst(a:fctx,a:fctx.pqStack[-1],ph)
else
call extend( a:fctx.pqStack[ -1 ], [ ph, '' ] )
if ph.name[-len(quoter.start) :] ==# quoter.start
let ph.name = ph.name[0 : -1 - len(quoter.start)]
let ph.displayText = ph.name
call add(a:fctx.pqStack[-1],a:fctx.phEvalContext.nIndAdd)
call add( a:fctx.pqStack, [''] )
elseif ph.name == quoter.end
let stack = remove(a:fctx.pqStack,-1)
call remove(stack,-1)
call remove(stack,-1)
call filter( stack, 'len(v:val) > 0' )
let nIndent = remove(a:fctx.pqStack[-1],-1)
let startPH = a:fctx.pqStack[-1][-2]
let id = xpt#ftsc#PushPHPieces(a:fctx.snipObject.ftScope,stack)
if startPH.name[ -1 : -1 ] == '!'
let funcCall = 'Echo(IsChanged()?EmbedPHs(' . string( id ) . '):0)'
let startPH.name = startPH.name[0 : -len(quoter.start)]
let startPH.displayText = startPH.name
else
let funcCall = 'Echo(!IsChanged()?EmbedPHs(' . string( id ) . '):0)'
endif
let a:fctx.snipObject.setting.postFilters[startPH.name] = xpt#flt#New(-nIndent,funcCall)
endif
endif
endfunction
fun! xpt#phfilter#Repetition(fctx)
let ph = a:fctx.ph
if type( ph ) == type( '' )
call xpt#phfilter#AppendRst(a:fctx,a:fctx.repStack[-1],ph)
else
call extend( a:fctx.repStack[ -1 ], [ ph, '' ] )
if ph.name =~ s:ptnRepetition && !has_key(a:fctx.snipObject.setting.postFilters,ph.name)
if !has_key(a:fctx.repHeads,ph.name)
let a:fctx.repHeads[ph.name] = 1
call add(a:fctx.repStack[-1],a:fctx.phEvalContext.nIndAdd)
call add( a:fctx.repStack, [''] )
else
call remove(a:fctx.repHeads,ph.name)
let stack = remove(a:fctx.repStack,-1)
call filter( stack, 'len(v:val) > 0' )
let nIndent = remove(a:fctx.repStack[-1],-1)
let startPH = a:fctx.repStack[-1][-2]
let id = xpt#ftsc#PushPHPieces(a:fctx.snipObject.ftScope,stack)
let funcCall = 'Echo(!IsChanged()?EmbedPHs(' . string( id ) . '):0)'
let a:fctx.snipObject.setting.postFilters[startPH.name] = xpt#flt#New(-nIndent,funcCall)
endif
endif
endif
endfunction
fun! xpt#phfilter#UpdateIndent(fctx,last)
let evalctx = a:fctx.phEvalContext
if a:last =~ '\V\n'
let evalctx.nIndAdd = xpt#util#LastIndent(a:last)
endif
endfunction
fun! xpt#phfilter#AppendRst(fctx,lst,ph)
let evalctx = a:fctx.phEvalContext
if a:ph =~ '\V\n'
let lines = split( a:ph, '\V\n', 1 )
let evalctx.pos[0] += len(lines) - 1
let evalctx.pos[1] = len(lines[-1])
else
let evalctx.pos[1] += len(a:ph)
endif
let a:lst[-1] .= a:ph
call xpt#phfilter#UpdateIndent(a:fctx,a:lst[-1])
endfunction
fun! xpt#phfilter#FeedPH(fctx)
if type( a:fctx.ph ) == type( {} ) && has_key( a:fctx.ph, 'value' )
let ph = s:MergeEltsIfAllString(a:fctx.ph)
else
let ph = a:fctx.ph
endif
if type( ph ) == type( '' )
call xpt#phfilter#AppendRst(a:fctx,a:fctx.rstPHs,ph)
else
call extend( a:fctx.rstPHs, [ ph, '' ] )
endif
endfunction
fun! s:MergeEltsIfAllString(ph)
if has_key( a:ph, 'value' ) && type( a:ph[ 'displayText' ] ) == type( '' ) && type( get( a:ph, 'leftEdge', '' ) ) == type( '' ) && type( get( a:ph, 'rightEdge', '' ) ) == type( '' )
return get( a:ph, 'leftEdge', '' ) . get( a:ph, 'displayText', '' ) . get( a:ph, 'rightEdge', '' )
else
return a:ph
endif
endfunction
let &cpo = s:oldcpo

View file

@ -0,0 +1,22 @@
if exists( "g:__AL_XPT_PRIORITY_f78d9s873942__" ) && g:__AL_XPT_PRIORITY_f78d9s873942__ >= XPT#ver
finish
endif
let g:__AL_XPT_PRIORITY_f78d9s873942__ = XPT#ver
let s:oldcpo = &cpo
set cpo-=< cpo+=B
let s:priorities = { 'lowest': 9999999, 'all':64, 'spec' : 48, 'like' : 32, 'lang' : 16, 'sub':8, 'personal' : 0, 'highest':-1, }
let s:priorities.default = s:priorities.lang
fun! xpt#priority#Get(pstr)
return s:priorities[a:pstr]
endfunction
fun! xpt#priority#Parse(pstr)
let pstr = a:pstr
if pstr =~ '\V\[+-]\$'
let pstr .= '1'
endif
let reg = '\V\(\w\+\|\[+-]\)\zs'
let prioParts = split(pstr,reg)
let prioParts[0] = get(s:priorities,prioParts[0],prioParts[0] - 0)
return eval( join( prioParts, '' ) )
endfunction
let &cpo = s:oldcpo

View file

@ -0,0 +1,118 @@
exec xpt#once#init
let s:oldcpo = &cpo
set cpo-=< cpo+=B
let s:log = xpt#debug#Logger( 'warn' )
let s:phase = { 'uninit':'uninit' , 'popup':'popup' , 'inited':'inited' , 'rendering':'rendering', 'rendered':'rendered' , 'iteminit':'iteminit' , 'fillin':'fillin' , 'post':'post' , 'finished':'finished' , }
let xpt#rctx#phase = s:phase
let p = s:phase
let s:phaseGraph = { p.uninit : [p.popup,p.inited], p.popup : [p.inited], p.inited : [p.rendering], p.rendering : [p.rendered], p.rendered : [p.iteminit], p.iteminit : [p.iteminit,p.fillin,p.post], p.fillin : [p.post,p.finished], p.post : [p.finished,p.iteminit], p.finished : [p.uninit], }
unlet p
fun! xpt#rctx#New(x)
let pre = "X" . len( a:x.stack ) . '_'
let inst = { 'ftScope':{}, 'level':len( a:x.stack ), 'snipObject':{}, 'snipSetting':{}, 'phase':s:phase.uninit, 'nextStep':-1, 'action':'', 'userPostAction':'', 'wrap':{}, 'userWrapped':{}, 'markNamePre':pre, 'item':{}, 'leadingPlaceHolder':{}, 'activeLeaderMarks':'innerMarks', 'history':[], 'namedStep':{}, 'processing':0, 'marks':{ 'tmpl':{ 'start':pre . '`tmpl`s', 'end':pre . '`tmpl`e' } }, 'itemDict':{}, 'itemList':[], 'groupList':[], 'lastContent':'', 'tmpmappings':{}, 'oriIndentkeys':{}, 'leadingCharToReindent':{}, }
let lst = split( &indentkeys, ',' )
let indentkeysList = []
for k in lst
if k == ""
let indentkeysList[ -1 ] .= ','
else
if k[ 0 ] == '0'
call add(indentkeysList,k)
endif
endif
endfor
for k in indentkeysList
if k[ 1 ] == '=' && len( k ) > 2
let inst.oriIndentkeys[k[2:]] = 1
else
let k = k[1:]
if k == ''
let k = ','
endif
let inst.leadingCharToReindent[k] = 1
endif
endfor
return inst
endfunction
fun! xpt#rctx#SwitchPhase(inst,nextPhase)
if -1 == match( s:phaseGraph[ a:inst.phase ], '\V\<' . a:nextPhase . '\>' )
throw 'XPT:RenderContext:switching from [' . a:inst.phase . '] to [' . a:nextPhase . '] is not allowed'
endif
let a:inst.phase = a:nextPhase
endfunction
fun! xpt#rctx#InitOrderedGroupList(rctx)
let a:rctx.firstList = copy(a:rctx.snipSetting.comeFirst)
let a:rctx.lastList = copy(a:rctx.snipSetting.comeLast)
endfunction
fun! xpt#rctx#AddDefaultPHFilters(rctx,ph)
if a:ph.name == ''
return
endif
let pfs = a:rctx.snipSetting.postFilters
if !has_key(pfs,a:ph.name)
if a:ph.name =~ '\V\w\+?\$'
let pfs[ a:ph.name ] = xpt#flt#New( 0, "EchoIfNoChange('')" )
endif
endif
endfunction
fun! xpt#rctx#DefaultMarks(rctx)
if a:rctx.phase == s:phase.post
return 'mark'
else
return 'innerMarks'
endif
endfunction
fun! xpt#rctx#UserOut(rctx,text)
let a:rctx.nextStep = s:R_NEXT
let a:rctx.userPostAction = a:text
endfunction
fun! xpt#rctx#UserOutAppend(rctx,text)
call xpt#rctx#UserOut(a:rctx,a:rctx.userPostAction . a:text)
endfunction
fun! xpt#rctx#AddPHToGroup(rctx,ph)
throw "do not use me any more"
let g = xpt#rctx#GetGroup(a:rctx,a:ph.name)
call xpt#group#InsertPH(g,a:ph,len(g.placeHolders))
return g
endfunction
fun! xpt#rctx#GetGroup(rctx,name)
if has_key(a:rctx.itemDict,a:name)
let g = a:rctx.itemDict[a:name]
else
let g = xpt#group#New(a:name,a:rctx.buildingSessionID)
endif
call xpt#rctx#AddGroup(a:rctx,g)
return g
endfunction
fun! xpt#rctx#AddGroup(rctx,g)
let [rctx,g] = [a:rctx,a:g]
let exist = has_key(rctx.itemDict,g.name)
if g.name != ''
let rctx.itemDict[g.name] = g
endif
if rctx.phase != s:phase.rendering
call add(rctx.firstList,g)
call filter( ctx.groupList, 'v:val isnot g' )
return
endif
if exist
return
endif
if g.name == ''
call add(rctx.groupList,g)
elseif s:AddToOrderList(rctx.firstList,g) || s:AddToOrderList(rctx.lastList,g)
return
else
call add(rctx.groupList,g)
endif
endfunction
fun! s:AddToOrderList(list,g)
let i = index(a:list,a:g.name)
if i != -1
let a:list[i] = a:g
return 1
else
return 0
endif
endfunction
let &cpo = s:oldcpo

View file

@ -0,0 +1,140 @@
if exists( "g:__AL_XPT_RENDER_VIM__" ) && g:__AL_XPT_RENDER_VIM__ >= XPT#ver
finish
endif
let g:__AL_XPT_RENDER_VIM__ = XPT#ver
let s:oldcpo = &cpo
set cpo-=< cpo+=B
let s:log = xpt#debug#Logger( 'warn' )
let s:log = xpt#debug#Logger( 'debug' )
exe XPT#importConst
fun! xpt#render#New(rctx,posStart,...)
let p = copy(a:posStart)
let nSp = a:0 == 0 ? 0 : a:1
let render = { 'rctx':a:rctx, 'outerIndent':xpt#util#getIndentNr( p ) + nSp, 'relIndent':0, 'nSpaceToAdd':nSp, 'start':copy( p ), 'pos':copy( p ), 'rst':[ '' ], 'marks':[], }
let p[1] -= 1
let render.offset = p[1] == 0 ? 0 : virtcol(p) - render.outerIndent
return render
endfunction
let s:buildingSeqNr = 0
let s:anonymouseIndex = 0
fun! xpt#render#GenScreenData(render)
let rctx = a:render.rctx
call add(a:render.marks,[rctx.marks.tmpl.start, copy( a:render.pos ), 'l', '\Ve\$' ] )
let rctx.groupList = []
call xpt#render#GenScreenDataOfPHs(a:render,rctx.snipObject.parsedSnip)
call add(a:render.marks,[rctx.marks.tmpl.end, copy( a:render.pos ), 'r', '\Ve\$' ] )
return [a:render.rst,a:render.marks]
endfunction
fun! xpt#render#GenScreenDataOfPHs(render,phs)
let rctx = a:render.rctx
call xpt#rctx#InitOrderedGroupList(rctx)
call xpt#render#BuildPHs(a:render,a:phs)
call filter( rctx.firstList, 'type(v:val) != ' . string( type( '' ) ) )
call filter( rctx.lastList, 'type(v:val) != ' . string( type( '' ) ) )
let rctx.groupList = rctx.firstList + rctx.groupList + rctx.lastList
return [a:render.rst,a:render.marks]
endfunction
let s:buildingSessionID = 0
let s:renderStack = []
fun! xpt#render#BuildPHs(render,phs)
if empty(s:renderStack)
let s:buildingSessionID += 1
let a:render.rctx.itemDict = {}
endif
call add(s:renderStack,a:render)
let a:render.rctx.buildingSessionID = s:buildingSessionID
if a:render.nSpaceToAdd != 0
let phs = [ repeat( ' ', a:render.nSpaceToAdd ) ] + a:phs
else
let phs = a:phs
endif
let phs = xpt#snip#EvalPresetFilters(a:render.rctx,phs,{ 'outerIndent':a:render.outerIndent, 'offset':a:render.offset, 'variables':{ '$_xN_OUTER_INDENT':a:render.outerIndent, '$_xOUTER_INDENT':repeat( ' ', a:render.outerIndent ), '$_xN_OFFSET':a:render.offset, '$_xOFFSET':repeat( ' ', a:render.offset ), } })
for ph in phs
if type(ph) == type({})
call xpt#rctx#AddDefaultPHFilters(a:render.rctx,ph)
endif
unlet ph
endfor
let s:buildingSeqNr += 1
for ph in phs
if type( ph ) == type( '' )
call xpt#render#AppendText(a:render,ph)
else
call s:BuildPH(a:render,ph)
endif
unlet ph
endfor
call remove(s:renderStack,-1)
endfunction
fun! xpt#render#AppendFilter(render,flt)
call xpt#flt#Eval(a:flt,a:render.rctx.ftScope.funcs, { 'nIndAdd' : a:render.relIndent } )
let text = get( a:flt.rst, 'text', '' )
call xpt#render#AppendText(a:render,text)
endfunction
fun! xpt#render#AppendText(render,text)
if a:text =~ '\V\n'
call xpt#render#AppendMultiLine(a:render,a:text,a:render.outerIndent)
else
let a:render.rst[-1] .= a:text
let a:render.pos[1] += len(a:text)
endif
endfunction
fun! xpt#render#AppendMultiLine(render,text,nIndent)
if a:nIndent != 0
let text = xpt#util#AddIndent(a:text,a:nIndent)
else
let text = a:text
endif
let textLines = split( text, "\n", 1 )
let a:render.rst[-1] .= textLines[0]
call extend(a:render.rst,textLines[1 :])
call xpt#render#UpdatePosInfo(a:render)
endfunction
fun! xpt#render#UpdatePosInfo(render)
let a:render.pos = [a:render.start[0] + len(a:render.rst) - 1, len(a:render.rst[-1]) + 1]
let iNonspace = match( a:render.rst[ -1 ], '\v[^ ]' )
let a:render.relIndent = iNonspace == -1 ? XPT#Strlen(a:render.rst[-1]) : iNonspace
endfunction
fun! s:BuildPH(render,ph)
let [rctx,ph] = [a:render.rctx,a:ph]
let g = xpt#rctx#GetGroup(rctx,ph.name)
if g.sessid == rctx.buildingSessionID
call xpt#group#InsertPH(g,a:ph,len(g.placeHolders))
else
call xpt#group#InsertPH(g,a:ph,0)
endif
call s:CreatePHMarkNames(rctx,g,ph)
call add(a:render.marks,[ph.mark.start, copy( a:render.pos ), 'l' ] )
if has_key( ph, 'isKey' )
call s:Append( a:render, ph, 'leftEdge' )
call add(a:render.marks,[ph.editMark.start, copy( a:render.pos ), 'l' ] )
call xpt#render#AppendText( a:render, ph[ 'displayText' ] )
call add(a:render.marks,[ph.editMark.end, copy( a:render.pos ), 'r' ] )
call s:Append( a:render, ph, 'rightEdge' )
else
call xpt#render#AppendText( a:render, ph[ 'displayText' ] )
endif
call add(a:render.marks,[ph.mark.end, copy( a:render.pos ), 'r' ] )
endfunction
fun! s:CreatePHMarkNames(rctx,g,ph)
if a:ph.name == ''
let markName = '``' . s:anonymouseIndex
let s:anonymouseIndex += 1
else
let markName = a:ph.name . s:buildingSeqNr . '`' . ( has_key( a:ph, 'isKey' ) ? 'k' : ( len( a:g.placeHolders ) - 1 ) )
endif
let markPre = a:rctx.markNamePre . markName . '`'
call extend(a:ph, { 'mark' : { 'start' : markPre . 'os', 'end':markPre . 'oe', }, }, 'force' )
if has_key( a:ph, 'isKey' )
call extend(a:ph, { 'editMark' : { 'start' : markPre . 'is', 'end':markPre . 'ie', }, }, 'force' )
let a:ph.innerMarks = a:ph.editMark
else
let a:ph.innerMarks = a:ph.mark
endif
endfunction
fun! s:Append(render,ph,key)
if has_key(a:ph,a:key)
call xpt#render#AppendText(a:render,a:ph[a:key])
endif
endfunction
let &cpo = s:oldcpo

View file

@ -0,0 +1,47 @@
exec xpt#once#init
let s:oldcpo = &cpo
set cpo-=< cpo+=B
let s:log = xpt#debug#Logger( 'warn' )
fun! xpt#settingswitch#New()
return { 'settings':[], 'saved':[], }
endfunction
fun! xpt#settingswitch#Add(inst,key,value)
if a:inst.saved != []
throw "settings are already saved and can not be added again"
endif
let a:inst.settings += [[a:key,a:value]]
endfunction
fun! xpt#settingswitch#AddList(inst,...)
if a:inst.saved != []
throw "settings are already saved and can not be added again"
endif
for item in a:000
let a:inst.settings += [[item[0],item[1]]]
endfor
endfunction
fun! xpt#settingswitch#Switch(inst)
if a:inst.saved != []
return
endif
for [key,value] in a:inst.settings
call insert(a:inst.saved,[key,eval(key)])
if type( value ) == type( '' )
exe 'let ' key '=' string( value )
elseif type(value) == type({})
if has_key( value, 'exe' )
exe value.exe
endif
endif
unlet value
endfor
endfunction
fun! xpt#settingswitch#Restore(inst)
if a:inst.saved == []
return
endif
for setting in a:inst.saved
exe 'let '. setting[0] . '=' . string( setting[1] )
endfor
let a:inst.saved = []
endfunction
let &cpo = s:oldcpo

View file

@ -0,0 +1,236 @@
if exists( "g:__AL_XPT_SNIP_VIM__" ) && g:__AL_XPT_SNIP_VIM__ >= XPT#ver
finish
endif
let g:__AL_XPT_SNIP_VIM__ = XPT#ver
let s:oldcpo = &cpo
set cpo-=< cpo+=B
let s:log = xpt#debug#Logger( 'warn' )
let s:log = xpt#debug#Logger( 'debug' )
exe XPT#importConst
fun! xpt#snip#DefExt(name,setting,lines)
call xpt#st#Extend(a:setting)
call XPTdefineSnippet(a:name,a:setting,a:lines)
endfunction
fun! xpt#snip#New(name,ftScope,snipText,prio,setting,patterns)
return { 'name':a:name, 'compiled':0, 'parsed':0, 'ftScope':a:ftScope, 'rawSnipText':a:snipText, 'snipText':a:snipText, 'priority':a:prio, 'setting':a:setting, 'ptn':a:patterns, }
endfunction
fun! xpt#snip#NewSlave(master,snipText)
return xpt#snip#New( '', a:master.ftScope, a:snipText, 0, a:master.setting,a:master.ptn)
endfunction
fun! xpt#snip#CompileAndParse(so)
if !a:so.parsed
if !a:so.compiled
call xpt#snip#Compile(a:so)
endif
call xpt#snip#Parse(a:so)
endif
endfunction
fun! xpt#snip#Compile(so)
call xpt#ftsc#Init(a:so.ftScope)
if a:so.snipText == ''
let a:so.compiledSnip = [ '' ]
return
endif
let rawLines = s:SplitLines(a:so)
let nIndent = len( matchstr( rawLines[0][0], '\V\^\s\*' ) )
let [l,r] = [a:so.ptn.l,a:so.ptn.r]
let [i,j,nlines,nitems] = [0,0,len(rawLines),len(rawLines[0])]
let [ st, linesCompiled ] = [ 'LeftEdge', [] ]
let buf = [ { 'nIndent' : 0, 'text' : '' } ]
while 1
let elt = rawLines[i][j]
let firstChar = matchstr( elt, '\v.' )
if firstChar == l
if st == 'LeftEdge'
let st = 'Name'
let texts = deepcopy(buf)
call map( texts, 'v:val.text' )
call extend(linesCompiled,texts)
let buf = [ { 'nIndent' : nIndent, 'text' : elt[ 1 : ] } ]
elseif st == 'Name'
call add( buf, { 'nIndent' : nIndent, 'text' : elt[ 1 : ] } )
elseif st == 'Filter'
let st = 'LeftEdge'
let followingText = buf[-1].text[1 :]
let buf[-1].text = buf[-1].text[0 : 0]
call add(linesCompiled,xpt#ph#New(a:so,buf))
let buf = [ { 'nIndent' : nIndent, 'text' : followingText } ]
continue
endif
elseif firstChar == r
if st == 'Name'
let st = 'Filter'
continue
elseif st == 'Filter'
call add( buf, { 'nIndent' : nIndent, 'text' : elt } )
endif
else
let buf[-1].text .= rawLines[i][j]
endif
let j += 1
if j >= nitems
let [i,j] = [i + 1,0]
if i >= nlines
break
endif
let buf[ -1 ].text .= "\n"
let [nIndent,nitems] = [ len( matchstr( rawLines[ i ][ 0 ], '\V\^\s\*' ) ), len( rawLines[ i ] ) ]
endif
endwhile
call filter( linesCompiled, 'len(v:val) > 0' )
let rst = []
for e in linesCompiled
call add(rst, type(e) == type({}) ? e : xpt#util#UnescapeChar(e,a:so.ptn.lr))
unlet e
endfor
let a:so.compiledSnip = rst
let a:so.compiled = 1
endfunction
fun! xpt#snip#TextToPlaceholders(text,ptn)
let [l,r] = [a:ptn.l,a:ptn.r]
let lr = l . r
let toks = xpt#snip#Tokenize(a:text, a:ptn) + ["", "", ""]
let elts = []
let buf = []
let i = -1
while i < len(toks) - 1
let i += 1
let tok = toks[i]
let chr = tok[0]
if chr != l && chr != r
if tok != ""
call add(elts, {'text': xpt#util#UnescapeChar(tok, lr)})
endif
continue
endif
if chr == l
call add(buf, {'text': xpt#util#UnescapeChar(tok[1:], lr)})
continue
endif
let ph = s:EltsToPh(buf)
call add(elts,ph)
let buf = []
if toks[i+1][0] == l
continue
endif
if toks[i + 1] == r
let [flt, iFilterEnd] = [{'text': ''}, i + 1]
else
if toks[i + 2] == r
let [flt, iFilterEnd] = [{'text': xpt#util#UnescapeChar(toks[i + 1], lr)}, i + 2]
else
continue
endif
end
if toks[iFilterEnd + 1] == r
let ph.postFilter = flt
let i = iFilterEnd + 1
else
let ph.liveFilter = flt
let i = iFilterEnd
endif
endwhile
return elts
endfunction
fun! s:EltsToPh(buf)
let buf = a:buf
if len(buf) == 0
throw 'xpt#snip#Unexpected: ' . r
elseif len(buf) == 1
let ph = { 'name': buf[0] }
elseif len(buf) == 2
let ph = { 'leftEdge': buf[0], 'name': buf[1] }
elseif len(buf) == 3
let ph = { 'leftEdge': buf[0], 'name': buf[1], 'rightEdge': buf[2] }
else
throw 'xpt#snip#TooMany: ' . string(buf)
endif
return ph
endfunction
fun! xpt#snip#Parse(so)
let a:so.parsedSnip = a:so.compiledSnip
let a:so.parsedSnip = xpt#snip#ReplacePH(a:so,a:so.setting.replacements)
let a:so.parsedSnip = xpt#snip#EvalInstantFilters(a:so)
let a:so.parsedSnip = xpt#snip#PostQuote(a:so)
let a:so.parsedSnip = xpt#snip#Repetition(a:so)
let a:so.parsed = 1
endfunction
fun! xpt#snip#ReplacePH(so,repls)
let phs = xpt#phfilter#Filter(a:so, 'xpt#phfilter#ReplacePH', { 'replParams' : a:repls } )
return phs
endfunction
fun! xpt#snip#EvalInstantFilters(so)
let phs = xpt#phfilter#Filter(a:so, 'xpt#phfilter#EvalInstantFilters', {'skip' : a:so.ptn.item_func . '\|$_x\w', 'forceNotSkip' : s:ptnPreEvalFunc } )
return phs
endfunction
fun! xpt#snip#PostQuote(so)
let pqContext = { 'pqStack' : [ [] ] }
let pqContext.rstPHs = pqContext.pqStack[0]
let phs = xpt#phfilter#Filter(a:so, 'xpt#phfilter#PostQuote', pqContext )
return phs
endfunction
fun! xpt#snip#Repetition(so)
let repContext = { 'repStack' : [ [] ], 'repHeads' : {} }
let repContext.rstPHs = repContext.repStack[0]
let phs = xpt#phfilter#Filter(a:so, 'xpt#phfilter#Repetition', repContext )
return phs
endfunction
fun! xpt#snip#EvalPresetFilters(rctx,phs,ctx)
let ctx = { 'rctx':a:rctx, 'srcPHs':a:phs, 'snipSetting':a:rctx.snipSetting, 'phEvalContext':a:ctx, }
let phs = xpt#phfilter#Filter(a:rctx.snipObject, 'xpt#phfilter#EvalPresetFilters', ctx )
return phs
endfunction
fun! xpt#snip#DumbCursorInPlace(so,phs)
for ph in a:phs
if type(ph) == type({}) && ph.name is 'cursor'
let ph.name = ''
let ph.displayText = ph.name
endif
unlet ph
endfor
endfunction
fun! xpt#snip#ParseInclusionStatement(so,statement)
let phptns = a:so.ptn
let ptn = '\V\^\[^(]\{-}('
let statement = a:statement
if statement =~ ptn && statement[ -1 : -1 ] == ')'
let name = matchstr(statement,ptn)[: -2]
let paramStr = statement[len(name) + 1 : -2]
let paramStr = xpt#util#UnescapeChar(paramStr,phptns.lr)
let params = {}
try
let params = eval(paramStr)
catch /.*/
XPT#info( 'XPT: Invalid parameter: ' . string( paramStr ) . ' Error=' . v:exception )
endtry
return [name,params]
else
return [statement,{}]
endif
endfunction
fun! s:SplitLines(so)
let delimiter = '\V\ze' . a:so.ptn.lft . '\|\ze' . a:so.ptn.rt
let lines = split( a:so.snipText, "\n", 1 )
call map( lines, 'split(v:val, delimiter, 1)' )
let lines[-1] += [a:so.ptn.l]
return lines
endfunction
fun! xpt#snip#Tokenize(text,ptn)
let delimiter = '\V\ze' . a:ptn.lft . '\|\ze' . a:ptn.rt
let toks = split(a:text,delimiter,0)
if len(toks) == 0
return ['']
end
let rst = []
for tok in toks
if tok == a:ptn.r
call add(rst,tok)
elseif tok[0] == a:ptn.r
call extend(rst,[a:ptn.r,tok[1:]])
else
call add(rst,tok)
end
endfor
return rst
endfunction
let &cpo = s:oldcpo

View file

@ -0,0 +1,26 @@
exec xpt#once#init
let s:oldcpo = &cpo
set cpo-=< cpo+=B
let s:log = xpt#debug#Logger( 'warn' )
exec XPT#importConst
fun! xpt#snipfile#New(filename)
let r = { 'filename':a:filename, 'ptn':xpt#snipfile#GenPattern( {'l':'`', 'r':'^'} ), 'priority':xpt#priority#Get('default'), 'filetype':'', 'inheritFT':0, }
return r
endfunction
fun! xpt#snipfile#Push()
let x = b:xptemplateData
let x.snipFileScopeStack += [x.snipFileScope]
unlet x.snipFileScope
endfunction
fun! xpt#snipfile#Pop()
let x = b:xptemplateData
if len(x.snipFileScopeStack) > 0
let x.snipFileScope = remove(x.snipFileScopeStack,-1)
else
throw "snipFileScopeStack is empty"
endif
endfunction
fun! xpt#snipfile#GenPattern(marks)
return { 'l':a:marks.l, 'r':a:marks.r, 'lr':a:marks.l . a:marks.r, 'lft':'\V' . s:nonEscaped . a:marks.l, 'rt':'\V' . s:nonEscaped . a:marks.r, 'item_var':'\V' . '$\w\+', 'item_qvar':'\V' . '{$\w\+}', 'item_func':'\V' . '\w\+(\.\*)', 'item_qfunc':'\V' . '{\w\+(\.\*)}', 'itemContent':'\V' . '\_.\{-}', 'item':'\V' . s:nonEscaped . a:marks.l . '\%(' . '\_.\{-}' . '\)' . s:nonEscaped . a:marks.r, }
endfunction
let &cpo = s:oldcpo

View file

@ -0,0 +1,465 @@
if exists( "g:__AL_XPT_SNIPFUNC_VIM__" ) && g:__AL_XPT_SNIPFUNC_VIM__ >= XPT#ver
finish
endif
let g:__AL_XPT_SNIPFUNC_VIM__ = XPT#ver
let s:oldcpo = &cpo
set cpo-=< cpo+=B
let s:log = xpt#debug#Logger( 'warn' )
let s:log = xpt#debug#Logger( 'debug' )
fun! xpt#snipfunc#Extend(container)
call extend( a:container, s:f, 'keep' )
endfunction
let s:f = {}
fun! s:f.Pre(a)
return a:a
endfunction
fun! s:f.SnipObject()
return self.phFilterContext isnot 0 ? self.phFilterContext.snipObject : self.renderContext.snipObject
endfunction
fun! s:f.PHs(snipText)
let so = self.SnipObject()
let slave = xpt#snip#NewSlave(so,a:snipText)
call xpt#snip#CompileAndParse(slave)
return slave.parsedSnip
endfunction
fun! s:f.Inline(snipText)
return { 'action' : 'embed', 'phs' : self.PHs( a:snipText ) }
endfunction
fun! s:f.Inc(targetName,keepCursor,params)
let so = self.SnipObject()
let snipDict = so.ftScope.allTemplates
if has_key(snipDict,a:targetName)
let tsnip = snipDict[a:targetName]
call xpt#snip#CompileAndParse(tsnip)
let phs = xpt#phfilter#Filter( tsnip, 'xpt#phfilter#ReplacePH', { 'replParams' : a:params } )
if !a:keepCursor
call xpt#snip#DumbCursorInPlace(tsnip,phs)
endif
call xpt#st#Merge(so.setting,tsnip.setting)
return { 'action' : 'embed', 'nIndent' : 0, 'phs' : phs }
else
return 0
endif
endfunction
fun! s:f.GetDict(...)
return
endfunction
fun! s:f.GetVar(name)
if a:name =~# '\V\^$_x'
let n = a:name[1 :]
if has_key(self,n)
return self[n]()
endif
endif
let varScopes = []
if has_key( self, 'evalContext' )
call add(varScopes,self.evalContext.variables)
endif
if has_key( self, 'renderContext' )
call add( varScopes, get( self.renderContext.snipSetting, 'variables', {} ) )
endif
call add(varScopes,self)
for sc in varScopes
let val = get(sc,a:name)
if val isnot 0
return val
endif
endfor
return a:name
endfunction
fun! s:f._xSnipName()
return self.renderContext.snipObject.name
endfunction
fun! s:f.EmbedWrappedText()
let wrapData = self.renderContext.userWrapped
if !has_key( wrapData, 'text' )
return 0
endif
let ph = self.phFilterContext.ph
if has_key( ph, 'isKey' )
let n = len(wrapData.lines)
let nIndent = self.phFilterContext.phEvalContext.pos[1] - self.phFilterContext.phEvalContext.nIndAdd
if self.phFilterContext.phEvalContext.pos[0] == 0
let nIndent += self.phFilterContext.phEvalContext.offset
endif
let sep = "\n"
let ph = extend(deepcopy(ph),{ 'name':'', 'value':1, }, 'force' )
unlet ph.isKey
let newPHs = []
let i = 0
while i < n
let newph = extend(deepcopy(ph),{ 'displayText':wrapData.lines[ i ], }, 'force' )
call extend(newPHs,[newph,sep])
let i += 1
endwhile
call remove(newPHs,-1)
return { 'action' : 'embed', 'nIndent' : nIndent, 'phs' : newPHs }
else
return { 'nIndent' : wrapData.indent, 'text':wrapData.text }
endif
endfunction
fun! s:f.WrapAlignAfter(min)
let userWrapped = self.renderContext.userWrapped
let n = max([a:min,userWrapped.max]) - len(userWrapped.curline)
return repeat( ' ', n )
endfunction
fun! s:f.WrapAlignBefore(min)
let userWrapped = self.renderContext.userWrapped
let n = max([a:min,userWrapped.max]) - len(userWrapped.lines[0])
return repeat( ' ', n )
endfunction
fun! s:f.Item()
return get( self.renderContext, 'item', {} )
endfunction
fun! s:f.ItemName()
return get( self.Item(), 'name', '' )
endfunction
fun! s:f.ItemFullname()
return get( self.Item(), 'fullname', '')
endfunction
fun! s:f.ItemValue() dict
return get( self.evalContext, 'userInput', '' )
endfunction
fun! s:f.PrevItem(n)
let hist = get( self.renderContext, 'history', [] )
return get(hist,a:n,{})
endfunction
fun! s:f.ItemInitValue()
return get( self.Item(), 'initValue', '' )
endfunction
fun! s:f.ItemInitValueWithEdge()
let [l,r] = self.ItemEdges()
return l . self.ItemInitValue() . r
endfunction
fun! s:f.ItemValueStripped(...)
let ptn = a:0 == 0 || a:1 =~ 'lr' ? '\V\^\s\*\|\s\*\$' : ( a:1 == 'l' ? '\V\^\s\*' : '\V\s\*\$' )
return substitute( self.ItemValue(), ptn, '', 'g' )
endfunction
fun! s:f.ItemPos()
return XPMposStartEnd(self.renderContext.leadingPlaceHolder.mark)
endfunction
fun! s:f.Vmatch(...)
let v = self.V()
for reg in a:000
if match(v,reg) != -1
return 1
endif
endfor
return 0
endfunction
fun! s:f.VMS(reg)
return matchstr(self.V(),a:reg)
endfunction
fun! s:f.ItemStrippedValue()
let v = self.V()
let [edgeLeft,edgeRight] = self.ItemEdges()
let v = substitute( v, '\V\^' . edgeLeft, '', '' )
let v = substitute( v, '\V' . edgeRight . '\$', '', '' )
return v
endfunction
fun! s:f.Phase() dict
return get( self.renderContext, 'phase', '' )
endfunction
fun! s:f.E(s)
return expand(a:s)
endfunction
fun! s:f.Context()
return self.renderContext
endfunction
fun! s:f.S(str,ptn,rep,...)
let flg = a:0 >= 1 ? a:1 : 'g'
return substitute(a:str,a:ptn,a:rep,flg)
endfunction
fun! s:f.SubstituteWithValue(ptn,rep,...)
let flg = a:0 >= 1 ? a:1 : 'g'
return substitute(self.V(),a:ptn,a:rep,flg)
endfunction
fun! s:f.HasStep(name)
let namedStep = get( self.renderContext, 'namedStep', {} )
return has_key(namedStep,a:name)
endfunction
fun! s:f.Reference(name)
let namedStep = get( self.renderContext, 'namedStep', {} )
return get( namedStep, a:name, '' )
endfunction
fun! s:f.Snippet(name)
return get( self.renderContext.ftScope.allTemplates, a:name, { 'tmpl' : '' } )[ 'tmpl' ]
endfunction
fun! s:f.Void(...)
return ""
endfunction
fun! s:f.Echo(...)
if a:0 > 0
return a:1
else
return ''
endif
endfunction
fun! s:f.EchoIf(isTrue,...)
if a:isTrue
return join( a:000, '' )
else
return self.V()
endif
endfunction
fun! s:f.EchoIfEq(expected,...)
if self.V() ==# a:expected
return join( a:000, '' )
else
return self.V()
endif
endfunction
fun! s:f.EchoIfNoChange(...)
if self.V0() ==# self.ItemName()
return join( a:000, '' )
else
return self.V()
endif
endfunction
fun! s:f.Commentize(text)
if has_key( self, '$CL' )
return self[ '$CL' ] . ' ' . a:text . ' ' . self[ '$CR' ]
elseif has_key( self, '$CS' )
return self[ '$CS' ] . ' ' . a:text
endif
return a:text
endfunction
fun! s:f.VoidLine()
return self.Commentize( 'void' )
endfunction
fun! s:f.Empty()
return self.ItemValue() == ''
endfunction
fun! s:f.IsChanged()
let initFull = self.ItemInitValueWithEdge()
let v = self.ItemValue()
return initFull !=# v
endfunction
fun! s:f.EmbedPHs(phsID)
let snipObject = self.renderContext.snipObject
return { 'action' : 'embed', 'phs':xpt#ftsc#GetPHPieces( snipObject.ftScope, a:phsID ) }
endfunction
fun! s:f.Build(...)
return { 'action' : 'build', 'text' : join( a:000, '' ) }
endfunction
fun! s:f.BuildIfChanged(...)
let v = substitute( self.V(), "\\V\n\\|\\s", '', 'g')
let fn = substitute( self.ItemInitValueWithEdge(), "\\V\n\\|\\s", '', 'g')
if v ==# fn || v == ''
return ''
else
return { 'action' : 'build', 'text' : join( a:000, '' ) }
endif
endfunction
fun! s:f.BuildIfNoChange(...)
let v = substitute( self.V(), "\\V\n\\|\\s", '', 'g')
let fn = substitute( self.ItemInitValueWithEdge(), "\\V\n\\|\\s", '', 'g')
if v ==# fn
return { 'action' : 'build', 'text' : join( a:000, '' ) }
else
return 0
endif
endfunction
fun! s:f.Trigger(name)
return {'action' : 'expandTmpl', 'tmplName' : a:name}
endfunction
fun! s:f.Finish(...)
return self.FinishPH( a:0 > 0 ? { 'text' : a:1 } : {} )
endfunction
fun! s:f.FinishOuter(...)
return self.FinishPH(a:0 > 0 ? { 'text' : a:1, 'marks' : 'mark' } : { 'marks' : 'mark' } )
endfunction
fun! s:f.FinishPH(opt)
let opt = a:opt
if empty(self.renderContext.groupList)
let o = { 'action' : g:XPTact.finishPH }
call extend( o, opt, 'keep' )
return o
else
return get( opt, 'text', 0 )
endif
endfunction
fun! s:f.Embed(snippetText)
return { 'action' : g:XPTact.embed, 'text' : a:snippetText }
endfunction
fun! s:f.Next(...)
let rst = { 'action' : 'next' }
if a:0 > 0
let phs = deepcopy(a:000)
call filter( phs, 'type(v:val)==' . type( '' ) )
if len(phs) < len(a:000)
let rst.phs = a:000
else
let text = join( a:000, '' )
let so = self.SnipObject()
if match(text,so.ptn.lft) >= 0
let rst.phs = self.PHs(text)
else
let rst.text = text
endif
endif
endif
return rst
endfunction
fun! s:f.Remove()
return { 'action' : 'remove' }
endfunction
fun! s:f.Choose(lst,...)
let val = { 'action' : 'pum', 'pum' : a:lst }
if a:0 == 1
let val.acceptEmpty = a:1 != 0
endif
return val
endfunction
fun! s:f.ChooseStr(...)
return copy(a:000)
endfunction
fun! s:f.Complete(key,...)
let val = { 'action' : 'complete', 'pum' : a:key }
if a:0 == 1
let val.acceptEmpty = a:1 != 0
endif
return val
endfunction
fun! s:f.xptFinishTemplateWith(postType) dict
endfunction
fun! s:f.xptFinishItemWith(postType) dict
endfunction
fun! s:f.UnescapeMarks(string) dict
let patterns = self.renderContext.snipObject.ptn
let charToEscape = '\(\[' . patterns.l . patterns.r . ']\)'
let r = substitute( a:string, '\v(\\*)\1\\?\V' . charToEscape, '\1\2', 'g')
return r
endfunction
fun! s:f.headerSymbol(...)
let h = expand('%:t')
let h = substitute(h, '\.', '_', 'g') " replace . with _
let h = substitute(h, '.', '\U\0', 'g') " make all characters upper case
return '__'.h.'__'
endfunction
fun! s:f.date(...)
return strftime( self.GetVar( '$DATE_FMT' ) )
endfunction
fun! s:f.datetime(...)
return strftime( self.GetVar( '$DATETIME_FMT' ) )
endfunction
fun! s:f.time(...)
return strftime( self.GetVar( '$TIME_FMT' ) )
endfunction
fun! s:f.file(...)
return expand("%:t")
endfunction
fun! s:f.fileRoot(...)
return expand("%:t:r")
endfunction
fun! s:f.fileExt(...)
return expand("%:t:e")
endfunction
fun! s:f.path(...)
return expand("%:p")
endfunction
fun! s:f.UpperCase(v)
return substitute(a:v, '.', '\u&', 'g')
endfunction
fun! s:f.LowerCase(v)
return substitute(a:v, '.', '\l&', 'g')
endfunction
fun! s:f.ItemEdges()
let leader = get( self.renderContext, 'leadingPlaceHolder', {} )
if has_key( leader, 'leftEdge' )
return [leader.leftEdge,leader.rightEdge]
else
return [ '', '' ]
endif
endfunction
fun! s:f.ItemCreate(name,edges,filters)
let [ml,mr] = XPTmark()
let item = ml . a:name
if has_key( a:edges, 'left' )
let item = ml . a:edges.left . item
endif
if has_key( a:edges, 'right' )
let item .= ml . a:edges.right
endif
let item .= mr
if has_key( a:filters, 'post' )
let item .= a:filters.post . mr . mr
endif
return item
endfunction
fun! s:f.ExpandIfNotEmpty(sep,item,...)
let v = self.V()
let [ml,mr] = XPTmark()
if a:0 != 0
let r = a:1
else
let r = ''
endif
let t = ( v == '' || v =~ '\V' . a:item ) ? '' : self.Build(v . ml . a:sep . ml . a:item . ml . r . mr . 'ExpandIfNotEmpty(' . string( a:sep ) . ', ' . string( a:item ) . ')' . mr . mr )
return t
endfunction
fun! s:f.ExpandInsideEdge(newLeftEdge,newRightEdge)
let v = self.V()
let fullname = self.ItemFullname()
let [el,er] = self.ItemEdges()
if v ==# fullname || v == ''
return ''
endif
return substitute( v, '\V' . er . '\$' , '' , '' ) . self.ItemCreate( self.ItemName(), { 'left' : a:newLeftEdge, 'right' : a:newRightEdge }, {} ) . er
endfunction
fun! s:f.NIndent()
return &shiftwidth
endfunction
fun! s:f.ResetIndent(nIndent,text)
return { 'action' : 'resetIndent', 'resetIndent':1, 'nIndent' : a:nIndent, 'text' : a:text }
endfunction
fun! s:f.CmplQuoter_pre() dict
if !g:xptemplate_brace_complete
return ''
endif
let v = substitute( self.ItemStrippedValue(), '\V\^\s\*', '', '' )
let first = matchstr( v, '\V\^\[''"]' )
if first == ''
return ''
endif
let v = substitute( v, '\V\[^' . first . ']', '', 'g' )
if v == first
return first
else
return ''
endif
endfunction
fun! s:f.AutoCmpl(keepInPost,list,...)
if !a:keepInPost && self.Phase() == 'post'
return ''
endif
if type(a:list) == type([])
let list = a:list
else
let list = [a:list] + a:000
endif
let v = self.V0()
if v == ''
return ''
endif
for word in list
if word =~ '\V\^' . v
return word[len(v) :]
endif
endfor
return ''
endfunction
let s:f.Edges = s:f.ItemEdges
let s:f.UE = s:f.UnescapeMarks
let s:f.VOID = s:f.Void
let s:f.R = s:f.Reference
let s:f.SV = s:f.SubstituteWithValue
let s:f.C = s:f.Context
let s:f.V0 = s:f.ItemStrippedValue
let s:f.IVE = s:f.ItemInitValueWithEdge
let s:f.VS = s:f.ItemValueStripped
let s:f.IV = s:f.ItemInitValue
let s:f.V = s:f.ItemValue
let s:f.NN = s:f.ItemFullname
let s:f.N = s:f.ItemName
let &cpo = s:oldcpo

View file

@ -0,0 +1,29 @@
exec xpt#once#init
let s:oldcpo = &cpo
set cpo-=< cpo+=B
let s:f = xpt#snipfunction#funcs
let s:num_keys = { "nIndent" : 1, "parseIndent" : 1, }
let s:action_names = { "build" : 1, "pum" : 1, "text" : 1, "next" : 1, "remove" : 1, "finishTemplate" : 1, }
fun! s:f.Action(...)
let rst = {}
for kvs in a:000
if type(kvs) == type({})
call extend(rst, kvs, 'force')
continue
endif
for kv in split(kvs, ' ', 0)
if has_key(s:action_names,kv)
let rst.action = kv
else
let [k, v] = split(kv, '=', 1)
if has_key(s:num_keys,k)
let rst[k] = v + 0
else
let rst[k] = v
endif
endif
endfor
endfor
return rst
endfunction
let &cpo = s:oldcpo

View file

@ -0,0 +1,69 @@
if exists( "g:__AL_XPT_EVALSUPPORT_f67523jhrk" ) && g:__AL_XPT_EVALSUPPORT_f67523jhrk >= 1
finish
endif
let g:__AL_XPT_EVALSUPPORT_f67523jhrk = 1
let s:oldcpo = &cpo
set cpo-=< cpo+=B
let s:f = xpt#snipfunction#funcs
fun! s:f.GetVar(name)
if a:name =~# '\V\^$_x'
let n = a:name[1 :]
return self.Call(n,[])
endif
let closures = self._ctx.closures
let i = len(closures)
while i > 0
let i = i - 1
let c = closures[i]
let v = get(c,a:name,0)
if v isnot 0
return v
endif
endwhile
return ''
endfunction
fun! s:f.Call(name,args)
let F = get(self,a:name,0)
if type(F) == type(function('tr'))
return call(F,a:args,self)
else
return call(function(a:name),a:args)
endif
endfunction
fun! s:f.Concat(...)
let lst = a:000
if len(lst) == 0
return ''
endif
let rst = {}
for e in lst
if type(e) == type(0)
if e == 0
return 0
else
let elt = string(e)
endif
else
let elt = e
endif
if type(elt) == type('')
let rst.text = get(rst, 'text', '') . elt
elseif type(elt) == type([])
let rst.action = get(rst, 'action', 'pum')
let rst.pum = get(rst, 'pum', elt)
else
if has_key(rst, 'text') && has_key(elt, 'text')
let rst.text .= elt.text
endif
call extend(rst, elt, 'keep')
endif
unlet e
unlet elt
endfor
let ks = keys(rst)
if len(ks) == 1 && ks[0] == 'text'
return rst.text
end
return rst
endfunction
let &cpo = s:oldcpo

View file

@ -0,0 +1,10 @@
if exists( "g:__AL_XPT_EVAL_y732hj43k__" ) && g:__AL_XPT_EVAL_y732hj43k__ >= XPT#ver
finish
endif
let g:__AL_XPT_EVAL_y732hj43k__ = XPT#ver
let s:oldcpo = &cpo
set cpo-=< cpo+=B
let s:f = {}
let xpt#snipfunction#funcs = s:f
runtime! autoload/xpt/snipfuncs/*
let &cpo = s:oldcpo

View file

@ -0,0 +1,16 @@
if exists( "g:__AL_XPT_SNIPLINE_VIM__" ) && g:__AL_XPT_SNIPLINE_VIM__ >= XPT#ver
finish
endif
let g:__AL_XPT_SNIPLINE_VIM__ = XPT#ver
let s:oldcpo = &cpo
set cpo-=< cpo+=B
let s:log = xpt#debug#Logger( 'warn' )
fun! xpt#snipline#New(elts)
if len(a:elts) == 0 || type(a:elts[0]) == type({})
let nIndent = 0
else
let nIndent = len( matchstr( a:elts[ 0 ], '\V\^ \*' ) )
endif
return { 'nIndent' : nIndent, 'elts' : a:elts }
endfunction
let &cpo = s:oldcpo

View file

@ -0,0 +1,113 @@
if exists( "g:__AL_XPT_ST_VIM__" ) && g:__AL_XPT_ST_VIM__ >= XPT#ver
finish
endif
let g:__AL_XPT_ST_VIM__ = XPT#ver
let s:oldcpo = &cpo
set cpo-=< cpo+=B
let s:log = xpt#debug#Logger( 'warn' )
exe XPT#importConst
let s:proto = { 'hidden':0, 'variables':{}, 'preValues':{}, 'onfocusFilters':{}, 'mappings':{}, 'liveFilters':{}, 'postFilters':{}, 'replacements':{}, 'postQuoter':{}, 'comeFirst':[], 'comeLast':[], }
let s:protoDefault = { 'preValues':{ 'cursor' : xpt#flt#New( 0, '$CURSOR_PH' ) }, 'onfocusFilters':{ 'cursor' : xpt#flt#New( 0, 'FinishPH({"text":""})' ) }, 'postQuoter':{ 'start' : '{{', 'end' : '}}' }, }
fun! xpt#st#New()
return deepcopy(s:proto)
endfunction
fun! xpt#st#Extend(setting)
for k in [ 'preValues', 'onfocusFilters', 'liveFilters', 'postFilters' ]
if has_key(a:setting,k)
for val in values(a:setting[k])
call xpt#flt#Extend(val)
endfor
endif
endfor
if has_key( a:setting, 'mappings' )
for phMapping in values(a:setting.mappings)
for mapFilter in values(phMapping.keys)
call xpt#flt#Extend(mapFilter)
endfor
endfor
endif
call extend( a:setting, deepcopy( s:proto ), 'keep' )
for [k,v] in items(s:protoDefault)
call extend( a:setting[ k ], deepcopy( v ), 'keep' )
endfor
endfunction
fun! xpt#st#RenderPhaseCopy(setting)
let setting = copy(a:setting)
for k in [ 'variables', 'preValues', 'onfocusFilters' , 'liveFilters', 'postFilters', 'comeFirst', 'comeLast' ]
let setting[k] = copy(setting[k])
endfor
let x = b:xptemplateData
if x.currentExt != {}
let setting.variables[ '$EXT' ] = x.currentExt.ext
let x.currentExt = {}
endif
return setting
endfunction
fun! xpt#st#What()
endfunction
fun! xpt#st#Simplify(setting)
call filter( a:setting, '!has_key(s:proto,v:key) || v:val!=s:proto[v:key]' )
endfunction
fun! xpt#st#Merge(setting,fromSettings)
let a:setting.comeFirst += a:fromSettings.comeFirst
let a:setting.comeLast = a:fromSettings.comeLast + a:setting.comeLast
call xpt#st#InitItemOrderList(a:setting)
call extend( a:setting.preValues, a:fromSettings.preValues, 'keep' )
call extend( a:setting.onfocusFilters, a:fromSettings.onfocusFilters, 'keep' )
call extend( a:setting.postFilters, a:fromSettings.postFilters, 'keep' )
call extend( a:setting.variables, a:fromSettings.variables, 'keep' )
for key in keys(a:fromSettings.mappings)
if !has_key(a:setting.mappings,key)
let a:setting.mappings[key] = { 'saver' : xpt#msvr#New( 1 ), 'keys' : {} }
endif
for keystroke in keys(a:fromSettings.mappings[key].keys)
let a:setting.mappings[key].keys[keystroke] = a:fromSettings.mappings[key].keys[keystroke]
call xpt#msvr#Add( a:setting.mappings[ key ].saver, 'i', keystroke )
endfor
endfor
endfunction
fun! xpt#st#Parse(setting,snipObject)
let st = a:setting
if get( st, 'wraponly' ) isnot 0
call extend( st, { 'iswrap' : 1, 'iswraponly' : 1, 'wrapPH' : st.wraponly }, 'force' )
elseif get( st, 'wrap' ) isnot 0
call extend( st, { 'iswrap' : 1, 'iswraponly' : 0, 'wrapPH' : st.wrap }, 'force' )
else
call extend( st, { 'iswrap' : 0, 'iswraponly' : 0 }, 'force' )
endif
if st.iswrap && st.wrapPH is 1
let st.wrapPH = 'cursor'
endif
if has_key(st, 'rawHint')
if st.rawHint =~ s:regEval
let x = b:xptemplateData
let x.renderContext.snipObject = a:snipObject
let st.hint = xpt#eval#Eval(st.rawHint, x.filetypes[x.snipFileScope.filetype].funcs, { 'variables' : st.variables } )
else
let st.hint = xpt#util#UnescapeChar(st.rawHint,s:nonsafe)
endif
endif
call xpt#st#ParsePostQuoter(st)
if has_key( st, 'extension' )
let ext = st.extension
let a:snipObject.ftScope.extensionTable[ext] = get(a:snipObject.ftScope.extensionTable,ext,[])
let a:snipObject.ftScope.extensionTable[ext] += [a:snipObject.name]
endif
endfunction
fun! xpt#st#ParsePostQuoter(setting)
if !has_key( a:setting, 'postQuoter' ) || type(a:setting.postQuoter) == type({})
return
endif
let quoters = split( a:setting.postQuoter, ',' )
if len(quoters) < 2
throw 'postQuoter must be separated with ","! :' . a:setting.postQuoter
endif
let a:setting.postQuoter = { 'start' : quoters[0], 'end' : quoters[1] }
endfunction
fun! xpt#st#InitItemOrderList(setting)
call filter( a:setting.comeLast, 'v:val!="cursor"' )
call add( a:setting.comeLast, 'cursor' )
let a:setting.comeFirst = xpt#util#RemoveDuplicate(a:setting.comeFirst)
let a:setting.comeLast = xpt#util#RemoveDuplicate(a:setting.comeLast)
endfunction
let &cpo = s:oldcpo

View file

@ -0,0 +1,244 @@
exe xpt#once#init
let s:oldcpo = &cpo
set cpo-=< cpo+=B
let s:log = xpt#debug#Logger( 'warn' )
exe XPT#importConst
let s:charsPatternTable = {}
fun! xpt#util#Flatten(arr)
let r = []
for e in a:arr
if type(e) == 3
call extend(r,xpt#util#Flatten(e))
else
let r += [e]
endif
unlet e
endfor
return r
endfunction
fun! xpt#util#SplitWith(str,char)
let s = split( a:str, '\V' . s:nonEscaped . a:char, 1 )
return s
endfunction
fun! xpt#util#UnescapeChar(str,chars)
if a:chars == ""
return a:str
endif
if has_key(s:charsPatternTable,a:chars)
return substitute( a:str, s:charsPatternTable[ a:chars ], '\1', 'g' )
else
return substitute( a:str, s:GetUnescapeCharPattern( a:chars ), '\1', 'g' )
endif
endfunction
fun! xpt#util#DeepExtend(to,from)
for key in keys(a:from)
if type(a:from[key]) == 4
if has_key(a:to,key)
call xpt#util#DeepExtend(a:to[key],a:from[key])
else
let a:to[key] = a:from[key]
endif
elseif type(a:from[key]) == 3
if has_key(a:to,key)
call extend(a:to[key],a:from[key])
else
let a:to[key] = a:from[key]
endif
else
let a:to[key] = a:from[key]
endif
endfor
endfunction
fun! xpt#util#RemoveDuplicate(list)
let dict = {}
let newList = []
for e in a:list
if !has_key(dict,e)
call add(newList,e)
endif
let dict[e] = 1
endfor
return newList
endfunction
fun! xpt#util#ExpandTab(text,n)
if stridx( a:text, " " ) < 0
return a:text
endif
let str = "\n" . a:text
let tabspaces = repeat( ' ', a:n )
let last = ''
while str != last
let last = str
let str = substitute( str, '\n *\zs ', tabspaces, 'g' )
endwhile
return str[1 :]
endfunction
fun! xpt#util#convertSpaceToTab(text)
if ( "\n" . a:text ) !~ '\V\n ' || &expandtab
return a:text
else
let tabspaces = repeat( ' ', &tabstop )
let lines = split( a:text, '\V\n', 1 )
let newlines = []
for line in lines
let newline = join( split( line, '\V\^\%(' . tabspaces . '\)', 1 ), ' ' )
let newlines += [newline]
endfor
return join( newlines, "\n" )
endif
endfunction
fun! xpt#util#SpaceToTab(lines)
if ! &expandtab && match( a:lines, '\v^ ' ) > -1
let cmd = 'join( split( v:val, ''\v^%('' . repeat( '' '', &tabstop ) . '')'', 1 ), '' '' )'
call map(a:lines,cmd)
endif
return a:lines
endfunction
fun! xpt#util#SpaceToTabExceptFirstLine(lines)
if ! &expandtab && len( a:lines ) > 1 && match( a:lines, '\v^ ', 1 ) > -1
let line0 = a:lines[0]
let cmd = 'join( split( v:val, ''\v^%('' . repeat( '' '', &tabstop ) . '')'', 1 ), '' '' )'
call map(a:lines,cmd)
let a:lines[0] = line0
endif
return a:lines
endfunction
fun! xpt#util#AddIndent(text,nIndent)
let baseIndent = repeat( " ", a:nIndent )
return substitute(a:text, '\n', '&' . baseIndent, 'g')
endfunction
fun! xpt#util#AddIndent2(text,nIndent)
let baseIndent = repeat( " ", a:nIndent )
if type( a:text ) == type( '' )
return substitute(a:text, '\n', '&' . baseIndent, 'g')
else
call map( a:text, string( baseIndent ) . '.v:val' )
let a:text[0] = a:text[0][a:nIndent :]
return a:text
endif
endfunction
fun! xpt#util#getIndentNr(pos)
let [ln,col] = a:pos
let line = matchstr( getline( ln ), '\V\^\s\*' )
if 1
if col == 1
return 0
else
let line = line[0 : col - 1 - 1]
return virtcol([ln,len(line)])
endif
else
let line = ( col == 1 ) ? '' : line[ 0 : col - 1 - 1 ]
let tabspaces = repeat( ' ', &tabstop )
return len( substitute( line, ' ', tabspaces, 'g' ) )
endif
endfunction
fun! xpt#util#LastIndent(text)
if a:text is ''
return 0
endif
let text = split( a:text, '\V\n', 1 )[ -1 ]
return len( matchstr( text, '\V\^\s\+' ) )
endfunction
fun! xpt#util#GetPreferedIndentNr(ln)
if &indentexpr == ''
return -1
else
let indentexpr = substitute( &indentexpr, '\Vv:lnum', a:ln, '' )
try
return eval(indentexpr)
catch /.*/
return -1
endtry
endif
endfunction
fun! xpt#util#TextBetween(posList)
return join(xpt#util#LinesBetween( a:posList ), "\n")
endfunction
fun! xpt#util#TextInLine(ln,s,e)
if a:s >= a:e
return ""
endif
return getline(a:ln)[a:s - 1 : a:e - 2]
endfunction
fun! xpt#util#LinesBetween(posList)
let [s,e] = a:posList
if s[0] > e[0] || e[0] == 0
return [""]
endif
let r = getline(s[0],e[0])
let r[-1] = strpart(r[-1],0,e[1] - 1)
let r[0] = strpart(r[0],s[1] - 1)
return r
endfunction
fun! xpt#util#SynNameStack(l,c)
if exists( '*synstack' )
let ids = synstack(a:l,a:c)
if empty(ids)
return []
endif
let names = []
for id in ids
let names = names + [synIDattr(id, "name")]
endfor
return names
else
return [synIDattr( synID( a:l, a:c, 0 ), "name" )]
endif
endfunction
fun! xpt#util#NearestSynName()
let pos = [ line( "." ), col( "." ) ]
let synName = synIDattr(synID(pos[0], pos[1], 1), "name")
if synName == ''
let prevPos = searchpos( '\S', 'bWn' )
if prevPos == [0,0]
return synName
endif
let synName = synIDattr(synID(prevPos[0], prevPos[1], 1), "name")
if synName == ''
return &filetype
endif
endif
return synName
endfunction
fun! xpt#util#CharsPattern(chars,...)
let is_magic = 0
if a:0 > 0 && a:1 is 1
let is_magic = 1
endif
let esc = '\['
if is_magic
let esc = '['
endif
let pattern = esc . escape( a:chars, '\]-^' ) . ']'
return pattern
endfunction
fun! s:GetUnescapeCharPattern(chars)
let chars = substitute( a:chars, '\\', '', 'g' )
let pattern = s:unescapeHead . '\ze\[' . escape( chars, '\]-^' ) . ']'
let s:charsPatternTable[a:chars] = pattern
return pattern
endfunction
fun! xpt#util#getCmdOutput(cmd)
let l:a = ""
redir => l:a
exe a:cmd
redir END
return l:a
endfunction
fun! xpt#util#Fallback(fbs)
let fbs = a:fbs
if len(fbs) > 0
let [key,flag] = fbs[0]
call remove(fbs,0)
if flag == 'feed'
call feedkeys( key, 'mt' )
return ''
else
return key
endif
else
return ''
endif
endfunction
let &cpo = s:oldcpo

View file

@ -0,0 +1,152 @@
2016-07-07
==========
Fixed
-----
* engine: always try to init buf data for xptemplate before XPTupdate. fixed: #79
2015-06-28
==========
Fixed
-----
* bracket: fix incorrect indent with cr
* engine: fix wrapper indent
* engine: normal-mode "x" breaks xpt
* filter: pass test 60-ph-func-Next 05-def-text-arg. Next move focus to next ph
* snippet-matching: snippet key should be stored in filetype instead of buffer
* snippet-matching: use keyword instead of word
* syntax: correct escaping nested mark
2015-06-17
==========
Fixed
-----
* engine: fix #69 mapping saver should not reinitiate when switching buffer
2015-06-02
==========
Fixed
-----
* engine: support hint of pum in dictionary type
* engine: post-filter uses outer-marks
* eval: concat text and Echo(). fix #68
2015-04-20
==========
Fixed
-----
* util: xpt#once#init path parsing in windows
2015-04-17
==========
Added
-----
* util: load .xpt.vim from working dir
Fixed
-----
* engine: quick-add snippet to buffer without filetype
2015-04-16
==========
Added
-----
* integration-test: of g:xptemplate_lib_filter
* option: g:xptemplate_lib_filter
2015-04-14
==========
Added
-----
* integration-test: 01-g-xptemplate_key_force_pum
* integration-test: 01-g-xptemplate_key
* integration-test: escaping in g:xptemplate_vars
* integration-test: 00-verboselog
* integration-test: snippet hint
Fixed
-----
* eval: \\$a should unescape one back slash
* eval: error message should not interrupt working flow
* hint: beside string, also accept number, dict and list value type
* util: xpt#once#init resolve symbolic link
2015-03-05
==========
Fixed
-----
* oop: skip verbose message when looking for class member
2015-03-03
==========
Added
-----
* integration-test: basic rendering.
* integration-test: indenting.
* integration-test: command 'XSET'.
* integration-test: pop up menu.
* integration-test: wrapper.
* integration-test: function:
`Build()` `BuildIfNoChange()` `BuildSnippet()` `Choose()` `Echo()` `Trigger()`.
* snippet: golang.
* doc: `Build()` `Echo()` `BuildIfNoChange()`.
* doc: gif screencast.
* doc: `g:xptemplate_break_undo`.
Changed
-------
* snippet: simplify markdown.
* engine: use closure for variable looking up.
* engine: filter action 'embed' is same with 'build'.
* engine: support to change only the visual mapping.
* engine: add conf `g:xptemplate_close_pum`.
Deprecated
----------
* action: 'embed'.
Removed
-------
* engine: several old fashion classes.
Fixed
-----
* engine: fix script-local mapping restore.
* readme: integration with latest supertab.
* engine: non-built default value should not move cursor to next.
* engine: correct several indent handling.
* engien: option 'preview' with completeopt.
* mapping: fix lost setting during applying BuildSnippet.

View file

@ -0,0 +1,173 @@
<Plug>XPTrawKey xptemplate.txt /*<Plug>XPTrawKey*
Build() xpt/snippet-function.txt /*Build()*
BuildSnippet() xpt/snippet-function.txt /*BuildSnippet()*
C() xpt-function.txt /*C()*
E({expr}) xpt-function.txt /*E({expr})*
Echo() xpt/snippet-function.txt /*Echo()*
Include: xpt.snippet.syn.txt /*Include:*
N() xpt-function.txt /*N()*
R({name}) xpt-function.txt /*R({name})*
S() xpt-function.txt /*S()*
S({expr},{pat},{sub},{flags}) xpt-function.txt /*S({expr},{pat},{sub},{flags})*
SV() xpt-function.txt /*SV()*
V() xpt-function.txt /*V()*
XPTcurrentPH xptemplate.txt /*XPTcurrentPH*
XPTembed xpt.snippet.syn.txt /*XPTembed*
XPTemplate xptemplate.txt /*XPTemplate*
XPTemplate() xpt.api.txt /*XPTemplate()*
XPTemplateMark() xpt.api.txt /*XPTemplateMark()*
XPTemplatePriority() xpt.api.txt /*XPTemplatePriority()*
XPTemplateTrigger() xpt.api.txt /*XPTemplateTrigger()*
XPTfollowingPH xptemplate.txt /*XPTfollowingPH*
XPTfuncs() xpt.api.txt /*XPTfuncs()*
XPTinclude xpt.snippet.syn.txt /*XPTinclude*
XPTinfo() xpt.api.txt /*XPTinfo()*
XPTinfoStr([fmt,[sep]]) xpt.api.txt /*XPTinfoStr([fmt,[sep]])*
XPTnextItem xptemplate.txt /*XPTnextItem*
XPTtgr() xpt.api.txt /*XPTtgr()*
XPTvar xpt.snippet.syn.txt /*XPTvar*
^ xpt.snippet.syn.txt /*^*
` xpt.snippet.syn.txt /*`*
`...^ xptemplate.txt /*`...^*
`::^ xpt.snippet.syn.txt /*`::^*
``` xpt.snippet.syn.txt /*```*
`cursor^ xpt.snippet.syn.txt /*`cursor^*
g:XPTaddBundle() xpt.api.txt /*g:XPTaddBundle()*
g:xptemplate_always_show_pum xpt/option.txt /*g:xptemplate_always_show_pum*
g:xptemplate_brace_complete xpt/option.txt /*g:xptemplate_brace_complete*
g:xptemplate_break_undo xpt/option.txt /*g:xptemplate_break_undo*
g:xptemplate_bundle xpt/option.txt /*g:xptemplate_bundle*
g:xptemplate_close_pum xpt/option.txt /*g:xptemplate_close_pum*
g:xptemplate_cwd_snippet xpt/option.txt /*g:xptemplate_cwd_snippet*
g:xptemplate_debug_log xpt/option.txt /*g:xptemplate_debug_log*
g:xptemplate_fallback xptemplate.txt /*g:xptemplate_fallback*
g:xptemplate_goback xptemplate.txt /*g:xptemplate_goback*
g:xptemplate_highlight xpt/option.txt /*g:xptemplate_highlight*
g:xptemplate_highlight_nested xpt/option.txt /*g:xptemplate_highlight_nested*
g:xptemplate_hook_before_cr xpt/option.txt /*g:xptemplate_hook_before_cr*
g:xptemplate_key xptemplate.txt /*g:xptemplate_key*
g:xptemplate_key_force_pum xptemplate.txt /*g:xptemplate_key_force_pum*
g:xptemplate_key_pum_only xptemplate.txt /*g:xptemplate_key_pum_only*
g:xptemplate_lib_filter xpt/option.txt /*g:xptemplate_lib_filter*
g:xptemplate_minimal_prefix xpt/option.txt /*g:xptemplate_minimal_prefix*
g:xptemplate_move_even_with_pum xpt/option.txt /*g:xptemplate_move_even_with_pum*
g:xptemplate_nav_cancel xptemplate.txt /*g:xptemplate_nav_cancel*
g:xptemplate_nav_next xptemplate.txt /*g:xptemplate_nav_next*
g:xptemplate_nav_prev xptemplate.txt /*g:xptemplate_nav_prev*
g:xptemplate_ph_pum_accept_empty xpt/option.txt /*g:xptemplate_ph_pum_accept_empty*
g:xptemplate_pum_quick_back xpt/option.txt /*g:xptemplate_pum_quick_back*
g:xptemplate_pum_tab_nav xpt/option.txt /*g:xptemplate_pum_tab_nav*
g:xptemplate_snippet_folders xpt/option.txt /*g:xptemplate_snippet_folders*
g:xptemplate_strict xpt/option.txt /*g:xptemplate_strict*
g:xptemplate_strip_left xpt/option.txt /*g:xptemplate_strip_left*
g:xptemplate_to_right xptemplate.txt /*g:xptemplate_to_right*
g:xptemplate_vars xpt/option.txt /*g:xptemplate_vars*
i_<C-\> xptemplate.txt /*i_<C-\\>*
i_<C-g> xptemplate.txt /*i_<C-g>*
i_<C-r><C-r><C-\> xptemplate.txt /*i_<C-r><C-r><C-\\>*
i_<S-tab> xptemplate.txt /*i_<S-tab>*
i_<tab> xptemplate.txt /*i_<tab>*
n_<C-g> xptemplate.txt /*n_<C-g>*
s_<C-\> xptemplate.txt /*s_<C-\\>*
s_<C-l> xptemplate.txt /*s_<C-l>*
s_<CR> xptemplate.txt /*s_<CR>*
s_<S-tab> xptemplate.txt /*s_<S-tab>*
s_<tab> xptemplate.txt /*s_<tab>*
self.renderContext xpt.api.txt /*self.renderContext*
v_<C-\> xptemplate.txt /*v_<C-\\>*
xpt xptemplate.txt /*xpt*
xpt-$ xpt.snippet.syn.txt /*xpt-$*
xpt-... xptemplate.txt /*xpt-...*
xpt-``` xpt.snippet.syn.txt /*xpt-```*
xpt-api xpt.api.txt /*xpt-api*
xpt-bundle xptemplate.txt /*xpt-bundle*
xpt-context xptemplate.txt /*xpt-context*
xpt-customize xptemplate.txt /*xpt-customize*
xpt-customize-highlight xptemplate.txt /*xpt-customize-highlight*
xpt-customize-variable xptemplate.txt /*xpt-customize-variable*
xpt-customize-variable-datetime xptemplate.txt /*xpt-customize-variable-datetime*
xpt-customize-variable-format xptemplate.txt /*xpt-customize-variable-format*
xpt-customize-variable-space xptemplate.txt /*xpt-customize-variable-space*
xpt-feature xptemplate.txt /*xpt-feature*
xpt-install xptemplate.txt /*xpt-install*
xpt-key-bind xptemplate.txt /*xpt-key-bind*
xpt-key-clear xptemplate.txt /*xpt-key-clear*
xpt-key-goback xptemplate.txt /*xpt-key-goback*
xpt-key-goto-right xptemplate.txt /*xpt-key-goto-right*
xpt-key-navigate xptemplate.txt /*xpt-key-navigate*
xpt-key-pum xptemplate.txt /*xpt-key-pum*
xpt-key-trigger xptemplate.txt /*xpt-key-trigger*
xpt-key-visual xptemplate.txt /*xpt-key-visual*
xpt-mixed xpt.snippet.syn.txt /*xpt-mixed*
xpt-name-matching xptemplate.txt /*xpt-name-matching*
xpt-nested xptemplate.txt /*xpt-nested*
xpt-option xpt/option.txt /*xpt-option*
xpt-personal-folder xptemplate.txt /*xpt-personal-folder*
xpt-personal-var xpt/option.txt /*xpt-personal-var*
xpt-placeholder-cursor xpt.snippet.syn.txt /*xpt-placeholder-cursor*
xpt-placeholder-default-value xpt.snippet.syn.txt /*xpt-placeholder-default-value*
xpt-placeholder-edge xpt.snippet.syn.txt /*xpt-placeholder-edge*
xpt-placeholder-left-mark xpt.snippet.syn.txt /*xpt-placeholder-left-mark*
xpt-placeholder-mark xpt.snippet.syn.txt /*xpt-placeholder-mark*
xpt-placeholder-ontime-filter xpt.snippet.syn.txt /*xpt-placeholder-ontime-filter*
xpt-placeholder-optional-ph xpt.snippet.syn.txt /*xpt-placeholder-optional-ph*
xpt-placeholder-post-filter xpt.snippet.syn.txt /*xpt-placeholder-post-filter*
xpt-placeholder-right-mark xpt.snippet.syn.txt /*xpt-placeholder-right-mark*
xpt-placeholder-special xpt.snippet.syn.txt /*xpt-placeholder-special*
xpt-popup xptemplate.txt /*xpt-popup*
xpt-priority-format xpt.snippet.syn.txt /*xpt-priority-format*
xpt-priority-value xpt.snippet.syn.txt /*xpt-priority-value*
xpt-repetition xptemplate.txt /*xpt-repetition*
xpt-snippet xpt.snippet.syn.txt /*xpt-snippet*
xpt-snippet-ComeFirst xpt.snippet.syn.txt /*xpt-snippet-ComeFirst*
xpt-snippet-ComeLast xpt.snippet.syn.txt /*xpt-snippet-ComeLast*
xpt-snippet-XPTinclude xpt.snippet.syn.txt /*xpt-snippet-XPTinclude*
xpt-snippet-XSET xpt.snippet.syn.txt /*xpt-snippet-XSET*
xpt-snippet-XSETm xpt.snippet.syn.txt /*xpt-snippet-XSETm*
xpt-snippet-abbr xpt.snippet.syn.txt /*xpt-snippet-abbr*
xpt-snippet-alias xpt.snippet.syn.txt /*xpt-snippet-alias*
xpt-snippet-body xpt.snippet.syn.txt /*xpt-snippet-body*
xpt-snippet-default-post-filter xpt.snippet.syn.txt /*xpt-snippet-default-post-filter*
xpt-snippet-default-value xpt.snippet.syn.txt /*xpt-snippet-default-value*
xpt-snippet-embed xpt.snippet.syn.txt /*xpt-snippet-embed*
xpt-snippet-expandable xpt.snippet.syn.txt /*xpt-snippet-expandable*
xpt-snippet-expression xpt.snippet.syn.txt /*xpt-snippet-expression*
xpt-snippet-function xpt/snippet-function.txt /*xpt-snippet-function*
xpt-snippet-function-ctx xpt.api.txt /*xpt-snippet-function-ctx*
xpt-snippet-header xpt.snippet.syn.txt /*xpt-snippet-header*
xpt-snippet-hidden xpt.snippet.syn.txt /*xpt-snippet-hidden*
xpt-snippet-hint xpt.snippet.syn.txt /*xpt-snippet-hint*
xpt-snippet-include xpt.snippet.syn.txt /*xpt-snippet-include*
xpt-snippet-instant-value xpt.snippet.syn.txt /*xpt-snippet-instant-value*
xpt-snippet-item xpt.snippet.syn.txt /*xpt-snippet-item*
xpt-snippet-keyword xpt.snippet.syn.txt /*xpt-snippet-keyword*
xpt-snippet-leading-placeholder xpt.snippet.syn.txt /*xpt-snippet-leading-placeholder*
xpt-snippet-mark xpt.snippet.syn.txt /*xpt-snippet-mark*
xpt-snippet-name xpt.snippet.syn.txt /*xpt-snippet-name*
xpt-snippet-name-matching-rule xpt.snippet.syn.txt /*xpt-snippet-name-matching-rule*
xpt-snippet-placeholder xpt.snippet.syn.txt /*xpt-snippet-placeholder*
xpt-snippet-post-filter xpt.snippet.syn.txt /*xpt-snippet-post-filter*
xpt-snippet-postQuoter xpt.snippet.syn.txt /*xpt-snippet-postQuoter*
xpt-snippet-preset-value xpt.snippet.syn.txt /*xpt-snippet-preset-value*
xpt-snippet-priority xpt.snippet.syn.txt /*xpt-snippet-priority*
xpt-snippet-repetition xpt.snippet.syn.txt /*xpt-snippet-repetition*
xpt-snippet-sample xpt.snippet.syn.txt /*xpt-snippet-sample*
xpt-snippet-setting xpt.snippet.syn.txt /*xpt-snippet-setting*
xpt-snippet-synonym xpt.snippet.syn.txt /*xpt-snippet-synonym*
xpt-snippet-syntax xpt.snippet.syn.txt /*xpt-snippet-syntax*
xpt-snippet-tutorial xpt.snippet.tutor.txt /*xpt-snippet-tutorial*
xpt-snippet-variable xpt.snippet.syn.txt /*xpt-snippet-variable*
xpt-snippet-wrap xpt.snippet.syn.txt /*xpt-snippet-wrap*
xpt-snippet-wraponly xpt.snippet.syn.txt /*xpt-snippet-wraponly*
xpt-substitute xpt-function.txt /*xpt-substitute*
xpt-tips xptemplate.txt /*xpt-tips*
xpt-tutor-define-snippet xpt.snippet.tutor.txt /*xpt-tutor-define-snippet*
xpt-tutor-snippet-file xpt.snippet.tutor.txt /*xpt-tutor-snippet-file*
xpt-usage xptemplate.txt /*xpt-usage*
xpt-with-supertab xptemplate.txt /*xpt-with-supertab*
xpt-wrapper-snippet xptemplate.txt /*xpt-wrapper-snippet*
xpt-write-common-snippet xptemplate.txt /*xpt-write-common-snippet*
xpt-write-lang-snippet xptemplate.txt /*xpt-write-lang-snippet*
xpt-write-snippet xptemplate.txt /*xpt-write-snippet*
xpt-{} xpt.snippet.syn.txt /*xpt-{}*
xptemplate xptemplate.txt /*xptemplate*

View file

@ -0,0 +1,35 @@
*S()* *xpt-substitute*
S({pattern},{replace},[{flag}])
Substitute typed content with pattern and replace. Just like
|substitute()|.
*C()*
C()
Get function context, see |xpt-snippet-function-ctx|.
*E({expr})*
E({expr})
Equals to |expand()|.
*N()*
N()
Current edited item name. Valid only to |xpt-snippet-post-filter|.
*V()*
V()
Current typed text. Valid only to |xpt-snippet-post-filter|.
*R({name})*
R({name})
Reference to history item. Get value by name.
*S({expr},{pat},{sub},{flags})*
S({expr},{pat},{sub},{flags})
Equals to |substitute()|.
*SV()*
SV()
Equals to S(V(),{pat},{sub},{flag}).
" vim:tw=78:ts=8:sw=8:sts=8:noet:ft=help:norl:

View file

@ -0,0 +1,153 @@
*xpt-api*
This file describes the public functions provided by XPTemplate which
can be used in snippets.
*g:XPTaddBundle()*
g:XPTaddBundle({filetype}, {bundle})
Load a bundle. {filetype} is the current buffer file type in most
case. And {bundle} is the file name which supplies the bundle.
For example loading jquery bundle for HTML buffer(or JAVASCRIPT buffer): >
call g:XPTaddBundle('javascript', 'jquery')
<
*XPTfuncs()*
g:XPTfuncs()
g:XPTfuncs() returns a |Dictionary| container of functions which can
be used in templates in the current buffer. The normal usage of
g:XPTfuncs() to define a template function is : >
let s:f = g:XPTfuncs()
fun! s:f.date() dict
return strftime("%Y %b %d")
endfunction
<
Now you can use functions and variables in the template : >
call XPTemplate("filehead", [
\'/**--------------------/// `sum^ \\\----------------------',
\' *',
\' * @version : `1.0^',
\' * @since : `date()^',
\' * @author : `$author^ | `$email^',
\' * @copyright `.com.cn^ ',
\' * @TODO : ',
\' * ',
\' *---------------------\\\ `sum^ ///----------------------*/',
\''])
<
*XPTemplate()*
XPTemplate({name} [, {context}], {template})
XPTemplate defines a template for the current buffer. It takes 2 or 3
parameters:
{name} is a string representing the key to trigger this template.
{context} can be omitted or an |Dictionary| which defines where this
template can be triggered. For now only "syn" is supported.
{template} is a string or |List|. |List| will be joined with "\n"
forming a template string. This saves you adding "\n" to each line.
*XPTemplateMark()*
XPTemplateMark({leftmark}, {rightmark})
XPTemplateMark defines which characters are used as item quoter in the
current buffer. See |xpt-placeholder-mark|.
NOTE this function affects only the current script and current buffer.
*XPTemplatePriority()*
XPTemplatePriority({priority})
XPTemplatePriority sets the default priority for the current *.xpt.vim
script and current buffer. See |xpt-priority-value|.
NOTE this function affects only the current script and current buffer.
*self.renderContext* *xpt-snippet-function-ctx*
The template context can be accessed from within an
|xpt-snippet-function|. For example in the "item-reference" function:
>
fun! s:f.R(name)
let ctx = self.renderContext
if has_key(ctx.namedStep, a:name)
return ctx.namedStep[a:name]
endif
return a:ctx.name
endfunction
<
*XPTtgr()*
XPTtgr( {snippetName} [, {option} ] )
Trigger an snippet of name {snippetName} in insert mode. This function
returns and |i_CTRL-R_=| expression. You should always use this
function following "<C-R>=".
As Example, the following two command defines auto-complete brace: >
call XPTemplate('brace', '{`^}')
inoremap { <C-r>=XPTtgr('brace')<CR>
<
After executing these 2 command, a "{" key-stroke produces a pair of
braces: "{}" and cursor left between them.
Table below lists all {option} keys: >
{option}.syn Regular expression defines pattern what syntax
name must match for snippet to trigger.
{option}.nosyn Regular expression defines pattern what syntax
name must NOT match for snippet to trigger.
{option}.literal Snippet can only be triggered in string or
comment. Same as
{option}.syn='\V\cstring\|comment'.
{option}.noliteral Snippet can only be triggered outside of
string or comment. Same as
{option}.nosyn='\V\cstring\|comment'.
{option}.k What should be produced if condition is not
satisfied to trigger snippet.
<
*XPTemplateTrigger()*
XPTemplateTrigger( {snippetName} [, {option} ] )
Deprecated.
Same as |XPTtgr()|.
*XPTinfo()*
XPTinfo()
Return 0 if no snippet in processing on screen.
Return an array representing snippets stack on screen in following
format:
>
[ {
"$snipname" : "<snippet-name>",
"$phname" : "<placeholder-name>"
}, ... ]
<
In outer-to-inner order
*XPTinfoStr([fmt,[sep]])*
XPTinfoStr([fmt,[sep]])
Return data of |XPTinfo()| in string.
Argument "fmt": format for rendering infomation of each nested snippet
in stack. Default value is "$snipname.$phname".
Argument "sep": string as a separator. Default value is " > ".
By default XPTinfoStr() returns: >
"<snip-a>.<ph-x> > <snip-inside-a>.<ph-y>..."
<
Example: Adding this function to 'statusline' as a indicator when
working with deeply nested snippets: >
let &statusline .= '%{XPTinfoStr()}'
<
" vim:tw=78:ts=8:sw=8:sts=8:noet:ft=help:norl:

View file

@ -0,0 +1,923 @@
*xpt-snippet-syntax*
XPT Snippet Syntax
by drdr.xp
drdr.xp@gmail.com
==============================================================================
Content table:
|xpt-snippet-sample|
|xpt-snippet-header|
|xpt-snippet-priority|
|xpt-priority-value|
|xpt-priority-format|
|xpt-snippet-keyword|
|xpt-snippet-mark|
|xpt-snippet-variable|
|xpt-snippet-function|
|xpt-snippet-XPTinclude|
|xpt-snippet-embed|
|xpt-snippet|
|xpt-snippet-name|
|xpt-snippet-setting|
|xpt-snippet-hint|
|xpt-snippet-hidden|
|xpt-snippet-alias|
|xpt-snippet-synonym|
|xpt-snippet-wrap|
|xpt-snippet-wraponly|
|xpt-snippet-abbr|
|xpt-snippet-body|
|xpt-snippet-include|
|xpt-snippet-XSET|
|xpt-snippet-XSETm|
|xpt-snippet-ComeFirst|
|xpt-snippet-ComeLast|
|xpt-snippet-postQuoter|
|xpt-snippet-item|
|xpt-snippet-placeholder|
|xpt-placeholder-mark|
|xpt-placeholder-left-mark| |`|
|xpt-placeholder-right-mark| |^|
|xpt-placeholder-edge|
|xpt-snippet-leading-placeholder|
|xpt-placeholder-special|
|xpt-placeholder-cursor|
|xpt-snippet-expression|
|xpt-snippet-instant-value|
|xpt-snippet-preset-value|
|xpt-snippet-default-value|
|xpt-snippet-post-filter|
|xpt-snippet-default-post-filter|
|xpt-placeholder-optional-ph|
|xpt-placeholder-default-value|
|xpt-placeholder-post-filter|
|xpt-placeholder-ontime-filter|
|xpt-snippet-expandable|
|xpt-snippet-repetition|
*xpt-snippet-sample*
A snippet file looks like this : >
XPTemplate priority=lang keyword=$ | |xpt-snippet-header|
let s:f = XPTfuncs() | |xpt-snippet-function|
XPTvar $TRUE true | |xpt-snippet-variable|
XPTvar $FALSE false |
XPTvar $NULL null |
XPTvar $UNDEFINED undefined |
|
XPTvar $CL /* |
XPTvar $CM * |
XPTvar $CR */ |
|
XPTinclude | |xpt-snippet-XPTinclude|
\ _common/common |
\ _comment/doubleSign |
\ _condition/c.like |
fun! s:f.js_filename() | |xpt-snippet-function|
return expand( "%" ) |
endfunction |
XPT cmt hint=/**\ @auth...\ */ | |xpt-snippet|
XSET author=$author | |xpt-snippet-XSET|
XSET email=$email | |xpt-snippet-XSET|
/** |\
* @author : `author^ | `email^ | \
* @description | +|xpt-snippet-body|
* `cursor^ | /
* @return {`Object^} `desc^ |/
*/
XPT for hint=for\ (var..;..;++)
for ( i=0; i<`len^; ++i ) { `cursor^ }
<
*xpt-snippet-header*
Each snippet file starts with a XPTemplate declaration for
snippet-scope setting, duplication load check, etc.
Format : >
XPTemplate [priority=lang] [keyword=#] [mark=`^]
<
There are 3 optional settings for 'XPTemplate' :
*xpt-snippet-priority*
Priority affects |xpt-snippet| and |xpt-snippet-variable|;
|xpt-snippet-function| is defined directly, so it isn't controlled by
|xpt-snippet-priority|. Snippets with a lower |xpt-snippet-priority|
override higher ones. Format : >
XPTemplate priority=<priority-value>
< See |xpt-priority-value|.
*xpt-priority-value*
Snippets are defined with a certain priority. One buffer might load
snippets with the same name. Only the snippet with the lowest priority
is used, others are ignored.
Priorities can be in the range from 0 to +oo. 0 is the highest
priority. Some predefined symbols stand for numeric priority
values : >
all : 64
spec : 48
like : 32
lang : 16
sub : 8
personal : 0
< Default priority is "lang" or 16.
You can set priority for each snippet by using |xpt-priority-format|.
Or set priority for all templates in the current file with
|XPTemplatePriority()|.
*xpt-priority-format*
Priority setting format : "priority[+/-[offset]]".
Following formats are all valid : >
3 3
lang 16
like+4 36 // like=32
all- 63 // all=64
all-1 63 // all=64
<
*xpt-snippet-keyword*
|xpt-snippet-keyword| defines what characters other than word chars
can be used as |xpt-snippet-name|.
You do not need to specify explicitly what char is
xpt-snippet-keyword. It is automatically added when non-word char
presents in snippet name. For example: >
XPT #include <`^.h>
<
After the above snippet loaded, "#" is added.
See also |xpt-snippet-name-matching-rule|.
*xpt-snippet-mark*
To specify which 2 characters are used as |xpt-placeholder-mark|
instead of the default |`| and |^|. Format : >
XPTemplate mark=~^
<
*xpt-$*
*XPTvar*
*xpt-snippet-variable*
|xpt-snippet-variable| can be used in :
|xpt-snippet-instant-value|
|xpt-snippet-preset-value|
|xpt-snippet-default-value|
|xpt-snippet-post-filter|
|xpt-placeholder-ontime-filter|
Format : >
XPTvar $VAR_NAME something
< Or with single quoter : >
XPTvar $VAR_NAME 'something'
< The only difference is that in single quoted strings space can be
freely used. Like this : >
XPTvar $VAR_NAME ' '
< Instead of using the escaped format "\ ".
It's also possible to set a variable to the empty value: >
XPTvar $VAR_NAME ''
<
Another example from C language : >
XPTvar $TRUE 1
< and a snippet defined as : >
XPT while1
while (`$TRUE^) {
`cursor^
}
< will generate : >
while (1) {
`cursor^
}
<
|xpt-snippet-variable| is used widely in XPTemplate, such as comment
definition, format customization, etc.
Personal information variables should be defined by using
|g:xptemplate_vars|. Variables defined with |g:xptemplate_vars|
override variables defined in any snippet files.
NOTE By convention the names of |xpt-snippet-variable| supplied by
XPTemplate start with an upper-case letter. User defined
variable name should start with a lower-case letter.
NOTE Override control of |xpt-snippet-variable| is affected by
|xpt-snippet-priority|.
*XPTinclude*
*xpt-snippet-XPTinclude*
Syntax : >
XPTinclude <folder_name_in_ftplugin>/<filename>
< The <filename> is only the file root, without ".xpt.vim".
XPTinclude can include several snippets at one time.
NOTE do NOT use |:runtime| to include other snippet files. XPTinclude
handles snippet priority, but |:runtime| does NOT.
*XPTembed*
*xpt-snippet-embed*
Syntax : >
XPTembed <folder_name_in_ftplugin>/<filename>
< |XPTembed| acts like |XPTinclude|, except it includes only snippet
files for nested languages, like JavaScript in HTML, or HTML in PHP.
NOTE TODO differences between XPTinclude by example.
*xpt-snippet*
The snippet part starts where the first "XPT ... " presents. Any
content after this command is no longer Vim script, but XPTemplate
snippets.
Each |xpt-snippet| defines one code snippet with the following
syntax : >
XPT <snippetName> [name=value] [name=value] ..
<snippet body>..
..XPT
< 'XPT' is the start of a snippet. '..XPT' is the end of a snippet, it
is optional. If '..XPT' does not present the snippet body ends at the
last non-empty line( but without the last line-break ).
*xpt-snippet-name*
<snippetName> is the name the user has to type to trigger this
snippet. It can only contain word-chars |\w| and
|xpt-snippet-keyword|.
Custom snippets (not provided by XPTemplate) should not start with "_"
by convention as these snippets are used by XPTemplate internally, see
also |xpt-snippet-include|.
*xpt-snippet-name-matching-rule*
When |xpt-key-trigger| key pressed, XPT search for snippet name from
cursor position backwards.
XPT search for longest matching of any snippet prefixes without
breaking any continous words.
For example there are 4 snippets defined: >
XPT a
-a
XPT *
-*
XPT a*
-a*
XPT *a
-*a
< Then what typed and what got is as below: >
a<C-\> -a
*<C-\> -*
a*<C-\> -a*
*a<C-\> -*a
*a<C-\> -*a
xa<C-\> // Nothing matched. Because to match "a"
word "xa" must be broken.
xa*<C-\> xa-*
x*a<C-\> x-*a
x*a*<C-\> x*-a*
<
*xpt-snippet-setting*
The 'name=value' defines snippet settings, including
|xpt-snippet-hint|
|xpt-snippet-hidden|
|xpt-snippet-alias|
*xpt-snippet-hint*
Set the 'menu' entry for the pop up menu; as a short description other
than |xpt-snippet-name|. Like the following C language popup menu : >
| #if #if ... |
| #ifdef #if ... |
| #ifndef #ifndef .. |
<
Syntax to set up hints: >
XPT for hint=for\ (..;..;++)
< Or : >
XPT for " for (..;..;++)
< The quote-hint must be at the end of |xpt-snippet| declaration.
Some characters( space, left quote and "$" ) need to be escaped in
hint text: >
<space> ( $
hint= yes yes yes
" no yes yes
<
With only the 'hint=' way:
space needs to be escaped.
With both these two ways :
"(" needs to be escaped if you do NOT want it to be evaluated
as a function call.
"$" needs to be escaped if you do NOT want it to be evaluated
as variable.
*xpt-snippet-hidden*
Set to 1 to prevent the snippet from being triggered by the user, but
it CAN be triggered from internal API, or included by other snippet.
Syntax: >
XPT for hidden=1 hint=...
< Or: >
XPT for hidden hint=...
<
See |xpt-snippet-include| and |xpt-api|.
*xpt-snippet-alias*
Make the snippet an alias to another snippet. Syntax : >
XPT forin hint=for\ ..\ in\ ..\ ..\ endfor
for `value^ in `list^
`cursor^
endfor
XPT foreach alias=forin hint=for\ ..\ in\ ..\ ..\ endfor
< This makes "forin" and "foreach" the same, but with possible different
settings.
NOTE |xpt-snippet-alias| can be used to create shortcuts.
*xpt-snippet-synonym*
Like |xpt-snippet-alias|, synonym gives a snippet another name.
Syntax : >
XPT snippetName synonym=a|b|c...
< Where a, b and c are all the names of this snippet. For example : >
XPT forin synonym=fin|fi hint=for\ ..\ in\ ..\ ..\ endfor
for `value^ in `list^
`cursor^
endfor
< This makes "forin", "fin" and "fi" the same.
NOTE |xpt-snippet-synonym| can be used to create shortcuts.
*xpt-snippet-wrap*
Wrapper snippets can be triggered in visual mode, place holder marked
as "wrap" is replaced with the text selected in visual mode.
Definition of wrapper snippet has no differences from normal
snippet except it declaring a place holder as wrapping holder. For
example: >
________/---------------------| wrapper declaration
XPT if wrap=job
if (`condition^){
`job^
}
<
Wrapping can be block-wise or line-wise. Wrapper place holder with
|xpt-placeholder-edge| is line-wise, or it is block-wise.
For example: >
XPT comment wrap=what
`/* `what` */^
< This is line-wise wrapper, it will result in: >
/* line1 */
/* line2 */
< But not: >
/* line1
line2 */
<
See also |xpt-wrapper-snippet| and |xpt-snippet-wraponly|.
*xpt-snippet-wraponly*
Normally, wrapper snippet can also be triggered in insert-mode, unless
"wraponly" declared. For example: >
________/------------| wrap only
XPT if wrap=job wraponly
if (`condition^){
`job^
}
<
*xpt-snippet-abbr*
{default:0}
Set to 1 to create |abbreviations| for this snippet.
Example: >
____/------------------------| create abbr
XPT if abbr
if ( ) { }
< Snippet defined as above will be triggered by typing "if<space>" or
"if<C-]>".
*xpt-snippet-body*
<snippet body> is all the OTHER text except the first line : >
XPT for hint=for\ (..;..;++)
for (`i^ = `0^; `i^ < `len^; ++`i^) { |
`cursor^ | snippet body
} |
< |xpt-snippet-body| contains snippet text and :
|xpt-snippet-XSET|
|xpt-snippet-XSETm|
Snippet with XSET command : >
XPT printf hint=printf\(...)
XSET elts=c_printfElts( R( 'pattern' ) )
printf( "`pattern^"`elts^ )
< NOTE XPTemplate use 4-spaces indent. No table-char indent is
allowed in snippet file.
NOTE XSET/XSETm commands can be placed anywhere inside a snippet.
*`::^* *Include:* *xpt-snippet-include*
`:<snipname>:^ Simple Include without "cursor".
`Include:<snipname>^ Include with "cursor" place holder.
`:<snipname>():^ Simple inclusion with parameter.
`Include:<snipname>()^ Inclusion with parameter.
Snippet can include another snippet, through inclusion place holder : >
`Include:snippetName^
< When inclusion occurs, |xpt-snippet-post-filter|,
|xpt-snippet-default-value| and |xpt-snippet-preset-value| is imported
too, if it does not override.
Short inclusion format : >
`:snippetName:^
< Only two ":" around snippet name are needed.
NOTE The only difference between "Include:" and "::" is "Include:"
keeps "cursor" place holder but "::" does not.
Take "if" snippet in file "_condition/c.like.xpt.vim" for example(
snippets are simplified for reading ): >
XPT _if hidden
if ( `condition^ ) {
`job^
}
XPT if hint=if\ (..)\ {..}\ else...
`:_if:^` `else...{{^ `Include:else^`}}^
< The real "if" includes the "_if" and "else" snippets.
NOTE Inclusion is literal, so that snippets with different
|xpt-snippet-mark| can not include each other.
NOTE By convention snippets of name started with "_" are internal
snippets. Normally these snippets are set with
|xpt-snippet-hidden| flag on and used for inclusion only.
Parameters of Inclusion:
Inclusion can have parameters passed to included snippet. Parameters
are name-value pairs. Names are placeholder name. Name-Values presents
in form of |Dictionary|:
`:<snipname>( { '<phname>' : '<new_phname>', ... } ):^
Place holders in sub-snippet presents in parameter are replaced.
*xpt-snippet-XSET*
In |xpt-snippet-body| XSET commands can be used anywhere to set :
|xpt-snippet-preset-value|
|xpt-snippet-default-value|
|xpt-snippet-post-filter|
XSET syntax to set |xpt-snippet-preset-value|: >
XSET itemname|pre=<expression>
< XSET syntax to set |xpt-snippet-default-value|: >
XSET itemname|def=<expression>
< or : >
XSET itemname=<expression>
< XSET syntax to set |xpt-snippet-post-filter|: >
XSET itemname|post=<expression>
< <expression> is |xpt-snippet-expression|. For example : >
XPT #include_user hint=include\ ""
XSET me=fileRoot()
#include "`me^.h"
< Item "me" is set to the file name without extension.
*xpt-snippet-XSETm*
"XSETm" is similar to |xpt-snippet-XSET| except it uses "\n" instead
of "=" in |xpt-snippet-XSET| and ends with "XSETm END". For
example : >
XPT if hint=if\ (..)\ {..}\ else...
if (`condition^) {
`job^
}` `else...^
XSETm else...|post
else {
`cursor^
}
XSETm END
<
*xpt-snippet-ComeFirst*
*xpt-snippet-ComeLast*
Special XSET keys "ComeFirst" and "ComeLast" specify the item render
order. Their value is a list of place holder names separated by space.
For example : >
XPT for hint=for\ (..;..;++)
XSET ComeFirst=0 len
for (`i^ = `0^; `i^ < `len^; ++`i^)`$BRloop^{
`cursor^
}
< So that "0" is focused first, then "len" and then "i".
*xpt-snippet-postQuoter*
The key "postQuoter" is designed to specify quoter do define
|xpt-snippet-expandable|. Default is "{{,}}".
*xpt-snippet-item*
In one snippet a group of |xpt-snippet-placeholder|s with the same
name is an "item". For example : >
XPT for hint=for\ (..;..;++)
for (`i^ = `0^; `i^ < `len^; ++`i^) {
`cursor^
}
< In this snippet there are 4 items : >
i, 0, len, cursor
< Item "i" has 3 |xpt-snippet-placeholder|s, the others have only 1.
*xpt-snippet-placeholder*
A place holder is a segment of a snippet which can be changed by the
user. It's tracked by XPTemplate to update the user input of
|xpt-snippet-placeholder|s within the same |xpt-snippet-item|.
The place holders are defined by |xpt-placeholder-mark|, by default
|`| and |^| are used. For example : >
XPT for hint=for\ (..;..;++)
for (`i^ = `0^; `i^ < `len^; ++`i^) {
`cursor^
}
< Sequentially, the place holders in this snippet are : >
i, 0, i, len, i, cursor
<
Note The placeholder can't contain any backslashes (\). If the default
value should contain any items which need to be escaped (like brackets
or you want to use backslashes directly), use the following syntax
(see |xpt-placeholder-default-value| for more information): >
`name^value with \() here^
<
*xpt-placeholder-left-mark* *`*
*xpt-placeholder-right-mark* *^*
*xpt-placeholder-mark*
|xpt-placeholder-mark| are the characters used to define
|xpt-snippet-placeholder|s of a snippet, by default |`| and |^|.
Or the |xpt-placeholder-left-mark| and |xpt-placeholder-right-mark|.
They can be changed locally, for the current snippet file, by
|xpt-snippet-mark|.
*```* *xpt-```* *xpt-placeholder-edge*
Besides |`| and |^|, additional |xpt-placeholder-left-mark|s can be
set inside place holder to add additional information: the edge.
Edge is some text around a place holder that is not selected when the
cursor jumps to this place holder, but it still can be edited. For
example : >
`(`xpt`)^
< This place holder is named "xpt" and the edges are "(" and ")". When
the cursor jumps onto it : >
(xpt)
***------ only xpt is selected
< Edges help with formatting issues.
Place holder can have only a left edge, for example : >
`(`xpt^
<
NOTE only |\_W| characters are acceptable in edges.
*xpt-snippet-leading-placeholder*
In an item one place holder is the leading place holder which accepts
user input. Others are update by XPTemplate automatically.
By default, the first place holder in item is the leading place
holder, or the one with a |xpt-placeholder-edge|. This allows it to
specify which place holder is the edit area.
For example : >
for (`i^ = `0^; `i^ < `len^; ++`i^) {
`cursor^
}
< In item "i", the first "i" before "=" is the leading one. But in this
snippet : >
for (`i^ = `0^; ``i^ < `len^; ++`i^) {
`cursor^
}
< The second "i", with double |`| before "<", is the leading one.
*xpt-placeholder-special*
Special place holders include : |xpt-placeholder-cursor| and
|xpt-snippet-wrap|.
*`cursor^* *xpt-placeholder-cursor*
Sets where cursor the stops after a snippet finished.
The item named "cursor" is a special one. It's always selected at last
and replaced with an empty string. When navigating to the "cursor"
item the snippet is complete.
*xpt-{}* *xpt-mixed* *xpt-snippet-expression*
Expression is a mixture of plain text, |xpt-snippet-variable| and
|xpt-snippet-function|.
Expression is used as the value of
|xpt-snippet-instant-value|
|xpt-snippet-preset-value|
|xpt-snippet-default-value|
|xpt-snippet-post-filter|
|xpt-placeholder-ontime-filter|.
Functions can be |xpt-snippet-function|s defined as member of
|XPTfuncs()| or native Vim functions.
Functions are called as member of rendering context :
|xpt-snippet-function-ctx|.
Functions or variables can be enclosed by "{}" to prevent function or
variable names messing up with the surrounding plain text.
Functions are not evaluated if "()" is escaped : >
S\(S("abc", '.', '\u&'))
< is evaluated to : >
S(ABC)
<
Escaping the '$' stops variable evaluation : >
\$author
< is evaluated to : >
$author
<
Escaping the "{}" : >
\{S("abc", '.', '\u&')}
< is evaluated to : >
{ABC}
< While : >
{S("abc", '.', '\u&')}
< is evaluated to : >
ABC
<
Another example, supposing you are editing a file named
"your_file_name.ext" : >
__{S(E("%:t"),".","\\u&")}__
< is evaluated to : >
__YOUR_FILE_NAME.EXT__
< And : >
this is S($author,".","-&")-
< is evaluated to : >
this is -d-r-d-r-.-x-p-
< See also:
|xpt-snippet-function|
|xpt-snippet-variable|
*xpt-snippet-instant-value*
There is a special case for |xpt-snippet-placeholder| when the place
holder's content is a |xpt-snippet-expression|. In this case the place
holder is evaluated at once, and no more further editing can happen on
this place holder. For example : >
XPT filehead
...
* @since : `strftime("%Y %b %d")^
...
<
*xpt-snippet-preset-value*
Preset values are like |xpt-snippet-default-value| but are applied
earlier. |xpt-snippet-default-value| are applied before the place
holders are focused; preset value are applied just after the snippet
is displayed on the screen.
To define preset values: >
XSET the_name|pre=<expression>
<
*xpt-snippet-default-value*
By default place holders use their name as the default value but you
can choose another text as default value by using : >
XSET the_name|def=<expression>
<
So that before cursor jumps to leading place holder of name
"the_name", the <expression> evaluated and applied to the place
holder.
Example : the "#ind" snippet defined as : >
XPT #ind
XSET me|def=fileRoot()
#include "`me^.h"
< In C language, type "#ind<C-\>" you get : >
#include "current_file_name.h"
<
NOTE : if default value expression contains only plain string and
|xpt-snippet-variable|, it is used as |xpt-snippet-preset-value|, too;
for better looking without any side-effect.
*xpt-snippet-post-filter*
Post filters are executed after the user presses <Tab> and change the
typed text. To define a post filter use : >
XSET the_name|post=<expression>
< Or use |xpt-snippet-postQuoter| : >
XPT enum hint=enum\ {\ ..\ }
enum `name^`$BRstc^{
`elt^;`
`...{{^
`elt^;`
`...^`}}^
}` `var^;
<
Some usually-used post filter functions are defined in
ftplugin/_common/common.xpt.vim.
For example for c language, "#ifndef" snippet is defined as follows : >
XPT #ifndef hint=#ifndef\ ..
XSET symbol=S(fileRoot(),'\.','_','g')
XSET symbol|post=UpperCase(V())
#ifndef `symbol^
# define `symbol^
`cursor^
#endif `$CL^ `symbol^ `$CR^
..XPT
<
When you pressing <tab> from the first item "symbol", typed content are
converted to upper case. Before <tab> pressed : >
#ifndef __gnu__
# define __gnu__
`cursor^
#endif /* __gnu__ */
< After <tab> pressed : >
#ifndef __GNU__
# define __GNU__
`cursor^
#endif /* __GNU__ */
<
*xpt-snippet-default-post-filter*
Place holder with some special has default post filter set. Following
sections discuss them.
Place holders have default place holder defined: >
\V\w\+? EchoIfNoChange('')
<
*xpt-placeholder-optional-ph*
If a place holder name matches pattern '\V\w\+?', "EchoIfNoChange('')"
is assigned as its post filter.
This makes the place holder optional.
For example a snippet defined as below: >
fun(`arg^`, `context?^)
< When you render this snippet, and cursor stays on "context?" : >
fun(arg, context?)
--------
\__ selected
< Pressing <Tab> clears it, and snippet becomes: >
fun(arg)
<
*xpt-placeholder-post-filter*
For each place holder a private post filter can also be set by using
the |^||^| syntax : >
XPT lowerUpper
lower : `text^
upper : `text^UpperCase(V())^^ <---- double "^"
< Press <Tab>, this snippet results in : >
lower : text
upper : TEXT
<
NOTE If both |xpt-snippet-post-filter| and
|xpt-placeholder-post-filter| are set, the place holder filter takes
effect.
*xpt-placeholder-default-value*
*xpt-placeholder-ontime-filter*
For each place holder an ontime filter can be set to filter the text
each time the user types something by using the |^| syntax : >
XPT lowerUpper
lower : `text^
upper : `text^UpperCase(V())^ <--- only one "^"
< Each time the user types something at place holder "text" the second
place holder is updated with the content converted to upper case.
NOTE ontime filter is used as |xpt-placeholder-default-value| for the
leading place holder.
*xpt-snippet-expandable*
Sometimes you want to create an additional piece of snippet other than
the original snippet. For example, add another "else" after an "if"
block. To do this use expandable : >
XPT if
if `cond^
`job^
`else...{{^else
`cursor^
`}}^
endif
< At the place holder "else..." press <Tab> to generate another else
block, the text quoted by {{ and }}. Press to <Cr> to clear "else...".
Another way to define expandable is by using XSET command to define a
post filter: >
XPT if
if (`condition^)`$BRif^{
`job^
}` `else...^
XSETm else...|post
else {
`cursor^
}
XSETm END
< These 2 methods are the same inside XPTemplate.
*xpt-snippet-repetition*
Repetition is only a special case utilizing expandable, that another
same expandable trigger residing inside the expandable part.
For example the "case"s in "switch". To specify the repetition part,
just wrap the part you want it to repeat with `...^. n is a number and
can be omitted. Take the case from "switch": >
XPT switch
switch (`^) {
`...^ | repetition part
case `^0^ : |
`^ |
break; |
`...^ |
default:
`^
}
<
When you trigger a repetition template it works as below: >
switch () { <------- cursor stays here
`...^
default:
`^
}
< Press <Tab>, the |`...^| is selected. Press <Tab> again to expand the
repetition part. Or press <Cr> |xpt-key-clear| to cancel the
repetition part. These 4 lines are expanded: >
switch () {
case `^ : | expanded
`^ |
break; |
`...^ |
default:
`^
}
< Enter the repetition part. There is another |`...^|, that is the
another repeat trigger.
Press <Tab> 3 times: >
switch () {
case 0 :
break;
case `^ : | selected repetition part
`^ |
break; |
`...^ |
default:
`^
}
<
Using named |`...^| allows you define multiple repetition parts in one
snippet. For example: >
XPT switch
switch (`^) {
`case...^ | repetition part
case `^0^ : |
`^ |
break; |
`case...^ |
default:
`^
}
<
NOTE If you want to use a repetition inside a |xpt-snippet-expandable|
you can't use the normal |`...^| placeholder. Instead use `...{{^ as
in the following example: >
`Maybe...{{^
With repeatable:
`...{{^
- repeat this
`...^
`}}^
`}}^
<
The first `}}^ ends the repetition, the second the expandable.
See |xpt-repetition| for using repetition.
" vim:tw=78:ts=8:sw=8:sts=8:noet:ft=help:norl:

View file

@ -0,0 +1,97 @@
*xpt-snippet-tutorial*
XPTemplate Snippet Tutorial
by drdr.xp
drdr.xp@gmail.com
==============================================================================
|xpt-tutor-define-snippet|
|xpt-tutor-snippet-file|
*xpt-tutor-define-snippet*
This section describes how to define snippet in runtime.
In Vim, call |XPTemplate()| to define a new snippet: >
:call XPTemplate( 'name', 'foo`bar^' )
< And Then in insert-mode, type: >
name<C-\>
< XPT generates: >
foobar
```\_____________ "bar" is selected
< Now you can edit the "bar".
The editable part is called place-holder, see
|xpt-snippet-placeholder|. By default place-holder is quoted with "`"
and "^".
*xpt-tutor-snippet-file*
Snippet defined by |XPTemplate()| can not be stored. To define
snippets which can be loaded every time you edit some kind of file,
you need to create a snippet file.
This first example snippet file is in C language.
1. Create snippet file.
In Linux/Mac: >
vim ~/.vim/ftplugin/c/hello.xpt.vim
< In Windows: >
vim ~/vimfiles/ftplugin/c/hello.xpt.vim
<
2. Define your first snippet.
Type in insert mode: >
skeleton<C-\>
< To create a very simple snippet file skeleton. It may look
like: >
XPTemplate priority=personal+
XPT helloxpt " tips about what this snippet do
Say hello to `xpt^
`xpt^ says hello
<
2.1 Short explanation.
: >
XPTemplate priority=personal+
< These 2 lines declare an XPT snippet file. See
|xpt-snippet-header|.
: >
XPT helloxpt " tips about what this snippet do
< "XPT" is the start symbol of a snippet. See |xpt-snippet|.
"helloxpt" is the trigger key. See |xpt-snippet-name|.
Text after the quote is hint text. See |xpt-snippet-hint|.
: >
Say hello to `xpt^
`xpt^ says hello
< These two lines are snippet body. See |xpt-snippet-body|.
3. Test the first snippet "hello".
Start edit a new file "xpt.c": >
vim xpt.c
< In insert-mode type: >
helloxpt<C-\>
< XPT generates: >
__________| "xpt" is selected
___/
Say hello to xpt
xpt says hello
```\_______________________| the second "xpt" will
| be updated lively
<
4. To create a full featured snippet skeleton, use "xpt" instead of
"skeleton".
5. To learn more about snippet file syntax, read |xpt-snippet-syntax|.
6. Existent snippet files may be good samples, for example
ftplugin/java/java.xpt.vim .
" vim:tw=78:ts=8:sw=8:sts=8:noet:ft=help:norl:

View file

@ -0,0 +1,17 @@
Thanks to:
Agassi
Agassi Yu
chen
Florian Preinstorfer
Gautier DI FOLCO
grassofhust
italiafreeware
kikijump
Kirill Klenov
liu
Lowe Thiderman
twinside
Vincent Berthoux
@bstaint
胡晋

View file

@ -0,0 +1,25 @@
- 4-space indent:
Used in snippet file.
Consistent with different 'tabstop', 'shiftwidth' setting.
- tab indent:
Used internally in XPTemplate.
Produced by converting 4 leading space to one tab.
These two above are VIM setting irrelavent. Snippet file can use either of
them, but 4-space indent is recommended.
- space indent:
Produced by expanding a `tab` char to `&shiftwidth` spaces.
These spaces occupies the same room as actual indent.
This is the second last step before putting text onto screen.
space indent texts are used internally.
Wrapped text is passing through in this style.
- actual indent:
Produced by convert `&tabstop` space to one tab if 'expandtab' not set.
This is the actual indent
The last two are VIM setting relavent.

View file

@ -0,0 +1,354 @@
*xpt-option*
==============================================================================
Table of Content ~
|g:xptemplate_always_show_pum|
|g:xptemplate_brace_complete|
|g:xptemplate_break_undo|
|g:xptemplate_bundle|
|g:xptemplate_close_pum|
|g:xptemplate_cwd_snippet|
|g:xptemplate_debug_log|
|g:xptemplate_highlight|
|g:xptemplate_highlight_nested|
|g:xptemplate_hook_before_cr|
|g:xptemplate_lib_filter|
|g:xptemplate_minimal_prefix|
|g:xptemplate_move_even_with_pum|
|g:xptemplate_ph_pum_accept_empty|
|g:xptemplate_pum_quick_back|
|g:xptemplate_pum_tab_nav|
|g:xptemplate_snippet_folders|
|g:xptemplate_strict|
|g:xptemplate_strip_left|
|g:xptemplate_vars|
*g:xptemplate_always_show_pum*
{default:0}
If set to 1, snippets is not triggered but popup menu shows even when
text user typed before cursor matches a snippet name.
For example, you have three snippets defined of names: "for", "forever"
and "forr". Typing "for<C-\>" results in a popup menu if
|g:xptemplate_always_show_pum| set to 1: >
for
|for |
|forloop |
|forr |
< Otherwise, "for<C-\>" triggers snippet "for".
See also: |g:xptemplate_key_force_pum|.
*g:xptemplate_brace_complete*
{default:1}
If set to 1, bracket characters are automatically expanded to bracket
pairs. For example typing "(" results in: >
( )
\______| cursor stops in mid of pairs of bracket
< "(", "[", "{", "'" and '"' are affected by this setting.
If set to string, only bracket or quote chars included in this setting
will be mapped. For example: >
let g:xptemplate_brace_complete = '([{'
< With this setting, quotes are not mapped.
*g:xptemplate_break_undo*
{default:0}
If set to 1, undo sequence will be broken with |i_CTRL-G_u| before
snippet triggered. This would help on rolling back when mistake was
made.
*g:xptemplate_bundle*
This option specifies what libraries will always be load to its file
type. For example: >
let g:xptemplate_bundle = 'javascript_jquery'
< This tells XPT to load jquery snippet to javascript language.
Or: >
let g:xptemplate_bundle = 'javascript_jquery,c_*'
< It tells XPT to load jquery, and all supplied library snippets for C
language.
Another way to load bundles is |g:XPTaddBundle()|.
*g:xptemplate_close_pum*
{default:0}
If set to 1, when trigger key(|g:xptemplate_key|) is pressed, before
doing anything, popup menu will be closed.
*g:xptemplate_cwd_snippet*
{default:0}
Set this to 1 to enable each vim buffer to automatically load file
".xpt.vim" from current working directory, as snippet file specific to
current directory( or project ).
Current ".xpt.vim" accepts only the most simple form of snippet, the
function call form: >
call XPTemplate( 'foo', '`foo^ says hello' )
<
*g:xptemplate_debug_log*
{default:''}
This option specifies whether and where to store debug log emitted
during xptemplate running. Unless you are a developer of xptempalte,
do not touch it.
Empty string disables any logging.
Non-empty string is interpreted as log file path. "~/" at start will
be replaced with "$HOME/".
Example: >
let g:xptemplate_debug_log = '~/.xpt.log'
<
*g:xptemplate_highlight*
{default:'next'}
Specifies which place holders are high lighted. The value of
|g:xptemplate_highlight| is a comma separated string.
Possible values are: "current", "following" and "next". Example: >
let g:xptemplate_highlight = 'following,next'
<
"current" lets XPTemplate highlight the place holder you are currently
editing. See |XPTcurrentPH|.
For example the first "i" in "for" snippet of C language: >
for ( i = 0; i < len; ++i ) {
\__________________________ highlighted
<
"following" lets XPTemplate highlight slave place holders which are
updated automatically. See |XPTfollowingPH|.
For example the second and third "i" in "for" snippet of C language: >
for ( i = 0; i < len; ++i ) {
\__________\________ highlighted
<
"next" lets XPTemplate highlight the place holders you are going to
edit. See |XPTnextItem|.
For example the "0" and "len" if "for" snippet of C language: >
for ( i = 0; i < len; ++i ) {
\______\\\_____________ highlighted
<
Set |g:xptemplate_highlight| to '' to disable highlight.
*g:xptemplate_highlight_nested*
{default:0}
If set to 1, highlight is also applied to outer snippet, not only the
deepest nested one. For example, If set to 1, the following positions
are highlighted: >
________________________| highlighted
_/ _/ ___/
for ( call( me ) = 0; call < len; call++ ) {
/* cursor */
~~~~~~~~~~~\__________________________| highlighted
}
< The first highlight position is from nested snippet "(". Others are
from outer snippet "for".
*g:xptemplate_hook_before_cr*
{default:''}
Add additional action before default xptemplate action when <CR>
pressed.
By default, xptemplate override key mapping of <CR>(local to
buffer)every time starting to applying a snippet. This might change
user prefered <CR> behavior if user has his own key mapping of <CR>
defined.
This conf let user to fix issues like this.
The following line in .vimrc appends "abc" every time <CR> pressed
during applying snippet: >
let g:xptemplate_hook_before_cr = 'abc'
<
And this appends current time every time <CR> pressed: >
fun! s:OutputDate()
return strftime('%c')
endfunction
inoremap <expr> <Plug>do_my_work <SID>OutputDate()
let g:xptemplate_hook_before_cr = '<Plug>do_my_work'
<
NOTE:
|g:xptemplate_hook_before_cr| does not accept <SID>.
And if you want to use <expr> mapping with
|g:xptemplate_hook_before_cr| , you need a in-the-middle
mapping like it does in the second example.
*g:xptemplate_lib_filter*
{default:.}
Value: unset: do not filter, load any snippet found.
string: regular expression.
list: list of regular expression.
If set, XPT loads only snippets(*.xpt.vim) from 'runtimepath' that
matches it or one of its elements.
NOTE: This option tries to match actual path of a snippet file.
Symbolic link would be resolved.
NOTE: Included snippet like "*/_common/common.xpt.vim" is essential
for other snippet to work thus it won't be affected by this
option.
For example: >
let g:xptemplate_lib_filter = [
\ '/my_snippets\>',
\ '/all_user_snippets/ftplugin/xml/' ]
< The above setting tells XPT to ignore snippet supplied by XPT but to
load only "*/my_snippets/ftplugin/*/*.xpt.vim", and use only "xml"
snippets from "*/all_user_snippets/ftplugin/xml/*.xpt.vim".
It would works the same as with: >
let g:xptemplate_lib_filter = '/my_snippets\>\|/all_user_snippets/ftplugin/xml/'
<
*g:xptemplate_minimal_prefix*
{default:0}
Posssible values: number or "full".
If set it to a number( N ), it means snippet is triggered( or pum
shows ) only when there are at least N |word| letters before cursor.
If set to "full", |g:xptemplate_key| searches for a snippet of name
matching exactly the word before cursor.
For example, you have only one snippet defined with name "xpt". The
following input will trigger "xpt" snippet, if
|g:xptemplate_minimal_prefix| set to 0 ( it also works with value 1 and
2, but not with 3 ): >
xp<C-\>
< "<C-\>" is the default trigger key.
If |g:xptemplate_minimal_prefix| set to "full", the above input can not
trigger "xpt" snippet.
*g:xptemplate_move_even_with_pum*
{default:0}
If set to 1, |g:xptemplate_nav_next| does not care whether pop up menu
shown or not. It will always move cursor to next item.
Otherwise, |g:xptemplate_nav_next| fall back to original mapping. This
could be helpfull for xpt working with supertab together.
*g:xptemplate_ph_pum_accept_empty*
{default:1}
When set to 1 popup menus for place holders accepts an empty input. So
when nothing typed pressing <Tab> closes the popup menu and sends the
cursor to the next place holder.
When not set <Tab> expands the text to the longest match and keeps the
popup menu open.
*g:xptemplate_pum_quick_back*
{default:1}
With popup menu, pressing "<BS>" removes minimal chars to reveil
more options.
If this is set to 0, pressing "<BS>" removes only 1 char.
For example, popup menu created with 3 options: >
"foo", "fooba", "foobar"
<
Typing "fooba" shrinks menu to: >
fooba
foobar
< Now pressing "<BS>" will remove 2 chars: "ba", and leave "foo", the
longest prefix that has 3 options.
Pressing "<BS>" again will remove "foo".
NOTE: Very large list might hang VIM for seconds. In this case set
this to 0 to get better performance.
This feature depends on a prefix dictionary of all of the
options. The prefix dictionary will be created every time
popup menu is called.
*g:xptemplate_pum_tab_nav*
{default:0}
Set to 1 to use <tab>/<S-tab>( shift + tab ) to navigate through pop
up menu. <tab> behaves like <C-n> and <S-tab> behaves like <C-p>. And
<CR> expands snippet.
*g:xptemplate_snippet_folders*
{default:[]}
NOTE: Unless you really want XPTemplate to touch your 'runtimepath',
do NOT use this. This setting changes 'runtimepath' and is
less recommended to use than 'runtimepath'. As you may already
know well about 'runtimepath' and 'ftplugin', it is better for
you to organize snippet files yourself, with 'runtimepath'.
A list to specify which other folders are used as snippet folders.
For example: >
let g:xptemplate_snippet_folders = [
\ $HOME . '/my_snippets',
\ '/all_user_snippets' ]
< Thus the snippet file "$HOME/my_snippets/ftplugin/c/my.c.xpt.vim" can
be loaded to C files.
And "/all_user_snippets/ftplugins/html/all.html.xpt.vim" can be loaded
to HTML files.
*g:xptemplate_strict*
{default:2}
Set to 0 to let XPTemplate do the best maintaining snippet rendering,
even if you have changed text outside of place holders.
Set to 1 to prevent incautious changing text outside place holders.
Otherwise you are free to change text outside of place holders.
Set to 2 to let XPTemplate stop rendering if ANY changes taken to text
outside of place holders.
Example : >
let g:xptemplate_strict = 1
<
*g:xptemplate_strip_left*
{default:1}
When set to 1 wrapper snippets |xpt-wrapper-snippet| remove space
before the first line.
*xpt-personal-var* *g:xptemplate_vars*
g:xptemplate_vars sets personal information variables used in
snippets, like "author" and "email", see |xpt-snippet-variable|.
Variables set with g:xptemplate_vars have the highest priority and
override any other variables set in *.xpt.vim. Syntax: >
let g:xptemplate_vars = 'name=value&name=value...'
< Example: >
let g:xptemplate_vars = '$author=xp\ \&\\\&123&$email=bal@bla'
let g:xptemplate_vars = 'author=xp\ \&\\\&123&email=bal@bla'
< Both the 2 lines above result in: >
'xp\ &\&123' and 'bal@bla'
< Or: >
let g:xptemplate_vars = exists('g:xptemplate_vars') ?
\ g:xptemplate_vars . '&' . '$other=bla'
\ : '$other=bla'
<
Entries are separated with '&'.
You can also set these settings in ftplugin/_common/personal.xpt.vim
in your runtime path using XPTvar |xpt-snippet-variable| (see also
|xpt-customize-variable|).
" vim: tw=78:ts=8:sw=8:sts=8:noet:ft=help:norl:

View file

@ -0,0 +1,107 @@
*xpt-snippet-function*
==============================================================================
Table of Content ~
|Build|
|BuildSnippet|
|Echo|
------------------------------------------------------------------------------
|xpt-snippet-function| can be used in :
|xpt-snippet-instant-value|
|xpt-snippet-preset-value|
|xpt-snippet-default-value|
|xpt-snippet-post-filter|
|xpt-placeholder-ontime-filter|
To define |xpt-snippet-function|, the function container must be
fetched by using |XPTfuncs()|. For example : >
let s:f = XPTfuncs()
fun! s:f.c_printfElts( v )
...
endfunction
< Then function 'c_printfElts' can be used in the snippet : >
XPT printf " printf\(...)
XSET elts=c_printfElts( R( 'pattern' ) )
printf( "`pattern^"`elts^ )
<
NOTE By convention the names of |xpt-snippet-function|s supplied by
XPTemplate start with an upper-case letter. User defined
function names should starts with a lower-case letter.
------------------------------------------------------------------------------
*Build()*
Build({snippet_text})
Build a piece of snippet text to replace the place holder on which
Build() is called.
Argument {snippet_text} is the content of snippet to build.
After calling it, place holder is removed and the first place holder
in this piece of snippet built is selected.
Context: >
XSET ph=Build('`a^ = `0^')
XSET ph|post=Build('`a^ = `0^')
<
See also: |BuildSnippet()|
*BuildSnippet()*
BuildSnippet({snippet})
Build an existent snippet to replace the place holder on which
BuildSnippet() is called.
Argument {snippet} is the name of snippet to build.
After calling it, place holder is removed and the first place holder
in this piece of snippet is selected.
Example snippets: >
XPT parent
XSET x=BuildSnippet( "child" )
-`x^=
XPT child
(`a^, `b^)
<
Type: >
parent<C-\>
< Got: >
-(a, b)=
< {a} and {b} is place holder
Context: >
XSET ph=BuildSnippet('a')
XSET ph|post=BuildSnippet('a')
<
See also: |Build()|
*Echo()*
Echo({string})
Put literal text {string} where it is called.
{string} can be any valid expression.
Place holders in {string} will not be built.
Context it works in: >
`Echo('a')^
XSET ph=Echo('a')
XSET ph|def=Echo('a')
XSET ph|pre=Echo('a')
XSET ph|post=Echo('a')
<
Example: >
XPT now
`Echo( strftime("%c") )^
<
See also: |Build()| |BuildSnippet()|
See also: |xpt-snippet-XSET|
" vim: tw=78:ts=8:sw=8:sts=8:noet:ft=help:norl:

View file

@ -0,0 +1,629 @@
*XPTemplate* For Vim version 7.2. Last change: 2009 Nov 08
*xptemplate*
*xpt*
XP's Snippet Template engine
by drdr.xp
drdr.xp@gmail.com
XPTemplate is a snippet rendering engine.
|xpt-install|
|xpt-usage|
|xpt-personal-var|
|xpt-feature|
|xpt-option|
|xpt-key-bind|
|xpt-tips|
|xpt-with-supertab|
|xpt-customize|
|xpt-write-snippet|
|xpt-snippet-syntax|
|xpt-snippet-tutorial|
|xpt-api|
*xpt-install*
Copy files and directories into one of your 'runtimepath's.
*xpt-usage*
To see what snippets have been defined for the current filetype, press
<C-r><C-r><C-\> in insert mode. See |xpt-key-pum|.
In insert mode type the snippet name and press <C-\> to insert a
snippet. Use <Tab> to navigate through the snippet template.
For example when editing a C file: >
for<C-\>
< generates: >
for ( i = 0; i < len; ++i ) {
/* cursor */
}
< The first "i" being selected is the current item you are editing. "0"
is the next item and you can navigate to it by pressing <Tab>.
To change the snippet trigger (<C-\>) see |xpt-key-trigger|, to change
the navigate key (<Tab>) see |xpt-key-navigate|.
NOTE with some European keyboards <C-\> does NOT work. In this case
you need to specify another key to trigger snippets.
Now type "abc", this results in: >
////````````````````````````| edit area
////
//// ////`````````````````| lively updated
//// //// ////`````'
for ( abc = 0; abc < len; ++abc ) {
/* cursor */
}
< Now press <Tab>, the cursor jumps to "0", the next item: >
//```````````````````````| focus here
for ( abc = 0; abc < len; ++abc ) {
/* cursor */
}
< After pressing <Tab> twice the snippet ends up with cursor staying at
line 2, column 8 (or the value of 'softtabstop'): >
for ( abc = 0; abc < len; ++abc ) {
} \\___________________________| cursor stays here
< The usage is described in more detail below.
For more information regarding the syntax of snippets see
|xpt-snippet-syntax|. To customize settings see |xpt-option|.
*xpt-feature*
Live typing update
Navigate forward and backward |xpt-key-navigate|
Popup hint |xpt-popup|
|xpt-snippet-hint|
Ordered place holders |xpt-snippet-ComeFirst|
Embedded functions and variables |xpt-snippet-function|
Repeatable snippet generation |xpt-repetition|
Nested snippets |xpt-nested|
Wrapper snippets |xpt-wrapper-snippet|
Inclusion on snippet level or file level|xpt-snippet-include|
|xpt-snippet-XPTinclude|
Template priority |xpt-snippet-priority|
Named item or anonymous item |xpt-snippet-item|
Default value |xpt-snippet-default-value|
Preset value |xpt-snippet-preset-value|
Snippet Bundle/Library Support |xpt-bundle|
and more...
*xpt-name-matching*
See |xpt-snippet-name-matching-rule|.
*xpt-popup*
If you type nothing or an incomplete snippet key and press <C-\>, a
popup menu shows up listing all possible snippet keys. For example: >
fo<C-\>
< Shows: >
for
forever
fornn
forr
<
After selecting the item from the popup menu, press <C-\> again to
trigger the snippet.
*xpt-nested*
Templates can be expanded inside another template. There is no
difference between using a nested template or a top-level template.
For example, when you edit a C file type switch<C-\> to generate a
switch block template: >
switch (fn) {
case 0 :
<-------------- cursor stops here after two <Tab>s
break;
...
default:
}
< Now the cursor stops between "case 0 :" and "break;", type: >
if<C-\>
< It becomes: >
switch (fn) { | upper level snippet
case 0 : |
if () { . nested snippet
.
} .
break; | upper level snippet
... |
default: |
|
} |
< Type <Tab>, <Tab>.. to navigate out of the nested snippet: >
switch (fn) {
case 0 :
if () {
}
break;
default:
<--------------cursor stops here
}
< Now cursor stops after "default:" and we get out back to the "switch"
snippet.
==============================================================================
*`...^* *xpt-...* *xpt-repetition*
Some segments can be defined as repeatable, for example the "case"s in
"switch". Specifying the repetition part is easy, just wrap the part
you want it to repeat with `...n^. n is a number and can be omitted if
only one repetition part is used.
Take the case from "switch": >
XPT switch
switch (`^) {
`...^ | repetition part
case `^0^ : |
`^ |
break; |
`...^ |
default:
`^
}
<
When you trigger a repetition template it works as below: >
switch () { <------- cursor stays here
`...^
default:
`^
}
< Press <Tab>, the |`...^| is selected. Press <Tab> again to expand the
repetition part. Or press <Cr> |xpt-key-clear| to cancel the
repetition part. These 4 lines are expanded: >
switch () {
case `^ : | expanded
`^ |
break; |
`...^ |
default:
`^
}
< Enter the repetition part. You may have noticed there is another
|`...^|, that is the another repeat trigger.
Press <Tab> 3 times: >
switch () {
case 0 :
break;
case `^ : | selected repetition part
`^ |
break; |
`...^ |
default:
`^
}
<
See also |xpt-snippet-repetition|.
*xpt-wrapper-snippet*
Wrapper snippets can be triggered in visual mode, place holder marked
as "wrap" is replaced with the text selected in visual mode.
Definition of wrapper snippet has no differences from normal
snippet except it declaring a place holder as wrapping holder. For
example: >
________/---------------------| wrapper declaration
XPT if wrap=job
if (`condition^){
`job^
}
<
For example the following snippet: >
XPT call_ wrap=wrapped
`name^(`wrapped^`, `^)`cursor^
< Use command |V| to select some text and press <C-\>. The selected text
is yanked and popup menu shows.
For example we have one line of text as below: >
a, b
< Select this line with command |V|.
And then press <C-\>, choose "call_" in the popup menu.
And finally it results in : >
name(a, b)
<
NOTE Wrapper snippet declared with "wraponly" can only be triggered
in visual mode, not in insert mode
*xpt-context*
You can define snippets that can only be triggered in certain
circumstances, for example in certain syntax items. Defining context
depended snippets is done by adding another parameter to the
XPTemplate call "{'syn' : 'the context name'}" : >
XPT para syn=comment
@param {`Object^} `name^ `desc^
< Now the snippet "para" can be only triggered in syntax items named
"comment".
==============================================================================
*xpt-key-bind*
Options can be set in |.vimrc| to modify XPTemplate's behaviors.
Key mappings:
|<Plug>XPTrawKey|
|g:xptemplate_key|
|g:xptemplate_key_pum_only|
|g:xptemplate_key_force_pum|
|g:xptemplate_key_visual|
|g:xptemplate_nav_next|
|g:xptemplate_nav_prev|
|g:xptemplate_nav_cancel|
|g:xptemplate_goback|
|g:xptemplate_to_right|
|g:xptemplate_fallback|
See also: |xpt-option|.
*<Plug>XPTrawKey*
Key mapping defined as: >
exe "inoremap <silent> <Plug>XPTrawKey " g:xptemplate_key
<
*i_<C-\>* *v_<C-\>* *xpt-key-trigger* *g:xptemplate_key*
{default:<C-\>}
The key to trigger snippets in insert mode.
Use |g:xptemplate_key| to change this mapping. Example: >
let g:xptemplate_key = '<Tab>'
<
NOTE: You can set this key to <Tab>, as most users do, for
convenience. In this case pressing <Tab> twice results in a normal
<Tab> if there is no snippet key matched.
*i_<C-r><C-r><C-\>* *xpt-key-pum* *g:xptemplate_key_pum_only*
{default:<C-r><C-r>g:xptemplate_key}
Show pop up menu at cursor position. Example: >
let g:xptemplate_key_pum_only = '<S-Tab>'
< By default, this key map is set to '<C-r><C-r>' concatenated with
|g:xptemplate_key| : '<C-r><C-r><C-\>'.
*g:xptemplate_key_force_pum*
{default:<C-r>g:xptemplate_key}
Behave like that with |g:xptemplate_always_show_pum| set.
If more than one snippet starts with( or exactly equals to ) the text
before cursor, pop up menu shows.
This key triggers snippet only when there is only one snippet of name
starts with the text before cursor.
See also: |g:xptemplate_always_show_pum|.
*s_<C-\>* *xpt-key-visual* *g:xptemplate_visual
{default:g:xptemplate_key}
The key to trigger snippets in visual mode.
Use |g:xptemplate_key_visual| to change this mapping. Example: >
let g:xptemplate_key_visual = '<Tab>'
<
*i_<tab>* *s_<tab>* *xpt-key-navigate* *g:xptemplate_nav_next*
{default:<Tab>}
After a snippet was triggered, this key navigates to the next item.
Use |g:xptemplate_nav_next| to change this mapping. Example: >
let g:xptemplate_nav_next = '<C-j>'
<
*i_<S-tab>* *s_<S-tab>* *g:xptemplate_nav_prev*
{default:<S-Tab>}
After a snippet was triggered, press this key to navigate back to the
previous item.
Use |g:xptemplate_nav_prev| to change this mapping. Example: >
let g:xptemplate_nav_prev = '<C-k>'
<
*s_<CR>* *xpt-key-clear* *g:xptemplate_nav_cancel*
{default:<Cr>}
Press to clear current place holder and jump to next.
Use |g:xptemplate_nav_cancel| to change this mapping. Example: >
let g:xptemplate_nav_cancel = '<C-c>'
<
*s_<C-l>* *xpt-key-goto-right* *g:xptemplate_to_right*
{default:<C-l>}
When a place holder is initially selected jump to the end of current
place holder and go into insert mode.
Use |g:xptemplate_to_right| to change this mapping. Example: >
let g:xptemplate_to_right = '<C-;>'
<
*g:xptemplate_fallback*
{default:<Plug>XPTrawKey}
If a try to trigger snippet( by pressing |g:xptemplate_key| ) does not
produce any match( full or partial ), contents of this setting is
output instead.
NOTE: Contents output is similar to user typing. And they CAN be
remapped. This may produce a invoke loop.
The default value of this setting is the literal text of
|g:xptemplate_key|, which is defined by |<Plug>XPTrawKey|.
For example, if you want a completion-popup menu to show when no snippet
matched, you can have this line added into your |.vimrc|: >
let g:xptemplate_fallback = '<C-n>'
<
*n_<C-g>* *i_<C-g>* *xpt-key-goback* *g:xptemplate_goback*
{default:<C-g>}
When you move the cursor outside of place holder you are editing,
pressing this key (in insert mode or normal mode) moves cursor back to
current place holder and selects the place holder text in select mode.
Use |g:xptemplate_goback| to change this mapping. Example: >
let g:xptemplate_goback = '<C-g>'
<
*xpt-customize-highlight*
You can specify which highlight Group to use for each kind of
highlight.
*XPTcurrentPH*
{default:DiffChange}
The highlight group of place holder you are editing. Example: >
highlight link XPTcurrentPH Visual
< This statement tells XPTemplate to use the highlight group "Visual" to
highlight "current" items. See |g:xptemplate_highlight|.
You can also define your highlight group directly. Example: >
highlight XPTcurrentPH gui=none guibg=blue
<
*XPTfollowingPH*
{default:CursorLine}
The highlight group of slave place holders you are editing. Like
|XPTcurrentPH|.
*XPTnextItem*
{default:IncSearch}
The highlight group of item you are going to edit. Like
|XPTcurrentPH|.
*xpt-bundle*
A bundle is a collection of snippets for a certain purpose. For
example a library support bundle like
"ftplugin/javascript/jquery.xpt.vim".
XPTemplate supplies two ways to load bundles: |g:xptemplate_bundle|
and |g:XPTaddBundle()|.
==============================================================================
*xpt-tips*
Want to use XPTemplate with ... together?
|xpt-with-supertab|
*xpt-with-supertab*
If you want to use supertab's <TAB> but you have also set XPT to use
<TAB>.
==============================================================================
*xpt-customize*
Global customization can be done with |xpt-option|.
Two options relate to personal settings:
|g:xptemplate_vars|
This is a easy way to set up your personal information like your name
and email address.
This option actually sets up two variables "$author" and "$email". See
|xpt-snippet-variable|
|g:xptemplate_bundle|
This option sets up which library you want to load.
*xpt-customize-variable*
|xpt-snippet-variable| are used to configure the snippet format.
Customization variables should be defined in a snippet file( like a
file in |xpt-personal-folder|) with "personal" priority, to guarantee
it will not be overrided by other snippet with lower priority. See
|xpt-priority-value|.
To create a snippet file to define your variables, see
|xpt-write-lang-snippet|.
See also: |xpt-customize-variable-format|
|xpt-customize-variable-space|
|xpt-customize-variable-datetime|
*xpt-customize-variable-format*
Each snippet has some variable defined to configure language format.
This is useful when some snippet are shared between languages, like
for loops in C and CPP or to accommodate different user preferences.
Brackets style variables may be defined as below: >
" if () ** {
" else ** {
XPTvar $BRif ' '
" } ** else {
XPTvar $BRel \n
" for () ** {
" while () ** {
" do ** {
XPTvar $BRloop ' '
" struct name ** {
XPTvar $BRstc ' '
" int fun() ** {
" class name ** {
XPTvar $BRfun ' '
< The "**" in comment marks where this variable should be used.
For example following is "for" snippet for both C and CPP: >
XPT for hint=for\ (..;..;++)
for (`i^ = `0^; `i^ < `len^; ++`i^)`$BRloop^{
`cursor^ ******************
}
< In C language "$BRloop" is set to ' '. In CPP "$BRloop" is set to
"\n". You can find them in "ftplugin/c/c.xpt.vim" and
"ftplugin/cpp/cpp.xpt.vim".
In C this snippet results in: >
for ( i = 0; i < 10; ++i ) {
}
< In CPP this snippet results in: >
for ( i = 0; i < 10; ++i )
{
}
<
*xpt-customize-variable-space*
Another set of variables is defined to customize spaces. They are: >
" int fun ** (
" class name ** (
XPTvar $SPfun ''
" int fun( ** arg ** )
" if ( ** condition ** )
" for ( ** statement ** )
" [ ** a, b ** ]
" { ** 'k' : 'v' ** }
XPTvar $SParg ' '
" if ** (
" while ** (
" for ** (
XPTvar $SPcmd ' '
" a = a ** + ** 1
" (a, ** b, ** )
" a ** = ** b
XPTvar $SPop ' '
< For example function snippet defined as below: >
XPT fun
int fun(`$SParg^`args^`$SParg^)
< If "$SParg" is set to ' ', snippet results in: >
int fun( args )
< If "$SParg" is set to '', snippet results in: >
int fun(args)
<
*xpt-customize-variable-datetime*
Variables discussed in this section defines how "date" and "time"
snippet displayed.
"$DATE_FMT" defines "date" snippet format. Default format is: >
XPTvar $DATE_FMT '%Y %b %d'
<
"$TIME_FMT" defines "time snippet format. Default format is: >
XPTvar $TIME_FMT '"%H:%M:%S"'
<
"$DATETIME_FMT" defines "datetime()" function format. Default format is: >
XPTvar $DATETIME_FMT '%c'
<
"datetime()" has no default snippet using it.
*xpt-personal-folder* *xpt-write-snippet*
Snippet file is actually |ftplugin| and with file extension
".xpt.vim", like "c.xpt.vim". So you can manage snippet files just
like the way you manage |ftplugin|.
You have THREE place to put your own snippets:
Path_to_xpt/personal
Recommended. Enough for most users. What you need to do is
putting snippet files into this folder.
Folders in |g:xptemplate_snippet_folders|
Deprecated, use 'runtimepath'.
Other 'runtimepath'
Need to manage 'runtimepath' yourself.
Details are discussed in following section.
*xpt-write-lang-snippet*
You can add snippets of new language, or add snippets to currently
supplied languages, in the same way.
Create a new file in some |ftplugin| directory. For example, if you want
to add some PHP snippet, you can create file: >
path_to_xpt/personal/ftplugin/php/your_snippets.xpt.vim
< Or: >
&runtimepath/ftplugin/php/your_snippets.xpt.vim
< &runtimepath can be ~/.vim in Unix like system, or ~/vimfiles/ folder
in Windows. See 'runtimepath'.
NOTE It is strongly recommended to add your own snippets in
"path_to_xpt/personal".
The file name "your_snippets.xpt.vim" has no limitation except it must
end with ".xpt.vim".
And then write your snippets in that file. Restart Vim to load them.
See |xpt-snippet-syntax| and |xpt-snippet-tutorial|.
*xpt-write-common-snippet*
If you want to add some snippets which don't belong to any language,
or you want to set multiple variables, you can use the "personal
common" snippet file.
1. Rename "personal/ftplugin/_common/personal_example.xpt.vim" to
"personal/ftplugin/_common/personal.xpt.vim". Or create one from
scratch.
2. Add your snippets into the "personal.xpt.vim".
"personal.xpt.vim" is loaded by _common/common.xpt.vim and has the
highest priority. Thus it's always loaded and there are no other
snippets overriding yours.
Example personal/ftplugin/_common/personal.xpt.vim : >
XPTemplate priority=personal
XPTvar $author your_name
XPTvar $email your_email
XPT yoursnippet " tips here
bla bla
< See |xpt-snippet-syntax| and |xpt-snippet-tutorial|.
==============================================================================
" vim:tw=78:ts=8:sw=8:sts=8:noet:ft=help:norl:

View file

@ -0,0 +1,19 @@
edit x.c
type:
"
wait
<space>
following config makes it break to:
"wait""
but it should be:
"wait "
i wait * wait<C-O>:echoh HintHL|echo "pid_t wait(int * status)"|echoh None<CR>
Last set from ~/bash.xp/vim.xp/plg-git/Hints-for-C-Library-Functions/ftplugin/c/hints_man2.vim
i waitpid * waitpid<C-O>:echoh HintHL|echo "pid_t waitpid(pid_t pid, int * status, int options)"|echoh None<CR>
Last set from ~/bash.xp/vim.xp/plg-git/Hints-for-C-Library-Functions/ftplugin/c/hints_man2.vim
i wait4 * wait4<C-O>:echoh HintHL|echo "pid_t wait4(pid_t pid, int * status, int options, struct rusage * rusage)"|echoh None<CR>
Last set from ~/bash.xp/vim.xp/plg-git/Hints-for-C-Library-Functions/ftplugin/c/hints_man2.vim
i wait3 * wait3<C-O>:echoh HintHL|echo "pid_t wait3(int * status, int options, struct rusage * rusage)"|echoh None<CR>
Last set from ~/bash.xp/vim.xp/plg-git/Hints-for-C-Library-Functions/ftplugin/c/hints_man2.vim

View file

@ -0,0 +1 @@
au BufRead,BufNewFile *.xpt.vim set filetype=xpt.vim

View file

@ -0,0 +1,5 @@
augroup XPTLogFiletype
au!
au BufRead,BufNewFile xpt-debug.log set filetype=xptlog
augroup END

View file

@ -0,0 +1,7 @@
You should *NOT* be here.
Please keep in mind that you should *NEVER* modify files in this folder.
I supposed you are here to add new snippets or refine some of them.
Please do it in ./personal folder. See :h xpt-personal-folder .

View file

@ -0,0 +1,11 @@
" NOTE: You can include this file into which uses C comment format. But It is
" recommended to include _comment/doubleSign (or singleSign,
" singleDouble) directly.
XPTemplate priority=like
XPTvar $CL /*
XPTvar $CM *
XPTvar $CR */
XPTinclude
\ _comment/doubleSign

View file

@ -0,0 +1,13 @@
" NOTE: You can include this file into which uses CPP comment format. But It
" is recommended to include _comment/doubleSign (or singleSign,
" singleDouble) directly.
XPTemplate priority=like-
XPTvar $CL /*
XPTvar $CM *
XPTvar $CR */
XPTvar $CS //
XPTinclude
\ _comment/singleDouble

View file

@ -0,0 +1,65 @@
XPTemplate priority=all-
let s:f = g:XPTfuncs()
" snippets for language whose comment sign is 2 signs, like c:"/* */"
" TODO friendly cursor place holder
XPTinclude
\ _common/common
fun! s:f._xCommentMidIndent()
let l = self.GetVar( '$CL' )
let m = self.GetVar( '$CM' )
if len( l ) <= len( m )
return ''
else
return ' '[ : len( l ) - len( m ) - 1 ]
endif
endfunction
fun! s:f._xCommentLeftWithoutMid()
let l = self.GetVar( '$CL' )
let m = self.GetVar( '$CM' )
if l == '' || m == ''
return l
endif
if l[ -len( m ) : ] == m
return l[ : -len( m ) -1 ]
else
return l
endif
endfunction
XPT _d_comment hidden wrap=what " $CL .. $CR
`$CL^ `what^^ `$CR^`^
XPT _d_commentBlock hidden wrap " $CL ..
`$_xCommentLeftWithoutMid^`$CM `cursor^
`$_xCommentMidIndent$CR^
XPT _d_commentDoc hidden wrap " $CL$CM ..
`$CL^`$CM^
`$_xCommentMidIndent$CM `cursor^
`$_xCommentMidIndent$CR^
XPT _d_commentLine hidden wrap=what " $CL .. $CR
XSET what=
`$CL `what` $CR^`^
XPT comment alias=_d_comment
XPT commentBlock alias=_d_commentBlock
XPT commentDoc alias=_d_commentDoc
XPT commentLine alias=_d_commentLine

View file

@ -0,0 +1,19 @@
XPTemplate priority=all-2
XPTinclude
\ _comment/common
\ _comment/singleSign
\ _comment/doubleSign
XPT comment alias=_d_comment
XPT commentBlock alias=_d_commentBlock
XPT commentDoc alias=_d_commentDoc
XPT commentLine alias=_s_commentLine
XPT commentLine2 alias=_d_commentLine

View file

@ -0,0 +1,42 @@
" priority is a bit lower than 'spec'
XPTemplate priority=spec+
echom "_comment/pattern is deprecated."
" XPTvar $CL Warn_$CL_IS_NOT_SET
" XPTvar $CM Warn_$CM_IS_NOT_SET
" XPTvar $CR Warn_$CR_IS_NOT_SET
" XPTvar $CS Warn_$CS_IS_NOT_SET
" ================================= Snippets ===================================
if has_key(s:v, '$CL') && has_key(s:v, '$CR')
call XPTdefineSnippet('cc', {'hint' : '$CL $CR'}, [ '`$CL^ `cursor^ `$CR^' ])
call XPTdefineSnippet('cc_', {'hint' : '$CL ... $CR'}, [ '`$CL^ `wrapped^ `$CR^' ])
" block comment
call XPTdefineSnippet('cb', {'hint' : '$CL ...'}, [
\'`$CL^',
\' `$CM^ `cursor^',
\' `$CR^' ])
" block doc comment
call XPTdefineSnippet('cd', {'hint' : '$CL$CM ...'}, [
\'`$CL^`$CM^',
\' `$CM^ `cursor^',
\' `$CR^' ])
endif
" line comment
if has_key(s:v, '$CS')
call XPTdefineSnippet('cl', {'hint' : '$CS'}, [ '`$CS^ `cursor^' ])
else
call XPTdefineSnippet('cl', {'hint' : '$CL .. $CR'}, [ '`$CL^ `cursor^ `$CR^' ])
endif

View file

@ -0,0 +1,19 @@
XPTemplate priority=all-2
XPTinclude
\ _comment/common
\ _comment/singleSign
\ _comment/doubleSign
XPT comment alias=_s_comment
XPT commentBlock alias=_s_commentBlock
XPT commentDoc alias=_d_commentDoc
XPT commentLine alias=_s_commentLine
XPT commentLine2 alias=_d_commentLine

View file

@ -0,0 +1,30 @@
XPTemplate priority=all-
XPTinclude
\ _comment/common
XPT _s_comment hidden wrap " $CS ..
`$CS `cursor^
XPT _s_commentBlock hidden wrap " $CS ..
`$CS `cursor^
XPT _s_commentDoc hidden wrap " $CS ..
`$CS^
`$CS `cursor^
`$CS^
XPT _s_commentLine hidden wrap " $CS ..
`$CS `cursor^
XPT comment alias=_s_comment
XPT commentBlock alias=_s_commentBlock
XPT commentDoc alias=_s_commentDoc
XPT commentLine alias=_s_commentLine

View file

@ -0,0 +1,11 @@
" NOTE: You can include this file into which uses XML comment format. But It is
" recommended to include _comment/doubleSign (or singleSign,
" singleDouble) directly.
XPTemplate priority=spec
XPTvar $CL <!--
XPTvar $CR -->
XPTinclude
\ _comment/doubleSign

View file

@ -0,0 +1,40 @@
XPTemplate priority=all-
let s:f = g:XPTfuncs()
" ========================= Function and Variables =============================
" draft increment implementation
fun! s:f.CntD() "{{{
let ctx = self.renderContext
if !has_key(ctx, '__counter')
let ctx.__counter = {}
endif
return ctx.__counter
endfunction "}}}
fun! s:f.CntStart(name, ...) "{{{
let d = self.CntD()
let i = a:0 >= 1 ? 0 + a:1 : 0
let d[a:name] = 0 + i
return ""
endfunction "}}}
fun! s:f.Cnt(name) "{{{
let d = self.CntD()
return d[a:name]
endfunction "}}}
fun! s:f.CntIncr(name, ...)"{{{
let i = a:0 >= 1 ? 0 + a:1 : 1
let d = self.CntD()
let d[a:name] += i
return d[a:name]
endfunction"}}}
" ================================= Snippets ===================================

View file

@ -0,0 +1,187 @@
XPTemplate priority=all
let s:f = g:XPTfuncs()
XPTinclude
\ _common/common
let s:pairs = { 'left' : "'" . '"([{<|*`+ ',
\ 'right': "'" . '")]}>|*`+ ', }
" TODO not perfect: hide right part if found right is already in input area.
" use searchpair() to improve
let s:crIndent = 0
fun! s:f.BracketRightPart( leftReg )
if has_key( self._ctx.renderContext, 'bracketComplete' )
return ''
endif
let v = self.V()
let v0 = v
let v = matchstr( v, a:leftReg )
if v == ''
return ''
endif
let v = join( reverse( split( v, '\V\s\{-}' ) ), '')
let v = tr( v, s:pairs.left, s:pairs.right )
if v0 =~ '\V\n\s\*\$'
let v = matchstr( v, '\V\S\+' )
return { "action" : "text", "nIndent" : -s:crIndent, "text" : "\n".v }
else
return v
endif
endfunction
fun! s:f.bkt_cmpl()
return self.BracketRightPart( self._ctx.renderContext.leftReg )
endfunction
fun! s:f.quote_cmpl()
let r = self._ctx.renderContext
let v = self.V()
let v = matchstr( v, r.leftReg )
if has_key( r, 'bracketComplete' )
return ''
elseif v == ''
return ''
else
return r.charRight
endif
endfunction
fun! s:f.quote_ontype()
let v = self.V()
if v == ''
return self.Finish()
elseif v =~ '\V\n'
return self.FinishOuter( v )
else
return 0
endif
endfunction
fun! s:f.bkt_ontype()
let v = self.V()
if v == ''
return self.Finish()
elseif v =~ '\V\n\s\*\$'
if &indentexpr != ''
let indentexpr = substitute( &indentexpr, '\Vv:lnum', 'line(".")', '' )
try
let nNewLineIndent = eval( indentexpr )
let s:crIndent = nNewLineIndent - indent( line( "." ) - 1 )
catch /.*/
let s:crIndent = self.NIndent()
endtry
else
let s:crIndent = self.NIndent()
endif
" create snippet indent. filter does not use actual indent string
let n_indent = xpt#indent#ActualToSnippetNr(s:crIndent)
let indent_str = repeat( ' ', n_indent )
let v = substitute( v, '\V\s\*\n\.\*', "\n", 'g' )
return self.FinishOuter( v . indent_str )
else
" nothing todo
return 0
endif
endfunction
fun! s:f.bkt_init( followingChar )
let r = self._ctx.renderContext
let r.char = self.GetVar( '$_xSnipName' )
let r.followingChar = a:followingChar
let r.leftReg = '\V\^' . r.char . r.followingChar . '\?'
let i = stridx( s:pairs.left, r.char )
if i != -1
let r.charRight = s:pairs.right[ i ]
call XPTmapKey( r.charRight, 'bkt_finish(' . string( r.charRight ) . ')' )
else
let r.charRight = ''
endif
return ''
endfunction
fun! s:f.bkt_finish( keyPressed )
let r = self._ctx.renderContext
if a:keyPressed != r.charRight
" may be outer snippet key bind
return a:keyPressed
endif
let r.bracketComplete = 1
let v = self.V()
if self.GetVar( '$SParg' ) == ' '
if v == r.char . r.followingChar
return self.FinishOuter( r.char . r.charRight )
else
return self.FinishOuter( v . r.charRight )
endif
else
return self.FinishOuter( v . r.charRight )
endif
endfunction
XPT _bracket hidden
XSET s|pre=Echo('')
XSET s|ontype=bkt_ontype()
XSET s=bkt_init(' ')
`$_xSnipName$SParg`s^`s^bkt_cmpl()^
XPT _quote hidden
XSET s|pre=Echo('')
XSET s|ontype=quote_ontype()
XSET s=bkt_init('')
`$_xSnipName`s^`s^quote_cmpl()^
XPT ( hidden alias=_bracket
XPT [ hidden alias=_bracket
XPT { hidden alias=_bracket
XPT < hidden alias=_bracket
XPT ' hidden alias=_quote
XPT " hidden alias=_quote

View file

@ -0,0 +1,37 @@
" disabled
finish
XPTemplate priority=all
let s:f = g:XPTfuncs()
fun! s:f.PathPumFrom( where )
let paths = split( globpath( a:where, '*' ), "\n" )
let paths = map( paths, 'v:val[len(' . string( a:where ) . '):]' )
return paths
endfunction
fun! s:f.ExpPathPumFrom( base )
" let prev = a:base . '/' . R( "p" )
let p = self.R( "p" )
let prev = a:base . p
return prev == ''
\ ? ''
\ : self.Build( p . '`p^Choose( PathPumFrom( ' . string(prev) . ' ) )^' )
endfunction
XPT FromHome " path starts from $HOME
XSET p|post=ExpPathPumFrom($HOME)
`p^Choose(PathPumFrom($HOME))^
XPT FromPwd " path starts from $PWD
XSET p|post=Echo(R( "p" ) == '' ? '' : Build( R( "p" ) . '`p^Choose( PathPumFrom( $PWD . R( "p" ), 0 ) )^' ) )
`p^Choose(PathPumFrom($PWD))^

View file

@ -0,0 +1,665 @@
" Default settings and functions used in every snippet file.
XPTemplate priority=all
" containers
let s:f = g:XPTfuncs()
XPTvar $author $author is not set, you need to set g:xptemplate_vars="$author=your_name" in .vimrc
XPTvar $email $email is not set, you need to set g:xptemplate_vars="$email=your_email@com" in .vimrc
XPTvar $VOID
" if () ** {
" else ** {
XPTvar $BRif ' '
" } ** else {
XPTvar $BRel \n
" for () ** {
" while () ** {
" do ** {
XPTvar $BRloop ' '
" struct name ** {
XPTvar $BRstc ' '
" int fun() ** {
" class name ** {
XPTvar $BRfun ' '
" int fun ** (
" class name ** (
XPTvar $SPfun ''
" int fun( ** arg ** )
" if ( ** condition ** )
" for ( ** statement ** )
" [ ** a, b ** ]
" { ** 'k' : 'v' ** }
XPTvar $SParg ' '
" if ** (
" while ** (
" for ** (
XPTvar $SPcmd ' '
" a ** = ** b
" a = a ** + ** 1
" (a, ** b, ** )
XPTvar $SPop ' '
XPTvar $DATE_FMT '%Y %b %d'
XPTvar $TIME_FMT '"%H:%M:%S"'
XPTvar $DATETIME_FMT '%c'
XPTvar $TRUE 1
XPTvar $FALSE 0
XPTvar $NULL 0
XPTvar $UNDEFINED 0
XPTvar $VOID_LINE
XPTvar $CURSOR_PH CURSOR
XPTinclude
\ _common/personal
\ _common/inlineComplete
\ _common/common.*
let s:f_prototype = xpt#snipfunction#funcs
call extend( s:f, s:f_prototype, 'error' )
fun! s:f._xSnipName()
return self._ctx.renderContext.snipObject.name
endfunction
fun! s:f.GetWrappedText()
let wrap = self._ctx.renderContext.wrap
let [ l, r ] = self.ItemEdges()
if !has_key( wrap, 'text' )
return 0
endif
if l == '' && r == ''
return { 'nIndent' : wrap.indent,
\ 'action' : 'text',
\ 'parseIndent' : 0,
\ 'text' : wrap.text }
else
let wrap.curline = wrap.lines[ 0 ]
let wrap.lines = wrap.lines[ 1 : ]
return wrap.curline
endif
endfunction
fun! s:f.WrapAlignAfter( min )
let wrap = self._ctx.renderContext.wrap
let n = max( [ a:min, wrap.max ] ) - len( wrap.curline )
return repeat( ' ', n )
endfunction
fun! s:f.WrapAlignBefore( min )
let wrap = self._ctx.renderContext.wrap
let n = max( [ a:min, wrap.max ] ) - len( wrap.lines[ 0 ] )
return repeat( ' ', n )
endfunction
fun! s:f.Item()
return get( self._ctx.renderContext, 'item', {} )
endfunction
" current name
fun! s:f.ItemName() "{{{
return get( self.Item(), 'name', '' )
endfunction "}}}
let s:f.N = s:f.ItemName
" name with edge
fun! s:f.ItemFullname() "{{{
return get( self.Item(), 'fullname', '')
endfunction "}}}
let s:f.NN = s:f.ItemFullname
" current value user typed
fun! s:f.ItemValue() dict "{{{
return self.GetVar( '$UserInput' )
endfunction "}}}
let s:f.V = s:f.ItemValue
fun! s:f.PrevItem( n )
let hist = get( self._ctx.renderContext, 'history', [] )
return get( hist, a:n, {} )
endfunction
fun! s:f.ItemInitValue()
return get( self.Item(), 'initValue', '' )
endfunction
let s:f.IV = s:f.ItemInitValue
fun! s:f.ItemValueStripped( ... )
let ptn = a:0 == 0 || a:1 =~ 'lr'
\ ? '\V\^\s\*\|\s\*\$'
\ : ( a:1 == 'l'
\ ? '\V\^\s\*'
\ : '\V\s\*\$' )
return substitute( self.ItemValue(), ptn, '', 'g' )
endfunction
let s:f.VS = s:f.ItemValueStripped
fun! s:f.ItemPos()
return XPMposStartEnd( self._ctx.renderContext.leadingPlaceHolder.mark )
endfunction
fun! s:f.ItemInitValueWithEdge()
let [ l, r ] = self.ItemEdges()
return l . self.IV() . r
endfunction
let s:f.IVE = s:f.ItemInitValueWithEdge
" if value match one of the regexps
fun! s:f.Vmatch( ... )
let v = self.V()
for reg in a:000
if match(v, reg) != -1
return 1
endif
endfor
return 0
endfunction
" value matchstr
fun! s:f.VMS( reg )
return matchstr(self.V(), a:reg)
endfunction
" edge stripped value
fun! s:f.ItemStrippedValue()
let v = self.V()
let [edgeLeft, edgeRight] = self.ItemEdges()
let v = substitute( v, '\V\^' . edgeLeft, '', '' )
let v = substitute( v, '\V' . edgeRight . '\$', '', '' )
return v
endfunction
let s:f.V0 = s:f.ItemStrippedValue
fun! s:f.Phase() dict
return get( self._ctx.renderContext, 'phase', '' )
endfunction
" TODO this is not needed at all except as a shortcut.
" equals to expand()
fun! s:f.E(s) "{{{
return expand(a:s)
endfunction "}}}
" return the context
fun! s:f.Context() "{{{
return self._ctx.renderContext
endfunction "}}}
let s:f.C = s:f.Context
" TODO this is not needed at all except as a shortcut.
" post filter substitute
fun! s:f.S(str, ptn, rep, ...) "{{{
let flg = a:0 >= 1 ? a:1 : 'g'
return substitute(a:str, a:ptn, a:rep, flg)
endfunction "}}}
" equals to S(C().value, ...)
fun! s:f.SubstituteWithValue(ptn, rep, ...) "{{{
let flg = a:0 >= 1 ? a:1 : 'g'
return substitute(self.V(), a:ptn, a:rep, flg)
endfunction "}}}
let s:f.SV = s:f.SubstituteWithValue
fun! s:f.HasStep( name )
let namedStep = get( self._ctx.renderContext, 'namedStep', {} )
return has_key( namedStep, a:name )
endfunction
" reference to another finished item value
fun! s:f.Reference(name) "{{{
let namedStep = get( self._ctx.renderContext, 'namedStep', {} )
return get( namedStep, a:name, '' )
endfunction "}}}
let s:f.R = s:f.Reference
fun! s:f.Snippet( name )
return get( self._ctx.renderContext.ftScope.allTemplates, a:name, { 'tmpl' : '' } )[ 'tmpl' ]
endfunction
" black hole
fun! s:f.Void(...) "{{{
return ""
endfunction "}}}
let s:f.VOID = s:f.Void
" Echo several expression and concat them.
" That's the way to use normal vim script expression instead of mixed string
fun! s:f.Echo( ... )
let text = ''
if a:0 > 0
let text = a:1
endif
return { 'action': 'text', 'text': text }
endfunction
fun! s:f.EchoIf( isTrue, ... )
if a:isTrue
return join( a:000, '' )
else
return self.V()
endif
endfunction
fun! s:f.EchoIfEq( expected, ... )
if self.V() ==# a:expected
return join( a:000, '' )
else
return self.V()
endif
endfunction
fun! s:f.EchoIfNoChange( ... )
if self.V0() ==# self.ItemName()
return join( a:000, '' )
else
return self.V()
endif
endfunction
fun! s:f.Commentize( text )
if has_key( self, '$CL' )
return self[ '$CL' ] . ' ' . a:text . ' ' . self[ '$CR' ]
elseif has_key( self, '$CS' )
return self[ '$CS' ] . ' ' . a:text
endif
return a:text
endfunction
fun! s:f.VoidLine()
return self.Commentize( 'void' )
endfunction
" Same with Echo* except echoed text is to be build to generate dynamic place
" holders
fun! s:f.Build( ... )
return { 'action' : 'build', 'text' : join( a:000, '' ) }
endfunction
let s:f.Embed = s:f.Build
fun! s:f.BuildSnippet( snipname )
return { 'action' : 'build', 'snippet' : a:snipname }
endfunction
fun! s:f.BuildIfChanged( ... )
let v = substitute( self.V(), "\\V\n\\|\\s", '', 'g')
" let fn = substitute( self.ItemFullname(), "\\V\n\\|\\s", '', 'g')
let fn = substitute( self.ItemInitValueWithEdge(), "\\V\n\\|\\s", '', 'g')
if v ==# fn || v == ''
return ''
else
return { 'action' : 'build', 'text' : join( a:000, '' ) }
endif
endfunction
fun! s:f.BuildIfNoChange( ... )
let v = substitute( self.V(), "\\V\n\\|\\s", '', 'g')
" let fn = substitute( self.ItemFullname(), "\\V\n\\|\\s", '', 'g')
let fn = substitute( self.ItemInitValueWithEdge(), "\\V\n\\|\\s", '', 'g')
if v ==# fn
return { 'action' : 'build', 'text' : join( a:000, '' ) }
else
return 0
endif
endfunction
" trigger nested template
fun! s:f.Trigger( name ) "{{{
return {'action' : 'expandTmpl', 'tmplName' : a:name}
endfunction "}}}
fun! s:f.Finish(...)
let opt = {}
if a:0 > 0
let opt.text = a:1
endif
return self.Fin(opt)
endfunction
fun! s:f.FinishOuter( ... )
let opt = {"marks" : "mark"}
if a:0 > 0
let opt.text = a:1
endif
return self.Fin(opt)
endfunction
fun! s:f.FinishInner( ... )
let opt = {"marks" : "innerMarks"}
if a:0 > 0
let opt.text = a:1
endif
return self.Fin(opt)
endfunction
fun! s:f.Fin(opt)
" there is still items left
if ! empty( self._ctx.renderContext.itemList )
return get(a:opt, 'text', 0)
endif
let r = {'action' : 'finishTemplate'}
if has_key(a:opt, 'text')
let r.text = a:opt.text
endif
if has_key(a:opt, 'marks')
let r.marks = a:opt.marks
endif
return r
endfunction
fun! s:f.Next( ... )
if a:0 == 0
return { 'nav' : 'next' }
else
return { 'nav' : 'next', 'text' : join( a:000, '' ) }
endif
endfunction
fun! s:f.Remove()
return { 'action' : 'text', 'nav' : 'next', 'text' : '' }
endfunction
" This function is intended to be used for popup selection :
" XSET bidule=Choose([' ','dabadi','dabada'])
fun! s:f.Choose( lst, ... ) "{{{
let val = { 'action' : 'pum', 'pum' : a:lst }
if a:0 == 1
let val.acceptEmpty = a:1 != 0
endif
return val
endfunction "}}}
fun! s:f.ChooseStr(...) "{{{
return copy( a:000 )
endfunction "}}}
" XXX
" Fill in postType, and finish template rendering at once.
" This make nested template rendering go back to upper level, top-level
" template rendering quit.
fun! s:f.xptFinishTemplateWith(postType) dict
endfunction
" XXX
" Fill in postType, jump to next item. For creating item being able to be
" automatically filled in
fun! s:f.xptFinishItemWith(postType) dict
endfunction
" TODO test me
fun! s:f.UnescapeMarks(string) dict
let patterns = self._ctx.renderContext.snipObject.ptn
let charToEscape = '\(\[' . patterns.l . patterns.r . ']\)'
let r = substitute( a:string, '\v(\\*)\1\\?\V' . charToEscape, '\1\2', 'g')
return r
endfunction
let s:f.UE = s:f.UnescapeMarks
fun! s:f.headerSymbol(...) "{{{
let h = expand('%:t')
let h = substitute(h, '\.', '_', 'g') " replace . with _
let h = substitute(h, '.', '\U\0', 'g') " make all characters upper case
return '__'.h.'__'
endfunction "}}}
fun! s:f.date(...) "{{{
return strftime( self.GetVar( '$DATE_FMT' ) )
endfunction "}}}
fun! s:f.datetime(...) "{{{
return strftime( self.GetVar( '$DATETIME_FMT' ) )
endfunction "}}}
fun! s:f.time(...) "{{{
return strftime( self.GetVar( '$TIME_FMT' ) )
endfunction "}}}
fun! s:f.file(...) "{{{
return expand("%:t")
endfunction "}}}
fun! s:f.fileRoot(...) "{{{
return expand("%:t:r")
endfunction "}}}
fun! s:f.fileExt(...) "{{{
return expand("%:t:e")
endfunction "}}}
fun! s:f.path(...) "{{{
return expand("%:p")
endfunction "}}}
fun! s:f.UpperCase( v )
return substitute(a:v, '.', '\u&', 'g')
endfunction
fun! s:f.LowerCase( v )
return substitute(a:v, '.', '\l&', 'g')
endfunction
" Return Item Edges
fun! s:f.ItemEdges() "{{{
let leader = get( self._ctx.renderContext, 'leadingPlaceHolder', {} )
if has_key( leader, 'leftEdge' )
return [ leader.leftEdge, leader.rightEdge ]
else
return [ '', '' ]
endif
endfunction "}}}
let s:f.Edges = s:f.ItemEdges
fun! s:f.ItemCreate( name, edges, filters )
let [ ml, mr ] = XPTmark()
let item = ml . a:name
if has_key( a:edges, 'left' )
let item = ml . a:edges.left . item
endif
if has_key( a:edges, 'right' )
let item .= ml . a:edges.right
endif
let item .= mr
if has_key( a:filters, 'post' )
let item .= a:filters.post . mr . mr
endif
return item
endfunction
" {{{ Quick Repetition
" If something typed, <tab>ing to next generate another item other than the
" typed.
"
" If nothing typed but only <tab> to next, clear it.
"
" Normal clear typed, also clear it
" TODO escape mark character in a:sep or a:item
" }}}
fun! s:f.ExpandIfNotEmpty( sep, item, ... ) "{{{
let v = self.V()
let [ ml, mr ] = XPTmark()
if a:0 != 0
let r = a:1
else
let r = ''
endif
" let t = ( v == '' || v == a:item || v == ( a:sep . a:item . r ) )
let t = ( v == '' || v =~ '\V' . a:item )
\ ? ''
\ : self.Build( v
\ . ml . a:sep . ml . a:item . ml . r . mr
\ . 'ExpandIfNotEmpty(' . string( a:sep ) . ', ' . string( a:item ) . ')' . mr . mr )
return t
endfunction "}}}
fun! s:f.ExpandInsideEdge( newLeftEdge, newRightEdge )
let v = self.V()
let fullname = self.ItemFullname()
let [ el, er ] = self.ItemEdges()
if v ==# fullname || v == ''
return ''
endif
return substitute( v, '\V' . er . '\$' , '' , '' )
\. self.ItemCreate( self.ItemName(), { 'left' : a:newLeftEdge, 'right' : a:newRightEdge }, {} )
\. er
endfunction
fun! s:f.NIndent()
return &shiftwidth
endfunction
fun! s:f.ResetIndent( nIndent, text )
return { 'action' : 'resetIndent', 'resetIndent' : 1, 'nIndent' : a:nIndent, 'text' : a:text }
endfunction
fun! s:f.CmplQuoter_pre() dict
if !g:xptemplate_brace_complete
return ''
endif
let v = substitute( self.ItemStrippedValue(), '\V\^\s\*', '', '' )
let first = matchstr( v, '\V\^\[''"]' )
if first == ''
return ''
endif
let v = substitute( v, '\V\[^' . first . ']', '', 'g' )
if v == first
" only 1 quoter
return first
else
return ''
endif
endfunction
fun! s:f.AutoCmpl( keepInPost, list, ... )
if !a:keepInPost && self.Phase() == 'post'
return ''
endif
if type( a:list ) == type( [] )
let list = a:list
else
let list = [ a:list ] + a:000
endif
let v = self.V0()
if v == ''
return ''
endif
for word in list
if word =~ '\V\^' . v
return word[ len( v ) : ]
endif
endfor
return ''
endfunction
" Short names are normally not good. Some alias to those short name functions are
" made, with meaningful names.
"
" They all start with prefix 'xpt'.
"
" ================================= Snippets ===================================
" Shortcuts
call XPTdefineSnippet('Author', {}, '`$author^')
call XPTdefineSnippet('Email', {}, '`$email^')
call XPTdefineSnippet("Date", {}, "`date()^")
call XPTdefineSnippet("File", {}, "`file()^")
call XPTdefineSnippet("Path", {}, "`path()^")
call XPTdefineSnippet('"_', {'hint' : '" .. "', 'wraponly' : 'w' }, '"`w^"')
call XPTdefineSnippet("'_", {'hint' : "' .. '", 'wraponly' : 'w' }, "'`w^'")
call XPTdefineSnippet("<_", {'hint' : '< .. >', 'wraponly' : 'w' }, '<`w^>')
call XPTdefineSnippet("(_", {'hint' : '( .. )', 'wraponly' : 'w' }, '(`w^)')
call XPTdefineSnippet("[_", {'hint' : '[ .. ]', 'wraponly' : 'w' }, '[`w^]')
call XPTdefineSnippet("{_", {'hint' : '{ .. }', 'wraponly' : 'w' }, '{`w^}')
call XPTdefineSnippet("`_", {'hint' : '` .. `', 'wraponly' : 'w' }, '\``w^\`')

View file

@ -0,0 +1,53 @@
XPTemplate priority=all
let s:f = g:XPTfuncs()
fun! s:Init()
let s:xptCompleteMap = [
\"''",
\'""',
\'()',
\'[]',
\'{}',
\'<>',
\'||',
\'**',
\'``',
\'++',
\' ',
\]
let s:xptCompleteLeft = join( map( deepcopy( s:xptCompleteMap ), 'v:val[0:0]' ), '' )
let s:xptCompleteRight = join( map( deepcopy( s:xptCompleteMap ), 'v:val[1:1]' ), '' )
endfunction
call s:Init()
delfunc s:Init
fun! s:f.CompleteRightPart( leftReg ) dict
if !g:xptemplate_brace_complete
return ''
endif
let v = self.V()
let v = matchstr( v, a:leftReg )
if v == ''
return ''
endif
let v = join( reverse( split( v, '\V\s\{-}' ) ), '')
let v = tr( v, s:xptCompleteLeft, s:xptCompleteRight )
return v
endfunction

View file

@ -0,0 +1,73 @@
XPTemplate priority=like
XPTvar $TRUE 1
XPTvar $FALSE 0
XPTvar $NULL NULL
" if () ** {
XPTvar $BRif ' '
" } ** else {
XPTvar $BRel \n
" int fun( ** arg ** )
" if ( ** condition ** )
XPTvar $SParg ''
" if ** (
XPTvar $SPcmd ' '
" a = a ** + ** 1
XPTvar $SPop ' '
XPTvar $VOID_LINE /* void */;
XPTvar $CURSOR_PH /* cursor */
XPT _if hidden
if`$SPcmd^(`$SParg^`condition^`$SParg^)`$BRif^{
`cursor^
}
XPT if wrap " if ( .. ) { .. }
`Include:_if^
XPT elif wrap " else if ( .. ) { .. }
else `Include:_if^
XPT else wrap " else { ... }
else`$BRif^{
`cursor^
}
XPT ifn alias=if " if (.. == $NULL) {..} else...
XSET condition=Embed('`a^`$SPop^==`$SPop^`$NULL^')
XPT ifnn alias=if " if (.. != $NULL) {..} else...
XSET condition=Embed('`a^`$SPop^!=`$SPop^`$NULL^')
XPT if0 alias=if " if (.. == 0) {..} else...
XSET condition=Embed('`a^`$SPop^==`$SPop^0')
XPT ifn0 alias=if " if (.. != 0) {..} else...
XSET condition=Embed('`a^`$SPop^!=`$SPop^0')
XPT ifee " if (..) {..} else if...
`:_if:^` `else_if...{{^`$BRel^`Include:elif^` `else_if...^`}}^
XPT switch wrap " switch (..) {case..}
switch (`$SParg^`var^`$SParg^)`$BRif^{
`Include:case^
}
..XPT
XPT case wrap " case ..:
case `constant^:
`cursor^
break;
XPT default " default ..:
default:
`cursor^

View file

@ -0,0 +1,28 @@
XPTemplate priority=spec
let s:f = g:XPTfuncs()
XPTvar $TRUE true
XPTvar $FALSE false
XPTvar $NULL null
XPTvar $UNDEFINED undefined
XPTvar $VOID_LINE /* void */;
XPTvar $BRif \n
XPTinclude
\ _common/common
\ _condition/c.like
" ========================= Function and Variables =============================
" ================================= Snippets ===================================
XPT ifu alias=if " if ($UNDEFINED == ..) {..} else...
XSET condition=Embed('`$UNDEFINED^`$SPop^==`$SPop^`var^')
XPT ifnu alias=if " if ($UNDEFINED == ..) {..} else...
XSET condition=Embed('`$UNDEFINED^`$SPop^!=`$SPop^`var^')

View file

@ -0,0 +1,38 @@
XPTemplate priority=like
let s:f = g:XPTfuncs()
XPTvar $TRUE 1
XPTvar $FALSE 0
XPTvar $NULL NULL
XPTvar $UNDEFINED NULL
XPTvar $VOID_LINE /* void */;
XPTvar $BRif \n
XPTinclude
\ _common/common
" ========================= Function and Variables =============================
" ================================= Snippets ===================================
XPT if hint=(if\ (then)\ (else))
(if [`condition^]
(`then^)
`else...{{^(`cursor^)`}}^)
XPT when hint=(when\ cond\ ..)
(when (`cond^)
(`todo0^)` `...^
(`todon^)` `...^)
XPT unless hint=(unless\ cond\ ..)
(unless (`cond^)
(`todo0^)` `...^
(`todon^)` `...^)

View file

@ -0,0 +1,51 @@
XPTemplate priority=like
let s:f = g:XPTfuncs()
XPTvar $TRUE 1
XPTvar $FALSE 0
XPTvar $NULL NULL
XPTvar $BRif ' '
XPTvar $BRloop ' '
XPTvar $BRstc ' '
XPTvar $BRfun ' '
XPTvar $VOID_LINE /* void */;
XPTvar $CURSOR_PH /* cursor */
XPTvar $CL /*
XPTvar $CM *
XPTvar $CR */
XPTinclude
\ _common/common
fun! s:f.c_fun_type_indent()
if self[ '$BRfun' ] == "\n"
" let sts = &softtabstop == 0 ? &tabstop : &softtabstop
return ' '
else
return ""
endif
endfunction
fun! s:f.c_fun_body_indent()
if self[ '$BRfun' ] == "\n"
" let sts = &softtabstop == 0 ? &tabstop : &softtabstop
return self.ResetIndent( -&shiftwidth, "\n" )
else
return " "
endif
endfunction
XPT main hint=main\ (argc,\ argv)
`c_fun_type_indent()^int`c_fun_body_indent()^main(`$SParg^int argc,`$SPop^char **argv`$SParg^)`$BRfun^{
`cursor^
return 0;
}
XPT fun wrap=curosr hint=func..\ (\ ..\ )\ {...
`c_fun_type_indent()^`int^`c_fun_body_indent()^`name^(`$SParg`param?`$SParg^)`$BRfun^{
`cursor^
}

View file

@ -0,0 +1,39 @@
XPTemplate priority=like
XPTvar $BRloop ' '
" int fun( ** arg ** )
" if ( ** condition ** )
" for ( ** statement ** )
" [ ** a, b ** ]
" { ** 'k' : 'v' ** }
XPTvar $SParg ''
" if ** (
" while ** (
" for ** (
XPTvar $SPcmd ' '
" a ** = ** a ** + ** 1
" (a, ** b, ** )
XPTvar $SPop ' '
fun! s:f.c_strip_type()
let v = self.ItemValue()
echom v
echom substitute(v, '\V\^\_.*\s', 'g')
return substitute(v, '\V\^\_.*\s', 'g')
endfunction
XPT for wrap " for (..;..;++)
for`$SPcmd^(`$SParg^`i^`$SPop^=`$SPop^`0^; `i^c_strip_type()^`$SPop^<`$SPop^`len^; `i^c_strip_type()^++`$SParg^)`$BRloop^{
`cursor^
}
XPT forr wrap " for (..;..;--)
for`$SPcmd^(`$SParg^`i^`$SPop^=`$SPop^`n^; `i^`$SPop^>`=$SPop`0^; `i^--`$SParg^)`$BRloop^{
`cursor^
}
XPT forever " for (;;) ..
for`$SPcmd^(;;) `cursor^

View file

@ -0,0 +1,37 @@
XPTemplate priority=like
XPTvar $TRUE 1
XPTvar $FALSE 0
XPTvar $NULL NULL
XPTvar $BRloop ' '
XPTvar $SParg ' '
XPTvar $SPcmd ' '
XPTvar $SPop ' '
XPT while wrap " while ( .. )
while`$SPcmd^(`$SParg^`condition^`$SParg^)`$BRloop^{
`cursor^
}
XPT do wrap " do { .. } while ( .. )
do`$BRloop^{
`cursor^
}`$BRloop^while`$SPcmd^(`$SParg^`condition^`$SParg^);
XPT while0 alias=do " do { .. } while ( $FALSE )
XSET condition=Embed( $FALSE )
XPT while1 alias=while " while ( $TRUE ) { .. }
XSET condition=Embed( $TRUE )
XPT whilenn alias=while " while ( $NULL != .. ) { .. }
XSET condition=Embed( $NULL . $SPop . '!=' . $SPop . '`x^' )

View file

@ -0,0 +1,68 @@
"
" standard for( i = 0; i < 10; i++ ) snippets
"
XPTemplate priority=all-
let s:f = g:XPTfuncs()
XPTvar $NULL NULL
XPTvar $BRloop ' '
XPTvar $SParg ''
XPTvar $SPcmd ' '
XPTvar $SPop ' '
XPTvar $VAR_PRE ''
XPTvar $FOR_SCOPE ''
XPTinclude
\ _common/common
fun! s:f.c_strip_type()
let v = self.ItemValue()
return substitute(v, '\V\^\_.\*\s', '', 'g')
endfunction
XPT for wrap " for (..;..;++)
for`$SPcmd^(`$SParg^`$FOR_SCOPE^`$VAR_PRE`i^`$SPop^=`$SPop^`0^; `i^c_strip_type()^`$SPop^<`$SPop^`len^; `i^c_strip_type()^++`$SParg^)`$BRloop^{
`cursor^
}
XPT forr wrap " for (..;..;--)
for`$SPcmd^(`$SParg^`$FOR_SCOPE^`$VAR_PRE`i^`$SPop^=`$SPop^`0^; `i^c_strip_type()^`$SPop^>`=$SPop`end^; `i^c_strip_type()^--`$SParg^)`$BRloop^{
`cursor^
}
XPT fornn wrap " for (..; $NULL != var; .. )
for`$SPcmd^(`$SParg^`$FOR_SCOPE^`$VAR_PRE`ptr^`$SPop^=`$SPop^`init^; `$NULL^`$SPop^!=`$SPop^`ptr^; `^R('ptr')^`$SParg^)`$BRloop^{
`cursor^
}
XPT forever " for (;;) ..
for`$SPcmd^(;;) `cursor^
..XPT
" Simplify
" XSET i|edgeLeft=$VAR_PRE
" XSET i|edgeRight=$VAR_PRE
" XSET $(= ($SParg
" XSET $)= $SParg)
" XSET $== $SPop=$SPop
" XSET $>= $SPop>
" XSET $e= =$SPop
" for`$SPcmd`$(`$FOR_SCOPE``i`$=`0; `i`$>`$e`end; `i++`$)`$BRloop{
" ^
" ..XPT
"
" for`SP(`SP`FOR_SCOPE`i`SP=`SP`0;`SP`i`SP>`SP`end;`SP`i++`SP)`SP{
"
" for$ ($ $FOR_SCOPE$i$ =$ $0;$ $i$ >$ $end;$ $i++$ )$ {
"
" for$ ($ $FOR_SCOPE${$VAR_PRE `i`}$ =$ $0;$ $i$ >$ $end;$ $i++$ )$ {
"
" for` (` `FOR_SCOPE`{$VAR_PRE `i`}` =` `0;` `{i/\v(\S+)$/\1/}` >` `{end:0::post=::focus=::live=};` `i++` )` {

View file

@ -0,0 +1,23 @@
XPTemplate priority=like-
" containers
let s:f = g:XPTfuncs()
XPTvar $TRUE true
XPTvar $FALSE false
XPTvar $NULL null
XPTvar $BRif
XPTvar $VOID_LINE /* void */;
" ================================= Snippets ===================================
XPT for " for i++
for`$SPcmd^(`$SParg^`int^ `i^`$SPop^=`$SPop^`0^; `i^`$SPop^<`$SPop^`len^; ++`i^`$SParg^)`$BRloop^{
`cursor^
}
XPT forr "for i--
for`$SPcmd^(`$SParg^`int^ `i^`$SPop^=`$SPop^`n^; `i^`$SPop^>`=^`$SPop^`end^; --`i^`$SParg^)`$BRloop^{
`cursor^
}

View file

@ -0,0 +1,48 @@
XPTemplate priority=like
let s:f = g:XPTfuncs()
XPTinclude
\ _common/common
XPT #inc " include <>
#include <`^.h>
XPT #include_user " include ""
XSET me=fileRoot()
#include "`me^.h"
XPT #ind alias=#include_user
XPT #if wrap " #if ..
#if `0^
`cursor^
#endif
XPT #ifdef wrap " #ifdef ..
#ifdef `symbol^
`cursor^
#endif `$CL^ `symbol^ `$CR^
XPT #ifndef wrap " #ifndef ..
#ifndef `symbol^
`cursor^
#endif `$CL^ `symbol^ `$CR^
XPT once wrap " #ifndef .. #define ..
XSET symbol=headerSymbol()
#ifndef `symbol^
# define `symbol^
`cursor^
#endif `$CL^ `symbol^ `$CR^

View file

@ -0,0 +1,105 @@
XPTemplate priorit=like
let s:f = g:XPTfuncs()
XPTvar $TRUE 1
XPTvar $FALSE 0
XPTvar $NULL NULL
XPTvar $UNDEFINED NULL
" a ** = ** a ** + ** 1
" (a, ** b, ** )
XPTvar $SPop ' '
" if () ** {
" else ** {
XPTvar $BRif ' '
" } ** else {
XPTvar $BRel \n
" for () ** {
" while () ** {
" do ** {
XPTvar $BRloop ' '
" struct name ** {
XPTvar $BRstc ' '
" int fun() ** {
" class name ** {
XPTvar $BRfun ' '
XPTinclude
\ _common/common
let s:printfElts = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
" %[flags][width][.precision][length]specifier
let s:printfItemPattern = '\V\C' . '%' . '\[+\- 0#]\*' . '\%(*\|\d\+\)\?' . '\(.*\|.\d\+\)\?' . '\[hlL]\?' . '\(\[cdieEfgGosuxXpn]\)'
let s:printfSpecifierMap = {
\'c' : 'char',
\'d' : 'int',
\'i' : 'int',
\'e' : 'scientific',
\'E' : 'scientific',
\'f' : 'float',
\'g' : 'float',
\'G' : 'float',
\'o' : 'octal',
\'s' : 'str',
\'u' : 'unsigned',
\'x' : 'decimal',
\'X' : 'Decimal',
\'p' : 'pointer',
\'n' : 'numWritten',
\}
fun! s:f.c_printf_elts( v, sep )
" remove '%%' representing a single '%'
let v = substitute( a:v, '\V%%', '', 'g' )
let [ ml, mr ] = XPTmark()
if v =~ '\V%'
let start = 0
let post = ''
let i = -1
while 1
let i += 1
let start = match( v, s:printfItemPattern, start )
if start < 0
break
endif
let eltList = matchlist( v, s:printfItemPattern, start )
if eltList[1] == '.*'
" need to specifying string length before string pointer
let post .= a:sep . self.GetVar( '$SPop' ) . ml . s:printfElts[ i ] . '_len' . mr
endif
let post .= a:sep . self.GetVar( '$SPop' ) . ml . s:printfElts[ i ] . '_' . s:printfSpecifierMap[ eltList[2] ] . mr
let start += len( eltList[0] )
endwhile
return post
else
return self.Next( '' )
endif
endfunction

View file

@ -0,0 +1,22 @@
XPTemplate priority=like
XPTvar $BRstc ' '
let s:f = g:XPTfuncs()
XPT enum hint=enum\ {\ ..\ }
XSET postQuoter={,}
enum `name^`$BRstc^{
`^
}
XPT struct hint=struct\ {\ ..\ }
struct `structName^`$BRstc^{
`^
}

View file

@ -0,0 +1,31 @@
XPTemplate priority=lang
" XPTvar $TRUE 1
" XPTvar $FALSE 0
" XPTvar $NULL NULL
" XPTvar $UNDEFINED NULL
XPTinclude
\ _common/common
XPTvar $CL /*
XPTvar $CM *
XPTvar $CR */
XPTvar $CS //
XPTinclude
\ _comment/singleDouble
XPTinclude
\ _condition/ecma
" ========================= Function and Variables =============================
" ================================= Snippets ===================================
XPT fun wrap " function ..( .. ) {..}
XSET arg*|post=ExpandIfNotEmpty(', ', 'arg*')
function` `name^ (`arg*^) {
`cursor^
}

View file

@ -0,0 +1,134 @@
XPTemplate priority=lang
let s:f = g:XPTfuncs()
XPTvar $TRUE 1
XPTvar $FALSE 0
XPTvar $NULL NULL
XPTvar $UNDEFINED NULL
XPTvar $VOID_LINE /* void */;
XPTvar $BRif \n
XPTinclude
\ _common/common
" ========================= Function and Variables =============================
" ================================= Snippets ===================================
XPT acc " access
access
..XPT
XPT ali " aliased
aliased
..XPT
XPT beg " begin .. end;
begin
`cursor^
end;
..XPT
XPT case " case .. is .. end case;
case `1^ is
`cursor^
end case;
..XPT
XPT eli " elsif .. then ...
elsif `1^ then
`cursor^
..XPT
XPT for " for .. in .. loop ... end loop;
for `1^ in `2^ loop
`cursor^
end loop;
..XPT
XPT fun " function .. return .. is ..._ end;
function `1^name^ return `2^ is
`3^
begin -- `1^
`cursor^
end `1^;
..XPT
XPT if " if .. then ... end if;
if `1^ then
`cursor^
end if;
..XPT
XPT loop " loop .. end loop;
loop
`cursor^
end loop;
..XPT
XPT pbo " package body .. is .. end ;
package body `1^name^ is
`cursor^
end `1^;
..XPT
XPT pac " package .. is .. end;
package `1^name^ is
`cursor^
end `1^;
..XPT
XPT pne " package .. is ..
package `1^ is `cursor^
..XPT
XPT pro " procedure .. begin .. end;
procedure `1^Procedure^ is
`2^
begin -- `mark^S(R('1'),'([a-zA-Z0-9_]*).*$','\1')^
`cursor^
end `mark^;
..XPT
XPT rec " record .. end record;
record
`cursor^
end record;
..XPT
XPT ret " return ..;
return `1^;
..XPT
XPT ty " type .. is ..;
type `1^ is `cursor^
..XPT
XPT u " use ..;
use `1^;
..XPT
XPT when " when .. => ..
when `1^ =>
`cursor^
..XPT
XPT whi " while .. loop .. end loop;
while `1^ loop
`cursor^
end loop;
..XPT
XPT wu " with ..; use ..;
with `what^; use `1^;
`cursor^
..XPT
XPT w " with ..;
with `1^;
..XPT

View file

@ -0,0 +1,78 @@
" finish " not finished
if !g:XPTloadBundle( 'c', 'autoimplem' ) && !exists('g:cppautoimplemneedc') && !exists('g:objcautoimlemneedc')
finish
endif
XPTemplate priority=lang-2
let s:f = g:XPTfuncs()
" ========================== Support functions ======================
let s:defaultImpl = { 'void' : ''
\, 'int' : "\treturn 0;"
\, 'unsigned int' : "\treturn 0;"
\, 'short' : "\treturn 0;"
\, 'unsigned short' : "\treturn 0;"
\, 'char' : "\treturn '\0';"
\, 'unsigned char' : "\treturn '\0';"
\, 'double': "\treturn 0.0;"
\, 'float' : "\treturn 0.0f;"
\, 'bool' : "\treturn false;"
\}
let s:f.todoText = "\t/* TODO : implement here */"
fun! s:f.GetDefaultImplementation( type )
if has_key( s:defaultImpl, a:type )
return s:defaultImpl[ a:type ]
endif
" check if type is a pointer.
if a:type =~ '.*\*$'
return "\treturn NULL;"
endif
return ''
endfunction
fun! s:f.GetImplementationFile() "{{{
let name = expand('%:p')
if name =~ '\.h$'
let name = substitute( name, 'h$', '[cC]*', '' )
elseif name =~ '\.hpp$'
let name = substitute( name, 'hpp$', '[cC]*', '' )
endif
return glob( name )
endfunction "}}}
fun! s:f.WriteFunToCpp() " {{{
let imple = s:f.GetImplementationFile()
if imple == ''
return
endif
let retType = self.R('retType')
let funName = self.R('funName')
let args = self.R( 'args' )
let methodBody = [ retType . ' ' . funName . '(' . args . ')'
\ , '{'
\ , s:f.todoText
\ , s:f.GetDefaultImplementation( retType )
\ , '}'
\ , '' ]
let txt = extend( readfile( imple ), methodBody )
call writefile( txt, imple )
return args
endfunction " }}}
" ================================= Snippets ===================================
XPT hfun " create proto in h and implementation in .c/.cc/.cpp
`retType^ `funName^( `args^WriteFunToCpp()^^);
..XPT

View file

@ -0,0 +1,110 @@
XPTemplate priority=lang
XPTvar $TRUE 1
XPTvar $FALSE 0
XPTvar $NULL NULL
XPTvar $BRif ' '
XPTvar $BRloop ' '
XPTvar $BRstc ' '
XPTvar $BRfun ' '
XPTvar $VOID_LINE /* void */;
XPTvar $CURSOR_PH /* cursor */
XPTinclude
\ _common/common
XPTvar $CL /*
XPTvar $CM *
XPTvar $CR */
XPTinclude
\ _comment/doubleSign
XPTinclude
\ _condition/c.like
\ _func/c.like
\ _loops/c.while.like
\ _preprocessor/c.like
\ _structures/c.like
\ _printf/c.like
XPTinclude
\ _loops/for
let s:f = g:XPTfuncs()
XPT _printfElts hidden
XSET elts|pre=Echo('')
XSET elts=c_printf_elts( R( 'pattern' ), ',' )
"`pattern^"`elts^
XPT printf " printf\(...)
printf(`$SParg^`:_printfElts:^`$SParg^)
XPT sprintf " sprintf\(...)
sprintf(`$SParg^`str^,`$SPop^`:_printfElts:^`$SParg^)
XPT snprintf " snprintf\(...)
snprintf(`$SParg^`str^,`$SPop^`size^,`$SPop^`:_printfElts:^`$SParg^)
XPT fprintf " fprintf\(...)
fprintf(`$SParg^`stream^,`$SPop^`:_printfElts:^`$SParg^)
XPT memcpy " memcpy (..., ..., sizeof (...) ... )
memcpy(`$SParg^`dest^,`$SPop^`source^,`$SPop^sizeof(`type^int^)`$SPop^*`$SPop^`count^`$SParg^)
XPT memset " memset (..., ..., sizeof (...) ... )
memset(`$SParg^`buffer^,`$SPop^`what^0^,`$SPop^sizeof(`$SParg^`type^int^`$SParg^)`$SPop^*`$SPop^`count^`$SParg^)
XPT malloc " malloc ( ... );
(`type^int^*)malloc(`$SParg^sizeof(`$SParg^`type^`$SParg^)`$SPop^*`$SPop^`count^`$SParg^)
XPT assert " assert (.., msg)
assert(`$SParg^`isTrue^,`$SPop^"`text^"`$SParg^)
XPT fcomment
/**
* @author : `$author^ | `$email^
* @description
* `cursor^
* @return {`int^} `desc^
*/
XPT para syn=comment " comment parameter
@param {`Object^} `name^ `desc^
XPT filehead
XSET cursor|pre=CURSOR
/**-------------------------/// `sum^ \\\---------------------------
*
* <b>`function^</b>
* @version : `1.0^
* @since : `date()^
*
* @description :
* `cursor^
* @usage :
*
* @author : `$author^ | `$email^
* @copyright `.com.cn^
* @TODO :
*
*--------------------------\\\ `sum^ ///---------------------------*/
..XPT
XPT call wraponly=param " ..( .. )
`name^(`$SParg^`param^`$SParg^)

View file

@ -0,0 +1,12 @@
" C99 relax some variable definition rules
" allowing to use C++/Java style for loop
if !g:XPTloadBundle( 'c', 'c99' )
finish
endif
XPTemplate priority=sub
XPTinclude
\ _common/common
\ _loops/java.for.like

View file

@ -0,0 +1,58 @@
XPTemplate priority=lang
let s:f = g:XPTfuncs()
XPTvar $TRUE 1
XPTvar $FALSE 0
XPTvar $NULL NULL
XPTvar $UNDEFINED NULL
XPTvar $VOID_LINE /* void */;
XPTvar $BRif \n
XPTinclude
\ _common/common
" ========================= Function and Variables =============================
" ================================= Snippets ===================================
XPT infos hint=Name:\ Version\:\ Synopsys:\ Descr:\ Author:\ ...
XSET Description...|post=\nDescription: `_^
XSET Author...|post=\nAuthor: `_^
XSET Maintainer...|post=\nMaintainer: `_^
Name: `name^
Version: `version^
Synopsis: `synop^
Build-Type: `Simple^
Cabal-Version: >= `ver^1.2^`
`Description...^`
`Author...^`
`Maintainer...^
XPT if hint=if\ ...\ else\ ...
if `cond^
`what^
`else...{{^else
`cursor^`}}^
XPT lib hint=library\ Exposed-Modules...
XSET another*|post=ExpandIfNotEmpty( ', ', 'another*' )
library
Exposed-Modules: `job^`
`more...{{^
`job^`
`...{{^
`job^`
`...^`}}^`}}^
Build-Depends: base >= `ver^2.0^`, `another*^
XPT exe hint=Main-Is:\ ..\ Build-Depends
XSET another*|post=ExpandIfNotEmpty( ', ', 'another*' )
Executable `execName^
Main-Is: `mainFile^
Build-Depends: base >= `ver^2.0^`, `another*^

View file

@ -0,0 +1,105 @@
XPTemplate priority=lang
let s:f = g:XPTfuncs()
XPTvar $TRUE 1
XPTvar $FALSE 0
XPTvar $NULL NULL
XPTvar $UNDEFINED NULL
" if () ** {
" else ** {
XPTvar $BRif '\n'
" } ** else {
XPTvar $BRel \n
" for () ** {
" while () ** {
" do ** {
XPTvar $BRloop '\n'
" struct name ** {
XPTvar $BRstc '\n'
" int fun() ** {
" class name ** {
XPTvar $BRfun '\n'
XPTinclude
\ _common/common
\ _condition/c.like
\ _loops/c.for.like
\ _loops/c.while.like
\ _preprocessor/c.like
" ========================= Function and Variables =============================
" ================================= Snippets ===================================
XPT fun " fun ( .. )
`type^ `name^(
)
{
`cursor^
}
XPT tech " technique ..
technique `techName^
{
`cursor^
};
XPT pass " pass ..
XSET vtarget=Choose(['arbvp1', 'vs_2_x', 'vs_3_0', 'vs_4_0', 'vp20', 'vp30', 'vp40', 'gp4vp', 'hlslv', 'glslv'])
XSET ftarget=Choose(['arbfp1', 'ps_2_x', 'ps_3_0', 'ps_4_0', 'fp20', 'fp30', 'fp40', 'gp4fp', 'hlslf', 'glslf'])
XSET gtarget=Choos(['gp4gp', 'gs_4_0', 'glslg'])
pass `passName^ {`common...{{^
VertexProgram = `compilev...{{^compile `vtarget^ `main^main^`}}^;
FragmentProgram = `compilef...{{^compile `ftarget^ `main^main^`}}^;`GeometryProgram...{{^
GeometryProgram = `compilef...{{^compile `gtarget^ `main^main^`}}^;`}}^
`}}^`cursor^
};
XPT interface " interface .. { .. }
interface `interfaceName^
{
`cursor^
};
XPT vertexProg " main vertex programm
XSET vout=Choose(['COLOR0', 'COLOR1', 'TEXCOORD0', 'TEXCOORD1', 'PSIZE'])
XSET vin=Choose(['POSITION', 'NORMAL', 'DIFFUSE', 'SPECULAR', 'TEXCOORD0', 'TEXCOORD1', 'TANGENT', 'BINORMAL', 'FOGCOORD'])
void main( `inputs...^ float`n^ `name^ : `vin^,
`inputs...^float4 `position^ : POSITION`outputs...^,
out float4 `name^ : `vout^`outputs...^ )
{
`cursor^
}
XPT fragProg " main vertex programm
XSET vin=Choose(['COLOR0', 'COLOR1', 'TEXCOORD0', 'TEXCOORD1', 'WPOS'])
void main( `inputs...^ float`n^ `name^ : `vin^,
`inputs...^float4 `color^ : COLOR`depth...{{^,
out float4 `name^ : DEPTH`}}^ )
{
`cursor^
}
XPT struct " struct .. { .. }
struct `structName^`inherit...{{^ : `interfaceName^`}}^
{
`cursor^
};
" ================================= Wrapper ===================================

View file

@ -0,0 +1,38 @@
XPTemplate priority=lang
XPTinclude
\ _common/common
XPT if " if ( cond )...
if ( `cond^ )
`cursor^
`else...{{^else( `cond^ )
`}}^endif( `cond^ )
..XPT
XPT foreach " foreach\(...) ... endofreach\( ... )
foreach (`varname^ `collection^)
`cursor^
endforeach(`varname^)
XPT set " set\(... ...)
set(`varname^ `cursor^)
XPT msg " message\("...")
message("`cursor^")
XPT function " function\(...) ... endfunction\(...)
function(`funcName^ `params^)
`cursor^
endfunction(`funcName^)
XPT macro " macro\(...) ... endmacro\(...)
macro( `macroName^ `params^ )
`cursor^
endmacro( `macroName^ )
XPT while " while\(...) ... endwhile\(...)
while( `condition^ )
`cursor^
enwhile( `condition^ )

View file

@ -0,0 +1,256 @@
" finish " not finished
if !g:XPTloadBundle( 'cpp', 'autoimplem' )
finish
endif
XPTemplate priority=lang-2
let s:f = g:XPTfuncs()
" To force loading the version (we need it)
let g:cppautoimplemneedc = 1
XPTinclude
\ _common/common
\ c/autoimplem
" ========================== Support functions ======================
" Count the number of blanck character before anything interesting
" has happened
fun! s:CalculateIndentation( ln ) "{{{
let i = 0
let spacecount = 0
let maxi = len( a:ln )
while i < maxi
let c = (a:ln)[i]
if c == ' '
let spacecount = spacecount + 1
elseif c == '\t'
let spacecount = spacecount + &tabstop
else
break
endif
let i = i + 1
endwhile
return i
endfunction "}}}
fun! s:f.GetLastStructClassDeclaration() "{{{
let lineNum = line('.')
let ourIndentation = s:CalculateIndentation( getline( lineNum ))
let lineNum = lineNum - 1
while lineNum >= 0
let txt = getline( lineNum )
if txt =~ '\(struct\)\|\(class\)'
if s:CalculateIndentation( txt ) < ourIndentation
return substitute( txt, '\s*\(\(struct\)\|\(class\)\)\s\+\(\S\+\).*', '\4', '' )
endif
endif
let lineNum = lineNum - 1
endwhile
return ""
endfunction "}}}
fun! s:f.WriteCtorToCpp() " {{{
let imple = s:f.GetImplementationFile()
if imple == ''
return
endif
let englobingClass = self.R('className')
let args = self.R( 'ctorArgs' )
let methodBody = [ englobingClass . '::' . englobingClass . '(' . args . ')'
\ , '{'
\ , s:f.todoText
\ , '}'
\ , '' ]
let txt = extend( readfile( imple ), methodBody )
call writefile( txt, imple )
return args
endfunction " }}}
fun! s:f.WriteDtorToCpp() " {{{
let imple = s:f.GetImplementationFile()
if imple == ''
return
endif
let englobingClass = self.R('className')
let methodBody = [ englobingClass . '::~' . englobingClass . '()'
\ , '{'
\ , s:f.todoText
\ , '}'
\ , '' ]
let txt = extend( readfile( imple ), methodBody )
call writefile( txt, imple )
return ''
endfunction " }}}
fun! s:f.WriteStaticToCpp()
let name = self.R('name')
let imple = s:f.GetImplementationFile()
if imple == ''
return name
endif
let englobingClass = self.GetLastStructClassDeclaration()
if englobingClass == ''
return name
endif
let methodBody = [ self.R('fieldType') . ' ' . englobingClass . '::' . name . ';' ]
let txt = extend( readfile( imple ), methodBody )
call writefile( txt, imple )
return name
endfunction
fun! s:f.WriteCopyCtorToCpp() " {{{
let cpy = self.R('cpy')
let imple = s:f.GetImplementationFile()
if imple == ''
return cpy
endif
let englobingClass = self.R('className')
let methodBody = [ englobingClass . '::' . englobingClass . '( const ' . englobingClass . ' &' . cpy . ' )'
\ , '{'
\ , s:f.todoText
\ , '}'
\ , '' ]
let txt = extend( readfile( imple ), methodBody )
call writefile( txt, imple )
return cpy
endfunction " }}}
fun! s:f.WriteMethodToCpp() "{{{
let imple = s:f.GetImplementationFile()
if imple == ''
return ''
endif
let englobingClass = self.GetLastStructClassDeclaration()
if englobingClass == ''
return ''
endif
let args = self.R( 'args' )
let constness = self.R( 'const?...' )
let retType = self.R( 'retType' )
let methodBody = [ retType . ' ' . englobingClass . '::' . self.R('funcName')
\ . '(' . args . ')' . constness
\ , '{'
\ , s:f.todoText
\ , s:f.GetDefaultImplementation( retType )
\ , '}'
\ , '' ]
let txt = extend( readfile( imple ), methodBody )
call writefile( txt, imple )
return ''
endfunction "}}}
fun! s:f.WriteOpOverloadToCpp()
let imple = s:f.GetImplementationFile()
if imple == ''
return ''
endif
let englobingClass = self.GetLastStructClassDeclaration()
if englobingClass == ''
return ''
endif
let inputType = self.R( 'inputType' )
let argName = self.R('inName' )
let constness = self.R( 'const?...' )
let retType = self.R( 'retType' )
let methodBody = [ retType . ' ' . englobingClass . '::operator ' . self.R('opName')
\ . '( const ' . inputType . ' ' . argName . ' )' . constness
\ , '{'
\ , s:f.todoText
\ , s:f.GetDefaultImplementation( retType )
\ , '}'
\ , '' ]
let txt = extend( readfile( imple ), methodBody )
call writefile( txt, imple )
return ''
endfunction
" ================================= Snippets ===================================
XPT hstatic " Static field + implementation
XSET name|post=WriteStaticToCpp()
static `fieldType^ `name^;
..XPT
XPT hmethod " class method + implementation
XSET cursor=WriteMethodToCpp()
`retType^ `funcName^( `args^ )`const?...{{^ const`}}^;`cursor^
..XPT
XPT hstruct " struct with skeletons written into .cpp
struct `className^
{
`constructor...{{^`^R('className')^( `ctorArgs^WriteCtorToCpp()^^ );
`}}^`destructor...{{^~`^R('className')^(`^WriteDtorToCpp()^^);
`}}^`copy constructor...{{^`^R('className')^( const `^R('className')^ &`cpy^WriteCopyCtorToCpp()^^ );
`}}^`cursor^
};
..XPT
XPT hclass " class with skeletons written into .cpp
XSET heritageQualifier=Choose(['public', 'private', 'protected'])
class `className^`inherit?...{{^ : `heritageQualifier^ `fatherName^`}}^
{
public:
`constructor...{{^`^R('className')^( `ctorArgs^WriteCtorToCpp()^^ );
`}}^`destructor...{{^~`^R('className')^(`^WriteDtorToCpp()^^);
`}}^`copy constructor...{{^`^R('className')^( const `^R('className')^ &`cpy^WriteCopyCtorToCpp()^^ );
`}}^`cursor^
private:
};
..XPT
XPT hctor " Class constructor writing skeleton to cpp
`className^GetLastStructClassDeclaration()^( `ctorArgs^WriteCtorToCpp()^^ );
..XPT
XPT hdtor " Class destructor writing skeleton to cpp
XSET cursor=WriteDtorToCpp()
~`className^GetLastStructClassDeclaration()^();`cursor^
..XPT
XPT hcopyctor " Class copy constructor writing skeleton to cpp
`className^GetLastStructClassDeclaration()^( const `className^& `cpy^WriteCopyCtorToCpp()^^ );
..XPT
XPT hoperator " operator overloading writing skeleton to cpp
XSET cursor=WriteOpOverloadToCpp()
`retType^GetLastStructClassDeclaration()&^ operator `opName^( const `inputType^GetLastStructClassDeclaration()&^ `inName^ )`const?...{{^ const`}}^;`cursor^
..XPT

View file

@ -0,0 +1,177 @@
XPTemplate priority=sub
" Setting priority of cpp to "sub" or "subset of language", makes it override
" all c snippet if conflict
XPTvar $TRUE true
XPTvar $FALSE false
XPTvar $NULL NULL
XPTvar $BRif \n
XPTvar $BRloop \n
XPTvar $BRloop \n
XPTvar $BRstc \n
XPTvar $BRfun \n
XPTvar $VOID_LINE /* void */;
XPTvar $CURSOR_PH /* cursor */
XPTvar $CL /*
XPTvar $CM *
XPTvar $CR */
XPTvar $CS //
XPTinclude
\ _common/common
\ _comment/singleDouble
\ _condition/c.like
\ _func/c.like
\ _loops/c.while.like
\ _loops/java.for.like
\ _preprocessor/c.like
\ _structures/c.like
XPTinclude
\ c/c
" ========================= Function and Variables =============================
let s:f = g:XPTfuncs()
function! s:f.cleanTempl( ctx, ... )
let cleaned = substitute( a:ctx, '\s*\(class\|typename\|int\|long\)\s*', '', 'g' )
return cleaned
endfunction
" ================================= Snippets ===================================
XPT all " ..begin, ..end,
`v^.begin(), `v^.end(), `cursor^
XPT vector " std::vector<..> ..;
std::vector<`type^> `var^;
`cursor^
XPT map " std::map<..,..> ..;
std::map<`typeKey^,`val^> `name^;
`cursor^
XPT class " class ..
class `className^`$BRfun^{
public:
`className^(`$SParg`ctorParam?`$SParg^);
~`className^();
`className^(`$SParg^const `className^ &cpy`$SParg^);
`cursor^
private:
};
`className^::`className^(`ctorParam?^)`$BRfun^{
}
`className^::~`className^()`$BRfun^{
}
`className^::`className^(`$SParg^gconst `className^ &cpy`$SParg^)`$BRfun^{
}
..XPT
XPT functor " class operator..
struct `className^
{
`closure...{{^`type^ `what^;
`_^R('className')^( `type^ n`what^ ) : `what^( n`what^ ) {}
`}}^`outType^ operator() ( `params^ )
{
`cursor^
}
};
..XPT
XPT namespace " namespace {}
namespace `name^
{
`cursor^
}
..XPT
XPT icastop " operator type ..
operator `typename^ ()
{ return `cursor^; }
..XPT
XPT castop " operator type ..
operator `typename^ ();
`className^::operator `typename^ ();
{ return `cursor^; }
..XPT
XPT iop " t operator .. ()
`type^ operator `opName^ ( `args^ )`$BRfun^{
`cursor^
}
..XPT
XPT op " t operator .. ()
`type^ operator `opName^ ( `args^ );
`type^ `className^::operator `opName^ ( `args^ )`$BRfun^{
}
..XPT
XPT templateclass " template <> class
template
<`templateParam^>
class `className^`$BRfun^{
public:
`className^(`$SParg`ctorParam?`$SParg^);
~`className^();
`className^(`$SParg^const `className^ &cpy`$SParg^);
`cursor^
private:
};
template <`templateParam^>
`className^<`_^cleanTempl(R('templateParam'))^^>::`className^(`ctorParam?^)`$BRfun^{
}
template <`templateParam^>
`className^<`_^cleanTempl(R('templateParam'))^^>::~`className^()`$BRfun^{
}
template <`templateParam^>
`className^<`_^cleanTempl(R('templateParam'))^^>::`className^(`$SParg^gconst `className^ &cpy`$SParg^)`$BRfun^{
}
..XPT
XPT try wrap=what " try .. catch..
try
{
`what^
}`$BRel^`Include:catch^
XPT catch " catch\( .. )
catch ( `except^ )
{
`cursor^
}
XPT externc wrap " #ifdef C++.... extern "c"...
#ifdef __cplusplus
extern "C" {
#endif
`cursor^
#ifdef __cplusplus
}
#endif
..XPT

View file

@ -0,0 +1,113 @@
XPTemplate priority=lang-
let s:f = g:XPTfuncs()
XPTvar $TRUE true
XPTvar $FALSE false
XPTvar $NULL null
XPTvar $BRif \n
XPTvar $BRloop \n
XPTvar $BRloop \n
XPTvar $BRstc \n
XPTvar $BRfun \n
XPTvar $VOID_LINE /* void */;
XPTvar $CURSOR_PH /* cursor */
XPTvar $CL /*
XPTvar $CM *
XPTvar $CR */
XPTinclude
\ _common/common
\ _comment/doubleSign
\ _condition/c.like
\ _loops/c.while.like
\ _loops/java.for.like
\ _structures/c.like
XPTinclude
\ c/c
" ========================= Function and Variables =============================
" ================================= Snippets ===================================
XPT foreach " foreach (.. in ..) {..}
foreach ( `var^ `e^ in `what^ )`$BRloop^{
`cursor^
}
XPT struct " struct { .. }
`public^ struct `structName^
{
`fieldAccess^public^ `type^ `name^;`...^
`fieldAccess^public^ `type^ `name^;`...^
}
XPT class " class +ctor
class `className^
{
public `className^(` `ctorParam` ^)
{
`cursor^
}
}
XPT main " static main string[]
public static void Main( string[] args )
{
`cursor^
}
XPT prop " .. .. {get set}
public `type^ `Name^
{`
`get...{{^
get { return `what^; }`}}^`
`set...{{^
set { `what^ = `value^; }`}}^
}
XPT namespace " namespace {}
namespace `name^
{
`cursor^
}
XPT try wrap=what " try .. catch .. finally
XSET handler=$CL handler $CR
try
{
`what^
}`
`...^
catch (`except^ e)
{
`handler^
}`
`...^`
`finally...{{^
finally
{
`cursor^
}`}}^
" ================================= Wrapper ===================================
XPT region_ wraponly=wrapped " #region #endregion
#region `regionText^
`wrapped^
`cursor^
#endregion /* `regionText^ */

View file

@ -0,0 +1,521 @@
XPTemplate priority=lang
let s:f = g:XPTfuncs()
XPTvar $VOID_LINE /* void */;
XPTvar $CURSOR_PH /* cursor */
XPTvar $CL /*
XPTvar $CM *
XPTvar $CR */
XPTinclude
\ _common/common
\ _comment/doubleSign
" ========================= Function and Variables =============================
fun! s:f.css_braced_post()
let v = self.V()
let v = substitute( v, '^\s*$', '', 'g' )
if v =~ '^\s*\w\+('
let name = matchstr( v, '^\s*\zs\w\+(' )
return self.Build( ' ' . name . self.ItemCreate( '', {}, {} ) . ')' )
else
return v
endif
endfunction
" ================================= Snippets ===================================
XPT globalcn " global css from Sina
body,ul,ol,li,p,h1,h2,h3,h4,h5,h6,form,fieldset,table,td,img,div{margin:0;padding:0;border:0;}
body{background:#fff;color:#333;font-size:12px; margin-top:5px;font-family:"宋体";}
ul,ol{list-style-type:none;}
select,input,img,select{vertical-align:middle;}
a{text-decoration:underline;}
a:link{color:#009;}
a:visited{color:#800080;}
a:hover,a:active,a:focus{color:#c00;}
.clearit{clear:both;}
XPT globalen " global css from Yahoo
html{color:#000;background:#FFF}
body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,code,form,fieldset,legend,input,textarea,p,blockquote,th,td{margin:0;padding:0}
table{border-collapse:collapse;border-spacing:0}
fieldset,img{border:0}
address,caption,cite,code,dfn,em,strong,th,var{font-style:normal;font-weight:normal}
li{list-style:none}
caption,th{text-align:left}
h1,h2,h3,h4,h5,h6{font-size:100%;font-weight:normal}
q:before,q:after{content:''}
abbr,acronym{border:0;font-variant:normal}
sup{vertical-align:text-top}
sub{vertical-align:text-bottom}
input,textarea,select{font-family:inherit;font-size:inherit;font-weight:inherit}
input,textarea,select{*font-size:100%}
legend{color:#000}
body{font:13px/1.231 arial,helvetica,clean,sans-serif;*font-size:small;*font:x-small}
select,input,button,textarea{font:99% arial,helvetica,clean,sans-serif}
table{font-size:inherit;font:100%}
pre,code,kbd,samp,tt{font-family:monospace;*font-size:108%;line-height:100%}
a{text-decoration:none}
a:hover,a:focus{text-decoration:underline}
strong{font-weight:bold}
input[type=submit]{cursor:pointer}
button{cursor:pointer}
XPT padding " padding:
padding: `v^`v^AutoCmpl( 1, 'auto', '0px' )^;
XPT width " width :
width: `^;
XPT height " height :
height: `^;
XPT backrep " background-repeat
XSET rep=Choose(['repeat', 'repeat-x','repeat-y','no-repeat'])
background-repeat: `rep^;
XPT azimuth " azimuth
XSET azim=Choose(['left-side', 'far-left', 'left', 'center-left', 'center', 'center-right', 'right', 'far-right', 'right-side', 'behind', 'leftwards', 'rightwards'])
azimuth: `azim^;
XPT backpos " background-position
XSET horiz=Choose(['left', 'center', 'right'])
XSET horiz|post=SV('^\s*$', '', 'g')
XSET vert=Choose(['top', 'center', 'bottom'])
XSET vert|post=SV('^\s*$', '', 'g')
background-position:` `vert`^` `horiz`^;
XPT border " border
XSET pos=ChooseStr( '-top', '-right', '-bottom', '-left' )
XSET thick=Choose(['thin', 'thick', 'medium'])
XSET thick|post=SV('^\s*$', '', 'g')
XSET kind=Choose(['none', 'hidden', 'dotted', 'dashed', 'solid', 'double', 'groove', 'ridge', 'inset', 'outset'])
XSET kind|post=SV('^\s*$', '', 'g')
XSET color=Choose(['rgb()', '#', 'transparent'])
XSET color|post=css_braced_post()
border`pos^:` `thick^` `kind^` `color^;
XPT backgroundattachment " background-attachment
XSET selec=Choose(['scroll', 'fixed'])
background-attachment: `selec^;
XPT backgroundcolor " background-color
XSET selec=Choose(['transparent', 'rgb()', '#'])
XSET selec|post=css_braced_post()
background-color:` `selec^;
XPT backgroundimage " background-image
XSET selec=Choose(['url()', 'none'])
XSET selec|post=css_braced_post()
background-image:` `selec^;
XPT backgroundrepeat " background-repeat
XSET selec=Choose(['repeat', 'repeat-x','repeat-y','no-repeat'])
background-repeat: `selec^;
XPT background " background
XSET selec=Choose(['url()', 'scroll', 'fixed', 'transparent', 'rgb()', '#', 'none', 'top', 'center', 'bottom' , 'left', 'right', 'repeat', 'repeat-x', 'repeat-y', 'no-repeat'])
XSET selec|post=css_braced_post()
background:` `selec^;
XPT bordercollapse " border-collapse
XSET selec=Choose(['collapse', 'separate'])
border-collapse: `selec^;
XPT bordercolor " border-color
XSET selec=Choose(['rgb()', '#', 'transparent'])
XSET selec|post=css_braced_post()
border-color:` `selec^;
XPT borderspacing " border-spacing
XSET select_disabled=Choose([''])
border-spacing: `select^;
XPT borderstyle " border-style
XSET selec=Choose(['none', 'hidden', 'dotted', 'dashed', 'solid', 'double', 'groove', 'ridge', 'inset', 'outset'])
border-style: `selec^;
XPT borderwidth " border-width
XSET selec=Choose(['thin', 'thick', 'medium'])
border-width: `selec^;
XPT bottom " bottom
XSET selec=Choose(['auto'])
bottom: `selec^;
XPT captionside " caption-side
XSET selec=Choose(['top', 'bottom'])
caption-side: `selec^;
XPT clear " clear
XSET selec=Choose(['none', 'left', 'right', 'both'])
clear: `selec^;
XPT clip " clip
XSET selec=Choose(['auto', 'rect('])
clip: `selec^;
XPT color " color
XSET selec=Choose(['rgb()', '#'])
XSET selec|post=css_braced_post()
color:` `selec^;
XPT content " content
XSET selec=Choose(['normal', 'attr(', 'open-quote', 'close-quote', 'no-open-quote', 'no-close-quote'])
content: `selec^;
XPT cursor " cursor
XSET selec=Choose(['url()', 'auto', 'crosshair', 'default', 'pointer', 'move', 'e-resize', 'ne-resize', 'nw-resize', 'n-resize', 'se-resize', 'sw-resize', 's-resize', 'w-resize', 'text', 'wait', 'help', 'progress'])
XSET selec|post=css_braced_post()
cursor:` `selec^;
XPT direction " direction
XSET selec=Choose(['ltr', 'rtl'])
direction: `selec^;
XPT display " display
XSET selec=Choose(['inline', 'block', 'list-item', 'run-in', 'inline-block', 'table', 'inline-table', 'table-row-group', 'table-header-group', 'table-footer-group', 'table-row', 'table-column-group', 'table-column', 'table-cell', 'table-caption', 'none'])
display: `selec^;
XPT elevation " elevation
XSET selec=Choose(['below', 'level', 'above', 'higher', 'lower'])
elevation: `selec^;
XPT emptycells " empty-cells
XSET selec=Choose(['show', 'hide'])
empty-cells: `selec^;
XPT float " float
XSET selec=Choose(['left', 'right', 'none'])
float: `selec^;
XPT fontfamily " font-family
XSET selec=Choose(['sans-serif', 'serif', 'monospace', 'cursive', 'fantasy'])
font-family: `selec^;
XPT fontsize " font-size
XSET selec=Choose(['xx-small', 'x-small', 'small', 'medium', 'large', 'x-large', 'xx-large', 'larger', 'smaller'])
font-size: `selec^;
XPT fontstyle " font-style
XSET selec=Choose(['normal', 'italic', 'oblique'])
font-style: `selec^;
XPT fontvariant " font-variant
XSET selec=Choose(['normal', 'small-caps'])
font-variant: `selec^;
XPT fontweight " font-weight
XSET selec=Choose(['normal', 'bold', 'bolder', 'lighter'])
font-weight: `selec^;
XPT font " font
XSET kind=Choose(['normal', 'italic', 'oblique', 'small-caps', 'bold', 'bolder', 'lighter'])
XSET kind|post=SV('^\s*$', '', 'g')
XSET size=Choose(['xx-small', 'x-small', 'small', 'medium', 'large', 'x-large', 'xx-large', 'larger', 'smaller'])
XSET size|post=SV('^\s*$', '', 'g')
XSET font=Choose(['sans-serif', 'serif', 'monospace', 'cursive', 'fantasy', 'caption', 'icon', 'menu', 'message-box', 'small-caption', 'status-bar'])
XSET font|post=SV('^\s*$', '', 'g')
font:` `kind`^` `size`^` `font`^;
XPT letterspacing " letter-spacing
XSET selec=Choose(['normal'])
letter-spacing: `selec^;
XPT lineheight " line-height
XSET selec=Choose(['normal'])
line-height: `selec^;
XPT liststyleimage " list-style-image
XSET selec=Choose(['url()', 'none'])
XSET selec|post=css_braced_post()
list-style-image:` `selec^;
XPT liststyleposition " list-style-position
XSET selec=Choose(['inside', 'outside'])
list-style-position: `selec^;
XPT liststyletype " list-style-type
XSET selec=Choose(['disc', 'circle', 'square', 'decimal', 'decimal-leading-zero', 'lower-roman', 'upper-roman', 'lower-latin', 'upper-latin', 'none'])
list-style-type: `selec^;
XPT margin " margin
XSET selec=Choose(['auto'])
margin: `selec^;
XPT maxheight " max-height
XSET selec=Choose(['auto'])
max-height: `selec^;
XPT maxwidth " max-width
XSET selec=Choose(['none'])
max-width: `selec^;
XPT minheight " min-height
XSET selec=Choose(['none'])
min-height: `selec^;
XPT minwidth " min-width
XSET selec=Choose(['none'])
min-width: `selec^;
XPT outline " outline
XSET color=Choose(['rgb()', '#'])
XSET color|post=css_braced_post()
XSET style=Choose(['none', 'hidden', 'dotted', 'dashed', 'solid', 'double', 'groove', 'ridge', 'inset', 'outset'])
XSET style|post=SV('^\s*$', '', 'g')
XSET width=Choose(['thin', 'thick', 'medium'])
XSET width|post=SV('^\s*$', '', 'g')
outline:` `width`^` `style`^` `color`^;
XPT outlinecolor " outline-color
XSET selec=Choose(['rgb()', '#'])
XSET selec|post=css_braced_post()
outline-color:` `selec^;
XPT outlinestyle " outline-style
XSET selec=Choose(['none', 'hidden', 'dotted', 'dashed', 'solid', 'double', 'groove', 'ridge', 'inset', 'outset'])
outline-style: `selec^;
XPT outlinewidth " outline-width
XSET selec=Choose(['thin', 'thick', 'medium'])
outline-width: `selec^;
XPT overflow " overflow
XSET selec=Choose(['visible', 'hidden', 'scroll', 'auto'])
overflow: `selec^;
XPT pagebreakinside " page-break-inside
XSET selec=Choose(['auto', 'avoid'])
page-break-inside: `selec^;
XPT pitch " pitch
XSET selec=Choose(['x-low', 'low', 'medium', 'high', 'x-high'])
pitch: `selec^;
XPT playduring " play-during
XSET selec=Choose(['url()', 'mix', 'repeat', 'auto', 'none'])
XSET selec|post=css_braced_post()
play-during:` `selec^;
XPT position " position
XSET selec=Choose(['static', 'relative', 'absolute', 'fixed'])
position: `selec^;
XPT quotes " quotes
XSET selec=Choose(['none'])
quotes: `selec^;
XPT speakheader " speak-header
XSET selec=Choose(['once', 'always'])
speak-header: `selec^;
XPT speaknumeral " speak-numeral
XSET selec=Choose(['digits', 'continuous'])
speak-numeral: `selec^;
XPT speakpunctuation " speak-punctuation
XSET selec=Choose(['code', 'none'])
speak-punctuation: `selec^;
XPT speak " speak
XSET selec=Choose(['normal', 'none', 'spell-out'])
speak: `selec^;
XPT speechrate " speech-rate
XSET selec=Choose(['x-slow', 'slow', 'medium', 'fast', 'x-fast', 'faster', 'slower'])
speech-rate: `selec^;
XPT tablelayout " table-layout
XSET selec=Choose(['auto', 'fixed'])
table-layout: `selec^;
XPT textindent " text-indent
text-indent: `^;
XPT textalign " text-align
XSET selec=Choose(['left', 'right', 'center', 'justify'])
text-align: `selec^;
XPT textdecoration " text-decoration
XSET selec=Choose(['none', 'underline', 'overline', 'line-through', 'blink'])
text-decoration: `selec^;
XPT texttransform " text-transform
XSET selec=Choose(['capitalize', 'uppercase', 'lowercase', 'none'])
text-transform: `selec^;
XPT top " top
XSET selec=Choose(['auto'])
top: `selec^;
XPT unicodebidi " unicode-bidi
XSET selec=Choose(['normal', 'embed', 'bidi-override'])
unicode-bidi: `selec^;
XPT verticalalign " vertical-align
XSET selec=Choose(['baseline', 'sub', 'super', 'top', 'text-top', 'middle', 'bottom', 'text-bottom'])
vertical-align: `selec^;
XPT visibility " visibility
XSET selec=Choose(['visible', 'hidden', 'collapse'])
visibility: `selec^;
XPT volume " volume
XSET selec=Choose(['silent', 'x-soft', 'soft', 'medium', 'loud', 'x-loud'])
volume: `selec^;
XPT whitespace " white-space
XSET selec=Choose(['normal', 'pre', 'nowrap', 'pre-wrap', 'pre-line'])
white-space: `selec^;
XPT wordspacing " word-spacing
XSET selec=Choose(['normal'])
word-spacing: `selec^;
XPT zindex " z-index
XSET selec=Choose(['auto'])
z-index: `selec^;
XPT bordertopcolor " border-top-color
XSET col=Choose(['rgb()', '#', 'transparent'])
XSET col|post=css_braced_post()
border-top-color:` `col^;
XPT borderbottomcolor " border-bottom-color
XSET col=Choose(['rgb()', '#', 'transparent'])
XSET col|post=css_braced_post()
border-bottom-color:` `col^;
XPT borderrightcolor " border-right-color
XSET col=Choose(['rgb()', '#', 'transparent'])
XSET col|post=css_braced_post()
border-right-color:` `col^;
XPT borderleftcolor " border-left-color
XSET col=Choose(['rgb()', '#', 'transparent'])
XSET col|post=css_braced_post()
border-left-color:` `col^;
XPT bordertopstyle " border-top-style
XSET col=Choose(['none', 'hidden', 'dotted', 'dashed', 'solid', 'double', 'groove', 'ridge', 'inset', 'outset'])
border-top-style: `col^;
XPT borderbottomstyle " border-bottom-style
XSET col=Choose(['none', 'hidden', 'dotted', 'dashed', 'solid', 'double', 'groove', 'ridge', 'inset', 'outset'])
border-bottom-style: `col^;
XPT borderrightstyle " border-right-style
XSET col=Choose(['none', 'hidden', 'dotted', 'dashed', 'solid', 'double', 'groove', 'ridge', 'inset', 'outset'])
border-right-style: `col^;
XPT borderleftstyle " border-left-style
XSET col=Choose(['none', 'hidden', 'dotted', 'dashed', 'solid', 'double', 'groove', 'ridge', 'inset', 'outset'])
border-left-style: `col^;
XPT bordertopwidth " border-top-width
XSET col=Choose(['rgb()', '#', 'transparent'])
XSET col|post=css_braced_post()
border-top-width:` `col^;
XPT borderbottomwidth " border-bottom-width
XSET col=Choose(['thin', 'thick', 'medium'])
border-bottom-width: `col^;
XPT borderrightwidth " border-right-width
XSET col=Choose(['thin', 'thick', 'medium'])
border-right-width: `col^;
XPT borderleftwidth " border-left-width
XSET col=Choose(['thin', 'thick', 'medium'])
border-left-width: `col^;
XPT pagebreakafter " page-break-after
XSET what=Choose(['auto', 'always', 'avoid', 'left', 'right'])
page-break-after: `what^;
XPT pagebreakbefore " page-break-before
XSET what=Choose(['auto', 'always', 'avoid', 'left', 'right'])
page-break-before: `what^;

View file

@ -0,0 +1,116 @@
XPTemplate priority=lang
let s:f = g:XPTfuncs()
XPTvar $VOID_LINE /* void */
XPTvar $CURSOR_PH /* cursor */
XPTvar $CL /*
XPTvar $CM
XPTvar $CR */
XPTinclude
\ _common/common
\ _comment/doubleSign
" ========================= Function and Variables =============================
" ================================= Snippets ===================================
XPT digraph " digraph .. { .. }
digraph `graphName^
{
`cursor^
}
..XPT
XPT graph " graph .. { .. }
graph `graphName^
{
`cursor^
}
..XPT
XPT subgraph " subgraph .. { .. }
subgraph `clusterName^
{
`cursor^
}
..XPT
XPT node " .. [...]
XSET shape=Choose(['box', 'polygon', 'ellipse', 'circle', 'point', 'egg', 'triangle', 'plaintext', 'diamond', 'trapezium', 'parallelogram', 'house', 'pentagon', 'hexagon', 'septagon', 'octagon', 'doublecircle', 'doubleoctagon', 'tripleoctagon', 'invtriangle', 'invtrapezium', 'invhouse', 'Mdiamond', 'Msquare', 'Mcircle', 'rect', 'rectangle', 'none', 'note', 'tab', 'folder', 'box3d', 'component'])
`node^` `details...{{^ [shape=`shape^, label="`^"]`}}^
..XPT
XPT lbl " [label=".."]
[label="`cursor^"]
XPT shapeNode "
`node^ [shape=`shape^` `label...{{^, label="`lbl^"`}}^]
..XPT
XPT circle alias=shapeNode " ..\[shape="circle"..]
XSET shape|pre=circle
XSET shape=Next()
XPT diamond alias=shapeNode " ..\[shape="diamond"..]
XSET shape|pre=diamond
XSET shape=Next()
XPT box alias=shapeNode " ..\[shape="box"..]
XSET shape|pre=box
XSET shape=Next()
XPT ellipse alias=shapeNode " ..\[shape="ellipse"..]
XSET shape|pre=ellipse
XSET shape=Next()
XPT record " ..\[shape="record", label=".."]
`node^ [shape=record, label="`<`id`>^ `lbl^`...^| `<`id`>^ `lbl^`...^"]
..XPT
XPT triangle " ..\[shape="triangle", label=".."]
`node^ [shape=triangle, label="`<`id`>^ `lbl^`...^| `<`id`>^ `lbl^`...^"]
..XPT
XPT row " {..|... }
{`<`id`>^ `lbl^`...^| `<`id`>^ `lbl^`...^}
..XPT
XPT col " {..|... }
{`<`id`>^ `lbl^`...^| `<`id`>^ `lbl^`...^}
..XPT
XPT subgraph_ wraponly=wrapped " subgraph .. { SEL }
subgraph `clusterName^
{
`wrapped^
}
..XPT

View file

@ -0,0 +1,135 @@
XPTemplate priority=lang
let s:f = g:XPTfuncs()
XPTvar $TRUE 1
XPTvar $FALSE 0
XPTvar $NULL NULL
XPTvar $UNDEFINED NULL
XPTvar $VOID_LINE /* void */;
XPTvar $CURSOR_PH cursor
XPTvar $BRif ' '
XPTvar $BRel \n
XPTvar $BRloop ' '
XPTvar $BRstc ' '
XPTvar $BRfun ' '
XPTinclude
\ _common/common
" ========================= Function and Variables =============================
" ================================= Snippets ===================================
XPT inc " -include ..
-include( "`cursor^.hrl").
XPT def " -define ..
-define( `what^, `def^ ).
XPT ifdef " -ifdef ..\-endif..
-ifdef( `what^ ).
`thenmacro^
``else...`
{{^-else.
`cursor^
`}}^-endif().
XPT ifndef " -ifndef ..\-endif
-ifndef( `what^ ).
`thenmacro^
``else...`
{{^-else.
`cursor^
`}}^-endif().
XPT record " -record ..,{..}
-record( `recordName^
,{ `field1^`...^
, `fieldn^`...^
}).
XPT if " if .. -> .. end
if
`cond^ ->
`body^` `...^;
`cond2^ ->
`bodyn^` `...^
end `cursor^
XPT case " case .. of .. -> .. end
case `matched^ of
`pattern^ ->
`body^`...^;
`patternn^ ->
`bodyn^`...^
end `cursor^
XPT receive " receive .. -> .. end
receive
`pattern^ ->
`body^` `...^;
`patternn^ ->
`body^` `...^`
`after...{{^
after
`afterBody^`}}^
end
XPT fun " fun .. -> .. end
fun (`params^) `_^ -> `body^`
`more...{{^;
(`params^) `_^ -> `body^`
`...{{^;
(`params^) `_^ -> `body^`
`...^`}}^`}}^
end `cursor^
XPT try wrap=what " try .. catch .. end
try `what^
catch
`except^ -> `toRet^`
`...^;
`except^ -> `toRet^`
`...^`
`after...{{^
after
`afterBody^`}}^
end `cursor^
XPT tryof " try .. of ..
try `what^ of
`pattern^ ->
`body^` `more...^;
`patternn^ ->
`body^` `more...^
catch
`excep^ -> `toRet^` `...^;
`except^ -> `toRet^` `...^`
`after...{{^
after
`afterBody^`}}^
end `cursor^
XPT function " f \( .. \) -> ..
`funName^ ( `args0^ ) `_^ ->
`body0^ `...^;
`name^R('funName')^ ( `argsn^ ) `_^ ->
`bodyn^`...^
.

View file

@ -0,0 +1,71 @@
if exists("b:__ERUBY_FTDETECT_VIM__")
finish
endif
let b:__ERUBY_FTDETECT_VIM__ = 1
if &filetype !~ 'eruby'
finish
endif
let s:skipPattern = 'synIDattr(synID(line("."), col("."), 0), "name") =~? "\\vstring|comment"'
let s:pattern = {
\ 'ruby' : {
\ 'start' : '\V\c<%',
\ 'mid' : '',
\ 'end' : '\V\c%>',
\ 'skip' : s:skipPattern,
\ },
\ 'javascript' : {
\ 'start' : '\V\c<script\_[^>]\*>',
\ 'mid' : '',
\ 'end' : '\V\c</script>',
\ 'skip' : s:skipPattern,
\ },
\ 'css' : {
\ 'start' : '\V\c<style\_[^>]\*>',
\ 'mid' : '',
\ 'end' : '\V\c</style>',
\ 'skip' : s:skipPattern,
\ },
\}
let s:topFT = 'eruby'
fun! XPT_erubyFiletypeDetect() "{{{
let pos = [ line( "." ), col( "." ) ]
let synName = xpt#util#NearestSynName()
if synName == ''
" top level ft is html
return s:topFT
else
for [ name, ftPattern ] in items( s:pattern )
let pos = searchpairpos( ftPattern.start, ftPattern.mid, ftPattern.end, 'nbW', ftPattern.skip )
if pos != [0, 0]
return name
endif
endfor
if synName =~ '^\cjavascript'
return 'javascript'
elseif synName =~ '^\ccss'
return 'css'
endif
return s:topFT
endif
endfunction "}}}
if exists( 'b:XPTfiletypeDetect' )
unlet b:XPTfiletypeDetect
endif
let b:XPTfiletypeDetect = function( 'XPT_erubyFiletypeDetect' )

View file

@ -0,0 +1,21 @@
XPTemplate priority=lang-
XPTinclude
\ _common/common
\ html/html
\ html/eruby*
XPTembed
\ ruby/ruby
\ javascript/javascript
\ css/css
" ========================= Function and Variables =============================
" ================================= Snippets ===================================
" ================================= Wrapper ===================================

View file

@ -0,0 +1,93 @@
XPTemplate priority=lang
let s:f = g:XPTfuncs()
XPTvar $TRUE 1
XPTvar $FALSE 0
XPTvar $NULL NULL
XPTvar $UNDEFINED NULL
XPTinclude
\ _common/common
" ========================= Function and Variables =============================
fun! s:f.ModuleName()
let rootfolder = substitute(getcwd(), '^.*[\\/]\([^\\/]\+\)$', '\1', '')
let filename = rootfolder . '/' . expand('%:h:h') . '/' . expand('%:t:r')
let stripped = substitute( filename, '[\\/]', '.', 'g' )
return substitute( stripped, "-tests$", ".tests", '' )
endfunction
" ================================= Snippets ===================================
XPT alias "ALIAS: ... ...
ALIAS: `newword^ `oldword^
XPT const "CONSTANT: ... ...
CONSTANT: `word^ `constantValue^
XPT if "... [ ... ] [ ... ] if
`cond^ [ `then^ ] [ `else^ ] if
XPT times "... [ ... ] times
`count^ [ `what^ ] times
XPT mod " USING: ... IN: ...
XSET moduleName=ModuleName()
USING: kernel sequences accessors ;
IN: `moduleName^
XPT quote " [ ... ]
[ `cursor^ ]
XPT arr " { ... }
{ `cursor^ }
XPT vec " V{ ... }
V{ `cursor^ }
XPT bi " [ ... ] [ ... ] bi
[ `first^ ] [ `cursor^ ] bi
XPT tri " [ ... ] [ ... ] [ ... ] tri
[ `first^ ] [ `second^ ] [ `cursor^ ] tri
XPT map " [ ... ] map
[ `cursor^ ] map
XPT filter " [ ... ] filter
[ `cursor^ ] filter
XPT dip " [ ... ] dip
[ `cursor^ ] dip
XPT cleave " { [ ... ] ... } cleave
{ [ `code^ ]`...^
[ `code^ ]`...^
} cleave
XPT when " [ ... ] when
[ `cursor^ ] when
XPT unless " [ ... ] unless
[ `cursor^ ] unless
XPT keep " [ ... ] keep
[ `cursor^ ] keep
XPT cond " { { [ ... ] [ ... ] } } cond
{ { [ `cond^ ] [ `code^ ] }`...^
{ [ `cond^ ] [ `code^ ] }`...^`default...{{^
[ `cursor^ ]`}}^
} cond
XPT case " { { ... [ ... ] } } case
{ { `case^ [ `code^ ] }`...^
{ `case^ [ `code^ ] }`...^`default...{{^
[ `cursor^ ]`}}^
} case
XPT test "[ ... ] [ ... ] unit-test
{ `ret^ } [ `test^ ] unit-test

View file

@ -0,0 +1,24 @@
XPTemplate priority=lang
let s:f = g:XPTfuncs()
XPTinclude
\ _common/common
XPT branch " [branch "..."]
[branch "`branchName^"]`remote...{{^
remote = `remote^`}}^`merge...{{^
merge = refs/heads/`branchName^`}}^
XPT remote " [remote "..."]
[remote "`remoteName^"]
url = `fetchUrl^
fetch = `fetchRef^
XPT user " Basic user configuration
[user]
name = `$Author^
email = `$Email^

View file

@ -0,0 +1,34 @@
XPTemplate priority=lang
let s:f = g:XPTfuncs()
XPTinclude
\ _common/common
XPT skeleton " basic file skeleton
set title "`plotTitle^"
set xlabel "`axisLabel^"
set ylabel "`ordinateLabel^"
plot "`valueFile^" title "`valueTitle^" `using...{{^using `columns^ `}}^ with linespoint
XPT label " axis labels
set xlabel "`axisLabel^"
set ylabel "`ordinateLabel^"
XPT fun " ... ( ... ) = ...
`funName^( `args^ )=`cursor^
XPT range " set xrange ...; set yrange ...
set xrange [`xMin^:`xMax^]
set yrange [`yMin^:`yMay^]
XPT tics " set xtics & ytics
set xtics `xTics^
set ytics `yTics^
XPT term " Change output terminal
XSET termMode=Choose(['svg', 'canvas','latex', 'postscript', 'x11','eps', 'xterm'])
set terminal `termMode^ enhanced`size...{{^ size `width^ `height^`}}^
set output "`filename^"

View file

@ -0,0 +1,179 @@
XPTemplate priority=lang
let s:f = g:XPTfuncs()
fun! s:f.MakeIntType( n )
let n = a:n
return matchstr(n, '\v^u') . "int" . matchstr(n, '\v\d+$' )
endfunction
XPTvar $TRUE true
XPTvar $FALSE false
XPTvar $NULL nil
XPTvar $UNDEFINED nil
XPTvar $SParg ''
XPTinclude
\ _common/common
\ _comment/c.like
XPT _dec hidden " $_xSnipName
`$_xSnipName^
XPT package alias=_dec
XPT import alias=_dec
XPT type alias=_dec
XPT const alias=_dec
XPT var alias=_dec
XPT _int " MakeIntType($_xSnipName)
`MakeIntType($_xSnipName)^
XPT i8 alias=_int
XPT i16 alias=_int
XPT i32 alias=_int
XPT i64 alias=_int
XPT u8 alias=_int
XPT u16 alias=_int
XPT u32 alias=_int
XPT u64 alias=_int
XPT struct " struct {
struct {
`cursor^
}
XPT func wrap " func () int {
func `n^(`p?^)` `int?^ {
`cursor^
}
XPT meth wrap " func (*T) () int {
func (`^) `n^(`p?^)` `int?^ {
`cursor^
}
XPT go " go func (){}()
go func (`p?^) {
`cursor^
}()
XPT tfunc " func Test
func Test`^(t *testing.T) {
`cursor^
}
XPT bfunc " func Test
func Benchmark`^(b *testing.B) {
`cursor^
for ii := 0; i < b.N; i++ {
}
}
XPT main " func main\()
func main() {
`cursor^
}
XPT println " fmt.Println\()
fmt.Println( `^ )
XPT sprintf " fmt.Sprintf\()
fmt.Sprintf( `^ )
XPT forever " for ;;
for ;; {
`cursor^
}
XPT for wrap " for i=0; i<10; i++
for `i^ := `0^; `i^ < `10^; `i^++ {
`cursor^
}
XPT forr wrap " for i=10; i>=0; i--
for `i^ := `10^; `i^ >= `0^; `i^-- {
`cursor^
}
XPT forrange wrap " for range
for `_^, `^ := range `^ {
`cursor^
}
XPT forin wrap alias=forrange
XPT if wrap " if {
if `^ {
`cursor^
}
XPT iftype wrap " if _, ok := x.(type); ok { ... }
if _, ok := `x^.( `tp^ ); ok {
`cursor^
}
XPT _ifeq wrap hidden " if x == $v {
XSET $v=0
if `^ == `$v^ {
`cursor^
}
XPT _ifne wrap hidden " if x != $v {
XSET $v=0
if `x^ != `$v^ {
`cursor^
}
XPT iferr " if err != nil {
if err != nil {
`cursor^
}
XPT ifn alias=_ifeq
XSET $v=nil
XPT ifnn alias=_ifne
XSET $v=nil
XPT if0 alias=_ifeq
XSET $v=0
XPT ifn0 alias=_ifne
XSET $v=0
XPT else
else {
`cursor^
}
XPT mps " map[string]
map[`string^]`T^
XPT mpi " map[string]
map[`int^]`T^
XPT mkc " make\(chan X, n, capa?)
make(chan `bool^, `0^`, `capa?^)
XPT mks " make\([]X, n, capa?)
make([]`bool^, `0^`, `capa?^)
XPT mkm " make\(map[X]Y, n, capa?)
make(map[`string^]`bool^`, `capa?^)
XPT mkms " make\(map[string]Y, n, capa?)
make(map[string]`bool^`, `capa?^)
XPT sel " select
select {
case `^:
`cursor^
}
XPT selc " select x <-ch
select {
case ``x?` := ^<-`ch^:
`cursor^
}
XPT switch " switch x {
switch `^ {
case `^:
`cursor^
}
XPT default " default:
default:
`cursor^
XPT test " if .. t.Errorf
if `^ {} else {
t.Errorf( `^ )
}
XPT ttype " if _, ok := x.(type); ok { ... }
if _, ok := `x^.( `tp^ ); ok {} else {
t.Errorf( "Expect `x^ to be `tp^ but: %v", `x^ )
}
XPT assert " if .. t.Errorf
if `^ {} else {
t.Fatalf( `^ )
}

View file

@ -0,0 +1,164 @@
XPTemplate priority=lang mark=`~
let s:f = g:XPTfuncs()
XPTvar $TRUE 1
XPTvar $FALSE 0
XPTvar $NULL NULL
XPTvar $UNDEFINED NULL
XPTvar $VOID_LINE /* void */;
XPTvar $BRif \n
XPTinclude
\ _common/common
\ _preprocessor/c.like
" ========================= Function and Variables =============================
" ================================= Snippets ===================================
XPT head " -----------------------------
--------------------------------------------------
---- `headName~
--------------------------------------------------
XPT class " class .. where..
class `context...{{~(`ctxt~) => `}}~`className~ `types~a~ where
`ar~ :: `type~ `...~
`methodName~ :: `methodType~`...~
`cursor~
XPT classcom " -- | class..
-- | `classDescr~
class `context...{{~(`ctxt~) => `}}~`className~ `types~a~ where
-- | `methodDescr~
`ar~ :: `type~ `...~
-- | `method_Descr~
`methodName~ :: `methodType~`...~
`cursor~
XPT datasum " data .. = ..|..|..
data `context...{{~(`ctxt~) => `}}~`typename~`typeParams~ ~=
`Constructor~ `ctorParams~VOID()~`
`...~
| `Ctor~ `params~VOID()~
`...~
`deriving...{{~deriving (`Eq,Show~)`}}~
`cursor~
XPT datasumcom " -- | data .. = ..|..|..
-- | `typeDescr~VOID()~
data `context...{{~(`ctxt~) => `}}~`typename~` `typeParams~ ~=
-- | `ConstructorDescr~
`Constructor~ `ctorParams~VOID()~`
`...~
-- | `Ctor descr~VOID()~
| `Ctor~ `params~VOID()~`
`...~
`deriving...{{~deriving (`Eq,Show~)`}}~
`cursor~
XPT parser " .. = .. <|> .. <|> .. <?>
`funName~ = `rule~`
`another_rule...{{~
<|> `rule~`
`more...{{~
<|> `rule~`
`more...~`}}~`}}~
`err...{{~<?> "`descr~"`}}~
`cursor~
XPT datarecord " data .. ={}
data `context...{{~(`ctxt~) => `}}~`typename~`typeParams~ ~=
`Constructor~ {
`field~ :: `type~`
`...{{~,
`fieldn~ :: `typen~`
`...~`}}~
}
`deriving...{{~deriving (`Eq, Show~)`}}~
`cursor~
XPT datarecordcom " -- | data .. ={}
-- | `typeDescr~
data `context...{{~(`ctxt~) => `}}~`typename~`typeParams~ ~=
`Constructor~ {
`field~ :: `type~ -- ^ `fieldDescr~`
`...{{~,
`fieldn~ :: `typen~ -- ^ `fielddescr~`
`...~`}}~
}
`deriving...{{~deriving (`Eq,Show~)`}}~
`cursor~
XPT instance " instance .. .. where
instance `className~ `instanceTypes~ where
`methodName~ `~ = `decl~ `...~
`method~ `~ = `declaration~`...~
`cursor~
XPT if " if .. then .. else
if `expr~
then `thenCode~
else `cursor~
XPT fun " fun pat = ..
`funName~ `pattern~ = `def~`
`...{{~
`name~R("funName")~ `pattern~ = `def~`
`...~`}}~
XPT funcom " -- | fun pat = ..
-- | `function_description~
`funName~ :: `type~
`name~R("funName")~ `pattern~ = `def~`
`...{{~
`name~R("funName")~ `pattern~ = `def~`
`...~`}}~
XPT funtype " .. :: .. => .. -> .. ->
`funName~ :: `context...{{~(`ctxt~)
=>`}}~ `type~ -- ^ `is~`
`...{{~
-> `type~ -- ^ `is~`
`...~`}}~
XPT options " {-# OPTIONS_GHC .. #-}
{-# OPTIONS_GHC `options~ #-}
XPT lang " {-# LANGUAGE .. #-}
{-# LANGUAGE `langName~ #-}
XPT inline " {-# INLINE .. #-}
{-# INLINE `phase...{{~[`2~] `}}~`funName~ #-}
XPT noninline " {-# NOINLINE .. #-}
{-# NOINLINE `funName~ #-}
XPT type " .. -> .. ->....
`context...{{~(`ctxt~) => `}}~`t1~ -> `t2~`...~ -> `t3~`...~
XPT deriving " deriving (...)
deriving (`classname~`...~,`classname~`...~)
XPT derivingstand " deriving instance ...
deriving instance `context...{{~`ctxt~ => `}}~`class~ `type~
XPT module " module .. () where ...
XSET moduleName=S(S(E('%:r'),'^.','\u&', ''), '[\\/]\(.\)', '.\u\1', 'g')
module `moduleName~ `exports...{{~( `cursor~
) `}}~where
XPT foldr " foldr (.... -> ...)
foldr (\ `e~ `acc~ -> `expr~) `init~ `lst~
XPT foldl " foldl' (.... -> ...)
foldl' (\ `acc~ `elem~ -> `expr~) `init~ `lst~
XPT map " map (... -> ...)
map (`elem~ -> `expr~) `list~

View file

@ -0,0 +1,31 @@
XPTemplate priority=lang
" containers
let s:f = g:XPTfuncs()
" inclusion
XPTinclude
\ _common/common
" ========================= Function and Variables =============================
" ================================= Snippets ===================================
XPT ln " ========...
==============================================================================
XPT fmt " vim: options...
vim:tw=78:ts=8:sw=8:sts=8:noet:ft=help:norl:
XPT q " : > ... <
: >
`cursor^
<
XPT r " |...|
|`content^|

View file

@ -0,0 +1,24 @@
" These snippets work only in html context of a eruby file
if &filetype != 'eruby'
finish
endif
XPTemplate priority=lang-
XPT ruby " <% ...
<%
`cursor^
%>
XPT r " <% ... %>
<% `cursor^ %>
XPT re " <%= ...
<%= `expr^ %>
XPT rc " <%# ...
<%# `cursor^ %>

View file

@ -0,0 +1,63 @@
if exists("b:__HTML_FTDETECT_VIM__")
finish
endif
let b:__HTML_FTDETECT_VIM__ = 1
" TODO xhtml support
if &filetype !~ 'html'
finish
endif
let s:skipPattern = 'synIDattr(synID(line("."), col("."), 0), "name") =~? "\\vstring|comment"'
let s:pattern = {
\ 'javascript' : {
\ 'start' : '\V\c<script\_[^>]\*>',
\ 'mid' : '',
\ 'end' : '\V\c</script>',
\ 'skip' : s:skipPattern,
\ },
\ 'css' : {
\ 'start' : '\V\c<style\_[^>]\*>',
\ 'mid' : '',
\ 'end' : '\V\c</style>',
\ 'skip' : s:skipPattern,
\ },
\}
fun! XPT_htmlFiletypeDetect() "{{{
let pos = [ line( "." ), col( "." ) ]
let synName = xpt#util#NearestSynName()
if synName == ''
" no character at current position or before curernt position
return &filetype
else
for [ name, ftPattern ] in items( s:pattern )
let pos = searchpairpos( ftPattern.start, ftPattern.mid, ftPattern.end, 'nbW', ftPattern.skip )
if pos != [0, 0]
return name
endif
endfor
if synName =~ '^\cjavascript'
return 'javascript'
elseif synName =~ '^\ccss'
return 'css'
endif
return &filetype
endif
endfunction "}}}
if exists( 'b:XPTfiletypeDetect' )
unlet b:XPTfiletypeDetect
endif
let b:XPTfiletypeDetect = function( 'XPT_htmlFiletypeDetect' )

View file

@ -0,0 +1,412 @@
" TODO entity char
" TODO back at 'base'
XPTemplate priority=lang
let s:f = g:XPTfuncs()
XPTinclude
\ _common/common
\ xml/xml
XPTvar $CURSOR_PH
XPTvar $CL <!--
XPTvar $CM
XPTvar $CR -->
XPTinclude
\ _comment/doubleSign
XPTembed
\ javascript/javascript
\ css/css
" ========================= Function and Variables =============================
fun! s:f.createTable(...) "{{{
let nrow_str = inputdialog("num of row:")
let nrow = nrow_str + 0
let ncol_str = inputdialog("num of column:")
let ncol = ncol_str + 0
let l = ""
let i = 0 | while i < nrow | let i += 1
let j = 0 | while j < ncol | let j += 1
let l .= "<tr>\n<td id=\"`pre^_".i."_".j."\"></td>\n</tr>\n"
endwhile
endwhile
return "<table id='`id^'>\n".l."</table>"
endfunction "}}}
let s:doctypes = {
\ 'HTML 3.2 Final' : 'html PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"',
\ 'HTML 4.0 Frameset' : 'html PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN" "http://www.w3.org/TR/REC-html40/frameset.dtd"',
\ 'HTML 4.0 Transitional' : 'html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd"',
\ 'HTML 4.0' : 'html PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"',
\ 'HTML 4.01 Frameset' : 'html PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd"',
\ 'HTML 4.01 Transitional' : 'html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"',
\ 'HTML 4.01' : 'html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"',
\ 'HTML 5' : 'HTML',
\ 'XHTML 1.0 Frameset' : 'html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd"',
\ 'XHTML 1.0 Strict' : 'html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"',
\ 'XHTML 1.0 Transitional' : 'html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"',
\ 'XHTML 1.1' : 'html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"',
\ 'XHTML Basic 1.0' : 'html PUBLIC "-//W3C//DTD XHTML Basic 1.0//EN" "http://www.w3.org/TR/xhtml-basic/xhtml-basic10.dtd"',
\ 'XHTML Basic 1.1' : 'html PUBLIC "-//W3C//DTD XHTML Basic 1.1//EN" "http://www.w3.org/TR/xhtml-basic/xhtml-basic11.dtd"',
\ 'XHTML Mobile 1.0' : 'html PUBLIC "-//WAPFORUM//DTD XHTML Mobile 1.0//EN" "http://www.wapforum.org/DTD/xhtml-mobile10.dtd"',
\ 'XHTML Mobile 1.1' : 'html PUBLIC "-//WAPFORUM//DTD XHTML Mobile 1.1//EN" "http://www.openmobilealliance.org/tech/DTD/xhtml-mobile11.dtd"',
\ 'XHTML Mobile 1.2' : 'html PUBLIC "-//WAPFORUM//DTD XHTML Mobile 1.2//EN" "http://www.openmobilealliance.org/tech/DTD/xhtml-mobile12.dtd"',
\}
fun! s:f.html_doctype_list()
return keys( s:doctypes )
endfunction
fun! s:f.html_doctype_post(v)
if has_key( s:doctypes, a:v )
return s:doctypes[ a:v ]
else
return ''
endif
endfunction
fun! s:f.html_enc()
return &fenc == '' ? &encoding : &fenc
endfunction
let s:nIndent = 0
fun! s:f.html_cont_ontype()
let v = self.V()
if v =~ '\V\n'
let v = matchstr( v, '\V\.\*\ze\n' )
let s:nIndent = &indentexpr != ''
\ ? eval( substitute( &indentexpr, '\Vv:lnum', 'line(".")', '' ) ) - indent( line( "." ) - 1 )
\ : self.NIndent()
return self.Finish( v . "\n" . repeat( ' ', s:nIndent ) )
else
return v
endif
endfunction
fun! s:f.html_cont_helper()
let v = self.V()
if v =~ '\V\n'
return self.ResetIndent( -s:nIndent, "\n" )
else
return ''
endif
endfunction
fun! s:f.html_tag_cmpl()
if !exists( 'b:xpt_html_tags' )
call htmlcomplete#LoadData()
let tagnames = sort( keys( b:html_omni ) )
let b:xpt_html_tags = []
let dict = {
\ 'vimxmlattrinfo' : 1,
\ 'vimxmlentities' : 1,
\ 'vimxmlroot' : 1,
\ 'vimxmltaginfo' : 1,
\ }
for t in tagnames
if !has_key( dict, t )
call add(b:xpt_html_tags, t)
endif
endfor
endif
return b:xpt_html_tags
endfunction
fun! s:f.html_close_tag()
let v = self.V()
if v =~ '\v/\s*$|^!'
return ''
else
return '</' . matchstr( v, '\v^\S+' ) . '>'
endif
endfunction
" ================================= Snippets ===================================
call XPTdefineSnippet("id", {'syn' : 'tag'}, 'id="`^"')
call XPTdefineSnippet("class", {'syn' : 'tag'}, 'class="`^"')
" TODO map < to tag
XPT tag hidden " <$_xSnipName>..</$_xSnipName>
XSET content|def=Echo( R( 't' ) =~ '\v/\s*$' ? Finish() : '' )
XSET content|ontype=html_cont_ontype()
<`t^$_xSnipName^>`content^`content^html_cont_helper()^`t^html_close_tag()^
..XPT
XPT _tag wrap=content hidden " <$_xSnipName >..</$_xSnipName>
XSET content|ontype=html_cont_ontype()
<`$_xSnipName^>`content^^`content^html_cont_helper()^</`$_xSnipName^>
..XPT
" XPT _t hidden " ..
" <`$_xSnipName^>`cont^</`$_xSnipName^>
XPT _tagAttr wrap=content hidden " <$_xSnipName >..</$_xSnipName>
XSET content|ontype=html_cont_ontype()
XSET att?=Echo('')
XSET att?|post=Echo(V()=~'\V\^ \$\|att?' ? '' : V())
<`$_xSnipName^` `att?^>`content^^`content^html_cont_helper()^</`$_xSnipName^>
..XPT
XPT _tagblock hidden " <$_xSnipName >\n .. \n</$_xSnipName>
<`$_xSnipName^>
`cursor^^
</`$_xSnipName^>
XPT _tagblockAttr hidden " <$_xSnipName >\n .. \n</$_xSnipName>
<`$_xSnipName^` `attr^>
`cursor^^
</`$_xSnipName^>
XPT _shorttag hidden " <$_xSnipName />
<`$_xSnipName^ />
XPT _shorttagAttr hidden " <$_xSnipName />
XSET att?=Echo('')
XSET att?|post=Echo(V()=~'\V\^ \$\|att?' ? '' : V())
<`$_xSnipName^` `att?^/>
..XPT
XPT doctype " <!DOCTYPE ***
XSET doctype=html_doctype_list()
XSET doctype|post=html_doctype_post( V() )
<!DOCTYPE `doctype^>
XPT html " <html><head>..<head><body>...
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
`:head:^
<body>
`cursor^
</body>
</html>
XPT head " <head>..</head>
<head>
`:contenttype:^
`:title:^
</head>
XPT contenttype " <meta http-equiv="Content-Type" content="...
<meta http-equiv="Content-Type" content="text/html; charset=`encoding^html_enc()^"/>
XPT title " <title>..</title>
<title>`title^expand('%:t:r')^</title>
XPT style " <style>..</style>
<style type="text/css" media="screen">
`cursor^
</style>
XPT meta " <meta ..>
<meta name="`meta_name^" content="`meta_content^" />
XPT link " <link rel=".." ..>
<link rel="`stylesheet^" type="`type^text/css^" href="`url^" />
XPT script " <script language="javascript"...
<script language="javascript" type="text/javascript">
`cursor^
</script>
..XPT
XPT scriptsrc " <script .. src=...
<script language="javascript" type="text/javascript" src="`js^"></script>
XPT body " <body>..</body>
<body>
`cursor^
</body>
XPT table alias=_tag
XPT tr alias=_tag
XPT td alias=_tag
XPT th alias=_tag
XPT fulltable hidden " create a full table
`createTable()^
XPT a wrap " <a href...
<a href="`href^">`cursor^</a>
..XPT
XPT div alias=_tag
XPT p alias=_tag
XPT ul alias=_tag
XPT ol alias=_tag
XPT li alias=_tag
XPT span alias=_tag
XPT br alias=_shorttag
XPT img alias=_shorttagAttr
XSET att?=Embed( 'src="`where^" alt="`alt^"' )
XPT h1 alias=_tag
XPT h2 alias=_tag
XPT h3 alias=_tag
XPT h4 alias=_tag
XPT h5 alias=_tag
XPT h6 alias=_tag
XPT iframe alias=_tagAttr
XSET att?=Embed( 'name="`name^"' )
" TODO enctype list : application/x-www-form-urlencoded
XPT form wrap " <form ..>..</form>
XSET method=ChooseStr( 'GET', 'POST' )
<form action="`action^" method="`method^" accept-charset="`html_enc()^" enctype="multipart/form-data">
`cursor^
</form>
XPT textarea alias=_tagAttr
XSET att?=Embed( 'name="`name^"' )
XPT input alias=_shorttagAttr
XSET att?=Embed( 'type="`type^" name="`name^" value="`value^"' )
XSET type=ChooseStr( 'text', 'password', 'checkbox', 'radio', 'submit', 'reset', 'file', 'hidden', 'image', 'button' )
" TODO other optional attribute like "checked", "readonly"
XPT _input_tmpl hidden " <input type=Echo($_xSnipName[1:]) ... />
<input type="`Echo($_xSnipName[1:])^" name="`name^" value="`value^" />
XPT itext alias=_input_tmpl
XPT ipassword alias=_input_tmpl
XPT icheckbox alias=_input_tmpl
XPT iradio alias=_input_tmpl
XPT isubmit alias=_input_tmpl
XPT ireset alias=_input_tmpl
XPT ifile alias=_input_tmpl
XPT ihidden alias=_input_tmpl
XPT iimage alias=_input_tmpl
XPT ibutton alias=_input_tmpl
XPT label alias=_tagAttr
XSET att?=Embed( 'for="`which^"' )
XPT select alias=_tagAttr
XSET att?=Embed( 'name="`name^"' )
XPT option alias=_tagAttr
XSET att?=Embed( 'value="`value^"' )
XPT fieldset " <fieldset ..
<fieldset>
<legend></legend>
`cursor^
</fieldset>
..XPT
" XPT sdiv alias=_t
" XPT diva " tips
" `:div( { 'content' : ':a:' } ):^
" html 5
" http://dev.w3.org/html5/html4-differences/Overview.html#character-encoding
" XPT section alias=_tag
" XPT article alias=_tag
" XPT aside alias=_tag
" XPT hgroup alias=_tag
" XPT header alias=_tag
" XPT footer alias=_tag
" XPT nav alias=_tag
" XPT figure alias=_tag
" XPT figcaption alias=_tag
" XPT video alias=_tag
" XPT audio alias=_tag
" XPT source alias=_tag
" XPT embed alias=_tag
" XPT mark alias=_tag
" XPT progress alias=_tag
" XPT meter alias=_tag
" XPT time alias=_tag
" XPT canvas alias=_tag
" XPT comand alias=_tag
" XPT details alias=_tag
" XPT datalist alias=_tag
" XPT keygen alias=_tag
" XPT output alias=_tag
" XPT ruby alias=_tag
" input type=
" tel
" search
" url
" email
" datetime
" date
" month
" week
" time
" datetime-local
" number
" range
" color

Some files were not shown because too many files have changed in this diff Show more