diff options
author | Martin Hanzel <mhanzel@gitlab.com> | 2019-06-25 13:19:29 +0300 |
---|---|---|
committer | Kushal Pandya <kushalspandya@gmail.com> | 2019-06-25 13:19:29 +0300 |
commit | de7abc06511fef0342af256075987903f68567bd (patch) | |
tree | 9527aca4e2d130fe30948f137791f12b9ed32343 /app/assets/javascripts/gfm_auto_complete.js | |
parent | e3fa9d122b0a593b0c6441a35cbad8ab6c8e70b9 (diff) |
Allow autocompleting scoped labels
The `:` key will no longer exit out of the autocomplete dialog,
allowing auto-completion of labels with colons in them.
Diffstat (limited to 'app/assets/javascripts/gfm_auto_complete.js')
-rw-r--r-- | app/assets/javascripts/gfm_auto_complete.js | 26 |
1 files changed, 24 insertions, 2 deletions
diff --git a/app/assets/javascripts/gfm_auto_complete.js b/app/assets/javascripts/gfm_auto_complete.js index 3b73dd83c9f..b308cd9c236 100644 --- a/app/assets/javascripts/gfm_auto_complete.js +++ b/app/assets/javascripts/gfm_auto_complete.js @@ -318,6 +318,7 @@ class GfmAutoComplete { } setupLabels($input) { + const instance = this; const fetchData = this.fetchData.bind(this); const LABEL_COMMAND = { LABEL: '/label', UNLABEL: '/unlabel', RELABEL: '/relabel' }; let command = ''; @@ -348,7 +349,6 @@ class GfmAutoComplete { })); }, matcher(flag, subtext) { - const match = GfmAutoComplete.defaultMatcher(flag, subtext, this.app.controllers); const subtextNodes = subtext .split(/\n+/g) .pop() @@ -366,6 +366,27 @@ class GfmAutoComplete { return null; }); + // If any label matches the inserted text after the last `~`, suggest those labels, + // even if any spaces or funky characters were typed. + // This allows matching labels like "Accepting merge requests". + const labels = instance.cachedData[flag]; + if (labels) { + if (!subtext.includes(flag)) { + // Do not match if there is no `~` before the cursor + return null; + } + const lastCandidate = subtext.split(flag).pop(); + if (labels.find(label => label.title.startsWith(lastCandidate))) { + return lastCandidate; + } + } else { + // Load all labels into the autocompleter. + // This needs to happen if e.g. editing a label in an existing comment, because normally + // label data would only be loaded only once you type `~`. + fetchData(this.$inputor, this.at); + } + + const match = GfmAutoComplete.defaultMatcher(flag, subtext, this.app.controllers); return match && match.length ? match[1] : null; }, filter(query, data, searchKey) { @@ -563,8 +584,9 @@ class GfmAutoComplete { const accentAChar = decodeURI('%C3%80'); const accentYChar = decodeURI('%C3%BF'); + // Holy regex, batman! const regexp = new RegExp( - `^(?:\\B|[^a-zA-Z0-9_\`${atSymbolsWithoutBar}]|\\s)${resultantFlag}(?!${atSymbolsWithBar})((?:[A-Za-z${accentAChar}-${accentYChar}0-9_'.+-]|[^\\x00-\\x7a])*)$`, + `^(?:\\B|[^a-zA-Z0-9_\`${atSymbolsWithoutBar}]|\\s)${resultantFlag}(?!${atSymbolsWithBar})((?:[A-Za-z${accentAChar}-${accentYChar}0-9_'.+-:]|[^\\x00-\\x7a])*)$`, 'gi', ); |