本文主要是介绍Monaco Editor系列(七)代码信息指示器CodeLens、使用API触发键盘事件、自动完成配置,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
前言:最近工作太忙了555,都没时间学习。端午节我要抽半天时间学习!(我自己都不信🤣)先总结一下下上一篇文章的知识点,我也忘得差不多了
- Range类详解 Range类和IRange接口,Range类是基类,上面保存各种 range 相关的方法;IRange接口是开放给开发者的接口,传参的时候传 IRange接口类型的数据即可,这样传参就方便多了,里面只有关键的 range 的位置信息,起始位置和结束位置。两者可以相互转换。
- 使用
monaco.editor.createModel()
方法,可以通过第三个参数 uri 设置语言。但是如果是自己开发,确定的语言,肯定就直接传了,目前没有发现这样传参很必要的使用场景。 monaco.Uri.parse()
将一个 url 地址,转换成 monaco 可用的 uri 标识。在 Monaco 编辑器中,Uri 经常用于表示打开的文件、编辑的文本或资源的位置。通过使用 Uri,可以在编辑器中准确地标识和操作这些资源。monaco.editor.create(容器, 配置项)
通过第二个参数的minimap属性,可以配置 minamap 的配置项
这篇文章继续学习学习学习!我爱学习!
一、代码信息指示器CodeLens
1、简介
在使用 VS Code 编辑器的时候,如果你使用了 Git 版本工具,那么就会看到这样的效果
这一行文字用来提示修改代码的人员和修改时间,并且不会占据真正的代码行
蓝色的还可以点击进去查看更详细的信息
这一交互的实现就是通过 monaco 的代码信息提示器 CodeLens 实现的,显示的版本提交的内容是通过插件 Gitlen 实现的。
CodeLens 为代码提供辅助信息,并不真正存在在文件中,复制的时候不会复制到剪切板。前面学过的 markers 跟 CodeLens 有点像,都是帮助开发者理解代码,并且存在于编辑器外,通过人为手动设置的。
CodeLens 通常是一行信息,它是作用于语言模型的,也就是通过 monaco.languages
命名空间设置。
2、使用
使用 CodeLens 需要使用 monaco.editor.registerCodeLensProvider 方法注册一个 Provider
官网也给出了这个方法的示例
registerCodeLensProvider
参数一:LanguageSelector
还是看一下在源码中的定义
node_modules/monaco-editor-core/monaco.d.ts
export type LanguageSelector = string | LanguageFilter | ReadonlyArray<string | LanguageFilter>;export interface LanguageFilter {readonly language?: string;readonly scheme?: string;readonly pattern?: string | IRelativePattern;readonly notebookType?: string;/*** This provider is implemented in the UI thread.*/readonly hasAccessToAllModels?: boolean;readonly exclusive?: boolean;/*** This provider comes from a builtin extension.*/readonly isBuiltin?: boolean;
}
这个参数的写法有三种:
1、 字符串 'javascript'
2、LanguageFilter
类型的对象,如果你不想给所有的某种语言的文件都增加,就可以通过对象的方式,来匹配你想设置 CodeLens 的文件
{language: 'javascript',pattern: '**/*.js'
}
但是这个匹配规则,emm,通过这样的路径匹配的方式,看源码没看出来怎么匹配的,太难了,不如还是用字符串
3、第三种是可以传一个LanguageFilter
类型的对象数组
参数二:CodeLensProvider
export interface CodeLensProvider {onDidChange?: IEvent<this>;provideCodeLenses(model: editor.ITextModel, token: CancellationToken): ProviderResult<CodeLensList>;resolveCodeLens?(model: editor.ITextModel, codeLens: CodeLens, token: CancellationToken): ProviderResult<CodeLens>;
}
一个监听函数 onDidChange
监听 CodeLens 的改变
provideCodeLenses
用来构建 CodeLens 数组
resolveCodeLens
没看出来什么作用
CodeLens
接口定义也挺简单的
export interface CodeLens {range: IRange;id?: string;command?: Command;
}
指定 CodeLens
出现的范围,以及唯一标识id,和绑定的 command
自定义命令。command
需要使用咱们之前学过的 addCommand
生成,可以指定点击 CodeLens
时候执行的回调函数
假设屏幕前的您已经拥有了一个编辑器
var commandId = editor.addCommand(0,function () {alert('CodeLens被点击啦');},""
);
monaco.languages.registerCodeLensProvider("javascript", {provideCodeLenses: function (model, token) {return {lenses: [{range: {startLineNumber: 1,startColumn: 1,endLineNumber: 2,endColumn: 1,},id: "First Line",command: {id: commandId,title: "我是第一行",},},],};},
});
点它
CodeLens
类的 range
是必填的,CodeLens 是一个没有办法占据多行的东东,而且肯定是从一行的起始位置开始的,所以其实只有 startLineNumber
属性能影响它的位置;id
和 command
都不是必填的,但是如果要指定点击的回调函数,就必须要填 command
了。
二、使用API触发键盘事件
我们的鼠标右键有很多的命令,以及快捷键也绑定了很多命令,
除了直接通过点击事件触发,我们还可以通过调API触发这些命令的回调函数,有点类似于使用js触发DOM元素的点击事件 ele.click()
。
手动触发命令有两种方法,
editor.trigger(source, handlerId)
第一个source
是自己定义的一个字符串- 先使用
editor.getAction(actionId)
获取action
实例,然后再使用action
的run()
方法执行对应的回调函数。
addAction()
function addAction() {editor.addAction({// 不能重复id: 'bomb',// 展示在菜单中的文本label: 'Didara Bomb',// 快捷键keybindings: [monaco.KeyMod.CtrlCmd | monaco.KeyCode.F10,// 组合按键monaco.KeyMod.chord(monaco.KeyMod.CtrlCmd | monaco.KeyCode.KeyD,monaco.KeyMod.CtrlCmd | monaco.KeyCode.KeyM)],// 前提条件 String// 暂时只找到这一个例子,判断编辑器语言是不是 javascriptprecondition: "editorLangId == 'javascript'",// 绑定快捷键的规则keybindingContext: "editorLangId == 'javascript'",// 指定操作应显示在上下文菜单的哪个组中 navigation表示默认组contextMenuGroupId: 'navigation',// 操作在菜单中的显示顺序contextMenuOrder: 1.5,// 操作执行的方法// @param editor ed.getPosition() 获取焦点坐标run: function (ed) {alert("艺术就是💣💣💣💣💥💥💥💥" + ed.getPosition());}});
}setTimeout(() => {editor.trigger('bomb', 'bomb')
}, 1000)
setTimeout(() => {const action = editor.getAction('bomb')action.run()
}, 2000)
我这里是自定义了一个命令,然后通过延时器触发了两次这个命令。对于内置命令也可以这样触发
内置命令有 154 个,根据学习大佬的文章得知这些命令在editor实例的_actions里面保存着
真的是,深似海,关键是文档太粗糙🤓🤓🤓
而且还不能直接打印 console.log(editor._action)
,这样子的结果是 undefined
,大概因为加横线的属性是私有属性
例如要手动触发字号放大
setTimeout(() => {editor.trigger('fontZoomIn', 'editor.action.fontZoomIn')
}, 1000)
或者
setTimeout(() => {editor.getAction('editor.action.fontZoomIn').run()
}, 1000)
三、自动完成配置
这一节讲的就是自动补全相关的配置项
monaco 官网提供的有自动补全配置项的相关案例 completion-provider-example
自动补全也在 Languages 命名空间的统治范围内
export function registerCompletionItemProvider(languageSelector: LanguageSelector, provider: CompletionItemProvider): IDisposable;
第一个参数和上面的 CodeLens 设置的时候传的一样,我们用的话,传递字符串就够用了
第二个参数的定义也和CodeLens传的第二个参数很类似
export interface CompletionItemProvider {triggerCharacters?: string[];provideCompletionItems(model: editor.ITextModel, position: Position, context: CompletionContext, token: CancellationToken): ProviderResult<CompletionList>;resolveCompletionItem?(item: CompletionItem, token: CancellationToken): ProviderResult<CompletionItem>;
}
其中配置的关键就是 provideCompletionItems
方法
接收的参数:
model
:当前语言模型
position
:当前光标的位置
context
:自动完成的上下文
返回的 CompletionItem
的定义也和 CodeLens
定义很类似
export interface CompletionList {suggestions: CompletionItem[];incomplete?: boolean;dispose?(): void;
}
所以在这个方法里,我们主要的任务就是构建 CompletionList
数组,然后返回出去
关键的属性就是 suggestions
,它是 CompletionItem
组成的数组,这个接口的定义有一丢丢的复杂,属性稍微有一丢丢多
export interface CompletionItem {/*** 展示在自动补全列表中的文本*/label: string | CompletionItemLabel;/*** 类型,决定显示的图标 可选项:monaco.languages.CompletionItemKind 枚举值*/kind: CompletionItemKind;/*** 枚举值CompletionItemTag 只有一个选项 如果设置了表示废弃,自动补全元素上会出现划线*/tags?: ReadonlyArray<CompletionItemTag>;/*** 提供信息的字符串,会出现在选项的最右侧,如果没设置,就显示右箭头*/detail?: string;/*** 选型的详细描述,字符串或者markdown 点击右箭头或者 detail显示出来*/documentation?: string | IMarkdownString;/*** 用来调整顺序的字符串 如果设置为 falsy,那么顺序会往后排,默认的顺序是数组定义的顺序*/sortText?: string;/*** 用来筛选当前选项是否可用,如果设置为 falsy,则不会显示*/filterText?: string;/*** 预设 布尔值 如果设置为true,那么就会被默认选中,此时直接回车就直接应用了*/preselect?: boolean;/*** 实际插入的代码*/insertText: string;/*** 插入时额外的规则 枚举值 KeepWhitespace(自动调整插入文本的缩进) InsertAsSnippet(将insertText当做片段插入)*/insertTextRules?: CompletionItemInsertTextRule;/*** 自动补全的位置*/range: IRange | CompletionItemRanges;/*** 是一个数组,里面元素是单个字符,当选中选项的时候,再输入这几个指定的字符,就会插入insertText,并且将制定字符加到后面* 默认的选中按键是enter,这几个区别是还会将字符加到后面*/commitCharacters?: string[];/*** 选中时自动追加多行内容*/additionalTextEdits?: editor.ISingleEditOperation[];/*** 选中后执行的回调*/command?: Command;
}
-
label
与detail
-
kind
-
documentation
-
tags: [monaco.languages.CompletionItemTag.Deprecated]
-
preselect: true
,对应的选项会自动被选中
-
commitCharacters: ['a', 'b','c']
先选中对应选项
然后按下按键a
-
additionalTextEdits
如图想在开头插入代码,它会直接插入到指定位置,但是还需要自己换行
command
配置选中选项后的回调 但是不能是自定义的
export interface Command {id: string;title: string;tooltip?: string;arguments?: any[];
}
通过 id 指定 monaco提供的命令
例如添加代码后立马注释
command: {id: 'editor.action.commentLine',title: '注释选中的行',
}
自动补全配置代码:
function createDependencyProposals(range) {return [{label: 'monaco',kind: monaco.languages.CompletionItemKind.Reference, // 控制图标documentation: "定义一个不能修改的常量", // 点击右侧按钮出现在下边,详细说明detail: '我是detail属性', // 出现在选项的最右侧,几个字的内容insertText: 'console.log("monaco可真是太好用了")', // 实际插入的代码range: range, // 范围// tags: [monaco.languages.CompletionItemTag.Deprecated], // 出现划线,表示不建议preselect: true, // 预选中// filterText: 'falsy', // 不显示insertTextRules: monaco.languages.CompletionItemInsertTextRule.KeepWhitespace, // 插入的规则 InsertAsSnippet:作为代码块插入;KeepWhitespace:插入后自动格式化commitCharacters: ['a', 'b','c'], // 选中后输入这几个字符,自动插入代码和字符// additionalTextEdits: [// {// range: {// startLineNumber: 1,// startColumn: 1,// endLineMumber: 1,// endColumn:1// },// text: '// 这是一行额外加进来的代码',// forceMoveMarkers: true,// }// ],command: {id: 'editor.action.commentLine',title: '注释选中的行',}},];
}monaco.languages.registerCompletionItemProvider("javascript", {provideCompletionItems: function (model, position) {var word = model.getWordUntilPosition(position);var range = {startLineNumber: position.lineNumber,endLineNumber: position.lineNumber,startColumn: word.startColumn,endColumn: word.endColumn,};return {suggestions: createDependencyProposals(range),};},
});
本篇文章主要介绍了三个功能
CodeLens 代码信息提示器的配置和自动补全配置很类似,都是隶属于 languages 命名空间,从函数名上看,都是通过注册 Provider 的方式,增加配置,里面传参也很类似,第一个参数都是语言,第二个是配置项
CodeLens 和 Markers 很类似,都是提供代码提示的,帮助开发者更好的理解代码,但是 Markers 是鼠标浮动到代码上才会出现,并且可以显示的内容比较多,CodeLens 直接显示在代码里面,占据独立一行,但是不占用行号,复制时不会被复制到剪切板中。
自动补全配置很厉害,可以自定义菜单中显示的名称和位置、插入的代码、插入后的回调函数等等。
使用API触发键盘事件或者命令比较简单,一个是使用 monaco.editor.trigger()
,指定要触发的命令的id;一个是先获取 action
,调用action.run()
方法。
这篇关于Monaco Editor系列(七)代码信息指示器CodeLens、使用API触发键盘事件、自动完成配置的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!