2021-05-03 14:27:32 +00:00
|
|
|
import _ from 'lodash';
|
|
|
|
|
import Fuse from 'fuse.js';
|
|
|
|
|
|
2021-05-03 16:04:54 +00:00
|
|
|
export function getSuggestionKeys(currentState) {
|
2021-05-03 14:27:32 +00:00
|
|
|
let suggestions = [];
|
|
|
|
|
_.keys(currentState).forEach((key) => {
|
|
|
|
|
_.keys(currentState[key]).forEach((key2) => {
|
|
|
|
|
_.keys(currentState[key][key2]).forEach((key3) => {
|
|
|
|
|
suggestions.push(`${key}.${key2}.${key3}`)
|
|
|
|
|
})
|
|
|
|
|
})
|
|
|
|
|
});
|
2021-05-03 16:04:54 +00:00
|
|
|
return suggestions;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function generateHints(word, suggestions) {
|
2021-05-03 14:27:32 +00:00
|
|
|
|
|
|
|
|
if(word === '') {
|
|
|
|
|
return suggestions;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const fuse = new Fuse(suggestions);
|
|
|
|
|
return fuse.search(word).map((result) => result.item);
|
|
|
|
|
}
|
|
|
|
|
|
2021-06-03 06:18:55 +00:00
|
|
|
export function computeCurrentWord(editor, _cursorPosition, ignoreBraces = false) {
|
2021-05-03 14:27:32 +00:00
|
|
|
const cursor = editor.getCursor();
|
|
|
|
|
const line = cursor.line;
|
|
|
|
|
const value = editor.getLine(line);
|
|
|
|
|
const sliced = value.slice(0, _cursorPosition);
|
2021-06-03 06:18:55 +00:00
|
|
|
|
|
|
|
|
const splitter = ignoreBraces ? ' ' : '{{';
|
|
|
|
|
|
|
|
|
|
const split = sliced.split(splitter);
|
2021-05-03 14:27:32 +00:00
|
|
|
const lastWord = split[split.length - 1];
|
|
|
|
|
return lastWord;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function makeOverlay(style) {
|
|
|
|
|
return {
|
|
|
|
|
token: function (stream, state) {
|
|
|
|
|
var ch;
|
|
|
|
|
if (stream.match("{{")) {
|
|
|
|
|
while ((ch = stream.next()) != null)
|
|
|
|
|
if (ch == "}" && stream.next() == "}") {
|
|
|
|
|
stream.eat("}");
|
|
|
|
|
return style;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
while (stream.next() != null && !stream.match("{{", false)) { }
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-06-03 06:18:55 +00:00
|
|
|
export function onBeforeChange(editor, change, ignoreBraces = false) {
|
|
|
|
|
|
|
|
|
|
if(!ignoreBraces) {
|
|
|
|
|
|
|
|
|
|
const cursor = editor.getCursor();
|
|
|
|
|
const line = cursor.line;
|
|
|
|
|
const ch = cursor.ch;
|
|
|
|
|
const value = editor.getLine(line);
|
|
|
|
|
const isLastCharacterBrace = value.slice(ch - 1, value.length) === '{';
|
|
|
|
|
|
|
|
|
|
if (isLastCharacterBrace && change.origin === '+input' && change.text[0] === '{') {
|
|
|
|
|
change.text[0] = '{}}'
|
|
|
|
|
// editor.setCursor({ line: 0, ch: ch })
|
|
|
|
|
}
|
2021-05-03 14:27:32 +00:00
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return change;
|
|
|
|
|
}
|
|
|
|
|
|
2021-06-03 06:18:55 +00:00
|
|
|
export function canShowHint(editor, ignoreBraces = false) {
|
2021-06-03 06:22:28 +00:00
|
|
|
|
|
|
|
|
if(!editor.hasFocus()) return false;
|
2021-06-03 06:18:55 +00:00
|
|
|
|
2021-05-03 14:27:32 +00:00
|
|
|
const cursor = editor.getCursor();
|
|
|
|
|
const line = cursor.line;
|
|
|
|
|
const ch = cursor.ch;
|
2021-06-03 06:18:55 +00:00
|
|
|
const value = editor.getLine(line);
|
|
|
|
|
|
|
|
|
|
if(ignoreBraces && value.length > 0) return true;
|
|
|
|
|
|
2021-05-03 14:27:32 +00:00
|
|
|
return value.slice(ch, ch + 2) === '}}';
|
|
|
|
|
}
|
|
|
|
|
|
2021-06-03 06:18:55 +00:00
|
|
|
export function handleChange(editor, onChange, suggestions, ignoreBraces = false) {
|
2021-05-03 14:27:32 +00:00
|
|
|
|
|
|
|
|
let state = editor.state.matchHighlighter;
|
|
|
|
|
editor.addOverlay(state.overlay = makeOverlay(state.options.style));
|
|
|
|
|
|
|
|
|
|
const cursor = editor.getCursor();
|
2021-06-03 06:18:55 +00:00
|
|
|
const currentWord = computeCurrentWord(editor, cursor.ch, ignoreBraces);
|
2021-05-03 16:04:54 +00:00
|
|
|
const hints = generateHints(currentWord, suggestions);
|
2021-05-03 14:27:32 +00:00
|
|
|
|
|
|
|
|
const options = {
|
|
|
|
|
alignWithWord: true,
|
2021-06-26 07:08:04 +00:00
|
|
|
completeSingle: false,
|
2021-05-03 14:27:32 +00:00
|
|
|
hint: function () {
|
|
|
|
|
return {
|
|
|
|
|
from: { line: cursor.line, ch: cursor.ch - currentWord.length },
|
|
|
|
|
to: cursor,
|
|
|
|
|
list: hints
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
};
|
2021-06-03 06:18:55 +00:00
|
|
|
if (canShowHint(editor, ignoreBraces)) {
|
2021-05-03 14:27:32 +00:00
|
|
|
editor.showHint(options);
|
|
|
|
|
}
|
2021-06-26 07:08:04 +00:00
|
|
|
};
|