Switch branches/tags
Nothing to show
Find file Copy path
0279ecf Apr 12, 2017
@miraks @forivall @dpidan @bencao @alienhard
124 lines (98 sloc) 4.05 KB
# Extends Sublime Text autocompletion to find matches in all open
# files. By default, Sublime only considers words from the current file.
import sublime_plugin
import sublime
import re
import time
from os.path import basename
# limits to prevent bogging down the system
def plugin_loaded():
global settings
settings = sublime.load_settings('All Autocomplete.sublime-settings')
class AllAutocomplete(sublime_plugin.EventListener):
def on_query_completions(self, view, prefix, locations):
if is_disabled_in(view.scope_name(locations[0])):
return []
words = []
# Limit number of views but always include the active view. This
# view goes first to prioritize matches close to cursor position.
other_views = [v for v in sublime.active_window().views() if !=]
views = [view] + other_views
views = views[0:MAX_VIEWS]
for v in views:
if len(locations) > 0 and ==
view_words = v.extract_completions(prefix, locations[0])
view_words = v.extract_completions(prefix)
view_words = filter_words(view_words)
view_words = fix_truncation(v, view_words)
words += [(w, v) for w in view_words]
words = without_duplicates(words)
matches = []
for w, v in words:
trigger = w
contents = w.replace('$', '\\$')
if != and v.file_name():
trigger += '\t(%s)' % basename(v.file_name())
matches.append((trigger, contents))
return matches
def is_disabled_in(scope):
excluded_scopes = settings.get("exclude_from_completion", [])
for excluded_scope in excluded_scopes:
if scope.find(excluded_scope) != -1:
return True
return False
def filter_words(words):
words = words[0:MAX_WORDS_PER_VIEW]
return [w for w in words if MIN_WORD_SIZE <= len(w) <= MAX_WORD_SIZE]
# keeps first instance of every word and retains the original order
# (n^2 but should not be a problem as len(words) <= MAX_VIEWS*MAX_WORDS_PER_VIEW)
def without_duplicates(words):
result = []
used_words = []
for w, v in words:
if w not in used_words:
result.append((w, v))
return result
# Ugly workaround for truncation bug in Sublime when using view.extract_completions()
# in some types of files.
def fix_truncation(view, words):
fixed_words = []
start_time = time.time()
for i, w in enumerate(words):
#The word is truncated if and only if it cannot be found with a word boundary before and after
# this fails to match strings with trailing non-alpha chars, like
# 'foo?' or 'bar!', which are common for instance in Ruby.
match = view.find(r'\b' + re.escape(w) + r'\b', 0)
truncated = is_empty_match(match)
if truncated:
#Truncation is always by a single character, so we extend the word by one word character before a word boundary
extended_words = []
view.find_all(r'\b' + re.escape(w) + r'\w\b', 0, "$0", extended_words)
if len(extended_words) > 0:
fixed_words += extended_words
# to compensate for the missing match problem mentioned above, just
# use the old word if we didn't find any extended matches
#Pass through non-truncated words
# if too much time is spent in here, bail out,
# and don't bother fixing the remaining words
if time.time() - start_time > MAX_FIX_TIME_SECS_PER_VIEW:
return fixed_words + words[i+1:]
return fixed_words
if sublime.version() >= '3000':
def is_empty_match(match):
return match.empty()
def is_empty_match(match):
return match is None