All linting done. Project is now lint warning free.
This commit is contained in:
parent
873b5b4ad4
commit
773869b1e1
16
pylintrc
16
pylintrc
@ -1,7 +1,5 @@
|
|||||||
[MASTER]
|
[MASTER]
|
||||||
|
|
||||||
msg-template="{path}:{line}: [{msg_id}({symbol}), {obj}] {msg}"
|
|
||||||
|
|
||||||
# Python code to execute, usually for sys.path manipulation such as
|
# Python code to execute, usually for sys.path manipulation such as
|
||||||
# pygtk.require().
|
# pygtk.require().
|
||||||
init-hook='import sys; sys.path.append("pythonx/")'
|
init-hook='import sys; sys.path.append("pythonx/")'
|
||||||
@ -38,13 +36,14 @@ disable=
|
|||||||
attribute-defined-outside-init,
|
attribute-defined-outside-init,
|
||||||
fixme,
|
fixme,
|
||||||
redefined-builtin,
|
redefined-builtin,
|
||||||
too-many-arguments,
|
|
||||||
too-many-instance-attributes,
|
|
||||||
too-many-public-methods,
|
|
||||||
too-few-public-methods,
|
too-few-public-methods,
|
||||||
|
too-many-arguments,
|
||||||
too-many-branches,
|
too-many-branches,
|
||||||
too-many-statements,
|
too-many-instance-attributes,
|
||||||
too-many-locals,
|
too-many-locals,
|
||||||
|
too-many-public-methods,
|
||||||
|
too-many-return-statements,
|
||||||
|
too-many-statements,
|
||||||
|
|
||||||
|
|
||||||
[REPORTS]
|
[REPORTS]
|
||||||
@ -57,6 +56,9 @@ output-format=text
|
|||||||
# Tells whether to display a full report or only the messages
|
# Tells whether to display a full report or only the messages
|
||||||
reports=yes
|
reports=yes
|
||||||
|
|
||||||
|
msg-template="{path}:{line}: [{msg_id}({symbol}), {obj}] {msg}"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[BASIC]
|
[BASIC]
|
||||||
|
|
||||||
@ -99,7 +101,7 @@ class-attribute-rgx=([A-Za-z_][A-Za-z0-9_]{2,30}|(__.*__))$
|
|||||||
inlinevar-rgx=[A-Za-z_][A-Za-z0-9_]*$
|
inlinevar-rgx=[A-Za-z_][A-Za-z0-9_]*$
|
||||||
|
|
||||||
# Good variable names which should always be accepted, separated by a comma
|
# Good variable names which should always be accepted, separated by a comma
|
||||||
good-names=i,j,k,ex,Run,_
|
good-names=i,j,a,b,x,y,k,ex,Run,_
|
||||||
|
|
||||||
# Bad variable names which should always be refused, separated by a comma
|
# Bad variable names which should always be refused, separated by a comma
|
||||||
bad-names=foo,bar,baz,toto,tutu,tata
|
bad-names=foo,bar,baz,toto,tutu,tata
|
||||||
|
@ -145,6 +145,9 @@ Following is the full stack trace:
|
|||||||
_vim.new_scratch_buffer(msg)
|
_vim.new_scratch_buffer(msg)
|
||||||
return wrapper
|
return wrapper
|
||||||
|
|
||||||
|
|
||||||
|
# TODO(sirver): This class has too many responsibilities - it should not also
|
||||||
|
# care for the parsing and managing of parsed snippets.
|
||||||
class SnippetManager(object):
|
class SnippetManager(object):
|
||||||
"""The main entry point for all UltiSnips functionality. All Vim functions
|
"""The main entry point for all UltiSnips functionality. All Vim functions
|
||||||
call methods in this class."""
|
call methods in this class."""
|
||||||
@ -162,7 +165,7 @@ class SnippetManager(object):
|
|||||||
"""Reset the class to the state it had directly after creation."""
|
"""Reset the class to the state it had directly after creation."""
|
||||||
self._vstate = VimState()
|
self._vstate = VimState()
|
||||||
self._test_error = test_error
|
self._test_error = test_error
|
||||||
self._snippets = defaultdict(lambda: SnippetDictionary())
|
self._snippets = defaultdict(SnippetDictionary)
|
||||||
self._filetypes = defaultdict(lambda: ['all'])
|
self._filetypes = defaultdict(lambda: ['all'])
|
||||||
self._visual_content = VisualContentPreserver()
|
self._visual_content = VisualContentPreserver()
|
||||||
|
|
||||||
@ -390,11 +393,8 @@ class SnippetManager(object):
|
|||||||
self._current_snippet_is_done()
|
self._current_snippet_is_done()
|
||||||
self._reinit()
|
self._reinit()
|
||||||
|
|
||||||
|
# TODO(sirver): This is only used by SnippetsFileParser
|
||||||
###################################
|
def report_error(self, msg):
|
||||||
# Private/Protect Functions Below #
|
|
||||||
###################################
|
|
||||||
def _error(self, msg):
|
|
||||||
"""Shows 'msg' as error to the user."""
|
"""Shows 'msg' as error to the user."""
|
||||||
msg = _vim.escape("UltiSnips: " + msg)
|
msg = _vim.escape("UltiSnips: " + msg)
|
||||||
if self._test_error:
|
if self._test_error:
|
||||||
@ -410,6 +410,9 @@ class SnippetManager(object):
|
|||||||
else:
|
else:
|
||||||
_vim.command("echoerr %s" % msg)
|
_vim.command("echoerr %s" % msg)
|
||||||
|
|
||||||
|
###################################
|
||||||
|
# Private/Protect Functions Below #
|
||||||
|
###################################
|
||||||
def _reinit(self):
|
def _reinit(self):
|
||||||
"""Resets transient state."""
|
"""Resets transient state."""
|
||||||
self._ctab = None
|
self._ctab = None
|
||||||
|
@ -1,14 +1,19 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
# encoding: utf-8
|
# encoding: utf-8
|
||||||
|
|
||||||
|
"""Commands to compare text objects and to guess how to transform from one to
|
||||||
|
another."""
|
||||||
|
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
from UltiSnips import _vim
|
from UltiSnips import _vim
|
||||||
from UltiSnips.position import Position
|
from UltiSnips.position import Position
|
||||||
|
|
||||||
def is_complete_edit(initial_line, a, b, cmds):
|
def is_complete_edit(initial_line, original, wanted, cmds):
|
||||||
buf = a[:]
|
"""Returns true if 'original' is changed to 'wanted' with the edit commands
|
||||||
|
in 'cmds'. Initial line is to change the line numbers in 'cmds'."""
|
||||||
|
buf = original[:]
|
||||||
for cmd in cmds:
|
for cmd in cmds:
|
||||||
ctype, line, col, char = cmd
|
ctype, line, col, char = cmd
|
||||||
line -= initial_line
|
line -= initial_line
|
||||||
@ -24,95 +29,133 @@ def is_complete_edit(initial_line, a, b, cmds):
|
|||||||
elif ctype == "I":
|
elif ctype == "I":
|
||||||
buf[line] = buf[line][:col] + char + buf[line][col:]
|
buf[line] = buf[line][:col] + char + buf[line][col:]
|
||||||
buf = '\n'.join(buf).split('\n')
|
buf = '\n'.join(buf).split('\n')
|
||||||
return len(buf) == len(b) and all(j==k for j,k in zip(buf, b))
|
return (len(buf) == len(wanted) and
|
||||||
|
all(j == k for j, k in zip(buf, wanted)))
|
||||||
|
|
||||||
def guess_edit(initial_line, lt, ct, vs):
|
def guess_edit(initial_line, last_text, current_text, vim_state):
|
||||||
"""
|
"""
|
||||||
Try to guess what the user might have done by heuristically looking at cursor movement
|
Try to guess what the user might have done by heuristically looking at
|
||||||
number of changed lines and if they got longer or shorter. This will detect most simple
|
cursor movement, number of changed lines and if they got longer or shorter.
|
||||||
movements like insertion, deletion of a line or carriage return.
|
This will detect most simple movements like insertion, deletion of a line
|
||||||
|
or carriage return. 'initial_text' is the index of where the comparison
|
||||||
|
starts, 'last_text' is the last text of the snippet, 'current_text' is the
|
||||||
|
current text of the snippet and 'vim_state' is the cached vim state.
|
||||||
|
|
||||||
|
Returns (True, edit_cmds) when the edit could be guessed, (False, None)
|
||||||
|
otherwise.
|
||||||
"""
|
"""
|
||||||
if not len(lt) and not len(ct): return True, ()
|
if not len(last_text) and not len(current_text):
|
||||||
pos = vs.pos
|
return True, ()
|
||||||
ppos = vs.ppos
|
pos = vim_state.pos
|
||||||
if len(lt) and (not ct or (len(ct) == 1 and not ct[0])): # All text deleted?
|
ppos = vim_state.ppos
|
||||||
|
|
||||||
|
# All text deleted?
|
||||||
|
if (len(last_text) and
|
||||||
|
(not current_text or
|
||||||
|
(len(current_text) == 1 and not current_text[0]))
|
||||||
|
):
|
||||||
es = []
|
es = []
|
||||||
if not ct: ct = ['']
|
if not current_text:
|
||||||
for i in lt:
|
current_text = ['']
|
||||||
|
for i in last_text:
|
||||||
es.append(("D", initial_line, 0, i))
|
es.append(("D", initial_line, 0, i))
|
||||||
es.append(("D", initial_line, 0, "\n"))
|
es.append(("D", initial_line, 0, "\n"))
|
||||||
es.pop() # Remove final \n because it is not really removed
|
es.pop() # Remove final \n because it is not really removed
|
||||||
if is_complete_edit(initial_line, lt, ct, es): return True, es
|
if is_complete_edit(initial_line, last_text, current_text, es):
|
||||||
|
return True, es
|
||||||
if ppos.mode == 'v': # Maybe selectmode?
|
if ppos.mode == 'v': # Maybe selectmode?
|
||||||
sv = list(map(int, _vim.eval("""getpos("'<")"""))); sv = Position(sv[1]-1,sv[2]-1)
|
sv = list(map(int, _vim.eval("""getpos("'<")""")))
|
||||||
ev = list(map(int, _vim.eval("""getpos("'>")"""))); ev = Position(ev[1]-1,ev[2]-1)
|
sv = Position(sv[1]-1, sv[2]-1)
|
||||||
|
ev = list(map(int, _vim.eval("""getpos("'>")""")))
|
||||||
|
ev = Position(ev[1]-1, ev[2]-1)
|
||||||
if "exclusive" in _vim.eval("&selection"):
|
if "exclusive" in _vim.eval("&selection"):
|
||||||
ppos.col -= 1 # We want to be inclusive, sorry.
|
ppos.col -= 1 # We want to be inclusive, sorry.
|
||||||
ev.col -= 1
|
ev.col -= 1
|
||||||
es = []
|
es = []
|
||||||
if sv.line == ev.line:
|
if sv.line == ev.line:
|
||||||
es.append(("D", sv.line, sv.col, lt[sv.line - initial_line][sv.col:ev.col+1]))
|
es.append(("D", sv.line, sv.col,
|
||||||
|
last_text[sv.line - initial_line][sv.col:ev.col+1]))
|
||||||
if sv != pos and sv.line == pos.line:
|
if sv != pos and sv.line == pos.line:
|
||||||
es.append(("I", sv.line, sv.col, ct[sv.line - initial_line][sv.col:pos.col+1]))
|
es.append(("I", sv.line, sv.col,
|
||||||
if is_complete_edit(initial_line, lt, ct, es): return True, es
|
current_text[sv.line - initial_line][sv.col:pos.col+1]))
|
||||||
|
if is_complete_edit(initial_line, last_text, current_text, es):
|
||||||
|
return True, es
|
||||||
if pos.line == ppos.line:
|
if pos.line == ppos.line:
|
||||||
if len(lt) == len(ct): # Movement only in one line
|
if len(last_text) == len(current_text): # Movement only in one line
|
||||||
llen = len(lt[ppos.line - initial_line])
|
llen = len(last_text[ppos.line - initial_line])
|
||||||
clen = len(ct[pos.line - initial_line])
|
clen = len(current_text[pos.line - initial_line])
|
||||||
if ppos < pos and clen > llen: # Likely that only characters have been added
|
if ppos < pos and clen > llen: # maybe only chars have been added
|
||||||
es = (
|
es = (
|
||||||
("I", ppos.line, ppos.col, ct[ppos.line - initial_line][ppos.col:pos.col]),
|
("I", ppos.line, ppos.col,
|
||||||
|
current_text[ppos.line - initial_line]
|
||||||
|
[ppos.col:pos.col]),
|
||||||
)
|
)
|
||||||
if is_complete_edit(initial_line, lt, ct, es): return True, es
|
if is_complete_edit(initial_line, last_text, current_text, es):
|
||||||
|
return True, es
|
||||||
if clen < llen:
|
if clen < llen:
|
||||||
if ppos == pos: # 'x' or DEL or dt or something
|
if ppos == pos: # 'x' or DEL or dt or something
|
||||||
es = (
|
es = (
|
||||||
("D", pos.line, pos.col, lt[ppos.line - initial_line][ppos.col:ppos.col + (llen - clen)]),
|
("D", pos.line, pos.col,
|
||||||
|
last_text[ppos.line - initial_line]
|
||||||
|
[ppos.col:ppos.col + (llen - clen)]),
|
||||||
)
|
)
|
||||||
if is_complete_edit(initial_line, lt, ct, es): return True, es
|
if is_complete_edit(initial_line, last_text,
|
||||||
|
current_text, es):
|
||||||
|
return True, es
|
||||||
if pos < ppos: # Backspacing or dT dF?
|
if pos < ppos: # Backspacing or dT dF?
|
||||||
es = (
|
es = (
|
||||||
("D", pos.line, pos.col, lt[pos.line - initial_line][pos.col:pos.col + llen - clen]),
|
("D", pos.line, pos.col,
|
||||||
|
last_text[pos.line - initial_line]
|
||||||
|
[pos.col:pos.col + llen - clen]),
|
||||||
)
|
)
|
||||||
if is_complete_edit(initial_line, lt, ct, es): return True, es
|
if is_complete_edit(initial_line, last_text,
|
||||||
elif len(ct) < len(lt): # Maybe some lines were deleted? (dd or so)
|
current_text, es):
|
||||||
|
return True, es
|
||||||
|
elif len(current_text) < len(last_text):
|
||||||
|
# where some lines deleted? (dd or so)
|
||||||
es = []
|
es = []
|
||||||
for i in range(len(lt)-len(ct)):
|
for i in range(len(last_text)-len(current_text)):
|
||||||
es.append( ("D", pos.line, 0, lt[pos.line - initial_line + i]))
|
es.append(("D", pos.line, 0,
|
||||||
es.append( ("D", pos.line, 0, '\n'))
|
last_text[pos.line - initial_line + i]))
|
||||||
if is_complete_edit(initial_line, lt, ct, es): return True, es
|
es.append(("D", pos.line, 0, '\n'))
|
||||||
else: # Movement in more than one line
|
if is_complete_edit(initial_line, last_text,
|
||||||
|
current_text, es):
|
||||||
|
return True, es
|
||||||
|
else:
|
||||||
|
# Movement in more than one line
|
||||||
if ppos.line + 1 == pos.line and pos.col == 0: # Carriage return?
|
if ppos.line + 1 == pos.line and pos.col == 0: # Carriage return?
|
||||||
es = (("I", ppos.line, ppos.col, "\n"),)
|
es = (("I", ppos.line, ppos.col, "\n"),)
|
||||||
if is_complete_edit(initial_line, lt, ct, es): return True, es
|
if is_complete_edit(initial_line, last_text,
|
||||||
|
current_text, es):
|
||||||
|
return True, es
|
||||||
return False, None
|
return False, None
|
||||||
|
|
||||||
def diff(a, b, sline = 0):
|
def diff(a, b, sline=0):
|
||||||
"""
|
"""
|
||||||
Return a list of deletions and insertions that will turn a into b. This is
|
Return a list of deletions and insertions that will turn 'a' into 'b'. This
|
||||||
done by traversing an implicit edit graph and searching for the shortest
|
is done by traversing an implicit edit graph and searching for the shortest
|
||||||
route. The basic idea is as follows:
|
route. The basic idea is as follows:
|
||||||
|
|
||||||
- Matching a character is free as long as there was no deletion/insertion
|
- Matching a character is free as long as there was no
|
||||||
before. Then, matching will be seen as delete + insert [1].
|
deletion/insertion before. Then, matching will be seen as delete +
|
||||||
|
insert [1].
|
||||||
- Deleting one character has the same cost everywhere. Each additional
|
- Deleting one character has the same cost everywhere. Each additional
|
||||||
character costs only have of the first deletion.
|
character costs only have of the first deletion.
|
||||||
- Insertion is cheaper the earlier it happes. The first character is more
|
- Insertion is cheaper the earlier it happens. The first character is
|
||||||
expensive that any later [2].
|
more expensive that any later [2].
|
||||||
|
|
||||||
[1] This is that world -> aolsa will be "D" world + "I" aolsa instead of
|
[1] This is that world -> aolsa will be "D" world + "I" aolsa instead of
|
||||||
"D" w , "D" rld, "I" a, "I" lsa
|
"D" w , "D" rld, "I" a, "I" lsa
|
||||||
[2] This is that "hello\n\n" -> "hello\n\n\n" will insert a newline after hello
|
[2] This is that "hello\n\n" -> "hello\n\n\n" will insert a newline after
|
||||||
and not after \n
|
hello and not after \n
|
||||||
"""
|
"""
|
||||||
d = defaultdict(list)
|
d = defaultdict(list) # pylint:disable=invalid-name
|
||||||
seen = defaultdict(lambda: sys.maxsize)
|
seen = defaultdict(lambda: sys.maxsize)
|
||||||
|
|
||||||
d[0] = [ (0,0,sline, 0, ()) ]
|
d[0] = [(0, 0, sline, 0, ())]
|
||||||
|
|
||||||
cost = 0
|
cost = 0
|
||||||
D_COST = len(a)+len(b)
|
deletion_cost = len(a)+len(b)
|
||||||
I_COST = len(a)+len(b)
|
insertion_cost = len(a)+len(b)
|
||||||
while True:
|
while True:
|
||||||
while len(d[cost]):
|
while len(d[cost]):
|
||||||
x, y, line, col, what = d[cost].pop()
|
x, y, line, col, what = d[cost].pop()
|
||||||
@ -125,17 +168,16 @@ def diff(a, b, sline = 0):
|
|||||||
nline = line
|
nline = line
|
||||||
if a[x] == '\n':
|
if a[x] == '\n':
|
||||||
ncol = 0
|
ncol = 0
|
||||||
nline +=1
|
nline += 1
|
||||||
lcost = cost + 1
|
lcost = cost + 1
|
||||||
if (what and what[-1][0] == "D" and what[-1][1] == line and
|
if (what and what[-1][0] == "D" and what[-1][1] == line and
|
||||||
what[-1][2] == col and a[x] != '\n'):
|
what[-1][2] == col and a[x] != '\n'):
|
||||||
# Matching directly after a deletion should be as costly as
|
# Matching directly after a deletion should be as costly as
|
||||||
# DELETE + INSERT + a bit
|
# DELETE + INSERT + a bit
|
||||||
lcost = (D_COST + I_COST)*1.5
|
lcost = (deletion_cost + insertion_cost)*1.5
|
||||||
if seen[x+1,y+1] > lcost:
|
if seen[x+1, y+1] > lcost:
|
||||||
d[lcost].append((x+1,y+1, nline, ncol, what))
|
d[lcost].append((x+1, y+1, nline, ncol, what))
|
||||||
seen[x+1,y+1] = lcost
|
seen[x+1, y+1] = lcost
|
||||||
|
|
||||||
if y < len(b): # INSERT
|
if y < len(b): # INSERT
|
||||||
ncol = col + 1
|
ncol = col + 1
|
||||||
nline = line
|
nline = line
|
||||||
@ -144,30 +186,34 @@ def diff(a, b, sline = 0):
|
|||||||
nline += 1
|
nline += 1
|
||||||
if (what and what[-1][0] == "I" and what[-1][1] == nline and
|
if (what and what[-1][0] == "I" and what[-1][1] == nline and
|
||||||
what[-1][2]+len(what[-1][-1]) == col and b[y] != '\n' and
|
what[-1][2]+len(what[-1][-1]) == col and b[y] != '\n' and
|
||||||
seen[x,y+1] > cost + (I_COST + ncol) // 2
|
seen[x, y+1] > cost + (insertion_cost + ncol) // 2
|
||||||
):
|
):
|
||||||
seen[x,y+1] = cost + (I_COST + ncol) // 2
|
seen[x, y+1] = cost + (insertion_cost + ncol) // 2
|
||||||
d[cost + (I_COST + ncol) // 2].append(
|
d[cost + (insertion_cost + ncol) // 2].append(
|
||||||
(x,y+1, line, ncol, what[:-1] + (
|
(x, y+1, line, ncol, what[:-1] + (
|
||||||
("I", what[-1][1], what[-1][2], what[-1][-1] + b[y]),) )
|
("I", what[-1][1], what[-1][2],
|
||||||
|
what[-1][-1] + b[y]),)
|
||||||
|
)
|
||||||
)
|
)
|
||||||
elif seen[x,y+1] > cost + I_COST + ncol:
|
elif seen[x, y+1] > cost + insertion_cost + ncol:
|
||||||
seen[x,y+1] = cost + I_COST + ncol
|
seen[x, y+1] = cost + insertion_cost + ncol
|
||||||
d[cost + ncol + I_COST].append((x,y+1, nline, ncol,
|
d[cost + ncol + insertion_cost].append((x, y+1, nline, ncol,
|
||||||
what + (("I", line, col,b[y]),))
|
what + (("I", line, col, b[y]),))
|
||||||
)
|
)
|
||||||
if x < len(a): # DELETE
|
if x < len(a): # DELETE
|
||||||
if (what and what[-1][0] == "D" and what[-1][1] == line and
|
if (what and what[-1][0] == "D" and what[-1][1] == line and
|
||||||
what[-1][2] == col and a[x] != '\n' and what[-1][-1] != '\n' and
|
what[-1][2] == col and a[x] != '\n' and
|
||||||
seen[x+1,y] > cost + D_COST // 2
|
what[-1][-1] != '\n' and
|
||||||
|
seen[x+1, y] > cost + deletion_cost // 2
|
||||||
):
|
):
|
||||||
seen[x+1,y] = cost + D_COST // 2
|
seen[x+1, y] = cost + deletion_cost // 2
|
||||||
d[cost + D_COST // 2].append((x+1,y, line, col, what[:-1] +
|
d[cost + deletion_cost // 2].append(
|
||||||
(("D",line, col, what[-1][-1] + a[x]),) )
|
(x+1, y, line, col, what[:-1] + (
|
||||||
|
("D", line, col, what[-1][-1] + a[x]),))
|
||||||
)
|
)
|
||||||
elif seen[x+1,y] > cost + D_COST:
|
elif seen[x+1, y] > cost + deletion_cost:
|
||||||
seen[x+1,y] = cost + D_COST
|
seen[x+1, y] = cost + deletion_cost
|
||||||
d[cost + D_COST].append((x+1,y, line, col, what +
|
d[cost + deletion_cost].append((x+1, y, line, col, what +
|
||||||
(("D",line, col, a[x]),) )
|
(("D", line, col, a[x]),))
|
||||||
)
|
)
|
||||||
cost += 1
|
cost += 1
|
||||||
|
@ -1,11 +1,17 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
# encoding: utf-8
|
# encoding: utf-8
|
||||||
|
|
||||||
|
"""Parsing of snippet files."""
|
||||||
|
|
||||||
import re
|
import re
|
||||||
import UltiSnips._vim as _vim
|
import UltiSnips._vim as _vim
|
||||||
|
|
||||||
# TODO(sirver): This could just as well be a function.
|
# TODO(sirver): This could just as well be a function. Also the
|
||||||
|
# interface should change to a stream of events - so that it does
|
||||||
|
# not need knowledge of SnippetManager.
|
||||||
class SnippetsFileParser(object):
|
class SnippetsFileParser(object):
|
||||||
|
"""Does the actual parsing."""
|
||||||
|
|
||||||
def __init__(self, ft, fn, snip_manager, file_data=None):
|
def __init__(self, ft, fn, snip_manager, file_data=None):
|
||||||
"""Parser 'fn' as filetype 'ft'."""
|
"""Parser 'fn' as filetype 'ft'."""
|
||||||
self._sm = snip_manager
|
self._sm = snip_manager
|
||||||
@ -19,33 +25,27 @@ class SnippetsFileParser(object):
|
|||||||
self._idx = 0
|
self._idx = 0
|
||||||
|
|
||||||
def _error(self, msg):
|
def _error(self, msg):
|
||||||
|
"""Reports 'msg' as an error."""
|
||||||
fn = _vim.eval("""fnamemodify(%s, ":~:.")""" % _vim.escape(self._fn))
|
fn = _vim.eval("""fnamemodify(%s, ":~:.")""" % _vim.escape(self._fn))
|
||||||
self._sm._error("%s in %s(%d)" % (msg, fn, self._idx + 1))
|
self._sm.report_error("%s in %s(%d)" % (msg, fn, self._idx + 1))
|
||||||
|
|
||||||
def _line(self):
|
def _line(self):
|
||||||
if self._idx < len(self._lines):
|
"""The current line or the empty string."""
|
||||||
line = self._lines[self._idx]
|
return self._lines[self._idx] if self._idx < len(self._lines) else ""
|
||||||
else:
|
|
||||||
line = ""
|
|
||||||
return line
|
|
||||||
|
|
||||||
def _line_head_tail(self):
|
def _line_head_tail(self):
|
||||||
|
"""Returns (first word, rest) of the current line."""
|
||||||
parts = re.split(r"\s+", self._line().rstrip(), maxsplit=1)
|
parts = re.split(r"\s+", self._line().rstrip(), maxsplit=1)
|
||||||
parts.append('')
|
parts.append('')
|
||||||
return parts[:2]
|
return parts[:2]
|
||||||
|
|
||||||
def _line_head(self):
|
|
||||||
return self._line_head_tail()[0]
|
|
||||||
|
|
||||||
def _line_tail(self):
|
|
||||||
return self._line_head_tail()[1]
|
|
||||||
|
|
||||||
def _goto_next_line(self):
|
def _goto_next_line(self):
|
||||||
|
"""Advances to and returns the next line."""
|
||||||
self._idx += 1
|
self._idx += 1
|
||||||
return self._line()
|
return self._line()
|
||||||
|
|
||||||
def _parse_first(self, line):
|
def _parse_first(self, line):
|
||||||
""" Parses the first line of the snippet definition. Returns the
|
"""Parses the first line of the snippet definition. Returns the
|
||||||
snippet type, trigger, description, and options in a tuple in that
|
snippet type, trigger, description, and options in a tuple in that
|
||||||
order.
|
order.
|
||||||
"""
|
"""
|
||||||
@ -80,10 +80,10 @@ class SnippetsFileParser(object):
|
|||||||
cs = ""
|
cs = ""
|
||||||
else:
|
else:
|
||||||
cs = cs[1:-1]
|
cs = cs[1:-1]
|
||||||
|
|
||||||
return (snip, cs, cdescr, coptions)
|
return (snip, cs, cdescr, coptions)
|
||||||
|
|
||||||
def _parse_snippet(self):
|
def _parse_snippet(self):
|
||||||
|
"""Parses the snippet that begins at the current line."""
|
||||||
line = self._line()
|
line = self._line()
|
||||||
|
|
||||||
(snip, trig, desc, opts) = self._parse_first(line)
|
(snip, trig, desc, opts) = self._parse_first(line)
|
||||||
@ -109,17 +109,19 @@ class SnippetsFileParser(object):
|
|||||||
self._globals[trig] = []
|
self._globals[trig] = []
|
||||||
self._globals[trig].append(cv)
|
self._globals[trig].append(cv)
|
||||||
elif snip == "snippet":
|
elif snip == "snippet":
|
||||||
self._sm.add_snippet(trig, cv, desc, opts, self._ft, self._globals, fn=self._fn)
|
self._sm.add_snippet(
|
||||||
|
trig, cv, desc, opts, self._ft, self._globals, fn=self._fn)
|
||||||
else:
|
else:
|
||||||
self._error("Invalid snippet type: '%s'" % snip)
|
self._error("Invalid snippet type: '%s'" % snip)
|
||||||
|
|
||||||
def parse(self):
|
def parse(self):
|
||||||
|
"""Parses the given file."""
|
||||||
while self._line():
|
while self._line():
|
||||||
head, tail = self._line_head_tail()
|
head, tail = self._line_head_tail()
|
||||||
if head == "extends":
|
if head == "extends":
|
||||||
if tail:
|
if tail:
|
||||||
self._sm.add_extending_info(self._ft,
|
self._sm.add_extending_info(self._ft,
|
||||||
[ p.strip() for p in tail.split(',') ])
|
[p.strip() for p in tail.split(',')])
|
||||||
else:
|
else:
|
||||||
self._error("'extends' without file types")
|
self._error("'extends' without file types")
|
||||||
elif head in ("snippet", "global"):
|
elif head in ("snippet", "global"):
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
# encoding: utf-8
|
# encoding: utf-8
|
||||||
|
|
||||||
import unittest
|
# pylint: skip-file
|
||||||
|
|
||||||
import os.path as p, sys; sys.path.append(p.join(p.dirname(__file__), ".."))
|
import unittest
|
||||||
|
|
||||||
from _diff import diff, guess_edit
|
from _diff import diff, guess_edit
|
||||||
from position import Position
|
from position import Position
|
@ -1,6 +1,8 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
# encoding: utf-8
|
# encoding: utf-8
|
||||||
|
|
||||||
|
# pylint: skip-file
|
||||||
|
|
||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
from position import Position
|
from position import Position
|
||||||
|
@ -1,14 +1,15 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
# encoding: utf-8
|
# encoding: utf-8
|
||||||
|
|
||||||
|
"""See module comment."""
|
||||||
|
|
||||||
from UltiSnips.text_objects._base import NoneditableTextObject
|
from UltiSnips.text_objects._base import NoneditableTextObject
|
||||||
|
|
||||||
class EscapedChar(NoneditableTextObject):
|
class EscapedChar(NoneditableTextObject):
|
||||||
"""
|
r"""
|
||||||
This class is a escape char like \$. It is handled in a text object to make
|
This class is a escape char like \$. It is handled in a text object to make
|
||||||
sure that siblings are correctly moved after replacing the text.
|
sure that siblings are correctly moved after replacing the text.
|
||||||
|
|
||||||
This is a base class without functionality just to mark it in the code.
|
This is a base class without functionality just to mark it in the code.
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@ -1,12 +1,13 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
# encoding: utf-8
|
# encoding: utf-8
|
||||||
|
|
||||||
|
"""A Mirror object contains the same text as its related tabstop."""
|
||||||
|
|
||||||
from UltiSnips.text_objects._base import NoneditableTextObject
|
from UltiSnips.text_objects._base import NoneditableTextObject
|
||||||
|
|
||||||
class Mirror(NoneditableTextObject):
|
class Mirror(NoneditableTextObject):
|
||||||
"""
|
"""See module docstring."""
|
||||||
A Mirror object mirrors a TabStop that is, text is repeated here
|
|
||||||
"""
|
|
||||||
def __init__(self, parent, tabstop, token):
|
def __init__(self, parent, tabstop, token):
|
||||||
NoneditableTextObject.__init__(self, parent, token)
|
NoneditableTextObject.__init__(self, parent, token)
|
||||||
|
|
||||||
@ -15,7 +16,7 @@ class Mirror(NoneditableTextObject):
|
|||||||
def _update(self, done):
|
def _update(self, done):
|
||||||
if self._ts.is_killed:
|
if self._ts.is_killed:
|
||||||
self.overwrite("")
|
self.overwrite("")
|
||||||
self._parent._del_child(self)
|
self._parent._del_child(self) # pylint:disable=protected-access
|
||||||
return True
|
return True
|
||||||
|
|
||||||
if self._ts not in done:
|
if self._ts not in done:
|
||||||
@ -25,4 +26,5 @@ class Mirror(NoneditableTextObject):
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
def _get_text(self):
|
def _get_text(self):
|
||||||
|
"""Returns the text used for mirroring. Overwritten by base classes."""
|
||||||
return self._ts.current_text
|
return self._ts.current_text
|
||||||
|
@ -13,6 +13,7 @@ from UltiSnips.text_objects._parser import parse_text_object
|
|||||||
|
|
||||||
class SnippetInstance(EditableTextObject):
|
class SnippetInstance(EditableTextObject):
|
||||||
"""See module docstring."""
|
"""See module docstring."""
|
||||||
|
# pylint:disable=protected-access
|
||||||
|
|
||||||
def __init__(self, snippet, parent, indent, initial_text,
|
def __init__(self, snippet, parent, indent, initial_text,
|
||||||
start, end, visual_content, last_re, globals):
|
start, end, visual_content, last_re, globals):
|
||||||
|
@ -1,11 +1,13 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
# encoding: utf-8
|
# encoding: utf-8
|
||||||
|
|
||||||
|
"""Implements `!v ` VimL interpolation."""
|
||||||
|
|
||||||
import UltiSnips._vim as _vim
|
import UltiSnips._vim as _vim
|
||||||
from UltiSnips.text_objects._base import NoneditableTextObject
|
from UltiSnips.text_objects._base import NoneditableTextObject
|
||||||
|
|
||||||
class VimLCode(NoneditableTextObject):
|
class VimLCode(NoneditableTextObject):
|
||||||
|
"""See module docstring."""
|
||||||
def __init__(self, parent, token):
|
def __init__(self, parent, token):
|
||||||
self._code = token.code.replace("\\`", "`").strip()
|
self._code = token.code.replace("\\`", "`").strip()
|
||||||
|
|
||||||
|
@ -1,6 +1,10 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
# encoding: utf-8
|
# encoding: utf-8
|
||||||
|
|
||||||
|
"""A ${VISUAL} placeholder that will use the text that was last visually
|
||||||
|
selected and insert it here. If there was no text visually selected, this will
|
||||||
|
be the empty string. """
|
||||||
|
|
||||||
import re
|
import re
|
||||||
|
|
||||||
import UltiSnips._vim as _vim
|
import UltiSnips._vim as _vim
|
||||||
@ -8,13 +12,9 @@ from UltiSnips.indent_util import IndentUtil
|
|||||||
from UltiSnips.text_objects._transformation import TextObjectTransformation
|
from UltiSnips.text_objects._transformation import TextObjectTransformation
|
||||||
from UltiSnips.text_objects._base import NoneditableTextObject
|
from UltiSnips.text_objects._base import NoneditableTextObject
|
||||||
|
|
||||||
class Visual(NoneditableTextObject,TextObjectTransformation):
|
_REPLACE_NON_WS = re.compile(r"[^ \t]")
|
||||||
"""
|
class Visual(NoneditableTextObject, TextObjectTransformation):
|
||||||
A ${VISUAL} placeholder that will use the text that was last visually
|
"""See module docstring."""
|
||||||
selected and insert it here. If there was no text visually selected,
|
|
||||||
this will be the empty string
|
|
||||||
"""
|
|
||||||
__REPLACE_NON_WS = re.compile(r"[^ \t]")
|
|
||||||
|
|
||||||
def __init__(self, parent, token):
|
def __init__(self, parent, token):
|
||||||
# Find our containing snippet for visual_content
|
# Find our containing snippet for visual_content
|
||||||
@ -25,7 +25,7 @@ class Visual(NoneditableTextObject,TextObjectTransformation):
|
|||||||
self._mode = snippet.visual_content.mode
|
self._mode = snippet.visual_content.mode
|
||||||
break
|
break
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
snippet = snippet._parent
|
snippet = snippet._parent # pylint:disable=protected-access
|
||||||
if not self._text:
|
if not self._text:
|
||||||
self._text = token.alternative_text
|
self._text = token.alternative_text
|
||||||
self._mode = "v"
|
self._mode = "v"
|
||||||
@ -37,7 +37,7 @@ class Visual(NoneditableTextObject,TextObjectTransformation):
|
|||||||
if self._mode != "v":
|
if self._mode != "v":
|
||||||
# Keep the indent for Line/Block Selection
|
# Keep the indent for Line/Block Selection
|
||||||
text_before = _vim.buf[self.start.line][:self.start.col]
|
text_before = _vim.buf[self.start.line][:self.start.col]
|
||||||
indent = self.__REPLACE_NON_WS.sub(" ", text_before)
|
indent = _REPLACE_NON_WS.sub(" ", text_before)
|
||||||
iu = IndentUtil()
|
iu = IndentUtil()
|
||||||
indent = iu.indent_to_spaces(indent)
|
indent = iu.indent_to_spaces(indent)
|
||||||
indent = iu.spaces_to_indent(indent)
|
indent = iu.spaces_to_indent(indent)
|
||||||
@ -52,6 +52,6 @@ class Visual(NoneditableTextObject,TextObjectTransformation):
|
|||||||
|
|
||||||
text = self._transform(text)
|
text = self._transform(text)
|
||||||
self.overwrite(text)
|
self.overwrite(text)
|
||||||
self._parent._del_child(self)
|
self._parent._del_child(self) # pylint:disable=protected-access
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
Loading…
Reference in New Issue
Block a user