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