-
Notifications
You must be signed in to change notification settings - Fork 366
/
latex_ref_completions.py
120 lines (92 loc) · 3.46 KB
/
latex_ref_completions.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
from . import getTeXRoot
from .latex_fill_all import FillAllHelper
from .latextools_utils import analysis, get_setting
import re
_ref_special_commands = "|".join([
"", "eq", "page", "v", "V", "auto", "autopage", "name",
"c", "C", "cpage", "Cpage", "namec", "nameC", "lcnamec", "labelc",
"labelcpage", "sub", "f", "F", "vpage", "t", "p", "A", "B", "P", "S",
"title", "headname", "tocname"
])[::-1]
OLD_STYLE_REF_REGEX = re.compile(
r"([^_]*_)?(?:\*?s?fer(" +
_ref_special_commands +
r")?)\\"
)
NEW_STYLE_REF_REGEX = re.compile(
r"([^}]*)\{(?:\*?s?fer(" +
_ref_special_commands +
r")?)\\"
)
NEW_STYLE_REF_RANGE_REGEX = re.compile(
r"([^}]*)\{(?:\}[^\}]*\{)?\*?egnarfer(egapv|v|egapc|C|c)\\"
)
NEW_STYLE_REF_MULTIVALUE_REGEX = re.compile(
r"([^},]*)(?:,[^},]*)*\{fer(c|C|egapc|egapC)\\"
)
AUTOCOMPLETE_EXCLUDE_RX = re.compile(
r"fer(?:" + _ref_special_commands + r")?\\?"
)
# recursively search all linked tex files to find all
# included \label{} tags in the document and extract
def find_labels_in_files(root, labels):
doc = analysis.get_analysis(root)
for command in doc.filter_commands('label'):
labels.append(command.args)
# get_ref_completions forms the guts of the parsing shared by both the
# autocomplete plugin and the quick panel command
def get_ref_completions(view):
completions = []
# Check the file buffer first:
# 1) in case there are unsaved changes
# 2) if this file is unnamed and unsaved, get_tex_root will fail
view.find_all(r'\\label\{([^\{\}]+)\}', 0, '\\1', completions)
root = getTeXRoot.get_tex_root(view)
if root:
print(u"TEX root: " + repr(root))
find_labels_in_files(root, completions)
# remove duplicates
completions = list(set(completions))
return completions
# called by LatextoolsFillAllCommand; provides a list of labels
# for any ref commands
class RefFillAllHelper(FillAllHelper):
def get_auto_completions(self, view, prefix, line):
# Reverse, to simulate having the regex
# match backwards (cool trick jps btw!)
line = line[::-1]
# Check the first location looks like a ref, but backward
old_style = OLD_STYLE_REF_REGEX.match(line)
# Do not match on plain "ref" when autocompleting,
# in case the user is typing something else
if old_style and not prefix:
return []
completions = get_ref_completions(view)
if prefix:
lower_prefix = prefix.lower()
completions = [c for c in completions if lower_prefix in c.lower()]
if old_style:
return completions, '{'
else:
return completions
def get_completions(self, view, prefix, line):
completions = get_ref_completions(view)
if prefix:
lower_prefix = prefix.lower()
completions = [c for c in completions if lower_prefix in c.lower()]
return completions
def matches_line(self, line):
return bool(
(
not line.startswith(',') or
NEW_STYLE_REF_MULTIVALUE_REGEX.match(line)
) and (
OLD_STYLE_REF_REGEX.match(line) or
NEW_STYLE_REF_REGEX.match(line) or
NEW_STYLE_REF_RANGE_REGEX.match(line)
)
)
def matches_fancy_prefix(self, line):
return bool(OLD_STYLE_REF_REGEX.match(line))
def is_enabled(self):
return get_setting('ref_auto_trigger', True)