From e59cbb82ba606d43d61c91034bf77bb2edcdca63 Mon Sep 17 00:00:00 2001 From: Andrew Kondratev Date: Tue, 5 Nov 2013 14:53:17 +1300 Subject: [PATCH 01/10] Hacking around auto-completion bug https://github.com/alienhard/SublimeAllAutocomplete/issues/18 --- all_views_completions.py | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/all_views_completions.py b/all_views_completions.py index 0ff63e2..666a16f 100644 --- a/all_views_completions.py +++ b/all_views_completions.py @@ -16,7 +16,7 @@ class AllAutocomplete(sublime_plugin.EventListener): - def on_query_completions(self, view, prefix, locations): + def on_query_completions(self, view, prefix, locations): words = [] # Limit number of views but always include the active view. This @@ -26,10 +26,19 @@ def on_query_completions(self, view, prefix, locations): views = views[0:MAX_VIEWS] for v in views: + print locations + + # Hacking around dash auto-completion bug + # https://github.com/alienhard/SublimeAllAutocomplete/issues/18 + #if len(locations) > 0 and v.id == view.id: + # view_words = v.extract_completions(prefix, locations[0]) + #else: + # view_words = v.extract_completions(prefix) if len(locations) > 0 and v.id == view.id: - view_words = v.extract_completions(prefix, locations[0]) + view_words = extract_completions_wdash(v,prefix,locations[0]) else: - view_words = v.extract_completions(prefix) + view_words = extract_completions_wdash(v,prefix); + view_words = filter_words(view_words) view_words = fix_truncation(v, view_words) words += view_words @@ -38,6 +47,18 @@ def on_query_completions(self, view, prefix, locations): matches = [(w, w.replace('$', '\\$')) for w in words] return matches +# extract auto-completions with dash +# see https://github.com/alienhard/SublimeAllAutocomplete/issues/18 +def extract_completions_wdash(v,prefix,location=0): + word_regions = v.find_all(prefix,0) + words = [] + + for wr in word_regions: + word = v.substr(v.word(wr)) + words.append(word) + + return words + 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] From fbf9bfc7af4b05dd9f22880dd57ca731faeb5ec3 Mon Sep 17 00:00:00 2001 From: Andrew Kondratev Date: Tue, 5 Nov 2013 17:31:52 +1300 Subject: [PATCH 02/10] removing redundant debugging stuff --- all_views_completions.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/all_views_completions.py b/all_views_completions.py index 666a16f..bbba26f 100644 --- a/all_views_completions.py +++ b/all_views_completions.py @@ -26,8 +26,6 @@ def on_query_completions(self, view, prefix, locations): views = views[0:MAX_VIEWS] for v in views: - print locations - # Hacking around dash auto-completion bug # https://github.com/alienhard/SublimeAllAutocomplete/issues/18 #if len(locations) > 0 and v.id == view.id: From a997292555737519fa9268942934305905e1f597 Mon Sep 17 00:00:00 2001 From: Andrew Kondratev Date: Wed, 6 Nov 2013 14:13:15 +1300 Subject: [PATCH 03/10] Adding settings to #18 hack, now you can choose to which sytaxes to apply this hack --- README.md | 12 ++++++++++++ all_views_completions.py | 31 +++++++++++++++++++++++-------- 2 files changed, 35 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index c29a52d..efa33b2 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,23 @@ All Autocomplete Sublime Text =========================================================== +This fork includes hack to fix sass and css dash-bug +https://github.com/alienhard/SublimeAllAutocomplete/issues/18 + Extends the default autocomplete to find matches in all open files. By default Sublime only considers words found in the current file. +Configure +--------- + +You can define settings "apply_with_dash_hack_syntaxes" in AllAutocomplete.sublime-settings to select to which sytaxes apply "-dash hack" + +You can also remove dash from "word_separators" option in syntax specific settings for CSS or SASS if you want to see all suggestions, +not only after pressing next dash. + + Install ------- diff --git a/all_views_completions.py b/all_views_completions.py index bbba26f..f9fd651 100644 --- a/all_views_completions.py +++ b/all_views_completions.py @@ -16,7 +16,13 @@ class AllAutocomplete(sublime_plugin.EventListener): - def on_query_completions(self, view, prefix, locations): + def __init__(self): + self.dash_hack_sytaxes = sublime.load_settings('AllAutocomplete.sublime-settings').get('apply_with_dash_hack_syntaxes') + if not self.dash_hack_sytaxes: + #using default settings + self.dash_hack_sytaxes = ["source.sass","source.css"] + + def on_query_completions(self, view, prefix, locations): words = [] # Limit number of views but always include the active view. This @@ -28,14 +34,17 @@ def on_query_completions(self, view, prefix, locations): for v in views: # Hacking around dash auto-completion bug # https://github.com/alienhard/SublimeAllAutocomplete/issues/18 - #if len(locations) > 0 and v.id == view.id: - # view_words = v.extract_completions(prefix, locations[0]) - #else: - # view_words = v.extract_completions(prefix) - if len(locations) > 0 and v.id == view.id: - view_words = extract_completions_wdash(v,prefix,locations[0]) + if is_need_to_be_hacked(v, self.dash_hack_sytaxes): + # apply hack for css and sass only + if len(locations) > 0 and v.id == view.id: + view_words = extract_completions_wdash(v,prefix,locations[0]) + else: + view_words = extract_completions_wdash(v,prefix); else: - view_words = extract_completions_wdash(v,prefix); + if len(locations) > 0 and v.id == view.id: + view_words = v.extract_completions(prefix, locations[0]) + else: + view_words = v.extract_completions(prefix) view_words = filter_words(view_words) view_words = fix_truncation(v, view_words) @@ -45,6 +54,12 @@ def on_query_completions(self, view, prefix, locations): matches = [(w, w.replace('$', '\\$')) for w in words] return matches +def is_need_to_be_hacked(v, dash_hack_sytaxes): + for syntax in dash_hack_sytaxes: + if v.scope_name(0).find(syntax) >= 0: + return True + return False + # extract auto-completions with dash # see https://github.com/alienhard/SublimeAllAutocomplete/issues/18 def extract_completions_wdash(v,prefix,location=0): From 5d7e2b1023937a73c41da1678da5bc50e099b96a Mon Sep 17 00:00:00 2001 From: Andrew Kondratev Date: Wed, 6 Nov 2013 14:14:05 +1300 Subject: [PATCH 04/10] Adding settings to #18 hack, now you can choose to which sytaxes to apply this hack --- AllAutocomplete.sublime-settings | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 AllAutocomplete.sublime-settings diff --git a/AllAutocomplete.sublime-settings b/AllAutocomplete.sublime-settings new file mode 100644 index 0000000..d45c917 --- /dev/null +++ b/AllAutocomplete.sublime-settings @@ -0,0 +1,3 @@ +{ + "apply_with_dash_hack_syntaxes": ["source.sass","source.css"] +} \ No newline at end of file From b2a84af98ac9a114a599e7adc79c05a009e33ced Mon Sep 17 00:00:00 2001 From: Andrew Kondratev Date: Wed, 6 Nov 2013 14:57:05 +1300 Subject: [PATCH 05/10] updating readme --- README.md | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index efa33b2..2bc849a 100644 --- a/README.md +++ b/README.md @@ -1,32 +1,39 @@ All Autocomplete Sublime Text =========================================================== -This fork includes hack to fix sass and css dash-bug -https://github.com/alienhard/SublimeAllAutocomplete/issues/18 - Extends the default autocomplete to find matches in all open files. By default Sublime only considers words found in the current file. +This is a fork of https://github.com/alienhard/SublimeAllAutocomplete/ -Configure ---------- - -You can define settings "apply_with_dash_hack_syntaxes" in AllAutocomplete.sublime-settings to select to which sytaxes apply "-dash hack" - -You can also remove dash from "word_separators" option in syntax specific settings for CSS or SASS if you want to see all suggestions, -not only after pressing next dash. +This fork includes hack to fix SASS and CSS dash bug +https://github.com/alienhard/SublimeAllAutocomplete/issues/18/ +http://sublimetext.userecho.com/topic/222861-/ Install ------- If you have Package Control installed in Sublime just press ctrl+shift+p (Windows, Linux) or cmd+shift+p (OS X) to open the Command Pallete. -Start typing 'install' to select 'Package Control: Install Package', then search for AllAutocomplete and select it. That's it. + +start typing "Package Control: Add Repository", press Enter and insert + https://github.com/andruhon/SublimeAllAutocomplete +press Enter, start typing "Package Control: Install Package", press Enter, start typing +"All Autocomplete" and select one with "https://github.com/andruhon/SublimeAllAutocomplete" URL You can also install this package manually by entering the Packages directory of Sublime Text 2/3 and issuing on a terminal: - git clone https://github.com/alienhard/SublimeAllAutocomplete + git clone https://github.com/andruhon/SublimeAllAutocomplete + + +Configure +--------- + +You can define settings "apply_with_dash_hack_syntaxes" in AllAutocomplete.sublime-settings to select to which sytaxes apply "-dash hack" + +You can also remove dash from "word_separators" option in syntax specific settings for CSS or SASS if you want to see all suggestions, +not only after pressing next dash. LICENSE From 72a0267bb7778ea96d3ca6851ee1ebb608fdd8d6 Mon Sep 17 00:00:00 2001 From: Andrew Kondratev Date: Wed, 6 Nov 2013 15:35:32 +1300 Subject: [PATCH 06/10] do not return suggestions on empty prefix (prevent from connflict with SublimeCodeIntel) --- AllAutocomplete.sublime-settings | 3 ++- all_views_completions.py | 23 ++++++++++++++++++----- 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/AllAutocomplete.sublime-settings b/AllAutocomplete.sublime-settings index d45c917..4808d61 100644 --- a/AllAutocomplete.sublime-settings +++ b/AllAutocomplete.sublime-settings @@ -1,3 +1,4 @@ { - "apply_with_dash_hack_syntaxes": ["source.sass","source.css"] + "apply_with_dash_hack_syntaxes": ["source.sass","source.css"], + "return_nothing_on_empty_prefix": true } \ No newline at end of file diff --git a/all_views_completions.py b/all_views_completions.py index f9fd651..2b76183 100644 --- a/all_views_completions.py +++ b/all_views_completions.py @@ -16,13 +16,22 @@ class AllAutocomplete(sublime_plugin.EventListener): + #default settings + dash_hack_sytaxes = ["source.sass","source.css"] + return_nothing_on_empty = True + def __init__(self): - self.dash_hack_sytaxes = sublime.load_settings('AllAutocomplete.sublime-settings').get('apply_with_dash_hack_syntaxes') - if not self.dash_hack_sytaxes: - #using default settings - self.dash_hack_sytaxes = ["source.sass","source.css"] + dash_hack_sytaxes = sublime.load_settings('AllAutocomplete.sublime-settings').get('apply_with_dash_hack_syntaxes') + return_nothing_on_empty = sublime.load_settings('AllAutocomplete.sublime-settings').get('return_nothing_on_empty_prefix') + + #using default settings + if dash_hack_sytaxes != None: + self.dash_hack_sytaxes = dash_hack_sytaxes + + if return_nothing_on_empty != None: + self.return_nothing_on_empty = return_nothing_on_empty - def on_query_completions(self, view, prefix, locations): + def on_query_completions(self, view, prefix, locations): words = [] # Limit number of views but always include the active view. This @@ -31,6 +40,10 @@ def on_query_completions(self, view, prefix, locations): views = [view] + other_views views = views[0:MAX_VIEWS] + if self.return_nothing_on_empty: + if not prefix: + return words; + for v in views: # Hacking around dash auto-completion bug # https://github.com/alienhard/SublimeAllAutocomplete/issues/18 From acbc706905a26f4bfda746042717c354224746a6 Mon Sep 17 00:00:00 2001 From: Andrew Kondratev Date: Wed, 6 Nov 2013 16:14:00 +1300 Subject: [PATCH 07/10] new do_not_search_in_current_view option --- AllAutocomplete.sublime-settings | 3 ++- all_views_completions.py | 31 ++++++++++++++++++++----------- 2 files changed, 22 insertions(+), 12 deletions(-) diff --git a/AllAutocomplete.sublime-settings b/AllAutocomplete.sublime-settings index 4808d61..c18df59 100644 --- a/AllAutocomplete.sublime-settings +++ b/AllAutocomplete.sublime-settings @@ -1,4 +1,5 @@ { "apply_with_dash_hack_syntaxes": ["source.sass","source.css"], - "return_nothing_on_empty_prefix": true + "return_nothing_on_empty_prefix": true, + "do_not_search_in_current_view": false } \ No newline at end of file diff --git a/all_views_completions.py b/all_views_completions.py index 2b76183..72194ba 100644 --- a/all_views_completions.py +++ b/all_views_completions.py @@ -19,10 +19,12 @@ class AllAutocomplete(sublime_plugin.EventListener): #default settings dash_hack_sytaxes = ["source.sass","source.css"] return_nothing_on_empty = True + not_search_in_current = True def __init__(self): dash_hack_sytaxes = sublime.load_settings('AllAutocomplete.sublime-settings').get('apply_with_dash_hack_syntaxes') return_nothing_on_empty = sublime.load_settings('AllAutocomplete.sublime-settings').get('return_nothing_on_empty_prefix') + not_search_in_current = sublime.load_settings('do_not_search_in_current_view').get('return_nothing_on_empty_prefix') #using default settings if dash_hack_sytaxes != None: @@ -31,7 +33,10 @@ def __init__(self): if return_nothing_on_empty != None: self.return_nothing_on_empty = return_nothing_on_empty - def on_query_completions(self, view, prefix, locations): + if not_search_in_current != None: + self.not_search_in_current = not_search_in_current + + def on_query_completions(self, view, prefix, locations): words = [] # Limit number of views but always include the active view. This @@ -45,19 +50,23 @@ def on_query_completions(self, view, prefix, locations): return words; for v in views: + view_words = [] + location = 0 # Hacking around dash auto-completion bug # https://github.com/alienhard/SublimeAllAutocomplete/issues/18 + + # Sublime probably already works fine with suggestions from current view + if self.not_search_in_current and v.id == view.id: + continue + + if len(locations) > 0 and v.id == view.id: + location = locations[0] + if is_need_to_be_hacked(v, self.dash_hack_sytaxes): # apply hack for css and sass only - if len(locations) > 0 and v.id == view.id: - view_words = extract_completions_wdash(v,prefix,locations[0]) - else: - view_words = extract_completions_wdash(v,prefix); - else: - if len(locations) > 0 and v.id == view.id: - view_words = v.extract_completions(prefix, locations[0]) - else: - view_words = v.extract_completions(prefix) + view_words = extract_completions_wdash(v,prefix); + else: + view_words = v.extract_completions(prefix, location) view_words = filter_words(view_words) view_words = fix_truncation(v, view_words) @@ -75,7 +84,7 @@ def is_need_to_be_hacked(v, dash_hack_sytaxes): # extract auto-completions with dash # see https://github.com/alienhard/SublimeAllAutocomplete/issues/18 -def extract_completions_wdash(v,prefix,location=0): +def extract_completions_wdash(v,prefix): word_regions = v.find_all(prefix,0) words = [] From 5537faa98176a5fd7640115aea670b0c57472f89 Mon Sep 17 00:00:00 2001 From: Andrew Kondratev Date: Sun, 2 Mar 2014 11:28:48 +1300 Subject: [PATCH 08/10] Adding debugging version --- README.md | 10 ++ all_views_completions.py.debug | 164 +++++++++++++++++++++++++++++++++ 2 files changed, 174 insertions(+) create mode 100644 all_views_completions.py.debug diff --git a/README.md b/README.md index 2bc849a..c191808 100644 --- a/README.md +++ b/README.md @@ -35,6 +35,16 @@ You can define settings "apply_with_dash_hack_syntaxes" in AllAutocomplete.subli You can also remove dash from "word_separators" option in syntax specific settings for CSS or SASS if you want to see all suggestions, not only after pressing next dash. +DEBUGGING +--------- +1. Uninstall plugin installed via package manager; +2. Clone (or unpack archive) plugin into your Packages directory; +3. rename all_views_completions.py to all_views_completions.py.ver, and all_views_completions.py.debug to all_views_completions.py; +4. restart sublime and run console (view->show console or ctrl+`); +5. Try using autocompletion, see what's in console. + +Good luck! + LICENSE ------- diff --git a/all_views_completions.py.debug b/all_views_completions.py.debug new file mode 100644 index 0000000..5a69dd4 --- /dev/null +++ b/all_views_completions.py.debug @@ -0,0 +1,164 @@ +# 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 + +# limits to prevent bogging down the system +MIN_WORD_SIZE = 3 +MAX_WORD_SIZE = 30 + +MAX_VIEWS = 20 +MAX_WORDS_PER_VIEW = 100 +MAX_FIX_TIME_SECS_PER_VIEW = 0.01 + +class AllAutocomplete(sublime_plugin.EventListener): + + #default settings + dash_hack_sytaxes = ["source.sass","source.css"] + return_nothing_on_empty = True + not_search_in_current = True + + def __init__(self): + print("initializing SublimeAllAutocomplete(SAA) plugin") + dash_hack_sytaxes = sublime.load_settings('AllAutocomplete.sublime-settings').get('apply_with_dash_hack_syntaxes') + return_nothing_on_empty = sublime.load_settings('AllAutocomplete.sublime-settings').get('return_nothing_on_empty_prefix') + not_search_in_current = sublime.load_settings('do_not_search_in_current_view').get('return_nothing_on_empty_prefix') + print("SAA: user settings:\n dash_hack_sytaxes:{0}\n return_nothing_on_empty:{1}\n not_search_in_current:{2}".format(dash_hack_sytaxes,return_nothing_on_empty,not_search_in_current)) + + #using default settings + if dash_hack_sytaxes != None: + self.dash_hack_sytaxes = dash_hack_sytaxes + + if return_nothing_on_empty != None: + self.return_nothing_on_empty = return_nothing_on_empty + + if not_search_in_current != None: + self.not_search_in_current = not_search_in_current + + print("SAA: Merged settings:\n dash_hack_sytaxes:{0}\n return_nothing_on_empty:{1}\n not_search_in_current:{2}".format(self.dash_hack_sytaxes,self.return_nothing_on_empty,self.not_search_in_current)) + + def on_query_completions(self, view, prefix, locations): + print("SAA: running completion query '{0}'".format(prefix)) + 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 v.id != view.id] + views = [view] + other_views + views = views[0:MAX_VIEWS] + print("SAA: views to process {0}".format(views)) + + if self.return_nothing_on_empty: + if not prefix: + print("SAA: returning nothing on empty query") + return words; + + for v in views: + view_words = [] + location = 0 + # Hacking around dash auto-completion bug + # https://github.com/alienhard/SublimeAllAutocomplete/issues/18 + + # Sublime probably already works fine with suggestions from current view + if self.not_search_in_current and v.id == view.id: + continue + + if len(locations) > 0 and v.id == view.id: + location = locations[0] + + if is_need_to_be_hacked(v, self.dash_hack_sytaxes): + # apply hack for css and sass only + view_words = extract_completions_wdash(v,prefix); + else: + view_words = v.extract_completions(prefix, location) + + view_words = filter_words(view_words) + view_words = fix_truncation(v, view_words) + words += view_words + + words = without_duplicates(words) + print("SAA: {0} words found".format(len(words))) + + matches = [(w, w.replace('$', '\\$')) for w in words] + return matches + +def is_need_to_be_hacked(v, dash_hack_sytaxes): + for syntax in dash_hack_sytaxes: + if v.scope_name(0).find(syntax) >= 0: + return True + return False + +# extract auto-completions with dash +# see https://github.com/alienhard/SublimeAllAutocomplete/issues/18 +def extract_completions_wdash(v,prefix): + print("SAA: extracting words with dashes") + word_regions = v.find_all(prefix,0) + words = [] + + for wr in word_regions: + word = v.substr(v.word(wr)) + words.append(word) + + print("SAA: {0} dash-words found".format(len(words))) + + return words + +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): + print("SAA: cleaning duplicates") + result = [] + for w in words: + if w not in result: + result.append(w) + return result + + +# Ugly workaround for truncation bug in Sublime when using view.extract_completions() +# in some types of files. +def fix_truncation(view, words): + print("SAA: fixing turncation") + 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 + else: + # to compensate for the missing match problem mentioned above, just + # use the old word if we didn't find any extended matches + fixed_words.append(w) + else: + #Pass through non-truncated words + fixed_words.append(w) + + # 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() +else: + def is_empty_match(match): + return match is None From 44e27795cf854d6fe5b9dd9ecb2832ef4db9b56b Mon Sep 17 00:00:00 2001 From: Andrew Kondratev Date: Mon, 3 Mar 2014 16:12:49 +1300 Subject: [PATCH 09/10] settings in context menu, fixing settings loading --- Main.sublime-menu | 34 ++++ README.md | 21 +-- SublimeAllAutocomplete.py | 172 ++++++++++++++++++ ...=> SublimeAllAutocomplete.sublime-settings | 2 +- all_views_completions.py | 150 --------------- all_views_completions.py.debug | 164 ----------------- 6 files changed, 216 insertions(+), 327 deletions(-) create mode 100644 Main.sublime-menu create mode 100644 SublimeAllAutocomplete.py rename AllAutocomplete.sublime-settings => SublimeAllAutocomplete.sublime-settings (51%) delete mode 100644 all_views_completions.py delete mode 100644 all_views_completions.py.debug diff --git a/Main.sublime-menu b/Main.sublime-menu new file mode 100644 index 0000000..6f1bdab --- /dev/null +++ b/Main.sublime-menu @@ -0,0 +1,34 @@ +[ + { + "caption": "Preferences", + "mnemonic": "n", + "id": "preferences", + "children": + [ + { + "caption": "Package Settings", + "mnemonic": "P", + "id": "package-settings", + "children": + [ + { + "caption": "SublimeAllAutocomplete", + "children": + [ + { + "command": "open_file", + "args": {"file": "${packages}/SublimeAllAutocomplete/SublimeAllAutocomplete.sublime-settings"}, + "caption": "Settings – Default" + }, + { + "command": "open_file", + "args": {"file": "${packages}/User/SublimeAllAutocomplete.sublime-settings"}, + "caption": "Settings – User" + } + ] + } + ] + } + ] + } +] diff --git a/README.md b/README.md index c191808..89b6d65 100644 --- a/README.md +++ b/README.md @@ -30,20 +30,17 @@ You can also install this package manually by entering the Packages directory of Configure --------- -You can define settings "apply_with_dash_hack_syntaxes" in AllAutocomplete.sublime-settings to select to which sytaxes apply "-dash hack" +Available options (with default values): +{ + "apply_with_dash_hack_syntaxes": ["source.sass","source.css"], + "return_nothing_on_empty_prefix": true, + "do_not_search_in_current_view": false +} -You can also remove dash from "word_separators" option in syntax specific settings for CSS or SASS if you want to see all suggestions, -not only after pressing next dash. - -DEBUGGING ---------- -1. Uninstall plugin installed via package manager; -2. Clone (or unpack archive) plugin into your Packages directory; -3. rename all_views_completions.py to all_views_completions.py.ver, and all_views_completions.py.debug to all_views_completions.py; -4. restart sublime and run console (view->show console or ctrl+`); -5. Try using autocompletion, see what's in console. +You can override this settings in user AllAutocomplete.sublime-settings (preferences->package settings->SublimeAllAutoComplete->Settings-User) -Good luck! +You can also remove dash from "word_separators" option in syntax specific settings for CSS or SASS if you want to see all suggestions, +not only after pressing next dash. (Settings-More->Syntax Specific-User, when file of particular syntax is open) LICENSE diff --git a/SublimeAllAutocomplete.py b/SublimeAllAutocomplete.py new file mode 100644 index 0000000..6b7c633 --- /dev/null +++ b/SublimeAllAutocomplete.py @@ -0,0 +1,172 @@ +# 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 + +# limits to prevent bogging down the system +MIN_WORD_SIZE = 3 +MAX_WORD_SIZE = 30 + +MAX_VIEWS = 20 +MAX_WORDS_PER_VIEW = 100 +MAX_FIX_TIME_SECS_PER_VIEW = 0.01 + +#Change this variable to True to se debug output +DEBUG = True + +class SubLimeallautocomplete(sublime_plugin.EventListener): + #default settings + dash_hack_sytaxes = ["source.scss","source.sass","source.css"] + return_nothing_on_empty = True + not_search_in_current = True + + def __init__(self): + if DEBUG: print("initializing Sublimeallautocomplete(SAA) plugin") + + #Loading settings when view is activated + def on_activated(self,view): + if DEBUG: print("\nActivating SAA for view",view) + self.plugin_settings = sublime.load_settings('SublimeAllAutocomplete.sublime-settings') + + dash_hack_sytaxes = self.plugin_settings.get('apply_with_dash_hack_syntaxes') + return_nothing_on_empty = self.plugin_settings.get('return_nothing_on_empty_prefix') + not_search_in_current = self.plugin_settings.get('do_not_search_in_current_view') + if DEBUG: print("SAA: user settings:\n dash_hack_sytaxes:{0}\n return_nothing_on_empty:{1}\n not_search_in_current:{2}".format(dash_hack_sytaxes,return_nothing_on_empty,not_search_in_current)) + + #using default settings + if dash_hack_sytaxes != None: + self.dash_hack_sytaxes = dash_hack_sytaxes + + if return_nothing_on_empty != None: + self.return_nothing_on_empty = return_nothing_on_empty + + if not_search_in_current != None: + self.not_search_in_current = not_search_in_current + + if DEBUG: print("SAA: Merged settings:\n dash_hack_sytaxes:{0}\n return_nothing_on_empty:{1}\n not_search_in_current:{2}\n".format(self.dash_hack_sytaxes,self.return_nothing_on_empty,self.not_search_in_current)) + + def on_query_completions(self, view, prefix, locations): + + if DEBUG: print("SAA: running completion query '{0}'".format(prefix)) + 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 v.id != view.id] + views = [view] + other_views + views = views[0:MAX_VIEWS] + if DEBUG: print("SAA: views to process {0}".format(views)) + + if self.return_nothing_on_empty: + if not prefix: + if DEBUG: print("SAA: returning nothing on empty query") + return words; + + for v in views: + view_words = [] + location = 0 + # Hacking around dash auto-completion bug + # https://github.com/alienhard/Sublimeallautocomplete/issues/18 + + # Sublime probably already works fine with suggestions from current view + if self.not_search_in_current and v.id == view.id: + continue + + if len(locations) > 0 and v.id == view.id: + location = locations[0] + + if self.is_need_to_be_hacked(v, self.dash_hack_sytaxes): + # apply hack for css and sass only + view_words = self.extract_completions_wdash(v,prefix); + else: + view_words = v.extract_completions(prefix, location) + + view_words = self.filter_words(view_words) + view_words = self.fix_truncation(v, view_words) + words += view_words + + words = self.without_duplicates(words) + if DEBUG: print("SAA: {0} words found".format(len(words))) + + matches = [(w, w.replace('$', '\\$')) for w in words] + return matches + + def is_need_to_be_hacked(self, v, dash_hack_sytaxes): + for syntax in dash_hack_sytaxes: + if v.scope_name(0).find(syntax) >= 0: + return True + return False + + # extract auto-completions with dash + # see https://github.com/alienhard/Sublimeallautocomplete/issues/18 + def extract_completions_wdash(self, v,prefix): + if DEBUG: print("SAA: extracting words with dashes") + word_regions = v.find_all(prefix,0) + words = [] + + for wr in word_regions: + word = v.substr(v.word(wr)) + words.append(word) + + if DEBUG: print("SAA: {0} dash-words found".format(len(words))) + + return words + + def filter_words(self, 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(self, words): + if DEBUG: print("SAA: cleaning duplicates") + result = [] + for w in words: + if w not in result: + result.append(w) + return result + + + # Ugly workaround for truncation bug in Sublime when using view.extract_completions() + # in some types of files. + def fix_truncation(self, view, words): + if DEBUG: print("SAA: fixing turncation") + 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 = self.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 + else: + # to compensate for the missing match problem mentioned above, just + # use the old word if we didn't find any extended matches + fixed_words.append(w) + else: + #Pass through non-truncated words + fixed_words.append(w) + + # 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 + + def is_empty_match(self, match): + if sublime.version() >= '3000': + return match.empty() + else: + return match is None \ No newline at end of file diff --git a/AllAutocomplete.sublime-settings b/SublimeAllAutocomplete.sublime-settings similarity index 51% rename from AllAutocomplete.sublime-settings rename to SublimeAllAutocomplete.sublime-settings index c18df59..05f3a4c 100644 --- a/AllAutocomplete.sublime-settings +++ b/SublimeAllAutocomplete.sublime-settings @@ -1,5 +1,5 @@ { - "apply_with_dash_hack_syntaxes": ["source.sass","source.css"], + "apply_with_dash_hack_syntaxes": ["source.scss","source.sass","source.css"], "return_nothing_on_empty_prefix": true, "do_not_search_in_current_view": false } \ No newline at end of file diff --git a/all_views_completions.py b/all_views_completions.py deleted file mode 100644 index 72194ba..0000000 --- a/all_views_completions.py +++ /dev/null @@ -1,150 +0,0 @@ -# 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 - -# limits to prevent bogging down the system -MIN_WORD_SIZE = 3 -MAX_WORD_SIZE = 30 - -MAX_VIEWS = 20 -MAX_WORDS_PER_VIEW = 100 -MAX_FIX_TIME_SECS_PER_VIEW = 0.01 - -class AllAutocomplete(sublime_plugin.EventListener): - - #default settings - dash_hack_sytaxes = ["source.sass","source.css"] - return_nothing_on_empty = True - not_search_in_current = True - - def __init__(self): - dash_hack_sytaxes = sublime.load_settings('AllAutocomplete.sublime-settings').get('apply_with_dash_hack_syntaxes') - return_nothing_on_empty = sublime.load_settings('AllAutocomplete.sublime-settings').get('return_nothing_on_empty_prefix') - not_search_in_current = sublime.load_settings('do_not_search_in_current_view').get('return_nothing_on_empty_prefix') - - #using default settings - if dash_hack_sytaxes != None: - self.dash_hack_sytaxes = dash_hack_sytaxes - - if return_nothing_on_empty != None: - self.return_nothing_on_empty = return_nothing_on_empty - - if not_search_in_current != None: - self.not_search_in_current = not_search_in_current - - def on_query_completions(self, view, prefix, locations): - 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 v.id != view.id] - views = [view] + other_views - views = views[0:MAX_VIEWS] - - if self.return_nothing_on_empty: - if not prefix: - return words; - - for v in views: - view_words = [] - location = 0 - # Hacking around dash auto-completion bug - # https://github.com/alienhard/SublimeAllAutocomplete/issues/18 - - # Sublime probably already works fine with suggestions from current view - if self.not_search_in_current and v.id == view.id: - continue - - if len(locations) > 0 and v.id == view.id: - location = locations[0] - - if is_need_to_be_hacked(v, self.dash_hack_sytaxes): - # apply hack for css and sass only - view_words = extract_completions_wdash(v,prefix); - else: - view_words = v.extract_completions(prefix, location) - - view_words = filter_words(view_words) - view_words = fix_truncation(v, view_words) - words += view_words - - words = without_duplicates(words) - matches = [(w, w.replace('$', '\\$')) for w in words] - return matches - -def is_need_to_be_hacked(v, dash_hack_sytaxes): - for syntax in dash_hack_sytaxes: - if v.scope_name(0).find(syntax) >= 0: - return True - return False - -# extract auto-completions with dash -# see https://github.com/alienhard/SublimeAllAutocomplete/issues/18 -def extract_completions_wdash(v,prefix): - word_regions = v.find_all(prefix,0) - words = [] - - for wr in word_regions: - word = v.substr(v.word(wr)) - words.append(word) - - return words - -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 = [] - for w in words: - if w not in result: - result.append(w) - 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 - else: - # to compensate for the missing match problem mentioned above, just - # use the old word if we didn't find any extended matches - fixed_words.append(w) - else: - #Pass through non-truncated words - fixed_words.append(w) - - # 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() -else: - def is_empty_match(match): - return match is None diff --git a/all_views_completions.py.debug b/all_views_completions.py.debug deleted file mode 100644 index 5a69dd4..0000000 --- a/all_views_completions.py.debug +++ /dev/null @@ -1,164 +0,0 @@ -# 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 - -# limits to prevent bogging down the system -MIN_WORD_SIZE = 3 -MAX_WORD_SIZE = 30 - -MAX_VIEWS = 20 -MAX_WORDS_PER_VIEW = 100 -MAX_FIX_TIME_SECS_PER_VIEW = 0.01 - -class AllAutocomplete(sublime_plugin.EventListener): - - #default settings - dash_hack_sytaxes = ["source.sass","source.css"] - return_nothing_on_empty = True - not_search_in_current = True - - def __init__(self): - print("initializing SublimeAllAutocomplete(SAA) plugin") - dash_hack_sytaxes = sublime.load_settings('AllAutocomplete.sublime-settings').get('apply_with_dash_hack_syntaxes') - return_nothing_on_empty = sublime.load_settings('AllAutocomplete.sublime-settings').get('return_nothing_on_empty_prefix') - not_search_in_current = sublime.load_settings('do_not_search_in_current_view').get('return_nothing_on_empty_prefix') - print("SAA: user settings:\n dash_hack_sytaxes:{0}\n return_nothing_on_empty:{1}\n not_search_in_current:{2}".format(dash_hack_sytaxes,return_nothing_on_empty,not_search_in_current)) - - #using default settings - if dash_hack_sytaxes != None: - self.dash_hack_sytaxes = dash_hack_sytaxes - - if return_nothing_on_empty != None: - self.return_nothing_on_empty = return_nothing_on_empty - - if not_search_in_current != None: - self.not_search_in_current = not_search_in_current - - print("SAA: Merged settings:\n dash_hack_sytaxes:{0}\n return_nothing_on_empty:{1}\n not_search_in_current:{2}".format(self.dash_hack_sytaxes,self.return_nothing_on_empty,self.not_search_in_current)) - - def on_query_completions(self, view, prefix, locations): - print("SAA: running completion query '{0}'".format(prefix)) - 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 v.id != view.id] - views = [view] + other_views - views = views[0:MAX_VIEWS] - print("SAA: views to process {0}".format(views)) - - if self.return_nothing_on_empty: - if not prefix: - print("SAA: returning nothing on empty query") - return words; - - for v in views: - view_words = [] - location = 0 - # Hacking around dash auto-completion bug - # https://github.com/alienhard/SublimeAllAutocomplete/issues/18 - - # Sublime probably already works fine with suggestions from current view - if self.not_search_in_current and v.id == view.id: - continue - - if len(locations) > 0 and v.id == view.id: - location = locations[0] - - if is_need_to_be_hacked(v, self.dash_hack_sytaxes): - # apply hack for css and sass only - view_words = extract_completions_wdash(v,prefix); - else: - view_words = v.extract_completions(prefix, location) - - view_words = filter_words(view_words) - view_words = fix_truncation(v, view_words) - words += view_words - - words = without_duplicates(words) - print("SAA: {0} words found".format(len(words))) - - matches = [(w, w.replace('$', '\\$')) for w in words] - return matches - -def is_need_to_be_hacked(v, dash_hack_sytaxes): - for syntax in dash_hack_sytaxes: - if v.scope_name(0).find(syntax) >= 0: - return True - return False - -# extract auto-completions with dash -# see https://github.com/alienhard/SublimeAllAutocomplete/issues/18 -def extract_completions_wdash(v,prefix): - print("SAA: extracting words with dashes") - word_regions = v.find_all(prefix,0) - words = [] - - for wr in word_regions: - word = v.substr(v.word(wr)) - words.append(word) - - print("SAA: {0} dash-words found".format(len(words))) - - return words - -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): - print("SAA: cleaning duplicates") - result = [] - for w in words: - if w not in result: - result.append(w) - return result - - -# Ugly workaround for truncation bug in Sublime when using view.extract_completions() -# in some types of files. -def fix_truncation(view, words): - print("SAA: fixing turncation") - 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 - else: - # to compensate for the missing match problem mentioned above, just - # use the old word if we didn't find any extended matches - fixed_words.append(w) - else: - #Pass through non-truncated words - fixed_words.append(w) - - # 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() -else: - def is_empty_match(match): - return match is None From b1d19a116a8fbc1d646a282b89b7fb22b0b652d8 Mon Sep 17 00:00:00 2001 From: Andrew Kondratev Date: Mon, 3 Mar 2014 16:16:27 +1300 Subject: [PATCH 10/10] Disable debug mode --- SublimeAllAutocomplete.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/SublimeAllAutocomplete.py b/SublimeAllAutocomplete.py index 6b7c633..c8dec10 100644 --- a/SublimeAllAutocomplete.py +++ b/SublimeAllAutocomplete.py @@ -15,7 +15,7 @@ MAX_FIX_TIME_SECS_PER_VIEW = 0.01 #Change this variable to True to se debug output -DEBUG = True +DEBUG = False class SubLimeallautocomplete(sublime_plugin.EventListener): #default settings @@ -169,4 +169,4 @@ def is_empty_match(self, match): if sublime.version() >= '3000': return match.empty() else: - return match is None \ No newline at end of file + return match is None