refactor: add editor-words plugin

This commit is contained in:
purocean
2022-03-10 17:35:42 +08:00
parent ce743a3c4e
commit 7f3ee5fead
3 changed files with 79 additions and 42 deletions
+2
View File
@@ -17,6 +17,7 @@ import statusBarGet from '@fe/plugins/status-bar-get'
import editorPaste from '@fe/plugins/editor-paste'
import editorAttachment from '@fe/plugins/editor-attachment'
import editorMarkdown from '@fe/plugins/editor-markdown'
import editorWords from '@fe/plugins/editor-words'
import editorEmoji from '@fe/plugins/editor-emoji'
import copyText from '@fe/plugins/copy-text'
import switchTodo from '@fe/plugins/switch-todo'
@@ -71,6 +72,7 @@ export default [
editorAttachment,
editorMarkdown,
editorEmoji,
editorWords,
copyText,
switchTodo,
imageViewer,
+2 -42
View File
@@ -1,59 +1,19 @@
/* eslint-disable no-template-curly-in-string */
import dayjs from 'dayjs'
import type * as Monaco from 'monaco-editor'
import { deleteLine, getEditor, getLineContent, getMonaco, getOneIndent, getValue, insert, replaceLine, whenEditorReady } from '@fe/services/editor'
import { deleteLine, getEditor, getLineContent, getMonaco, getOneIndent, insert, replaceLine, whenEditorReady } from '@fe/services/editor'
import type { Plugin } from '@fe/context'
import { t } from '@fe/services/i18n'
import { getSetting } from '@fe/services/setting'
import { isKeydown } from '@fe/core/command'
function getWords (content: string) {
const words = new Set<string>()
if (content.length > 50000) {
return words
}
const identifier = /[a-zA-Z_]+\w/g
while (true) {
if (words.size > 1000) {
break
}
const res = identifier.exec(content)
if (!res) {
break
}
if (res[0].length > 2 && res[0].length < 15) {
words.add(res[0])
}
}
return words
}
function createDependencyProposals (range: Monaco.IRange, model: Monaco.editor.ITextModel, position: Monaco.Position): Monaco.languages.CompletionItem[] {
function createDependencyProposals (range: Monaco.IRange): Monaco.languages.CompletionItem[] {
const monaco = getMonaco()
const currentWord = model.getWordUntilPosition(position).word
const replaceRange = { ...range, endColumn: range.startColumn + 1 }
const result: Monaco.languages.CompletionItem[] = []
getWords(getValue()).forEach((word, i) => {
if (currentWord !== word) {
result.push({
label: { label: word },
kind: monaco.languages.CompletionItemKind.Text,
insertText: word,
range: replaceRange,
sortText: (10000 + i).toString()
})
}
})
;[
{ name: '/ ![]() Image', insertText: '![${2:Img}]($1)' },
{ name: '/ []() Link', insertText: '[${2:Link}]($1)' },
+75
View File
@@ -0,0 +1,75 @@
import type * as Monaco from 'monaco-editor'
import type { Ctx, Plugin } from '@fe/context'
function getWords (content: string) {
const words = new Set<string>()
if (content.length > 50000) {
return words
}
const identifier = /[a-zA-Z_]+\w/g
while (true) {
if (words.size > 1000) {
break
}
const res = identifier.exec(content)
if (!res) {
break
}
if (res[0].length > 2 && res[0].length < 15) {
words.add(res[0])
}
}
return words
}
class WordsCompletionProvider implements Monaco.languages.CompletionItemProvider {
private readonly monaco: typeof Monaco
private readonly ctx: Ctx
constructor (monaco: typeof Monaco, ctx: Ctx) {
this.monaco = monaco
this.ctx = ctx
}
public async provideCompletionItems (model: Monaco.editor.IModel, position: Monaco.Position): Promise<Monaco.languages.CompletionList | undefined> {
const currentWord = model.getWordUntilPosition(position)
const result: Monaco.languages.CompletionItem[] = []
getWords(model.getValue()).forEach((word, i) => {
if (currentWord.word !== word) {
result.push({
label: { label: word },
kind: this.monaco.languages.CompletionItemKind.Text,
insertText: word,
range: new this.monaco.Range(
position.lineNumber,
currentWord.startColumn,
position.lineNumber,
currentWord.endColumn,
),
sortText: i.toString().padStart(7)
})
}
})
return { suggestions: result }
}
}
export default {
name: 'editor-words',
register: (ctx) => {
ctx.editor.whenEditorReady().then(({ monaco }) => {
monaco.languages.registerCompletionItemProvider(
'markdown',
new WordsCompletionProvider(monaco, ctx)
)
})
}
} as Plugin