forked from evandrocoan/AutoFileName
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathcontext.py
110 lines (93 loc) · 3.5 KB
/
context.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
# Shamefully stolen from https://github.com/sagold/FuzzyFilePath
import sublime
import re
ID = "Context"
NEEDLE_SEPARATOR = ">\"\'\(\)\{\}"
NEEDLE_SEPARATOR_BEFORE = "\"\'\(\{"
NEEDLE_SEPARATOR_AFTER = "^\"\'\)\}"
NEEDLE_CHARACTERS = "\.A-Za-z0-9\-\_$"
NEEDLE_INVALID_CHARACTERS = "\"\'\)=\:\(<>\n\{\}"
DELIMITER = "\s\:\(\[\=\{"
def get_context(view):
error = False
valid = True
valid_needle = True
selection = view.sel()
position = selection[0].begin() if selection else ""
# regions
line_region = view.line(position)
word_region = view.word(position)
# word (folder/file name) can start with @, ~ or other symbols
while re.match(r'[^\/\\\s\n\w\'\"`]', view.substr(sublime.Region(word_region.a - 1, word_region.a))):
word_region = sublime.Region(word_region.a - 1, word_region.b)
pre_region = sublime.Region(line_region.a, word_region.a)
post_region = sublime.Region(word_region.b, line_region.b)
# text
line = view.substr(line_region)
word = view.substr(word_region)
pre = view.substr(pre_region)
post = view.substr(post_region)
# word can equal "('./')" or "'./'" when the path contains only a special characters, like require('./')
enquoted_symbols_match = re.search(r'(\(?[\'"`])(\W+)([\'"`]\)?)', word)
if enquoted_symbols_match:
word = enquoted_symbols_match.group(2)
pre = pre + enquoted_symbols_match.group(1)
post = post + enquoted_symbols_match.group(3)
error = re.search("[" + NEEDLE_INVALID_CHARACTERS + "]", word)
# grab everything in 'separators'
needle = ""
separator = False
pre_match = ""
# search for a separator before current word, i.e. <">path/to/<position>
pre_quotes = re.search("(["+NEEDLE_SEPARATOR_BEFORE+"])([^"+NEEDLE_SEPARATOR+"]*)$", pre)
if pre_quotes:
needle += pre_quotes.group(2) + word
separator = pre_quotes.group(1)
pre_match = pre_quotes.group(2)
else:
# use whitespace as separator
pre_quotes = re.search("(\s)([^"+NEEDLE_SEPARATOR+"\s]*)$", pre)
if pre_quotes:
needle = pre_quotes.group(2) + word
separator = pre_quotes.group(1)
pre_match = pre_quotes.group(2)
if pre_quotes:
post_quotes = re.search("^(["+NEEDLE_SEPARATOR_AFTER+"]*)", post)
if post_quotes:
needle += post_quotes.group(1)
else:
valid = False
elif not re.search("["+NEEDLE_INVALID_CHARACTERS+"]", needle):
needle = pre + word
else:
needle = word
# grab prefix
prefix_region = sublime.Region(line_region.a, pre_region.b - len(pre_match) - 1)
prefix_line = view.substr(prefix_region)
# # print("prefix line", prefix_line)
#define? (["...", "..."]) -> before?
# before: ABC =:([
prefix = re.search("\s*(["+NEEDLE_CHARACTERS+"]+)["+DELIMITER+"]*$", prefix_line)
if prefix is None:
# validate array, like define(["...", ".CURSOR."])
prefix = re.search("^\s*(["+NEEDLE_CHARACTERS+"]+)["+DELIMITER+"]+", prefix_line)
if prefix:
# print("prefix:", prefix.group(1))
prefix = prefix.group(1)
if separator is False:
# print(ID, "separator undefined => invalid", needle)
valid_needle = False
valid = False
elif re.search("["+NEEDLE_INVALID_CHARACTERS+"]", needle):
# print("["+NEEDLE_INVALID_CHARACTERS+"]", needle)
# print(ID, "invalid characters in needle => invalid", needle)
valid_needle = False
valid = False
elif prefix is None and separator.strip() == "":
# print(ID, "prefix undefined => invalid", needle)
valid = False
return {
"is_valid": valid and valid_needle and not error,
"word": word,
"prefix": prefix,
}