aboutsummaryrefslogtreecommitdiff
path: root/src/services/completion/completion.js
blob: 8a6eba7e4d03dab635e0caf98bde67aa2633f71b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
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 = splitByWhitespaceBoundary(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 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
    }
    // 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,
  splitByWhitespaceBoundary,
  replaceWord
}

export default completion