.gitignore added
[dotfiles/.git] / .config / coc / extensions / node_modules / coc-snippets / python / ultisnips.py
1 import re, os, vim, string, random
2 from collections import deque, namedtuple
3
4 _Placeholder = namedtuple("_FrozenPlaceholder", ["current_text", "start", "end"])
5 _VisualContent = namedtuple("_VisualContent", ["mode", "text"])
6 _Position = namedtuple("_Position", ["line", "col"])
7
8
9 class _SnippetUtilCursor(object):
10     def __init__(self, cursor):
11         self._cursor = [cursor[0] - 1, cursor[1]]
12         self._set = False
13
14     def preserve(self):
15         self._set = True
16         self._cursor = [vim.buf.cursor[0], vim.buf.cursor[1]]
17
18     def is_set(self):
19         return self._set
20
21     def set(self, line, column):
22         self.__setitem__(0, line)
23         self.__setitem__(1, column)
24
25     def to_vim_cursor(self):
26         return (self._cursor[0] + 1, self._cursor[1])
27
28     def __getitem__(self, index):
29         return self._cursor[index]
30
31     def __setitem__(self, index, value):
32         self._set = True
33         self._cursor[index] = value
34
35     def __len__(self):
36         return 2
37
38     def __str__(self):
39         return str((self._cursor[0], self._cursor[1]))
40
41
42 class IndentUtil(object):
43
44     """Utility class for dealing properly with indentation."""
45
46     def __init__(self):
47         self.reset()
48
49     def reset(self):
50         """Gets the spacing properties from Vim."""
51         self.shiftwidth = int(
52             vim.eval("exists('*shiftwidth') ? shiftwidth() : &shiftwidth")
53         )
54         self._expandtab = vim.eval("&expandtab") == "1"
55         self._tabstop = int(vim.eval("&tabstop"))
56
57     def ntabs_to_proper_indent(self, ntabs):
58         """Convert 'ntabs' number of tabs to the proper indent prefix."""
59         line_ind = ntabs * self.shiftwidth * " "
60         line_ind = self.indent_to_spaces(line_ind)
61         line_ind = self.spaces_to_indent(line_ind)
62         return line_ind
63
64     def indent_to_spaces(self, indent):
65         """Converts indentation to spaces respecting Vim settings."""
66         indent = indent.expandtabs(self._tabstop)
67         right = (len(indent) - len(indent.rstrip(" "))) * " "
68         indent = indent.replace(" ", "")
69         indent = indent.replace("\t", " " * self._tabstop)
70         return indent + right
71
72     def spaces_to_indent(self, indent):
73         """Converts spaces to proper indentation respecting Vim settings."""
74         if not self._expandtab:
75             indent = indent.replace(" " * self._tabstop, "\t")
76         return indent
77
78
79 class SnippetUtil(object):
80
81     """Provides easy access to indentation, etc.
82
83     This is the 'snip' object in python code.
84
85     """
86
87     def __init__(self, _initial_indent, start, end, context):
88         self._ind = IndentUtil()
89         self._visual = _VisualContent(
90             vim.eval("visualmode()"), vim.eval('get(g:,"coc_selected_text","")')
91         )
92         self._initial_indent = _initial_indent
93         self._reset("")
94         self._start = start
95         self._end = end
96         self._context = context
97
98     def _reset(self, cur):
99         """Gets the snippet ready for another update.
100
101         :cur: the new value for c.
102
103         """
104         self._ind.reset()
105         self._cur = cur
106         self._rv = ""
107         self._changed = False
108         self.reset_indent()
109
110     def shift(self, amount=1):
111         """Shifts the indentation level. Note that this uses the shiftwidth
112         because thats what code formatters use.
113
114         :amount: the amount by which to shift.
115
116         """
117         self.indent += " " * self._ind.shiftwidth * amount
118
119     def unshift(self, amount=1):
120         """Unshift the indentation level. Note that this uses the shiftwidth
121         because thats what code formatters use.
122
123         :amount: the amount by which to unshift.
124
125         """
126         by = -self._ind.shiftwidth * amount
127         try:
128             self.indent = self.indent[:by]
129         except IndexError:
130             self.indent = ""
131
132     def mkline(self, line="", indent=""):
133         """Creates a properly set up line.
134
135         :line: the text to add
136         :indent: the indentation to have at the beginning
137                  if None, it uses the default amount
138
139         """
140         return indent + line
141
142     def reset_indent(self):
143         """Clears the indentation."""
144         self.indent = self._initial_indent
145
146     # Utility methods
147     @property
148     def fn(self):  # pylint:disable=no-self-use,invalid-name
149         """The filename."""
150         return vim.eval('expand("%:t")') or ""
151
152     @property
153     def basename(self):  # pylint:disable=no-self-use
154         """The filename without extension."""
155         return vim.eval('expand("%:t:r")') or ""
156
157     @property
158     def ft(self):  # pylint:disable=invalid-name
159         """The filetype."""
160         return self.opt("&filetype", "")
161
162     @property
163     def rv(self):  # pylint:disable=invalid-name
164         """The return value.
165
166         The text to insert at the location of the placeholder.
167
168         """
169         return self._rv
170
171     @rv.setter
172     def rv(self, value):  # pylint:disable=invalid-name
173         """See getter."""
174         self._changed = True
175         self._rv = value
176
177     @property
178     def _rv_changed(self):
179         """True if rv has changed."""
180         return self._changed
181
182     @property
183     def c(self):  # pylint:disable=invalid-name
184         """The current text of the placeholder."""
185         return ""
186
187     @property
188     def v(self):  # pylint:disable=invalid-name
189         """Content of visual expansions."""
190         return self._visual
191
192     @property
193     def p(self):
194         if "coc_last_placeholder" in vim.vars:
195             p = vim.vars["coc_last_placeholder"]
196             start = _Position(p["start"]["line"], p["start"]["col"])
197             end = _Position(p["end"]["line"], p["end"]["col"])
198             return _Placeholder(p["current_text"], start, end)
199         return None
200
201     @property
202     def context(self):
203         return self._context
204
205     def opt(self, option, default=None):  # pylint:disable=no-self-use
206         """Gets a Vim variable."""
207         if vim.eval("exists('%s')" % option) == "1":
208             try:
209                 return vim.eval(option)
210             except vim.error:
211                 pass
212         return default
213
214     def __add__(self, value):
215         """Appends the given line to rv using mkline."""
216         self.rv += "\n"  # pylint:disable=invalid-name
217         self.rv += self.mkline(value)
218         return self
219
220     def __lshift__(self, other):
221         """Same as unshift."""
222         self.unshift(other)
223
224     def __rshift__(self, other):
225         """Same as shift."""
226         self.shift(other)
227
228     @property
229     def snippet_start(self):
230         """
231         Returns start of the snippet in format (line, column).
232         """
233         return self._start
234
235     @property
236     def snippet_end(self):
237         """
238         Returns end of the snippet in format (line, column).
239         """
240         return self._end
241
242     @property
243     def buffer(self):
244         return vim.buf
245
246
247 class ContextSnippet(object):
248     def __init__(self):
249         self.buffer = vim.current.buffer
250         self.window = vim.current.window
251         self.cursor = _SnippetUtilCursor(vim.current.window.cursor)
252         self.line = vim.call("line", ".") - 1
253         self.column = vim.call("col", ".") - 1
254         line = vim.call("getline", ".")
255         self.after = line[self.column :]
256         if "coc_selected_text" in vim.vars:
257             self.visual_mode = vim.eval("visualmode()")
258             self.visual_text = vim.vars["coc_selected_text"]
259         else:
260             self.visual_mode = None
261             self.visual_text = ""
262         if "coc_last_placeholder" in vim.vars:
263             p = vim.vars["coc_last_placeholder"]
264             start = _Position(p["start"]["line"], p["start"]["col"])
265             end = _Position(p["end"]["line"], p["end"]["col"])
266             self.last_placeholder = _Placeholder(p["current_text"], start, end)
267         else:
268             self.last_placeholder = None