From f5e4ad601ac47f7b0a2f3cdc24e0f6be9be17d21 Mon Sep 17 00:00:00 2001 From: Shpuld Shpuldson Date: Thu, 27 Aug 2020 16:46:23 +0300 Subject: [PATCH 1/3] wip start --- src/services/completion/completion.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/services/completion/completion.js b/src/services/completion/completion.js index df83d03d..f74f8048 100644 --- a/src/services/completion/completion.js +++ b/src/services/completion/completion.js @@ -4,6 +4,7 @@ export const replaceWord = (str, toReplace, replacement) => { return str.slice(0, toReplace.start) + replacement + str.slice(toReplace.end) } +// This seems to work fine export const wordAtPosition = (str, pos) => { const words = splitIntoWords(str) const wordsWithPosition = addPositionToWords(words) @@ -11,6 +12,7 @@ export const wordAtPosition = (str, pos) => { return find(wordsWithPosition, ({ start, end }) => start <= pos && end > pos) } +// This works fine export const addPositionToWords = (words) => { return reduce(words, (result, word) => { const data = { @@ -34,6 +36,7 @@ export const addPositionToWords = (words) => { }, []) } +// This needs to be altered, split words at space export const splitIntoWords = (str) => { // Split at word boundaries const regex = /\b/ From 0347d79bda97a90eab3afaf9ab6aafb784b2e10d Mon Sep 17 00:00:00 2001 From: Shpuld Shpuldson Date: Fri, 28 Aug 2020 12:02:52 +0300 Subject: [PATCH 2/3] Rewrite word split imperatively for control --- src/services/completion/completion.js | 53 +++++++++---------- .../services/completion/completion.spec.js | 43 ++++++++++----- 2 files changed, 54 insertions(+), 42 deletions(-) diff --git a/src/services/completion/completion.js b/src/services/completion/completion.js index f74f8048..8a6eba7e 100644 --- a/src/services/completion/completion.js +++ b/src/services/completion/completion.js @@ -4,15 +4,13 @@ export const replaceWord = (str, toReplace, replacement) => { return str.slice(0, toReplace.start) + replacement + str.slice(toReplace.end) } -// This seems to work fine export const wordAtPosition = (str, pos) => { - const words = splitIntoWords(str) + const words = splitByWhitespaceBoundary(str) const wordsWithPosition = addPositionToWords(words) return find(wordsWithPosition, ({ start, end }) => start <= pos && end > pos) } -// This works fine export const addPositionToWords = (words) => { return reduce(words, (result, word) => { const data = { @@ -36,37 +34,36 @@ export const addPositionToWords = (words) => { }, []) } -// This needs to be altered, split words at space -export const splitIntoWords = (str) => { - // Split at word boundaries - const regex = /\b/ - const triggers = /[@#:]+$/ - - let split = str.split(regex) - - // Add trailing @ and # to the following word. - const words = reduce(split, (result, word) => { - if (result.length > 0) { - let previous = result.pop() - const matches = previous.match(triggers) - if (matches) { - previous = previous.replace(triggers, '') - word = matches[0] + word - } - result.push(previous) +export const splitByWhitespaceBoundary = (str) => { + let result = [] + let currentWord = '' + for (let i = 0; i < str.length; i++) { + const currentChar = str[i] + // Starting a new word + if (!currentWord) { + currentWord = currentChar + continue } - result.push(word) - - return result - }, []) - - return words + // current character is whitespace while word isn't, or vice versa: + // add our current word to results, start over the current word. + if (!!currentChar.trim() !== !!currentWord.trim()) { + result.push(currentWord) + currentWord = currentChar + continue + } + currentWord += currentChar + } + // Add the last word we were working on + if (currentWord) { + result.push(currentWord) + } + return result } const completion = { wordAtPosition, addPositionToWords, - splitIntoWords, + splitByWhitespaceBoundary, replaceWord } diff --git a/test/unit/specs/services/completion/completion.spec.js b/test/unit/specs/services/completion/completion.spec.js index 8a41c653..81d3a26a 100644 --- a/test/unit/specs/services/completion/completion.spec.js +++ b/test/unit/specs/services/completion/completion.spec.js @@ -1,8 +1,8 @@ -import { replaceWord, addPositionToWords, wordAtPosition, splitIntoWords } from '../../../../../src/services/completion/completion.js' +import { replaceWord, addPositionToWords, wordAtPosition, splitByWhitespaceBoundary } from '../../../../../src/services/completion/completion.js' describe('addPositiontoWords', () => { it('adds the position to a word list', () => { - const words = ['hey', 'this', 'is', 'fun'] + const words = ['hey', ' ', 'this', ' ', 'is', ' ', 'fun'] const expected = [ { @@ -11,19 +11,34 @@ describe('addPositiontoWords', () => { end: 3 }, { - word: 'this', + word: ' ', start: 3, - end: 7 + end: 4 }, { - word: 'is', - start: 7, + word: 'this', + start: 4, + end: 8 + }, + { + word: ' ', + start: 8, end: 9 }, { - word: 'fun', + word: 'is', start: 9, + end: 11 + }, + { + word: ' ', + start: 11, end: 12 + }, + { + word: 'fun', + start: 12, + end: 15 } ] @@ -33,11 +48,11 @@ describe('addPositiontoWords', () => { }) }) -describe('splitIntoWords', () => { +describe('splitByWhitespaceBoundary', () => { it('splits at whitespace boundaries', () => { - const str = 'This is a #nice @test for you, @idiot.' - const expected = ['This', ' ', 'is', ' ', 'a', ' ', '#nice', ' ', '@test', ' ', 'for', ' ', 'you', ', ', '@idiot', '.'] - const res = splitIntoWords(str) + const str = 'This is a #nice @test for you, @idiot@idiot.com' + const expected = ['This', ' ', 'is', ' ', 'a', ' ', '#nice', ' ', '@test', ' ', 'for', ' ', 'you,', ' ', '@idiot@idiot.com'] + const res = splitByWhitespaceBoundary(str) expect(res).to.eql(expected) }) @@ -57,13 +72,13 @@ describe('wordAtPosition', () => { describe('replaceWord', () => { it('replaces a word (with start and end) with another word in a given string', () => { - const str = 'hey @take, how are you' - const wordsWithPosition = addPositionToWords(splitIntoWords(str)) + const str = 'hey @take , how are you' + const wordsWithPosition = addPositionToWords(splitByWhitespaceBoundary(str)) const toReplace = wordsWithPosition[2] expect(toReplace.word).to.eql('@take') - const expected = 'hey @takeshitakenji, how are you' + const expected = 'hey @takeshitakenji , how are you' const res = replaceWord(str, toReplace, '@takeshitakenji') expect(res).to.eql(expected) }) From 4da248f8bc592fc1b7d24fbc1e2021bab2663f29 Mon Sep 17 00:00:00 2001 From: Shpuld Shpuldson Date: Fri, 28 Aug 2020 12:35:02 +0300 Subject: [PATCH 3/3] update changelog for autocomplete fixes --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 43e53e60..66abfa65 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ## [Unreleased] ## [Unreleased patch] +### Fixed +- Autocomplete won't stop at the second @, so it'll still work with "@lain@l" and not start over. +- Fixed weird autocomplete behavior when you write ":custom_emoji: ?" ## [2.1.0] - 2020-08-28 ### Added