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]
|
||||
|
||||
msg-template="{path}:{line}: [{msg_id}({symbol}), {obj}] {msg}"
|
||||
|
||||
# Python code to execute, usually for sys.path manipulation such as
|
||||
# pygtk.require().
|
||||
init-hook='import sys; sys.path.append("pythonx/")'
|
||||
@ -38,13 +36,14 @@ disable=
|
||||
attribute-defined-outside-init,
|
||||
fixme,
|
||||
redefined-builtin,
|
||||
too-many-arguments,
|
||||
too-many-instance-attributes,
|
||||
too-many-public-methods,
|
||||
too-few-public-methods,
|
||||
too-many-arguments,
|
||||
too-many-branches,
|
||||
too-many-statements,
|
||||
too-many-instance-attributes,
|
||||
too-many-locals,
|
||||
too-many-public-methods,
|
||||
too-many-return-statements,
|
||||
too-many-statements,
|
||||
|
||||
|
||||
[REPORTS]
|
||||
@ -57,6 +56,9 @@ output-format=text
|
||||
# Tells whether to display a full report or only the messages
|
||||
reports=yes
|
||||
|
||||
msg-template="{path}:{line}: [{msg_id}({symbol}), {obj}] {msg}"
|
||||
|
||||
|
||||
|
||||
[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_]*$
|
||||
|
||||
# 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-names=foo,bar,baz,toto,tutu,tata
|
||||
|
@ -145,6 +145,9 @@ Following is the full stack trace:
|
||||
_vim.new_scratch_buffer(msg)
|
||||
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):
|
||||
"""The main entry point for all UltiSnips functionality. All Vim functions
|
||||
call methods in this class."""
|
||||
@ -162,7 +165,7 @@ class SnippetManager(object):
|
||||
"""Reset the class to the state it had directly after creation."""
|
||||
self._vstate = VimState()
|
||||
self._test_error = test_error
|
||||
self._snippets = defaultdict(lambda: SnippetDictionary())
|
||||
self._snippets = defaultdict(SnippetDictionary)
|
||||
self._filetypes = defaultdict(lambda: ['all'])
|
||||
self._visual_content = VisualContentPreserver()
|
||||
|
||||
@ -390,11 +393,8 @@ class SnippetManager(object):
|
||||
self._current_snippet_is_done()
|
||||
self._reinit()
|
||||
|
||||
|
||||
###################################
|
||||
# Private/Protect Functions Below #
|
||||
###################################
|
||||
def _error(self, msg):
|
||||
# TODO(sirver): This is only used by SnippetsFileParser
|
||||
def report_error(self, msg):
|
||||
"""Shows 'msg' as error to the user."""
|
||||
msg = _vim.escape("UltiSnips: " + msg)
|
||||
if self._test_error:
|
||||
@ -410,6 +410,9 @@ class SnippetManager(object):
|
||||
else:
|
||||
_vim.command("echoerr %s" % msg)
|
||||
|
||||
###################################
|
||||
# Private/Protect Functions Below #
|
||||
###################################
|
||||
def _reinit(self):
|
||||
"""Resets transient state."""
|
||||
self._ctab = None
|
||||
|
@ -1,14 +1,19 @@
|
||||
#!/usr/bin/env python
|
||||
# encoding: utf-8
|
||||
|
||||
"""Commands to compare text objects and to guess how to transform from one to
|
||||
another."""
|
||||
|
||||
from collections import defaultdict
|
||||
import sys
|
||||
|
||||
from UltiSnips import _vim
|
||||
from UltiSnips.position import Position
|
||||
|
||||
def is_complete_edit(initial_line, a, b, cmds):
|
||||
buf = a[:]
|
||||
def is_complete_edit(initial_line, original, wanted, cmds):
|
||||
"""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:
|
||||
ctype, line, col, char = cmd
|
||||
line -= initial_line
|
||||
@ -24,95 +29,133 @@ def is_complete_edit(initial_line, a, b, cmds):
|
||||
elif ctype == "I":
|
||||
buf[line] = buf[line][:col] + char + buf[line][col:]
|
||||
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
|
||||
number of changed lines and if they got longer or shorter. This will detect most simple
|
||||
movements like insertion, deletion of a line or carriage return.
|
||||
Try to guess what the user might have done by heuristically looking at
|
||||
cursor movement, number of changed lines and if they got longer or shorter.
|
||||
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, ()
|
||||
pos = vs.pos
|
||||
ppos = vs.ppos
|
||||
if len(lt) and (not ct or (len(ct) == 1 and not ct[0])): # All text deleted?
|
||||
if not len(last_text) and not len(current_text):
|
||||
return True, ()
|
||||
pos = vim_state.pos
|
||||
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 = []
|
||||
if not ct: ct = ['']
|
||||
for i in lt:
|
||||
if not current_text:
|
||||
current_text = ['']
|
||||
for i in last_text:
|
||||
es.append(("D", initial_line, 0, i))
|
||||
es.append(("D", initial_line, 0, "\n"))
|
||||
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?
|
||||
sv = list(map(int, _vim.eval("""getpos("'<")"""))); sv = Position(sv[1]-1,sv[2]-1)
|
||||
ev = list(map(int, _vim.eval("""getpos("'>")"""))); ev = Position(ev[1]-1,ev[2]-1)
|
||||
sv = list(map(int, _vim.eval("""getpos("'<")""")))
|
||||
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"):
|
||||
ppos.col -= 1 # We want to be inclusive, sorry.
|
||||
ev.col -= 1
|
||||
es = []
|
||||
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:
|
||||
es.append(("I", sv.line, sv.col, ct[sv.line - initial_line][sv.col:pos.col+1]))
|
||||
if is_complete_edit(initial_line, lt, ct, es): return True, es
|
||||
es.append(("I", sv.line, sv.col,
|
||||
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 len(lt) == len(ct): # Movement only in one line
|
||||
llen = len(lt[ppos.line - initial_line])
|
||||
clen = len(ct[pos.line - initial_line])
|
||||
if ppos < pos and clen > llen: # Likely that only characters have been added
|
||||
if len(last_text) == len(current_text): # Movement only in one line
|
||||
llen = len(last_text[ppos.line - initial_line])
|
||||
clen = len(current_text[pos.line - initial_line])
|
||||
if ppos < pos and clen > llen: # maybe only chars have been added
|
||||
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 ppos == pos: # 'x' or DEL or dt or something
|
||||
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?
|
||||
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
|
||||
elif len(ct) < len(lt): # Maybe some lines were deleted? (dd or so)
|
||||
if is_complete_edit(initial_line, last_text,
|
||||
current_text, es):
|
||||
return True, es
|
||||
elif len(current_text) < len(last_text):
|
||||
# where some lines deleted? (dd or so)
|
||||
es = []
|
||||
for i in range(len(lt)-len(ct)):
|
||||
es.append( ("D", pos.line, 0, lt[pos.line - initial_line + i]))
|
||||
for i in range(len(last_text)-len(current_text)):
|
||||
es.append(("D", pos.line, 0,
|
||||
last_text[pos.line - initial_line + i]))
|
||||
es.append(("D", pos.line, 0, '\n'))
|
||||
if is_complete_edit(initial_line, lt, ct, es): return True, es
|
||||
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?
|
||||
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
|
||||
|
||||
def diff(a, b, sline=0):
|
||||
"""
|
||||
Return a list of deletions and insertions that will turn a into b. This is
|
||||
done by traversing an implicit edit graph and searching for the shortest
|
||||
Return a list of deletions and insertions that will turn 'a' into 'b'. This
|
||||
is done by traversing an implicit edit graph and searching for the shortest
|
||||
route. The basic idea is as follows:
|
||||
|
||||
- Matching a character is free as long as there was no deletion/insertion
|
||||
before. Then, matching will be seen as delete + insert [1].
|
||||
- Matching a character is free as long as there was no
|
||||
deletion/insertion before. Then, matching will be seen as delete +
|
||||
insert [1].
|
||||
- Deleting one character has the same cost everywhere. Each additional
|
||||
character costs only have of the first deletion.
|
||||
- Insertion is cheaper the earlier it happes. The first character is more
|
||||
expensive that any later [2].
|
||||
- Insertion is cheaper the earlier it happens. The first character is
|
||||
more expensive that any later [2].
|
||||
|
||||
[1] This is that world -> aolsa will be "D" world + "I" aolsa instead of
|
||||
"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
|
||||
and not after \n
|
||||
[2] This is that "hello\n\n" -> "hello\n\n\n" will insert a newline after
|
||||
hello and not after \n
|
||||
"""
|
||||
d = defaultdict(list)
|
||||
d = defaultdict(list) # pylint:disable=invalid-name
|
||||
seen = defaultdict(lambda: sys.maxsize)
|
||||
|
||||
d[0] = [(0, 0, sline, 0, ())]
|
||||
|
||||
cost = 0
|
||||
D_COST = len(a)+len(b)
|
||||
I_COST = len(a)+len(b)
|
||||
deletion_cost = len(a)+len(b)
|
||||
insertion_cost = len(a)+len(b)
|
||||
while True:
|
||||
while len(d[cost]):
|
||||
x, y, line, col, what = d[cost].pop()
|
||||
@ -131,11 +174,10 @@ def diff(a, b, sline = 0):
|
||||
what[-1][2] == col and a[x] != '\n'):
|
||||
# Matching directly after a deletion should be as costly as
|
||||
# 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:
|
||||
d[lcost].append((x+1, y+1, nline, ncol, what))
|
||||
seen[x+1, y+1] = lcost
|
||||
|
||||
if y < len(b): # INSERT
|
||||
ncol = col + 1
|
||||
nline = line
|
||||
@ -144,30 +186,34 @@ def diff(a, b, sline = 0):
|
||||
nline += 1
|
||||
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
|
||||
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
|
||||
d[cost + (I_COST + ncol) // 2].append(
|
||||
seen[x, y+1] = cost + (insertion_cost + ncol) // 2
|
||||
d[cost + (insertion_cost + ncol) // 2].append(
|
||||
(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:
|
||||
seen[x,y+1] = cost + I_COST + ncol
|
||||
d[cost + ncol + I_COST].append((x,y+1, nline, ncol,
|
||||
)
|
||||
elif seen[x, y+1] > cost + insertion_cost + ncol:
|
||||
seen[x, y+1] = cost + insertion_cost + ncol
|
||||
d[cost + ncol + insertion_cost].append((x, y+1, nline, ncol,
|
||||
what + (("I", line, col, b[y]),))
|
||||
)
|
||||
if x < len(a): # DELETE
|
||||
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
|
||||
seen[x+1,y] > cost + D_COST // 2
|
||||
what[-1][2] == col and a[x] != '\n' and
|
||||
what[-1][-1] != '\n' and
|
||||
seen[x+1, y] > cost + deletion_cost // 2
|
||||
):
|
||||
seen[x+1,y] = cost + D_COST // 2
|
||||
d[cost + D_COST // 2].append((x+1,y, line, col, what[:-1] +
|
||||
(("D",line, col, what[-1][-1] + a[x]),) )
|
||||
seen[x+1, y] = cost + deletion_cost // 2
|
||||
d[cost + deletion_cost // 2].append(
|
||||
(x+1, y, line, col, what[:-1] + (
|
||||
("D", line, col, what[-1][-1] + a[x]),))
|
||||
)
|
||||
elif seen[x+1,y] > cost + D_COST:
|
||||
seen[x+1,y] = cost + D_COST
|
||||
d[cost + D_COST].append((x+1,y, line, col, what +
|
||||
elif seen[x+1, y] > cost + deletion_cost:
|
||||
seen[x+1, y] = cost + deletion_cost
|
||||
d[cost + deletion_cost].append((x+1, y, line, col, what +
|
||||
(("D", line, col, a[x]),))
|
||||
)
|
||||
cost += 1
|
||||
|
@ -1,11 +1,17 @@
|
||||
#!/usr/bin/env python
|
||||
# encoding: utf-8
|
||||
|
||||
"""Parsing of snippet files."""
|
||||
|
||||
import re
|
||||
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):
|
||||
"""Does the actual parsing."""
|
||||
|
||||
def __init__(self, ft, fn, snip_manager, file_data=None):
|
||||
"""Parser 'fn' as filetype 'ft'."""
|
||||
self._sm = snip_manager
|
||||
@ -19,28 +25,22 @@ class SnippetsFileParser(object):
|
||||
self._idx = 0
|
||||
|
||||
def _error(self, msg):
|
||||
"""Reports 'msg' as an error."""
|
||||
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):
|
||||
if self._idx < len(self._lines):
|
||||
line = self._lines[self._idx]
|
||||
else:
|
||||
line = ""
|
||||
return line
|
||||
"""The current line or the empty string."""
|
||||
return self._lines[self._idx] if self._idx < len(self._lines) else ""
|
||||
|
||||
def _line_head_tail(self):
|
||||
"""Returns (first word, rest) of the current line."""
|
||||
parts = re.split(r"\s+", self._line().rstrip(), maxsplit=1)
|
||||
parts.append('')
|
||||
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):
|
||||
"""Advances to and returns the next line."""
|
||||
self._idx += 1
|
||||
return self._line()
|
||||
|
||||
@ -80,10 +80,10 @@ class SnippetsFileParser(object):
|
||||
cs = ""
|
||||
else:
|
||||
cs = cs[1:-1]
|
||||
|
||||
return (snip, cs, cdescr, coptions)
|
||||
|
||||
def _parse_snippet(self):
|
||||
"""Parses the snippet that begins at the current line."""
|
||||
line = self._line()
|
||||
|
||||
(snip, trig, desc, opts) = self._parse_first(line)
|
||||
@ -109,11 +109,13 @@ class SnippetsFileParser(object):
|
||||
self._globals[trig] = []
|
||||
self._globals[trig].append(cv)
|
||||
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:
|
||||
self._error("Invalid snippet type: '%s'" % snip)
|
||||
|
||||
def parse(self):
|
||||
"""Parses the given file."""
|
||||
while self._line():
|
||||
head, tail = self._line_head_tail()
|
||||
if head == "extends":
|
||||
|
@ -1,9 +1,9 @@
|
||||
#!/usr/bin/env python
|
||||
# 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 position import Position
|
@ -1,6 +1,8 @@
|
||||
#!/usr/bin/env python
|
||||
# encoding: utf-8
|
||||
|
||||
# pylint: skip-file
|
||||
|
||||
import unittest
|
||||
|
||||
from position import Position
|
||||
|
@ -1,14 +1,15 @@
|
||||
#!/usr/bin/env python
|
||||
# encoding: utf-8
|
||||
|
||||
"""See module comment."""
|
||||
|
||||
from UltiSnips.text_objects._base import NoneditableTextObject
|
||||
|
||||
class EscapedChar(NoneditableTextObject):
|
||||
"""
|
||||
r"""
|
||||
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.
|
||||
|
||||
This is a base class without functionality just to mark it in the code.
|
||||
"""
|
||||
pass
|
||||
|
||||
|
@ -1,12 +1,13 @@
|
||||
#!/usr/bin/env python
|
||||
# encoding: utf-8
|
||||
|
||||
"""A Mirror object contains the same text as its related tabstop."""
|
||||
|
||||
from UltiSnips.text_objects._base import NoneditableTextObject
|
||||
|
||||
class Mirror(NoneditableTextObject):
|
||||
"""
|
||||
A Mirror object mirrors a TabStop that is, text is repeated here
|
||||
"""
|
||||
"""See module docstring."""
|
||||
|
||||
def __init__(self, parent, tabstop, token):
|
||||
NoneditableTextObject.__init__(self, parent, token)
|
||||
|
||||
@ -15,7 +16,7 @@ class Mirror(NoneditableTextObject):
|
||||
def _update(self, done):
|
||||
if self._ts.is_killed:
|
||||
self.overwrite("")
|
||||
self._parent._del_child(self)
|
||||
self._parent._del_child(self) # pylint:disable=protected-access
|
||||
return True
|
||||
|
||||
if self._ts not in done:
|
||||
@ -25,4 +26,5 @@ class Mirror(NoneditableTextObject):
|
||||
return True
|
||||
|
||||
def _get_text(self):
|
||||
"""Returns the text used for mirroring. Overwritten by base classes."""
|
||||
return self._ts.current_text
|
||||
|
@ -13,6 +13,7 @@ from UltiSnips.text_objects._parser import parse_text_object
|
||||
|
||||
class SnippetInstance(EditableTextObject):
|
||||
"""See module docstring."""
|
||||
# pylint:disable=protected-access
|
||||
|
||||
def __init__(self, snippet, parent, indent, initial_text,
|
||||
start, end, visual_content, last_re, globals):
|
||||
|
@ -1,11 +1,13 @@
|
||||
#!/usr/bin/env python
|
||||
# encoding: utf-8
|
||||
|
||||
"""Implements `!v ` VimL interpolation."""
|
||||
|
||||
import UltiSnips._vim as _vim
|
||||
from UltiSnips.text_objects._base import NoneditableTextObject
|
||||
|
||||
class VimLCode(NoneditableTextObject):
|
||||
"""See module docstring."""
|
||||
def __init__(self, parent, token):
|
||||
self._code = token.code.replace("\\`", "`").strip()
|
||||
|
||||
|
@ -1,6 +1,10 @@
|
||||
#!/usr/bin/env python
|
||||
# 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 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._base import NoneditableTextObject
|
||||
|
||||
_REPLACE_NON_WS = re.compile(r"[^ \t]")
|
||||
class Visual(NoneditableTextObject, TextObjectTransformation):
|
||||
"""
|
||||
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
|
||||
"""
|
||||
__REPLACE_NON_WS = re.compile(r"[^ \t]")
|
||||
"""See module docstring."""
|
||||
|
||||
def __init__(self, parent, token):
|
||||
# Find our containing snippet for visual_content
|
||||
@ -25,7 +25,7 @@ class Visual(NoneditableTextObject,TextObjectTransformation):
|
||||
self._mode = snippet.visual_content.mode
|
||||
break
|
||||
except AttributeError:
|
||||
snippet = snippet._parent
|
||||
snippet = snippet._parent # pylint:disable=protected-access
|
||||
if not self._text:
|
||||
self._text = token.alternative_text
|
||||
self._mode = "v"
|
||||
@ -37,7 +37,7 @@ class Visual(NoneditableTextObject,TextObjectTransformation):
|
||||
if self._mode != "v":
|
||||
# Keep the indent for Line/Block Selection
|
||||
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()
|
||||
indent = iu.indent_to_spaces(indent)
|
||||
indent = iu.spaces_to_indent(indent)
|
||||
@ -52,6 +52,6 @@ class Visual(NoneditableTextObject,TextObjectTransformation):
|
||||
|
||||
text = self._transform(text)
|
||||
self.overwrite(text)
|
||||
self._parent._del_child(self)
|
||||
self._parent._del_child(self) # pylint:disable=protected-access
|
||||
|
||||
return True
|
||||
|
Loading…
Reference in New Issue
Block a user