mirror of
https://github.com/hedgedoc/hedgedoc.git
synced 2025-05-14 07:04:45 -04:00

* Remove unnecessary capture group from regex Signed-off-by: Tilman Vatteroth <git@tilmanvatteroth.de> * Rename component to make name more expressive Signed-off-by: Tilman Vatteroth <git@tilmanvatteroth.de> * Remove redundant expression Signed-off-by: Tilman Vatteroth <git@tilmanvatteroth.de> * Filter vbscript links Signed-off-by: Tilman Vatteroth <git@tilmanvatteroth.de> * Remove superfluous parameter Signed-off-by: Tilman Vatteroth <git@tilmanvatteroth.de> * Check if handler is set Signed-off-by: Tilman Vatteroth <git@tilmanvatteroth.de> * Fix doc Signed-off-by: Tilman Vatteroth <git@tilmanvatteroth.de>
114 lines
3.1 KiB
TypeScript
114 lines
3.1 KiB
TypeScript
/*
|
|
* SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file)
|
|
*
|
|
* SPDX-License-Identifier: AGPL-3.0-only
|
|
*/
|
|
|
|
import { Editor, Hint, Hints, Pos } from 'codemirror'
|
|
import { findWordAtCursor, generateHintListByPrefix, Hinter } from './index'
|
|
import { showErrorNotification } from '../../../../redux/ui-notifications/methods'
|
|
import { Logger } from '../../../../utils/logger'
|
|
|
|
type highlightJsImport = typeof import('../../../common/hljs/hljs')
|
|
|
|
const log = new Logger('Autocompletion > CodeBlock')
|
|
const wordRegExp = /^```((?:\w|-|_|\+)*)$/
|
|
let allSupportedLanguages: string[] = []
|
|
|
|
/**
|
|
* Fetches the highlight js chunk.
|
|
* @return the retrieved highlight js api
|
|
*/
|
|
const loadHighlightJs = async (): Promise<highlightJsImport | null> => {
|
|
try {
|
|
return await import('../../../common/hljs/hljs')
|
|
} catch (error) {
|
|
showErrorNotification('common.errorWhileLoadingLibrary', { name: 'highlight.js' })(error as Error)
|
|
log.error('Error while loading highlight.js', error)
|
|
return null
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Extracts the language from the current line in the editor.
|
|
*
|
|
* @param editor The editor that contains the search time
|
|
* @return null if no search term could be found or the found word and the cursor position.
|
|
*/
|
|
const extractSearchTerm = (
|
|
editor: Editor
|
|
): null | {
|
|
searchTerm: string
|
|
startIndex: number
|
|
endIndex: number
|
|
} => {
|
|
const searchTerm = findWordAtCursor(editor)
|
|
const searchResult = wordRegExp.exec(searchTerm.text)
|
|
if (searchResult === null) {
|
|
return null
|
|
}
|
|
|
|
return {
|
|
searchTerm: searchResult[1],
|
|
startIndex: searchTerm.start,
|
|
endIndex: searchTerm.end
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Builds the list of languages that are supported by highlight js or custom embeddings.
|
|
* @return An array of language names
|
|
*/
|
|
const buildLanguageList = async (): Promise<string[]> => {
|
|
const highlightJs = await loadHighlightJs()
|
|
|
|
if (highlightJs === null) {
|
|
return []
|
|
}
|
|
|
|
if (allSupportedLanguages.length === 0) {
|
|
allSupportedLanguages = highlightJs.default
|
|
.listLanguages()
|
|
.concat('csv', 'flow', 'html', 'js', 'markmap', 'abc', 'graphviz', 'mermaid', 'vega-lite')
|
|
}
|
|
|
|
return allSupportedLanguages
|
|
}
|
|
|
|
/**
|
|
* Creates a codemirror autocompletion hint with supported highlight js languages.
|
|
*
|
|
* @param editor The codemirror editor that requested the autocompletion
|
|
* @return The generated {@link Hints} or null if no hints exist.
|
|
*/
|
|
const codeBlockHint = async (editor: Editor): Promise<Hints | null> => {
|
|
const searchResult = extractSearchTerm(editor)
|
|
if (!searchResult) {
|
|
return null
|
|
}
|
|
|
|
const languages = await buildLanguageList()
|
|
if (languages.length === 0) {
|
|
return null
|
|
}
|
|
const suggestions = generateHintListByPrefix(searchResult.searchTerm, languages)
|
|
if (!suggestions) {
|
|
return null
|
|
}
|
|
const lineIndex = editor.getCursor().line
|
|
return {
|
|
list: suggestions.map(
|
|
(suggestion: string): Hint => ({
|
|
text: '```' + suggestion + '\n\n```\n',
|
|
displayText: suggestion
|
|
})
|
|
),
|
|
from: Pos(lineIndex, searchResult.startIndex),
|
|
to: Pos(lineIndex, searchResult.endIndex)
|
|
}
|
|
}
|
|
|
|
export const CodeBlockHinter: Hinter = {
|
|
wordRegExp,
|
|
hint: codeBlockHint
|
|
}
|