Monaco Editor系列(七)代码信息指示器CodeLens、使用API触发键盘事件、自动完成配置

本文主要是介绍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 属性能影响它的位置;idcommand 都不是必填的,但是如果要指定点击的回调函数,就必须要填 command 了。

二、使用API触发键盘事件

我们的鼠标右键有很多的命令,以及快捷键也绑定了很多命令,
在这里插入图片描述
除了直接通过点击事件触发,我们还可以通过调API触发这些命令的回调函数,有点类似于使用js触发DOM元素的点击事件 ele.click()
手动触发命令有两种方法,

  • editor.trigger(source, handlerId) 第一个 source 是自己定义的一个字符串
  • 先使用 editor.getAction(actionId) 获取 action 实例,然后再使用 actionrun() 方法执行对应的回调函数。
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;
}
  • labeldetail
    在这里插入图片描述

  • 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触发键盘事件、自动完成配置的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!


原文地址:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.chinasem.cn/article/1033222

相关文章

Mac备忘录怎么导出/备份和云同步? Mac备忘录使用技巧

《Mac备忘录怎么导出/备份和云同步?Mac备忘录使用技巧》备忘录作为iOS里简单而又不可或缺的一个系统应用,上手容易,可以满足我们日常生活中各种记录的需求,今天我们就来看看Mac备忘录的导出、... 「备忘录」是 MAC 上的一款常用应用,它可以帮助我们捕捉灵感、记录待办事项或保存重要信息。为了便于在不同

通过cmd获取网卡速率的代码

《通过cmd获取网卡速率的代码》今天从群里看到通过bat获取网卡速率两段代码,感觉还不错,学习bat的朋友可以参考一下... 1、本机有线网卡支持的最高速度:%v%@echo off & setlocal enabledelayedexpansionecho 代码开始echo 65001编码获取: >

Java集成Onlyoffice的示例代码及场景分析

《Java集成Onlyoffice的示例代码及场景分析》:本文主要介绍Java集成Onlyoffice的示例代码及场景分析,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要... 需求场景:实现文档的在线编辑,团队协作总结:两个接口 + 前端页面 + 配置项接口1:一个接口,将o

qtcreater配置opencv遇到的坑及实践记录

《qtcreater配置opencv遇到的坑及实践记录》我配置opencv不管是按照网上的教程还是deepseek发现都有些问题,下面是我的配置方法以及实践成功的心得,感兴趣的朋友跟随小编一起看看吧... 目录电脑环境下载环境变量配置qmake加入外部库测试配置我配置opencv不管是按照网上的教程还是de

如何Python使用设置word的页边距

《如何Python使用设置word的页边距》在编写或处理Word文档的过程中,页边距是一个不可忽视的排版要素,本文将介绍如何使用Python设置Word文档中各个节的页边距,需要的可以参考下... 目录操作步骤代码示例页边距单位说明应用场景与高级用China编程途小结在编写或处理Word文档的过程中,页边距是一个

Logback在SpringBoot中的详细配置教程

《Logback在SpringBoot中的详细配置教程》SpringBoot默认会加载classpath下的logback-spring.xml(推荐)或logback.xml作为Logback的配置... 目录1. Logback 配置文件2. 基础配置示例3. 关键配置项说明Appender(日志输出器

SpringBoot项目Web拦截器使用的多种方式

《SpringBoot项目Web拦截器使用的多种方式》在SpringBoot应用中,Web拦截器(Interceptor)是一种用于在请求处理的不同阶段执行自定义逻辑的机制,下面给大家介绍Sprin... 目录一、实现 HandlerInterceptor 接口1、创建HandlerInterceptor实

使用JavaConfig配置Spring的流程步骤

《使用JavaConfig配置Spring的流程步骤》JavaConfig是Spring框架提供的一种基于Java的配置方式,它通过使用@Configuration注解标记的类来替代传统的XML配置文... 目录一、什么是 JavaConfig?1. 核心注解2. 与 XML 配置的对比二、JavaConf

使用Python和Tkinter实现html标签去除工具

《使用Python和Tkinter实现html标签去除工具》本文介绍用Python和Tkinter开发的HTML标签去除工具,支持去除HTML标签、转义实体并输出纯文本,提供图形界面操作及复制功能,需... 目录html 标签去除工具功能介绍创作过程1. 技术选型2. 核心实现逻辑3. 用户体验增强如何运行

SpringBoot实现Kafka动态反序列化的完整代码

《SpringBoot实现Kafka动态反序列化的完整代码》在分布式系统中,Kafka作为高吞吐量的消息队列,常常需要处理来自不同主题(Topic)的异构数据,不同的业务场景可能要求对同一消费者组内的... 目录引言一、问题背景1.1 动态反序列化的需求1.2 常见问题二、动态反序列化的核心方案2.1 ht