Files
2026-07-13 12:30:20 +08:00

135 lines
4.3 KiB
JavaScript
Vendored

(function (mod) {
mod(
(this.CompleteEmoji = {}),
CodeMirror,
HyperMD.FoldEmoji
);
})(function (exports, CodeMirror, FoldEmoji) {
/**
* Create a hint function for codemirror/addon/hint/show-hint
* and a HyperMD editor with fold-emoji actived
*
* @see https://codemirror.net/doc/manual.html#addon_show-hint
*/
exports.createHintFunc = function () {
var editor = null
var defaultDict = {}
var previewShown = false
var previewContainer = document.createElement('div')
previewContainer.setAttribute('class', 'CodeMirror-hints HyperMD-complete-preview')
return function (cm, options) {
let cursor = cm.getCursor(), line = cm.getLine(cursor.line);
// PATCHED don't mixup with checkboxse
if (/^\s*-\s\[\s/.test(line)) {
hidePreview()
return null
}
let start = cursor.ch, end = cursor.ch;
// while (start && /[-\w:]/.test(line.charAt(start - 1)))--start
// while (end < line.length && /[-\w:]/.test(line.charAt(end)))++end
// PATCHED (removed \s, allowed us too see links dialog always)
const unicodeWordRegex = /[\p{L}\p{N}_\s:-]/u; // \p{L} matches any letter, \p{N} matches any number
while (start && unicodeWordRegex.test(line.charAt(start - 1))) --start;
while (end < line.length && unicodeWordRegex.test(line.charAt(end))) ++end;
// if (start === end) {
// hidePreview()
// return null
// }
let word = line.slice(start, cursor.ch).toLowerCase()
let wordEmpty = word.length === 0
/** @type {Array<Record<string,string>>} */
// var dicts = [defaultDict] // for now we only use links autocompletion
var dicts = []
var myEmojiDict = (cm.getOption('hmdFoldEmoji') || {}).myEmoji
if (myEmojiDict) dicts.push(myEmojiDict())
var result = {
list: [],
from: CodeMirror.Pos(cursor.line, start),
to: CodeMirror.Pos(cursor.line, end)
}
// PATCHED: if the user typed `[[` (wiki-link opener), the completion
// should insert `name]]` so the result is `[[name]]` instead of the
// classical `[name](url)`. We detect by looking two chars before the
// word start; both must be `[`.
var isWiki = start >= 2
&& line.charAt(start - 1) === '['
&& line.charAt(start - 2) === '['
var list = result.list
for (var i = 0; i < dicts.length; i++) {
var dict = dicts[i]
if (!dict) continue
for (var key in dict) {
if (wordEmpty || key.slice(0, word.length) === word || key.toLowerCase().includes(word.toLowerCase())) {
var insertText = isWiki ? key + ']]' : dict[key]
list.push({text: insertText, displayText: key})
}
}
}
CodeMirror.on(result, "select", showPreview)
CodeMirror.on(result, "close", hidePreview)
// PATCHED: notify the app when a completion is inserted, so it can add a
// backlink in the linked-to file.
CodeMirror.on(result, "pick", function (completion) {
if (typeof onLinkPicked === 'function') onLinkPicked(completion.text)
})
return result
}
function hidePreview() {
if (previewShown) {
document.body.removeChild(previewContainer)
previewShown = false
}
}
/**
*
* @param {string} completion
* @param {HTMLElement} element
*/
function showPreview(completion, element) {
return;
var foldEmoji = FoldEmoji.getAddon(editor)
/** @type {Node} */
var newNode =
((completion in foldEmoji.myEmoji) && foldEmoji.myEmoji[completion](completion))
|| foldEmoji.emojiRenderer(completion)
|| document.createTextNode(defaultDict[completion])
|| null
if (newNode) { // yes, this is a emoji
if (!previewShown) {
previewShown = true
document.body.appendChild(previewContainer)
}
var oldNode = previewContainer.firstChild
if (oldNode) previewContainer.removeChild(oldNode)
previewContainer.appendChild(newNode)
var loc = element.parentElement.style
var pcStyle = previewContainer.style
pcStyle.left = Number.parseFloat(loc.left) + element.parentElement.offsetWidth + 'px'
pcStyle.top = loc.top
} else {
hidePreview()
}
}
}
})