Merged ryans awesome python improvements

This commit is contained in:
Holger Rapp 2010-08-02 15:21:03 +02:00
commit 1f5771989c
14 changed files with 645 additions and 109 deletions

View File

@ -10,14 +10,15 @@ c = '#'
cs = vim.eval("&commentstring") cs = vim.eval("&commentstring")
if len(cs) == 3: if len(cs) == 3:
c = cs[0] c = cs[0]
snip.locals["c"] = c
res = (len(t[1])+4)*c + '\n' + c + ' '`${1:content}`!p snip.rv = (len(t[1])+4)*c
c = '#' snip.locals["bar"] = snip.rv
cs = vim.eval("&commentstring") snip += c + ' '`${1:content}`!p
if len(cs) == 3: c = snip.locals["c"]
c = cs[0]
res = ' ' + c + '\n' + (len(t[1])+4)*c` snip.rv = ' ' + c
snip += snip.locals["bar"]`
$0 $0
endsnippet endsnippet
@ -27,15 +28,17 @@ c = '#'
cs = vim.eval("&commentstring") cs = vim.eval("&commentstring")
if len(cs) == 3: if len(cs) == 3:
c = cs[0] c = cs[0]
snip.locals["c"] = c
snip.locals["bar"] = 75*c
res = 75*c + '\n' + c + " "+ (71-len(t[1]))/2*' ' snip.rv = snip.locals["bar"]
snip += c + " " + (71-len(t[1]))/2*' '
`${1:content}`!p `${1:content}`!p
c = '#' c = snip.locals["c"]
cs = vim.eval("&commentstring")
if len(cs) == 3:
c = cs[0]
a = 71-len(t[1]); res = (a/2 + a%2) * " " + " " + c + '\n' + 75*c` a = 71-len(t[1])
snip.rv = (a/2 + a%2) * " " + " " + c
snip += snip.locals["bar"]`
$0 $0
endsnippet endsnippet

View File

@ -9,7 +9,7 @@ snippet def "#ifndef … #define … #endif"
endsnippet endsnippet
snippet inc "#include "" (inc)" snippet inc "#include "" (inc)"
#include "${1:`!p res=fn.split('.')[-2]+'.h'`}" #include "${1:`!p snip.rv = snip.basename + '.h'`}"
endsnippet endsnippet
snippet Inc "#include <> (Inc)" snippet Inc "#include <> (Inc)"
@ -46,11 +46,13 @@ endsnippet
snippet once "Include header once only guard" snippet once "Include header once only guard"
#ifndef ${1:`!p #ifndef ${1:`!p
if not len(cur): if not snip.c:
import random, string import random, string
name = re.sub(r'[^A-Za-z0-9]+','_', fn).upper() name = re.sub(r'[^A-Za-z0-9]+','_', snip.fn).upper()
rand = ''.join(random.sample(string.ascii_letters+string.digits, 8)) rand = ''.join(random.sample(string.ascii_letters+string.digits, 8))
res = ('%s_%s' % (name,rand)).upper()`} snip.rv = ('%s_%s' % (name,rand)).upper()
else:
snip.rv = snip.c`}
#define $1 #define $1
${0} ${0}
@ -85,8 +87,7 @@ printf("${1:%s}\n"${1/([^%]|%%)*(%.)?.*/(?2:, :\);)/}$2${1/([^%]|%%)*(%.)?.*/(?2
endsnippet endsnippet
snippet st "struct" snippet st "struct"
struct ${1:`!p if fn != "": res = fn.split(".")[-2].lower()+"_t" struct ${1:`!p snip.rv = (snip.basename or "name") + "_t"`}
else: res = "name"`}
{ {
${0:/* data */} ${0:/* data */}
}; };

View File

@ -8,11 +8,7 @@ ${1:v}${1/^.*?(-)?(>)?$/(?2::(?1:>:.))/}begin(), $1${1/^.*?(-)?(>)?$/(?2::(?1:>:
endsnippet endsnippet
snippet cl "class .. (class)" snippet cl "class .. (class)"
class ${1:`!p class ${1:`!p snip.rv = snip.basename or "name"`}
if len(fn):
res = fn.split(".")[-2].lower()+ '_t'
else:
res = "name"`}
{ {
public: public:
${1/(\w+).*/$1/} (${2:arguments}); ${1/(\w+).*/$1/} (${2:arguments});
@ -24,9 +20,7 @@ private:
endsnippet endsnippet
snippet ns "namespace .. (namespace)" snippet ns "namespace .. (namespace)"
namespace${1/.+/ /m}${1:`!p namespace${1/.+/ /m}${1:`!p snip.rv = snip.basename or "name"`}
if len(fn): res = fn.split(".")[-2].lower()
else: res ="name"`}
{ {
$0 $0
}${1/.+/ \/* /m}$1${1/.+/ *\/ /m} }${1/.+/ \/* /m}$1${1/.+/ *\/ /m}

View File

@ -3,32 +3,33 @@
snippet sec "Section marker" b snippet sec "Section marker" b
============================================================================= =============================================================================
${1:SECTION}`!p ${1:SECTION}`!p
file_start = fn.split('.')[0] file_start = snip.fn.split('.')[0]
sec_name = t[1].strip("1234567890. ").lower().replace(' ', '-') sec_name = t[1].strip("1234567890. ").lower().replace(' ', '-')
res = ("*%s-%s*" % (file_start, sec_name)).rjust(77-len(t[1]))` snip.rv = ("*%s-%s*" % (file_start, sec_name)).rjust(77-len(t[1]))`
$0 $0
endsnippet endsnippet
snippet ssec "Sub section marker" b snippet ssec "Sub section marker" b
${1:Subsection}`!p ${1:Subsection}`!p
file_start = fn.split('.')[0] file_start = snip.fn.split('.')[0]
sec_name = t[1].strip("1234567890. ").lower().replace(' ', '-') sec_name = t[1].strip("1234567890. ").lower().replace(' ', '-')
sec_title = ("*%s-%s*" % (file_start, sec_name)).rjust(77-len(t[1])) sec_title = ("*%s-%s*" % (file_start, sec_name)).rjust(77-len(t[1]))
res = sec_title + "\n" + "-"*len(t[1])` snip.rv = sec_title
snip += "-"*len(t[1])`
$0 $0
endsnippet endsnippet
snippet sssec "Subsub Section marker" b snippet sssec "Subsub Section marker" b
${1:SubSubsection}:`!p ${1:SubSubsection}:`!p
file_start = fn.split('.')[0] file_start = fn.split('.')[0]
sec_name = t[1].strip("1234567890. ").lower().replace(' ', '-') sec_name = t[1].strip("1234567890. ").lower().replace(' ', '-')
sec_title = ("*%s-%s*" % (file_start, sec_name)).rjust(77-len(t[1])) sec_title = ("*%s-%s*" % (file_start, sec_name)).rjust(77-len(t[1]))
res = sec_title` snip.rv = sec_title`
$0 $0
endsnippet endsnippet

View File

@ -112,12 +112,12 @@ endsnippet
# HTML TAGS # # HTML TAGS #
############# #############
snippet input "Input with Label" snippet input "Input with Label"
<label for="${2:${1/[[:alpha:]]+|( )/(?1:_:\L$0)/g}}">$1</label><input type="${3:text/submit/hidden/button}" name="${4:$2}" value="$5"${6: id="${7:$2}"}`!p if vim.eval("&filetype").startswith("x"): res = '/'`> <label for="${2:${1/[[:alpha:]]+|( )/(?1:_:\L$0)/g}}">$1</label><input type="${3:text/submit/hidden/button}" name="${4:$2}" value="$5"${6: id="${7:$2}"}`!p if snip.ft.startswith("x"): snip.rv = '/'`>
endsnippet endsnippet
snippet input "XHTML <input>" snippet input "XHTML <input>"
<input type="${1:text/submit/hidden/button}" name="${2:some_name}" value="$3"${4: id="${5:$2}"}`!p if vim.eval("&filetype").startswith("x"): res = '/'`> <input type="${1:text/submit/hidden/button}" name="${2:some_name}" value="$3"${4: id="${5:$2}"}`!p if snip.ft.startswith("x"): snip.rv = '/'`>
endsnippet endsnippet
@ -143,15 +143,12 @@ snippet mailto "XHTML <a mailto: >"
endsnippet endsnippet
snippet base "XHTML <base>" snippet base "XHTML <base>"
<base href="$1"${2: target="$3"}`!p if vim.eval("&filetype").startswith("x"): res = '/'`> <base href="$1"${2: target="$3"}`!p if snip.ft.startswith("x"): snip.rv = '/'`>
endsnippet endsnippet
snippet body "XHTML <body>" snippet body "XHTML <body>"
<body id="${1:`!p <body id="${1:`!p
if len(fn): snip.rv = snip.fn and 'Hallo' or 'Nothin'
res = "Hallo"
else:
res = "Nothin"
`}"${2: onload="$3"}> `}"${2: onload="$3"}>
$0 $0
</body> </body>
@ -164,14 +161,12 @@ snippet div "XHTML <div>"
endsnippet endsnippet
snippet form "XHTML <form>" snippet form "XHTML <form>"
<form action="${1:`!p if len(fn): <form action="${1:`!p
res = fn.split('.')[-2] snip.rv = (snip.basename or 'unnamed') + '_submit'
else: `}" method="${2:get}" accept-charset="utf-8">
res = "unnamed"
res += '_submit'`}" method="${2:get}" accept-charset="utf-8">
$0 $0
<p><input type="submit" value="Continue →"`!p if vim.eval("&filetype").startswith("x"): res = '/'`></p> <p><input type="submit" value="Continue →"`!p if snip.ft.startswith("x"): snip.rv = '/'`></p>
</form> </form>
endsnippet endsnippet
@ -181,21 +176,18 @@ endsnippet
snippet head "XHTML <head>" snippet head "XHTML <head>"
<head> <head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8"`!p if vim.eval("&filetype").startswith("x"): res = '/'`> <meta http-equiv="Content-type" content="text/html; charset=utf-8"`!p if snip.ft.startswith("x"): snip.rv = '/'`>
<title>${1:`!p if len(fn): <title>${1:`!p snip.rv = snip.basename or "Page Title"`}</title>
res = fn.split('.')[-2]
else:
res = "Page Title"`}</title>
$0 $0
</head> </head>
endsnippet endsnippet
snippet link "XHTML <link>" snippet link "XHTML <link>"
<link rel="${1:stylesheet}" href="${2:/css/master.css}" type="text/css" media="${3:screen}" title="${4:no title}" charset="${5:utf-8}"`!p if vim.eval("&filetype").startswith("x"): res = '/'`> <link rel="${1:stylesheet}" href="${2:/css/master.css}" type="text/css" media="${3:screen}" title="${4:no title}" charset="${5:utf-8}"`!p if snip.ft.startswith("x"): snip.rv = '/'`>
endsnippet endsnippet
snippet meta "XHTML <meta>" snippet meta "XHTML <meta>"
<meta name="${1:name}" content="${2:content}"`!p if vim.eval("&filetype").startswith("x"): res = '/'`> <meta name="${1:name}" content="${2:content}"`!p if snip.ft.startswith("x"): snip.rv = '/'`>
endsnippet endsnippet
snippet scriptsrc "XHTML <script src...>" snippet scriptsrc "XHTML <script src...>"
@ -222,10 +214,7 @@ snippet table "XHTML <table>"
endsnippet endsnippet
snippet title "XHTML <title>" snippet title "XHTML <title>"
<title>${1:`!p if len(fn): <title>${1:`!p snip.rv = snip.basename or "Page Title"`}</title>
res = fn.split('.')[-2]
else:
res = "Page Title"`}</title>
endsnippet endsnippet
snippet fieldset "Fieldset" snippet fieldset "Fieldset"
@ -238,15 +227,15 @@ endsnippet
snippet movie "Embed QT movie (movie)" b snippet movie "Embed QT movie (movie)" b
<object width="$2" height="$3" classid="clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B" codebase="http://www.apple.com/qtactivex/qtplugin.cab"> <object width="$2" height="$3" classid="clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B" codebase="http://www.apple.com/qtactivex/qtplugin.cab">
<param name="src" value="$1"`!p if vim.eval("&filetype").startswith("x"): res = '/'`> <param name="src" value="$1"`!p snip.locals['xhtml'] = snip.ft.startswith("x") and "/" or ""; snip.rv = snip.locals['xhtml']`>
<param name="controller" value="$4"`!p if vim.eval("&filetype").startswith("x"): res = '/'`> <param name="controller" value="$4"`!p snip.rv = snip.locals['xhtml']`>
<param name="autoplay" value="$5"`!p if vim.eval("&filetype").startswith("x"): res = '/'`> <param name="autoplay" value="$5"`!p snip.rv = snip.locals['xhtml']`>
<embed src="${1:movie.mov}" <embed src="${1:movie.mov}"
width="${2:320}" height="${3:240}" width="${2:320}" height="${3:240}"
controller="${4:true}" autoplay="${5:true}" controller="${4:true}" autoplay="${5:true}"
scale="tofit" cache="true" scale="tofit" cache="true"
pluginspage="http://www.apple.com/quicktime/download/" pluginspage="http://www.apple.com/quicktime/download/"
`!p if vim.eval("&filetype").startswith("x"): res = '/'`> `!p snip.rv = snip.locals['xhtml']`>
</object> </object>
endsnippet endsnippet

View File

@ -27,10 +27,8 @@ catch (${1:Exception} ${2:e}) {
endsnippet endsnippet
snippet cl "class" b snippet cl "class" b
class ${1:`!p if len(fn): class ${1:`!p
res = fn.split('.')[-2] snip.rv = snip.basename or "untitled"`} ${2:extends ${3:Parent} }${4:implements ${5:Interface} }{
else:
res = "untitled"`} ${2:extends ${3:Parent} }${4:implements ${5:Interface} }{
$0 $0
} }
endsnippet endsnippet
@ -92,10 +90,7 @@ import
endsnippet endsnippet
snippet in "interface" b snippet in "interface" b
interface ${1:`!p if len(fn): interface ${1:`!p snip.rv = snip.basename or "untitled"`} ${2:extends ${3:Parent} }{
res = fn.split('.')[-2]
else:
res = "untitled"`} ${2:extends ${3:Parent} }{
$0 $0
} }
endsnippet endsnippet
@ -176,10 +171,7 @@ synchronized
endsnippet endsnippet
snippet tc "test case" snippet tc "test case"
public class ${1:`!p if len(fn): public class ${1:`!p snip.rv = snip.basename or "untitled"`} extends ${2:TestCase} {
res = fn.split('.')[-2]
else:
res = "untitled"`} extends ${2:TestCase} {
$0 $0
} }
endsnippet endsnippet

View File

@ -18,23 +18,74 @@ endsnippet
########## ##########
# COMMON # # COMMON #
########## ##########
# The smart def and smart class snippets use a global option called
# "g:ultisnips_python_style" which, if set to "doxygen" will use doxygen
# style comments in docstrings.
snippet class "smart class" b snippet class "smart class" b
class ${1:MyClass}(${2:object}): class ${1:MyClass}(${2:object}):
"""${3:Docstring for $1}""" """ ${3:Docstring for $1 }"""
def __init__( self${4/([^,])?(.*)/(?1:, )/}${4:arg} ): def __init__(self$4):
""" """ ${5:TODO: Fill me in}`!p
TODO: Fill me in snip >> 2
${4/.+/(?0:\n)/}${4/(\A\s*,\s*\Z)|,?\s*([A-Za-z_][A-Za-z0-9_]*)\s*(=[^,]*)?(,\s*|$)/(?2: $2 - describe me here\n)/g} """
${2/object$|(.+)/(?1: $0.__init__\(self\)\n\n)/}${4/(\A\s*,\s*\Z)|,?\s*([A-Za-z_][A-Za-z0-9_]*)\s*(=[^,]*)?(,\s*|$)/(?2: self._$2 = $2\n)/g} args = [arg.split('=')[0].strip() for arg in t[4].split(',') if arg]
args = [arg for arg in args if arg and arg != "self"]
if args:
snip += ""
for arg in args:
style = snip.opt("g:ultisnips_python_style", "normal")
if style == "doxygen":
snip += "@param %s TODO" % arg
else:
snip += ":%s: TODO" % arg
if args:
snip += '"""'
else:
snip.rv += ' """'
for sup in t[2].split(","):
sup = sup.strip()
snip += sup + ".__init__(self)"
for arg in args:
snip += "self._%s = %s" % (arg, arg)
`
$0
endsnippet endsnippet
snippet def "smart def" b snippet def "smart def" b
def ${1:function}(${2/([^,])?(.*)/(?1:)/}${2:arg}): def ${1:function}(${2:self}):
"""${3:Docstring for $1} """ ${3:TODO: Docstring for $1}`!p
${2/.+/(?0:\n)/}${2/(\A\s*,\s*\Z)|,?\s*([A-Za-z_][A-Za-z0-9_]*)\s*(=[^,]*)?(,\s*|$)/ :param $2: description\n/g} snip >> 1
:returns: description
""" args = [arg.split('=')[0].strip() for arg in t[2].split(',') if arg]
args = [arg for arg in args if arg and arg != "self"]
if args:
snip += ""
snip.locals["style"] = style = snip.opt("g:ultisnips_python_style", "normal")
for arg in args:
if style == "doxygen":
snip += "@param %s TODO" % arg
else:
snip += ":%s: TODO" % arg
`${4:
`!p
style = snip.locals["style"]
if style == "doxygen":
snip.rv = "@return"
else:
snip.rv = ":returns:"` ${5:TODO}
}"""
${0:pass} ${0:pass}
endsnippet endsnippet

View File

@ -1,30 +1,30 @@
snippet part "Part" b snippet part "Part" b
`!p res=len(t[1])*'*'` `!p snip.rv = len(t[1])*'*'`
${1:Part name} ${1:Part name}
`!p res=len(t[1])*'*'` `!p snip.rv = len(t[1])*'*'`
$0 $0
endsnippet endsnippet
snippet sec "Section" b snippet sec "Section" b
${1:Section name} ${1:Section name}
`!p res=len(t[1])*'='` `!p snip.rv = len(t[1])*'='`
$0 $0
endsnippet endsnippet
snippet ssec "Subsection" b snippet ssec "Subsection" b
${1:Section name} ${1:Section name}
`!p res=len(t[1])*'-'` `!p snip.rv = len(t[1])*'-'`
$0 $0
endsnippet endsnippet
snippet sssec "Subsubsection" b snippet sssec "Subsubsection" b
${1:Section name} ${1:Section name}
`!p res=len(t[1])*'^'` `!p snip.rv = len(t[1])*'^'`
$0 $0
endsnippet endsnippet

View File

@ -13,9 +13,9 @@ snippet !env "#!/usr/bin/env (!env)"
endsnippet endsnippet
snippet temp "Tempfile" snippet temp "Tempfile"
${1:TMPFILE}="$(mktemp -t ${2:`!p res = re.sub(r'[^a-zA-Z]', '_', fn) ${1:TMPFILE}="$(mktemp -t ${2:`!p
if not len(res): snip.rv = re.sub(r'[^a-zA-Z]', '_', snip.fn) or "untitled"
res = "untitled"`})" `})"
${3:${4/(.+)/trap "/}${4:rm -f '$${1/.*\s//}'}${4/(.+)/" 0 # EXIT\n/}${5/(.+)/trap "/}${5:rm -f '$${1/.*\s//}'; exit 1}${5/(.+)/" 2 # INT\n/}${6/(.+)/trap "/}${6:rm -f '$${1/.*\s//}'; exit 1}${6/(.+)/" 1 15 # HUP TERM\n/}} ${3:${4/(.+)/trap "/}${4:rm -f '$${1/.*\s//}'}${4/(.+)/" 0 # EXIT\n/}${5/(.+)/trap "/}${5:rm -f '$${1/.*\s//}'; exit 1}${5/(.+)/" 2 # INT\n/}${6/(.+)/trap "/}${6:rm -f '$${1/.*\s//}'; exit 1}${6/(.+)/" 1 15 # HUP TERM\n/}}
endsnippet endsnippet

View File

@ -5,8 +5,8 @@
# We use a little hack so that the snippet is expanded # We use a little hack so that the snippet is expanded
# and parsed correctly # and parsed correctly
snippet snip "Snippet definition" ! snippet snip "Snippet definition" !
`!p res="snippet"` ${1:Tab_trigger} "${2:Description}" ${3:!b} `!p snip.rv = "snippet"` ${1:Tab_trigger} "${2:Description}" ${3:!b}
$0 $0
`!p res="endsnippet"` `!p snip.rv = "endsnippet"`
endsnippet endsnippet

View File

@ -17,7 +17,7 @@ endif
endsnippet endsnippet
snippet guard snippet guard
if exists('${1:did_`!p res=fn.replace('.','_')`}') || &cp${2: || version < 700} if exists('${1:did_`!p snip.rv = snip.fn.replace('.','_')`}') || &cp${2: || version < 700}
finish finish
endif endif
let $1 = 1${3} let $1 = 1${3}

View File

@ -261,16 +261,71 @@ endsnippet
4.3.3 Python: *UltiSnips-python* 4.3.3 Python: *UltiSnips-python*
By far the most powerful interpolation is by using python code. The syntax is By far the most powerful interpolation is by using python code. The syntax is
similar to the one for Vimscript, but in python code the value of the python similar to the one for Vimscript, but in python code the value of the property
variable "res" is inserting at the position of the code. Also, the code is "rv" on the "snip" object is inserted at the position of the code. Also, the
inside a `!p ` block. Python code gets some special variables defined which code is inside a `!p ` block. Python code gets some special variables defined
can be used: > which can be used: >
fn - The current filename fn - The current filename
path - The complete path to the current file path - The complete path to the current file
t - The values of the placeholders, t[1] -> current text of ${1} and so on t - The values of the placeholders, t[1] -> current text of ${1} and so on
cur - The current text of the placeholder. You can check if this is != "" snip - Provides easy indentation handling, and snippet-local variables.
to make sure that the interpolation is only done once
The snip object provides the following methods: >
snip.mkline(line="", indent=None):
Returns a line ready to be appended to the result. If indent
is None, then mkline prepends spaces and/or tabs appropriate to the
current tabstop and expandtab variables.
snip.shift(amount=1):
Shifts the default indentation level used by mkline right by the
number of spaces defined by shiftwidth, 'amount' times.
snip.unshift(amount=1):
Shifts the default indentation level used by mkline left by the
number of spaces defined by shiftwidth, 'amount' times.
snip.reset_indent():
Resets the indentation level to its initial value.
snip.opt(var, default):
Checks if the vim variable "var" has been set, if so, it returns it,
otherwise it returns "default".
The snip object provides some properties as well: >
snip.locals:
Is a dictionary which is available to any python block inside the
snippet.
snip.rv:
the text that will fill this python block's position, it always starts
out as an empty string. This deprecates the "res" variable.
snip.c:
the text currently in the python block's position in the snippet
in it. You can check if snip.c is != "" to make sure that the
interpolation is only done once. This deprecates the "cur" variable.
snip.fn:
the current filename.
snip.basename:
the current filename without it's extension.
snip.ft:
the current filetype.
The snip object also provides some operators to make python snippets
easier: >
snip >> amount:
is equivalent to snip.shift(amount)
snip << amount:
is equivalent to snip.unshift(amount)
snip += line:
is equivalent to "snip.rv += '\n' + snip.mkline(line)"
Also, the vim, re, os, string and random modules are already imported inside Also, the vim, re, os, string and random modules are already imported inside
the snippet code. This allows for very flexible snippets. For example, the the snippet code. This allows for very flexible snippets. For example, the
@ -279,7 +334,7 @@ uppercase and right aligned:
------------------- SNIP ------------------- ------------------- SNIP -------------------
snippet wow snippet wow
${1:Text}`!p res = (75-2*len(t[1]))*' '+t[1].upper()` ${1:Text}`!p snip.rv = (75-2*len(t[1]))*' '+t[1].upper()`
endsnippet endsnippet
------------------- SNAP ------------------- ------------------- SNAP -------------------
wow<tab>Hello World -> wow<tab>Hello World ->
@ -557,6 +612,7 @@ Contributers are listed in chronological order:
JCEB - Jan Christoph Ebersbach JCEB - Jan Christoph Ebersbach
Michael Henry Michael Henry
Chris Chambers Chris Chambers
Ryan Wooden
8.2 Snippets *UltiSnips-contrisnippets* 8.2 Snippets *UltiSnips-contrisnippets*
------------ ------------
@ -564,6 +620,7 @@ Contributers are listed in chronological order:
Contributers are listed in chronological order: Contributers are listed in chronological order:
Alec Thomas (Python, smart def) Alec Thomas (Python, smart def)
Ryan Wooden

View File

@ -225,7 +225,7 @@ class _TOParser(object):
new_content = content new_content = content
new_content = new_content.strip() new_content = new_content.strip()
return PythonCode(self._p, start, end, new_content) return PythonCode(self._p, start, end, new_content, self._indent)
############# #############
# VimL Code # # VimL Code #
@ -704,16 +704,194 @@ class _Tabs(object):
return "" return ""
return ts.current_text return ts.current_text
class SnippetUtil(object):
""" Provides easy access to indentation, and
snippet-local variables, which can be accessed by
any PythonCode object in the snippet.
"""
def __init__(self, initial_indent, cur="", snippet=None):
if snippet:
self._locals = snippet.locals
else:
self._locals = {}
self._sw = int(vim.eval("&sw"))
self._sts = int(vim.eval("&sts"))
self._et = (vim.eval("&expandtab") == "1")
self._ts = int(vim.eval("&ts"))
self._initial_indent = self._indent_to_spaces(initial_indent)
self._reset(cur)
def _reset(self, cur):
""" Gets the snippet ready for another update.
:cur: the new value for c.
"""
self._c = cur
self._rv = ""
self._changed = False
self.reset_indent()
def shift(self, amount=1):
""" Shifts the indentation level.
Note that this uses the shiftwidth because thats what code
formatters use.
:amount: the amount by which to shift.
"""
self.indent += " " * self._sw * amount
def unshift(self, amount=1):
""" Unshift the indentation level.
Note that this uses the shiftwidth because thats what code
formatters use.
:amount: the amount by which to unshift.
"""
by = -self._sw * amount
try:
self.indent = self.indent[:by]
except IndexError:
indent = ""
def _indent_to_spaces(self, indent):
""" converts indentation to spaces. """
indent = indent.replace(" " * self._ts, "\t")
right = (len(indent) - len(indent.rstrip(" "))) * " "
indent = indent.replace(" ", "")
indent = indent.replace('\t', " " * self._ts)
return indent + right
def _spaces_to_indent(self, indent):
""" Converts spaces to proper indentation respecting
et, ts, etc.
"""
if not self._et:
indent = indent.replace(" " * self._ts, '\t')
return indent
def mkline(self, line="", indent=None):
""" Creates a properly set up line.
:line: the text to add
:indent: the indentation to have at the beginning
if None, it uses the default amount
"""
if indent == None:
indent = self.indent
# this deals with the fact that the first line is
# already properly indented
if '\n' not in self._rv:
try:
indent = indent[len(self._initial_indent):]
except IndexError:
indent = ""
indent = self._spaces_to_indent(indent)
return indent + line
def reset_indent(self):
""" Clears the indentation. """
self.indent = self._initial_indent
# Utility methods
@property
def fn(self):
""" The filename. """
return vim.eval('expand("%:t")') or ""
@property
def basename(self):
""" The filename without extension. """
return vim.eval('expand("%:t:r")') or ""
@property
def ft(self):
""" The filetype. """
return self.opt("&filetype", "")
# Necessary stuff
@property
def rv(self):
""" The return value.
This is a list of lines to insert at the
location of the placeholder.
Deprecates res.
"""
return self._rv
@rv.setter
def rv(self, value):
self._changed = True
self._rv = value
@property
def _rv_changed(self):
""" True if rv has changed. """
return self._changed
@property
def c(self):
""" The current text of the placeholder.
Deprecates cur.
"""
return self._c
@property
def locals(self):
""" Provides snippet local variables. """
return self._locals
def opt(self, option, default=None):
""" Gets a vim variable. """
if vim.eval("exists('%s')" % option) == "1":
try:
return vim.eval(option)
except vim.error:
pass
return default
# Syntatic sugar
def __add__(self, value):
""" Appends the given line to rv using mkline. """
self.rv += '\n' # handles the first line properly
self.rv += self.mkline(value)
return self
def __lshift__(self, other):
""" Same as unshift. """
self.unshift(other)
def __rshift__(self, other):
""" Same as shift. """
self.shift(other)
class PythonCode(TextObject): class PythonCode(TextObject):
def __init__(self, parent, start, end, code): def __init__(self, parent, start, end, code, indent=""):
code = code.replace("\\`", "`") code = code.replace("\\`", "`")
# Find our containing snippet for snippet local data
snippet = parent
while snippet and not isinstance(snippet, SnippetInstance):
try:
snippet = snippet._parent
except AttributeError:
snippet = None
self._snip = SnippetUtil(indent, snippet=snippet)
# Add Some convenience to the code # Add Some convenience to the code
self._code = "import re, os, vim, string, random\n" + code self._code = "import re, os, vim, string, random\n" + code
TextObject.__init__(self, parent, start, end, "") TextObject.__init__(self, parent, start, end, "")
def _do_update(self): def _do_update(self):
path = vim.eval('expand("%")') path = vim.eval('expand("%")')
if path is None: if path is None:
@ -721,17 +899,22 @@ class PythonCode(TextObject):
fn = os.path.basename(path) fn = os.path.basename(path)
ct = self.current_text ct = self.current_text
self._snip._reset(ct)
d = { d = {
't': _Tabs(self), 't': _Tabs(self),
'fn': fn, 'fn': fn,
'path': path, 'path': path,
'cur': ct, 'cur': ct,
'res': ct, 'res': ct,
'snip' : self._snip,
} }
exec self._code in d exec self._code in d
self.current_text = str(d["res"])
if self._snip._rv_changed:
self.current_text = self._snip.rv
else:
self.current_text = str(d["res"])
def __repr__(self): def __repr__(self):
return "PythonCode(%s -> %s)" % (self._start, self._end) return "PythonCode(%s -> %s)" % (self._start, self._end)
@ -768,6 +951,8 @@ class SnippetInstance(TextObject):
if end is None: if end is None:
end = Position(0,0) end = Position(0,0)
self.locals = {}
TextObject.__init__(self, parent, start, end, initial_text) TextObject.__init__(self, parent, start, end, initial_text)
_TOParser(self, initial_text, indent).parse() _TOParser(self, initial_text, indent).parse()

273
test.py
View File

@ -461,24 +461,26 @@ print "Hallo Welt"
############################ ############################
# PythonCode Interpolation # # PythonCode Interpolation #
############################ ############################
class PythonCode_SimpleExample(_VimTest):
#### Deprecated way ##########
class PythonCodeOld_SimpleExample(_VimTest):
snippets = ("test", """hi `!p res = "Hallo"` End""") snippets = ("test", """hi `!p res = "Hallo"` End""")
keys = "test" + EX keys = "test" + EX
wanted = "hi Hallo End" wanted = "hi Hallo End"
class PythonCode_ReferencePlaceholder(_VimTest): class PythonCodeOld_ReferencePlaceholder(_VimTest):
snippets = ("test", """${1:hi} `!p res = t[1]+".blah"` End""") snippets = ("test", """${1:hi} `!p res = t[1]+".blah"` End""")
keys = "test" + EX + "ho" keys = "test" + EX + "ho"
wanted = "ho ho.blah End" wanted = "ho ho.blah End"
class PythonCode_ReferencePlaceholderBefore(_VimTest): class PythonCodeOld_ReferencePlaceholderBefore(_VimTest):
snippets = ("test", """`!p res = len(t[1])*"#"`\n${1:some text}""") snippets = ("test", """`!p res = len(t[1])*"#"`\n${1:some text}""")
keys = "test" + EX + "Hallo Welt" keys = "test" + EX + "Hallo Welt"
wanted = "##########\nHallo Welt" wanted = "##########\nHallo Welt"
class PythonCode_TransformedBeforeMultiLine(_VimTest): class PythonCodeOld_TransformedBeforeMultiLine(_VimTest):
snippets = ("test", """${1/.+/egal/m} ${1:`!p snippets = ("test", """${1/.+/egal/m} ${1:`!p
res = "Hallo"`} End""") res = "Hallo"`} End""")
keys = "test" + EX keys = "test" + EX
wanted = "egal Hallo End" wanted = "egal Hallo End"
class PythonCode_IndentedMultiline(_VimTest): class PythonCodeOld_IndentedMultiline(_VimTest):
snippets = ("test", """start `!p a = 1 snippets = ("test", """start `!p a = 1
b = 2 b = 2
if b > a: if b > a:
@ -488,6 +490,267 @@ else:
keys = " test" + EX keys = " test" + EX
wanted = " start b isbigger a end" wanted = " start b isbigger a end"
#### New way ##########
class PythonCode_UseNewOverOld(_VimTest):
snippets = ("test", """hi `!p res = "Old"
snip.rv = "New"` End""")
keys = "test" + EX
wanted = "hi New End"
class PythonCode_SimpleExample(_VimTest):
snippets = ("test", """hi `!p snip.rv = "Hallo"` End""")
keys = "test" + EX
wanted = "hi Hallo End"
class PythonCode_ReferencePlaceholder(_VimTest):
snippets = ("test", """${1:hi} `!p snip.rv = t[1]+".blah"` End""")
keys = "test" + EX + "ho"
wanted = "ho ho.blah End"
class PythonCode_ReferencePlaceholderBefore(_VimTest):
snippets = ("test", """`!p snip.rv = len(t[1])*"#"`\n${1:some text}""")
keys = "test" + EX + "Hallo Welt"
wanted = "##########\nHallo Welt"
class PythonCode_TransformedBeforeMultiLine(_VimTest):
snippets = ("test", """${1/.+/egal/m} ${1:`!p
snip.rv = "Hallo"`} End""")
keys = "test" + EX
wanted = "egal Hallo End"
class PythonCode_MultilineIndented(_VimTest):
snippets = ("test", """start `!p a = 1
b = 2
if b > a:
snip.rv = "b isbigger a"
else:
snip.rv = "a isbigger b"` end""")
keys = " test" + EX
wanted = " start b isbigger a end"
class PythonCode_SimpleAppend(_VimTest):
snippets = ("test", """hi `!p snip.rv = "Hallo1"
snip += "Hallo2"` End""")
keys = "test" + EX
wanted = "hi Hallo1\nHallo2 End"
class PythonCode_MultiAppend(_VimTest):
snippets = ("test", """hi `!p snip.rv = "Hallo1"
snip += "Hallo2"
snip += "Hallo3"` End""")
keys = "test" + EX
wanted = "hi Hallo1\nHallo2\nHallo3 End"
class PythonCode_MultiAppend(_VimTest):
snippets = ("test", """hi `!p snip.rv = "Hallo1"
snip += "Hallo2"
snip += "Hallo3"` End""")
keys = "test" + EX
wanted = "hi Hallo1\nHallo2\nHallo3 End"
class PythonCode_MultiAppendSimpleIndent(_VimTest):
snippets = ("test", """hi
`!p snip.rv="Hallo1"
snip += "Hallo2"
snip += "Hallo3"`
End""")
keys = """
test""" + EX
wanted = """
hi
Hallo1
Hallo2
Hallo3
End"""
class PythonCode_SimpleMkline(_VimTest):
snippets = ("test", r"""hi
`!p snip.rv="Hallo1\n"
snip.rv += snip.mkline("Hallo2") + "\n"
snip.rv += snip.mkline("Hallo3")`
End""")
keys = """
test""" + EX
wanted = """
hi
Hallo1
Hallo2
Hallo3
End"""
class PythonCode_MultiAppendShift(_VimTest):
snippets = ("test", r"""hi
`!p snip.rv="i1"
snip += "i1"
snip >> 1
snip += "i2"
snip << 2
snip += "i0"
snip >> 3
snip += "i3"`
End""")
keys = """
test""" + EX
wanted = """
hi
i1
i1
i2
i0
i3
End"""
class PythonCode_MultiAppendShiftMethods(_VimTest):
snippets = ("test", r"""hi
`!p snip.rv="i1\n"
snip.rv += snip.mkline("i1\n")
snip.shift(1)
snip.rv += snip.mkline("i2\n")
snip.unshift(2)
snip.rv += snip.mkline("i0\n")
snip.shift(3)
snip.rv += snip.mkline("i3")`
End""")
keys = """
test""" + EX
wanted = """
hi
i1
i1
i2
i0
i3
End"""
class PythonCode_ResetIndent(_VimTest):
snippets = ("test", r"""hi
`!p snip.rv="i1"
snip >> 1
snip += "i2"
snip.reset_indent()
snip += "i1"
snip << 1
snip += "i0"
snip.reset_indent()
snip += "i1"`
End""")
keys = """
test""" + EX
wanted = """
hi
i1
i2
i1
i0
i1
End"""
# TODO
# Different mixes of ts, et, sts, sw
class PythonCode_IndentEtSw(_VimTest):
def _options_on(self):
self.send(":set sw=3\n")
self.send(":set expandtab\n")
def _options_off(self):
self.send(":set sw=8\n")
self.send(":set noexpandtab\n")
snippets = ("test", r"""hi
`!p snip.rv = "i1"
snip >> 1
snip += "i2"
snip << 2
snip += "i0"
snip >> 1
snip += "i1"
`
End""")
keys = """ test""" + EX
wanted = """ hi
i1
i2
i0
i1
End"""
class PythonCode_IndentEtSwOffset(_VimTest):
def _options_on(self):
self.send(":set sw=3\n")
self.send(":set expandtab\n")
def _options_off(self):
self.send(":set sw=8\n")
self.send(":set noexpandtab\n")
snippets = ("test", r"""hi
`!p snip.rv = "i1"
snip >> 1
snip += "i2"
snip << 2
snip += "i0"
snip >> 1
snip += "i1"
`
End""")
keys = """ test""" + EX
wanted = """ hi
i1
i2
i0
i1
End"""
class PythonCode_IndentNoetSwTs(_VimTest):
def _options_on(self):
self.send(":set sw=3\n")
self.send(":set ts=4\n")
def _options_off(self):
self.send(":set sw=8\n")
self.send(":set ts=8\n")
snippets = ("test", r"""hi
`!p snip.rv = "i1"
snip >> 1
snip += "i2"
snip << 2
snip += "i0"
snip >> 1
snip += "i1"
`
End""")
keys = """ test""" + EX
wanted = """ hi
i1
\t i2
i0
i1
End"""
# Test using 'opt'
class PythonCode_OptExists(_VimTest):
def _options_on(self):
self.send(':let g:UStest="yes"\n')
def _options_off(self):
self.send(":unlet g:UStest\n")
snippets = ("test", r"""hi `!p snip.rv = snip.opt("g:UStest") or "no"` End""")
keys = """test""" + EX
wanted = """hi yes End"""
class PythonCode_OptNoExists(_VimTest):
snippets = ("test", r"""hi `!p snip.rv = snip.opt("g:UStest") or "no"` End""")
keys = """test""" + EX
wanted = """hi no End"""
# locals
class PythonCode_Locals(_VimTest):
snippets = ("test", r"""hi `!p snip.locals["a"] = "test"
snip.rv = "nothing"` `!p snip.rv = snip.locals["a"]
` End""")
keys = """test""" + EX
wanted = """hi nothing test End"""
########################### ###########################
# VimScript Interpolation # # VimScript Interpolation #
########################### ###########################