Skip to content
This repository was archived by the owner on Mar 12, 2020. It is now read-only.

Commit deb3441

Browse files
committed
Improved handling of quotes in completions
1 parent bbc8b37 commit deb3441

File tree

2 files changed

+43
-24
lines changed

2 files changed

+43
-24
lines changed

SQLTools.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -331,7 +331,7 @@ def on_query_completions(view, prefix, locations):
331331
lineStartToLocation = sublime.Region(lineStartPoint, currentPoint)
332332
try:
333333
lineStr = view.substr(lineStartToLocation)
334-
prefix = re.split('[^\w.]+', lineStr).pop()
334+
prefix = re.split('[^`\"\w.]+', lineStr).pop()
335335
except Exception as e:
336336
Log(e)
337337

SQLToolsAPI/Completion.py

Lines changed: 42 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,18 @@
1616

1717
# this function is generously used in completions code to get rid
1818
# of all sorts of leading and trailing quotes in RDBMS identifiers
19-
def _stipQuotes(ident):
19+
def _stripQuotes(ident):
2020
return ident.strip('"\'`')
2121

22+
# used for formatting output
23+
def _stripQuotesOnDemand(ident, doStrip=True):
24+
if doStrip:
25+
return ident.strip('"\'`')
26+
return ident
27+
28+
def _startsWithQuote(ident):
29+
quotes = ('`', '"')
30+
return ident.startswith(quotes)
2231

2332
def _stripPrefix(text, prefix):
2433
if text.startswith(prefix):
@@ -85,32 +94,32 @@ def prefixMatchScore(self, search, exactly=False):
8594
# match parent exactly and partially match name
8695
if '.' in target and '.' in search:
8796
searchList = search.split('.')
88-
searchObject = _stipQuotes(searchList.pop())
89-
searchParent = _stipQuotes(searchList.pop())
97+
searchObject = _stripQuotes(searchList.pop())
98+
searchParent = _stripQuotes(searchList.pop())
9099
targetList = target.split('.')
91-
targetObject = _stipQuotes(targetList.pop())
92-
targetParent = _stipQuotes(targetList.pop())
100+
targetObject = _stripQuotes(targetList.pop())
101+
targetParent = _stripQuotes(targetList.pop())
93102
if (searchParent == targetParent and
94103
self._stringMatched(targetObject, searchObject, exactly)):
95104
return 1 # highest score
96105

97106
# second part matches ?
98107
if '.' in target:
99-
targetObjectNoQuote = _stipQuotes(target.split('.').pop())
100-
searchNoQuote = _stipQuotes(search)
108+
targetObjectNoQuote = _stripQuotes(target.split('.').pop())
109+
searchNoQuote = _stripQuotes(search)
101110
if self._stringMatched(targetObjectNoQuote, searchNoQuote, exactly):
102111
return 2
103112
else:
104-
targetNoQuote = _stipQuotes(target)
105-
searchNoQuote = _stipQuotes(search)
113+
targetNoQuote = _stripQuotes(target)
114+
searchNoQuote = _stripQuotes(search)
106115
if self._stringMatched(targetNoQuote, searchNoQuote, exactly):
107116
return 3
108117
else:
109118
return 0
110119
return 0
111120

112121
# format completion item according to sublime text completions format
113-
def format(self):
122+
def format(self, stripQuotes=False):
114123
typeDisplay = ''
115124
if self.type == 'Table':
116125
typeDisplay = self.type
@@ -124,13 +133,15 @@ def format(self):
124133
typeDisplay = 'Col'
125134

126135
if not typeDisplay:
127-
return (self.ident, self.ident)
136+
return (self.ident, _stripQuotesOnDemand(self.ident, stripQuotes))
128137

129138
part = self.ident.split('.')
130139
if len(part) > 1:
131-
return ("{0}\t({1} {2})".format(part[1], part[0], typeDisplay), part[1])
140+
return ("{0}\t({1} {2})".format(part[1], part[0], typeDisplay),
141+
_stripQuotesOnDemand(part[1], stripQuotes))
132142

133-
return ("{0}\t({1})".format(self.ident, typeDisplay), self.ident)
143+
return ("{0}\t({1})".format(self.ident, typeDisplay),
144+
_stripQuotesOnDemand(self.ident, stripQuotes))
134145

135146

136147
class Completion:
@@ -171,7 +182,10 @@ def getBasicAutoCompleteList(self, prefix):
171182
if len(autocompleteList) == 0:
172183
return None
173184

174-
autocompleteList = [item.format() for item in autocompleteList]
185+
# return completions with or without quotes?
186+
# determined based on ident after last dot
187+
startsWithQuote = _startsWithQuote(prefix.split(".").pop())
188+
autocompleteList = [item.format(startsWithQuote) for item in autocompleteList]
175189
return autocompleteList
176190

177191
def getAutoCompleteList(self, prefix, sql, sqlToCursor):
@@ -232,7 +246,12 @@ def getAutoCompleteList(self, prefix, sql, sqlToCursor):
232246
if not autocompleteList:
233247
return None, False
234248

235-
autocompleteList = [item.format() for item in autocompleteList]
249+
# return completions with or without quotes?
250+
# determined based on ident after last dot
251+
startsWithQuote = _startsWithQuote(prefix.split(".").pop())
252+
print("checking: " + prefix.split(".").pop())
253+
print("starts with quote: " + str(startsWithQuote))
254+
autocompleteList = [item.format(startsWithQuote) for item in autocompleteList]
236255
return autocompleteList, inhibit
237256

238257
def _noDotsCompletions(self, prefix, identifiers, joinAlias=None):
@@ -439,7 +458,7 @@ def _joinConditionCompletions(self, identifiers, joinAlias=None):
439458
(ident.alias, col)
440459
for col in self.allColumns
441460
if (col.prefixMatchScore(prefixForColumnMatch, exactly=True) > 0 and
442-
_stipQuotes(col.name).lower().endswith('id'))
461+
_stripQuotes(col.name).lower().endswith('id'))
443462
]
444463

445464
if ident.alias == joinAlias:
@@ -451,20 +470,20 @@ def _joinConditionCompletions(self, identifiers, joinAlias=None):
451470
for joinAlias, joinColumn in joinAliasColumns:
452471
# str.endswith can be matched against a tuple
453472
columnsToMatch = None
454-
if _stipQuotes(joinColumn.name).lower() == 'id':
473+
if _stripQuotes(joinColumn.name).lower() == 'id':
455474
columnsToMatch = (
456-
_stipQuotes(joinColumn.parent).lower() + _stipQuotes(joinColumn.name).lower(),
457-
_stipQuotes(joinColumn.parent).lower() + '_' + _stipQuotes(joinColumn.name).lower()
475+
_stripQuotes(joinColumn.parent).lower() + _stripQuotes(joinColumn.name).lower(),
476+
_stripQuotes(joinColumn.parent).lower() + '_' + _stripQuotes(joinColumn.name).lower()
458477
)
459478
else:
460479
columnsToMatch = (
461-
_stipQuotes(joinColumn.name).lower(),
462-
_stipQuotes(joinColumn.parent).lower() + _stipQuotes(joinColumn.name).lower(),
463-
_stipQuotes(joinColumn.parent).lower() + '_' + _stipQuotes(joinColumn.name).lower()
480+
_stripQuotes(joinColumn.name).lower(),
481+
_stripQuotes(joinColumn.parent).lower() + _stripQuotes(joinColumn.name).lower(),
482+
_stripQuotes(joinColumn.parent).lower() + '_' + _stripQuotes(joinColumn.name).lower()
464483
)
465484

466485
for otherAlias, otherColumn in sqlOtherColumns:
467-
if _stipQuotes(otherColumn.name).lower().endswith(columnsToMatch):
486+
if _stripQuotes(otherColumn.name).lower().endswith(columnsToMatch):
468487
sideA = joinAlias + '.' + joinColumn.name
469488
sideB = otherAlias + '.' + otherColumn.name
470489

0 commit comments

Comments
 (0)