diff options
Diffstat (limited to 'src/services/completion/completion.js')
| -rw-r--r-- | src/services/completion/completion.js | 70 |
1 files changed, 70 insertions, 0 deletions
diff --git a/src/services/completion/completion.js b/src/services/completion/completion.js new file mode 100644 index 00000000..8788d837 --- /dev/null +++ b/src/services/completion/completion.js @@ -0,0 +1,70 @@ +import { reduce, find } from 'lodash' + +export const replaceWord = (str, toReplace, replacement) => { + return str.slice(0, toReplace.start) + replacement + str.slice(toReplace.end) +} + +export const wordAtPosition = (str, pos) => { + const words = splitIntoWords(str) + const wordsWithPosition = addPositionToWords(words) + + return find(wordsWithPosition, ({start, end}) => start <= pos && end > pos) +} + +export const addPositionToWords = (words) => { + return reduce(words, (result, word) => { + const data = { + word, + start: 0, + end: word.length + } + + if (result.length > 0) { + const previous = result.pop() + + data.start += previous.end + data.end += previous.end + + result.push(previous) + } + + result.push(data) + + return result + }, []) +} + +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) + } + result.push(word) + + return result + }, []) + + return words +} + +const completion = { + wordAtPosition, + addPositionToWords, + splitIntoWords, + replaceWord +} + +export default completion |
