From 302ae0bc0461da4ce174c6165ac0f875994ecbd7 Mon Sep 17 00:00:00 2001 From: Jeff Booher Date: Mon, 7 Apr 2014 15:17:07 -0700 Subject: [PATCH 1/6] add fuzzy code hint searching --- src/extensions/default/CSSCodeHints/main.js | 52 +++++++++++++++++++-- 1 file changed, 48 insertions(+), 4 deletions(-) diff --git a/src/extensions/default/CSSCodeHints/main.js b/src/extensions/default/CSSCodeHints/main.js index 63df241fdad..383d62af6fb 100644 --- a/src/extensions/default/CSSCodeHints/main.js +++ b/src/extensions/default/CSSCodeHints/main.js @@ -33,13 +33,19 @@ define(function (require, exports, module) { HTMLUtils = brackets.getModule("language/HTMLUtils"), LanguageManager = brackets.getModule("language/LanguageManager"), TokenUtils = brackets.getModule("utils/TokenUtils"), + StringMatch = brackets.getModule("utils/StringMatch"), + PreferencesManager = brackets.getModule("preferences/PreferencesManager"), CSSProperties = require("text!CSSProperties.json"), properties = JSON.parse(CSSProperties); // Context of the last request for hints: either CSSUtils.PROP_NAME, // CSSUtils.PROP_VALUE or null. - var lastContext; + var lastContext, + matcher = null, // string matcher for hints + prefs = PreferencesManager.getExtensionPrefs("CSSCodeHints"); + prefs.definePreference("fuzzy-matching", "boolean", true); + /** * @constructor */ @@ -49,6 +55,33 @@ define(function (require, exports, module) { this.exclusion = null; } + /** + * Returns the preferences used to add/remove the menu items + * @return {{fuzzyMatching: boolean}} + */ + function getPreferences() { + // It's senseless to look prefs up for the current file, instead look them up for + // the current project (or globally) + return { + fuzzyMatching : prefs.get("fuzzy-matching", PreferencesManager.CURRENT_PROJECT) + }; + } + + /** + * Create a new StringMatcher instance, if needed. + * + * @return {StringMatcher} - a StringMatcher instance. + */ + function getStringMatcher() { + if (!matcher) { + matcher = new StringMatch.StringMatcher({ + preferPrefixMatches: false + }); + } + + return matcher; + } + /** * Get the CSS style text of the file open in the editor for this hinting session. * For a CSS file, this is just the text of the file. For an HTML file, @@ -206,7 +239,9 @@ define(function (require, exports, module) { valueArray, namedFlows, result, - selectInitial = false; + selectInitial = false, + matcher = getStringMatcher(), + useFuzzyMatching = getPreferences().fuzzyMatching; // Clear the exclusion if the user moves the cursor with left/right arrow key. @@ -249,7 +284,11 @@ define(function (require, exports, module) { } result = $.map(valueArray, function (pvalue, pindex) { - if (pvalue.indexOf(valueNeedle) === 0) { + if (!useFuzzyMatching) { + if (pvalue.indexOf(needle) === 0) { + return pvalue; + } + } else if (matcher.match(pvalue, needle)) { return pvalue; } }).sort(); @@ -269,9 +308,14 @@ define(function (require, exports, module) { lastContext = CSSUtils.PROP_NAME; needle = needle.substr(0, this.info.offset); result = $.map(properties, function (pvalues, pname) { - if (pname.indexOf(needle) === 0) { + if (!useFuzzyMatching) { + if (pname.indexOf(needle) === 0) { + return pname; + } + } else if (matcher.match(pname, needle)) { return pname; } + }).sort(); return { From 6d638b2049d6e88cacbc7e0c4b2ba8fa3ca3c6f9 Mon Sep 17 00:00:00 2001 From: Jeff Booher Date: Mon, 7 Apr 2014 15:23:47 -0700 Subject: [PATCH 2/6] fix css value hints --- src/extensions/default/CSSCodeHints/main.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/extensions/default/CSSCodeHints/main.js b/src/extensions/default/CSSCodeHints/main.js index 383d62af6fb..dd2b3a59518 100644 --- a/src/extensions/default/CSSCodeHints/main.js +++ b/src/extensions/default/CSSCodeHints/main.js @@ -285,10 +285,10 @@ define(function (require, exports, module) { result = $.map(valueArray, function (pvalue, pindex) { if (!useFuzzyMatching) { - if (pvalue.indexOf(needle) === 0) { + if (pvalue.indexOf(valueNeedle) === 0) { return pvalue; } - } else if (matcher.match(pvalue, needle)) { + } else if (matcher.match(pvalue, valueNeedle)) { return pvalue; } }).sort(); From 1d03eacdd1a9be8a9ee261418adc929de47d0d9c Mon Sep 17 00:00:00 2001 From: Jeff Booher Date: Tue, 22 Apr 2014 12:55:11 -0700 Subject: [PATCH 3/6] rtc: remove pref lever and don't retain state between matches --- src/extensions/default/CSSCodeHints/main.js | 49 ++------------------- 1 file changed, 4 insertions(+), 45 deletions(-) diff --git a/src/extensions/default/CSSCodeHints/main.js b/src/extensions/default/CSSCodeHints/main.js index dd2b3a59518..7d050c44af7 100644 --- a/src/extensions/default/CSSCodeHints/main.js +++ b/src/extensions/default/CSSCodeHints/main.js @@ -41,11 +41,8 @@ define(function (require, exports, module) { // Context of the last request for hints: either CSSUtils.PROP_NAME, // CSSUtils.PROP_VALUE or null. var lastContext, - matcher = null, // string matcher for hints - prefs = PreferencesManager.getExtensionPrefs("CSSCodeHints"); + stringMatcherOptions = { preferPrefixMatches: true }; - prefs.definePreference("fuzzy-matching", "boolean", true); - /** * @constructor */ @@ -55,33 +52,6 @@ define(function (require, exports, module) { this.exclusion = null; } - /** - * Returns the preferences used to add/remove the menu items - * @return {{fuzzyMatching: boolean}} - */ - function getPreferences() { - // It's senseless to look prefs up for the current file, instead look them up for - // the current project (or globally) - return { - fuzzyMatching : prefs.get("fuzzy-matching", PreferencesManager.CURRENT_PROJECT) - }; - } - - /** - * Create a new StringMatcher instance, if needed. - * - * @return {StringMatcher} - a StringMatcher instance. - */ - function getStringMatcher() { - if (!matcher) { - matcher = new StringMatch.StringMatcher({ - preferPrefixMatches: false - }); - } - - return matcher; - } - /** * Get the CSS style text of the file open in the editor for this hinting session. * For a CSS file, this is just the text of the file. For an HTML file, @@ -239,9 +209,7 @@ define(function (require, exports, module) { valueArray, namedFlows, result, - selectInitial = false, - matcher = getStringMatcher(), - useFuzzyMatching = getPreferences().fuzzyMatching; + selectInitial = false; // Clear the exclusion if the user moves the cursor with left/right arrow key. @@ -284,11 +252,7 @@ define(function (require, exports, module) { } result = $.map(valueArray, function (pvalue, pindex) { - if (!useFuzzyMatching) { - if (pvalue.indexOf(valueNeedle) === 0) { - return pvalue; - } - } else if (matcher.match(pvalue, valueNeedle)) { + if (StringMatch.stringMatch(pvalue, valueNeedle, stringMatcherOptions)) { return pvalue; } }).sort(); @@ -308,14 +272,9 @@ define(function (require, exports, module) { lastContext = CSSUtils.PROP_NAME; needle = needle.substr(0, this.info.offset); result = $.map(properties, function (pvalues, pname) { - if (!useFuzzyMatching) { - if (pname.indexOf(needle) === 0) { - return pname; - } - } else if (matcher.match(pname, needle)) { + if (StringMatch.stringMatch(pname, needle, stringMatcherOptions)) { return pname; } - }).sort(); return { From ec4e752300eacb26238a8a7c7d24bb1be2cd9fe1 Mon Sep 17 00:00:00 2001 From: Jeff Booher Date: Wed, 23 Apr 2014 17:29:13 -0700 Subject: [PATCH 4/6] remove unnecessary module --- src/extensions/default/CSSCodeHints/main.js | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/extensions/default/CSSCodeHints/main.js b/src/extensions/default/CSSCodeHints/main.js index 7d050c44af7..38722325a43 100644 --- a/src/extensions/default/CSSCodeHints/main.js +++ b/src/extensions/default/CSSCodeHints/main.js @@ -34,7 +34,6 @@ define(function (require, exports, module) { LanguageManager = brackets.getModule("language/LanguageManager"), TokenUtils = brackets.getModule("utils/TokenUtils"), StringMatch = brackets.getModule("utils/StringMatch"), - PreferencesManager = brackets.getModule("preferences/PreferencesManager"), CSSProperties = require("text!CSSProperties.json"), properties = JSON.parse(CSSProperties); @@ -255,7 +254,9 @@ define(function (require, exports, module) { if (StringMatch.stringMatch(pvalue, valueNeedle, stringMatcherOptions)) { return pvalue; } - }).sort(); + }); + + var newResult = StringMatch.basicMatchSort(result); return { hints: result, @@ -275,7 +276,9 @@ define(function (require, exports, module) { if (StringMatch.stringMatch(pname, needle, stringMatcherOptions)) { return pname; } - }).sort(); + }); + + var newResult = StringMatch.basicMatchSort(result); return { hints: result, From ac809b01898ab38b9e83f1c76e216e5b93f650b1 Mon Sep 17 00:00:00 2001 From: Jeff Booher Date: Thu, 24 Apr 2014 09:14:16 -0700 Subject: [PATCH 5/6] better match sorting --- src/extensions/default/CSSCodeHints/main.js | 23 +++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/src/extensions/default/CSSCodeHints/main.js b/src/extensions/default/CSSCodeHints/main.js index 38722325a43..f0eba703bad 100644 --- a/src/extensions/default/CSSCodeHints/main.js +++ b/src/extensions/default/CSSCodeHints/main.js @@ -251,12 +251,17 @@ define(function (require, exports, module) { } result = $.map(valueArray, function (pvalue, pindex) { - if (StringMatch.stringMatch(pvalue, valueNeedle, stringMatcherOptions)) { - return pvalue; + var result = StringMatch.stringMatch(pvalue, valueNeedle, stringMatcherOptions); + if (result) { + return result; } }); - var newResult = StringMatch.basicMatchSort(result); + StringMatch.basicMatchSort(result); + + result = $.map(result, function (entry) { + return entry.label; + }); return { hints: result, @@ -272,13 +277,19 @@ define(function (require, exports, module) { lastContext = CSSUtils.PROP_NAME; needle = needle.substr(0, this.info.offset); + result = $.map(properties, function (pvalues, pname) { - if (StringMatch.stringMatch(pname, needle, stringMatcherOptions)) { - return pname; + var result = StringMatch.stringMatch(pname, needle, stringMatcherOptions); + if (result) { + return result; } }); - var newResult = StringMatch.basicMatchSort(result); + StringMatch.basicMatchSort(result); + + result = $.map(result, function (entry) { + return entry.label; + }); return { hints: result, From f02f4c4e2eec20ed1e93817b0e3d98b6c74c97be Mon Sep 17 00:00:00 2001 From: Jeff Booher Date: Thu, 24 Apr 2014 09:59:39 -0700 Subject: [PATCH 6/6] fixed extension test failures --- .../default/CSSCodeHints/unittests.js | 34 ++++++++++++++++--- 1 file changed, 29 insertions(+), 5 deletions(-) diff --git a/src/extensions/default/CSSCodeHints/unittests.js b/src/extensions/default/CSSCodeHints/unittests.js index b76c2dacb78..7138ccb7d6d 100644 --- a/src/extensions/default/CSSCodeHints/unittests.js +++ b/src/extensions/default/CSSCodeHints/unittests.js @@ -93,7 +93,17 @@ define(function (require, exports, module) { expect(hintList.indexOf("div")).toBe(-1); expect(hintList[0]).toBe(expectedFirstHint); } - + + // compares lists to ensure they are the same + function verifyListsAreIdentical(hintList, values) { + var i; + expect(hintList.length).toBe(values.length); + for (i = 0; i < values.length; i++) { + expect(hintList[i]).toBe(values[i]); + } + } + + function selectHint(provider, expectedHint, implicitChar) { var hintList = expectHints(provider, implicitChar); expect(hintList.indexOf(expectedHint)).not.toBe(-1); @@ -175,7 +185,11 @@ define(function (require, exports, module) { testEditor.setCursorPos({ line: 9, ch: 12 }); var hintList = expectHints(CSSCodeHints.cssPropHintProvider); verifyAttrHints(hintList, "border-color"); // filtered on "border-color" - expect(hintList.length).toBe(1); + verifyListsAreIdentical(hintList, ["border-color", + "border-left-color", + "border-top-color", + "border-bottom-color", + "border-right-color"]); }); it("should list prop-name hints at end of property-value finished by ;", function () { @@ -383,8 +397,18 @@ define(function (require, exports, module) { it("should list prop-name hints inside multi-line styletags with cursor in last line", function () { testEditor.setCursorPos({ line: 10, ch: 5 }); // inside style, after colo var hintList = expectHints(CSSCodeHints.cssPropHintProvider); - verifyAttrHints(hintList, "color"); // filtered on "colo" - expect(hintList.length).toBe(1); + verifyListsAreIdentical(hintList, ["color", + "border-color", + "background-color", + "border-left-color", + "border-top-color", + "outline-color", + "border-bottom-color", + "border-right-color", + "text-decoration-color", + "text-emphasis-color", + "column-count", + "column-rule-color"]); }); it("should NOT list prop-name hints between closed styletag and new opening styletag", function () { @@ -588,7 +612,7 @@ define(function (require, exports, module) { testEditor.setCursorPos({ line: 66, ch: 16 }); // after flow-from: m var hintList = expectHints(CSSCodeHints.cssPropHintProvider); - verifyAllValues(hintList, ["main"]); + verifyListsAreIdentical(hintList, ["main", "lim"]); }); });