codemirror 5前端代码编辑器资料整理。

news2024/11/25 9:44:58

CodeMirror 是基于js的源代码编辑器组件,它支持javascript等多种高级语言,tampermonkey内置的代码编辑器就是基于它。它的按键组合方式兼容vim,emacs等,调用者还可自定义”自动完成“的列表窗口,自由度极高,相当成熟。

但是这个库也是问题多多,很需要深度配置、改良优化。

前排提示:由于信息闭塞,所以才研究了 codemirror 5。研究完才发现, codemirror 5官方基本处于弃坑状态,issue没人理。最新版本是 codemirror 6,仍在开发当中,但各方面效果已经,明显优于 codemirror 5。

0. 入门

入门很简单,可以F12观察官方demo是怎么实现的:

https://codemirror.net/ (codemirror 6

https://codemirror.net/examples/

https://codemirror.net/5/

关键代码:

<!-- Create a simple CodeMirror instance -->
<link rel="stylesheet" href="lib/codemirror.css">
<script src="lib/codemirror.js"></script>
<script>
  var editor = CodeMirror.fromTextArea(myTextarea, {
    lineNumbers: true
  });
  v
</script>

官方demo都是直接运行在文档页面上的。而且在编辑框内,显示的是demo自身的代码。有许多这样的小例子。

附本地运行方式:

  1. 从GitHub下载整个仓库,里面有些(比如核心库codemirror.js)是需要编译后才能运行,但有些就是普通的js代码(比如各种addon、mode),以及样式文件 codemirror.css。
  2. 从cdn或官方的demo示例中查找核心库地址:codemirror.js,这虽然是多模块编译出来的,但未经混淆,直接用vscode阅读修改并无不可,甚至效率更高。
  3. 编辑并预览 demo.html。

1. 需求:用任意键触发自动完成

https://stackoverflow.com/questions/13744176/codemirror-autocomplete-after-any-keyup

关键代码:

editor.on("keyup", function (cm, event) {
//  …… 判断条件,过滤一些按键,过滤某些上下文情况。
            CodeMirror.commands.autocomplete(cm, null, {completeSingle: false});
    });

如果只要ctrl+space触发自动完成的话,是这样配置的:

var editor=CodeMirror.fromTextArea(document.getElementById("code"),{
		……
		, extraKeys:{"Ctrl-Space":"autocomplete"}
		// 或者 :
		, extraKeys:{"Ctrl-Space":'Ctrl-Space': (cm) => 				 
			{
				cm.showHint()
			}}
		}	
	});

2. 让自动完成窗口同时 ① 包含 buffer 中提取的上下文关键词(anyword)②包含 javascript 语言的关键词。

https://discuss.codemirror.net/t/anyword-hinting-while-in-javascript-mode/1506/7

关键代码:

	function hintingFunction(cm) {
		const anyhint = CodeMirror.hint.anyword(cm, options)
		const jshint = CodeMirror.hint.javascript(cm, options)
		const words = new Set([...anyhint.list, ...jshint.list])
		if (words.size > 0) {
			return {
				list: Array.from(words), 
				from: jshint.from, 
				to: jshint.to
			}
		}
	}
	
	…… { completeSingle: false, hint: hintingFunction } …… 

如果只学习官方的短demo:

	CodeMirror.commands.autocomplete = function(cm) {
		CodeMirror.showHint(cm, CodeMirror.hint.anyword);
	}

,这样是不行的,因为只返回了anyword分析出的上下文关键词,导致javascript关键词被覆盖!

而 gpt 给的答案则更是搞笑:

	CodeMirror.commands.autocomplete = function(cm) {
		CodeMirror.showHint(cm, CodeMirror.hint.anyword);
		CodeMirror.showHint(cm, CodeMirror.hint.javascript);
	}

整天瞎编,机器人这会儿的鼻子已经到达银河系中心了吧!

注意需要正确引入 “codemirror5-master/mode/javascript/javascript.js”,不然没有 CodeMirror.hint.javascript(自动完成),还要引入 “codemirror5-master/addon/hint/javascript-hint.js”,不然也没有 mode:"application/javascript" (语法高亮)!

3. 换行回车时,保持原有缩进。

这是 tampermonkey 编辑器最让我不爽的一点:每次在方法之间换行,都把缩进吃了。后来干脆换用vscode + @require file:///本地文件.user.js 的方式,不再用它的内置编辑器。现在,我几乎站在了同一起点,自然要比前辈做得好!

查阅资料后发现,原来“把缩进吃了”是特性,而不是bug,关掉即可:

mode : ……
, smartIndent: false

真是杀马特啊。

可关掉之后,function() { 回车后,就不会自动添加应该有的缩进了,伤脑筋……

最后通过修改 codemirror.js,让杀马特indent只自动增、不自动减:

if (how == "smart") {
	……
	indentation = Math.max(state.indented, indentation);

4. 禁止自动滚动

给安卓用,需要禁止在点击屏幕、设置光标的时候,自动发生横向滚动,以便检阅代码。

复述需求:当移动设备用户检阅代码时,很有可能正在查看长代码行,到触碰到代码行底部时,可能意外导致横向滚动归零。

此功能看起来难于实现,实则很简单:新增options.scrollOnClick,未设置时,不触发 ensureCursorVisible 即可:

  function setSelectionNoUndo(doc, sel, options) {
  	……
	if(doc.cm && doc.cm.options.scrollOnClick) // 不自动触发横向滚动,除非打字。
    if (!(options && options.scroll === false) && doc.cm && doc.cm.getOption("readOnly") != "nocursor")
      { ensureCursorVisible(doc.cm); }
  }

5. 重排自动完成列表,使常用关键词前置化

比如 敲v,自动列表为:

请添加图片描述
不合理。

通过进一步修改上面的 hintingFunction 来完成:

 		if (words.size > 0) {
			var list = Array.from(words);
			console.log(list);
			if(list[0][0]=='v'){
				var varIdx = list.indexOf("var");
				if(varIdx>0) { // 如果关键词 var 排位大于零,则交换。
					var tmp = list[0];
					list[0] = "var";
					list[varIdx] = tmp;
				}
			}
			……

方法简单粗暴,但管用:
请添加图片描述

6. 多文档与编辑状态

像scintilla这种,是一个ui呈现,切换多份不同的文件buffer。

CodeMirror 有所不同,可以从多个 TextArea 创建多份 editor 实例,比较方便。

编辑状态:需要知晓当前文档是否可以:保存、撤销、重做等状态。

↳→→ 查看 文档是否被修改:editor.doc.isClean()

↳→→ 设置 文档已保存:editor.doc.markClean()

查看 当前修改堆栈:editor.doc.history

↳→→→ 分为 : editor.doc.history.done 撤销栈、 editor.doc.history.undone 重做栈,是否读取长度就可以了呢?不行,因为修改文本选择也会算入其中。因此需要筛选出其中的 changes:

请添加图片描述

不关键代码:

		function updatePreview() {
			console.log('编辑器状态 需要保存='+!editor.doc.isClean(), "可撤销="+backable(), "可重做="+forwardable())
		}

7. 实战之实现安卓端 用户脚本编辑器

webview-gm 可以让普通的安卓weview也支持运行用户脚本(如via浏览器)。webview-gm-demo 项目中自带的编辑器就是一个 editortext,可以用 codemirror 改进。

实测在安卓端发现一个比较严重的BUG,如果用 \t 缩进,则用输入法打字的时候,会自动删除 \t 后面打出来的字符,而且是持续化删除,不知如何解决,已在github上反馈问题,顺便帮via浏览器出出名,锦上添花。(android 10 chars got deleted automatically & continuously sometimes #7036)

反馈问题后就睡觉了,第二天还是没消息。无奈只好自己下手。有人可能会问, – "为什么不用空格缩进呢? " – 空格缩进 太乱,有的用四个空格,有的用两个,甚至一个,不规范。而且用 tab 缩进还有一个空格缩进无法比拟的好处:如果需要将输入光标移动至行首,tab缩进的,只需点击第一个 tab 的前半部分即可;而多个空格缩进的,则需要精确点击第一个空格之前才行,实为反人类设计。

这种小问题无非是哪处开关问题。我用肉眼稍微扫描一遍代码,就已经定位问题所在:

option("inputStyle", mobile ? "contenteditable" : "textarea", function () {

通过在editor构造参数中传入 inputStyle : “textarea” 似乎即可解决问题。

然而…… 在 textarea 的编辑方式下,安卓上的文本选择没有了,无法选择代码段,这个bug一样严重。

所以……需要继续研究。需要开启打log模式,通过不断地运行、记录,来摸清代码运行路线,来定位问题症结所在。

最终,发现在 inputStyle : “contenteditable” 的编辑模式下,安卓输入法会将文本输入到 tab 元素之中,而tab元素有个 cm-text 属性,导致新输入的文本被忽略:

    function walk(node) {
      if (node.nodeType == 1) {
        var cmText = node.getAttribute("cm-text");
        if (cmText) {
          addText(cmText);
          return
        }
<span class="cm-tab" role="presentation" cm-text="	">    h</span>

可以看到,tab 元素里面其实还是四个空格,只不过用 cm-text=" " 标明了这其实是一个 \t 符号。可以修改相关代码,取消 cm-text 的遮蔽作用。

令人欣慰的是,codemirror 竟然会检测环境中的变量,比如在 via 浏览器中是这样的:
请添加图片描述
打出来后,似乎还能进一步读取对象的属性!

codemirror 6 更进一步,默认配置就是这样的,融合了anyword hints 与 javascript hints,var关键词也处于首位,而且还有方法模板、关键词双击高亮,更像ide了。

不过 codemirror 6 首页demo里的库是混淆过的,github 仓库里代码很少,不知是怎么一个结构。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Android studio 按钮状态列表

1.创建一个drawable&#xff0c;类型selector 。 <?xml version"1.0" encoding"utf-8"?> <selector xmlns:android"http://schemas.android.com/apk/res/android"><!--被按下状态 --><item android:state_pressed"…

信息安全复习三:古典密码之设计好的密码算法

一.章节梗概 讨论以下算法&#xff0c;理解怎么设计好的密码算法的关键问题 1.Caesar cipher 2.单字母表密码 3.Playfairmima 4.维吉尼亚密码 5.自动生成密码 二.Caesar cipher 2.1 穷举攻击 穷举攻击定义&#xff1a;尝试所有密钥直到有一个合法密钥能够把密文还原成明文&…

软考软件设计师 操作系统笔记

操作系统地位 程序顺序执行&#xff08;进程管理&#xff09; 程序顺序执行的特征&#xff0c;顺序性封闭性可再现性 前趋图 P1结束后 V操作 SS1 P2操作前先执行S S -1 此时S0 一个箭头对应一个信号量 程序并发执行和前驱图 找到输入i计算c输出p&#xff0c;如果找不到就…

结合实战,浅析GB/T28181(十)——媒体流保活

1 问题现象 在实际项目对接过程中&#xff0c;我们有时会碰到这样的问题&#xff1a;视频正在播放着&#xff0c;突然停止了。然后ping一下&#xff0c;也能ping通&#xff01;下级平台或上级平台看起来也在线&#xff0c;看起来不是网络的问题。这到底咋回事呢&#xff1f;一…

实验室电磁铁EM4S的技术参数

锦正茂科技自主研发的电磁铁&#xff0c;可以通过更换电磁铁极头在一定范围内改善磁场的大小和磁场的均匀度 &#xff0c;并且可以通过调整极头间距改变磁场的大小&#xff0c;该种类型的电磁铁能够很好的与客户设计的磁场平台兼容。主要用于磁滞现象研究、磁化系数测量、霍尔效…

公派访问学者签证申请需提交的材料

公派访问学者签证申请需提交的材料: 1、《公派留学人员基本情况表》。 2、留学基金委出具的《同意派出函》复印件一份(特殊项目除外)。 3、录取文件复印件一份。(如您是改派国别、延期派出、缩短在外留学期限等&#xff0c;还要提交留学基金委出具的相关文件复印件一份)。 4…

dtype = torch.float32到底有什么用

dtype torch.float32到底有什么用 解决&#xff1a;RuntimeError: expected scalar type Long but found Float 先看一个例子 要计算 z x0 w1x1 w2x2 其中w [-0.2,0.15,0.15] 于是你开始尝试 其中torch.mv用于矩阵*向量 此时你发现他需要你提供float格式的数据 你查看发…

(一)MYSQL实战——用户权限控制管理

前言 mysql作为目前最流行的关系型数据库&#xff0c;被广泛使用在各种系统服务中&#xff0c;本节内容主要是关于mysql数据库在生产环境中用户、权限等相关内容的设置说明&#xff0c;便于我们更好的使用和管理我们的数据库。 正文 SQL的分类 ①数据查询语言&#xff08;Da…

SpringBoot日志

日志有什么用&#xff1f; 日志最主要的用途就是排查和定位错误&#xff0c;除此之外&#xff0c;日志还可以将错误信息具体化&#xff0c;比如时间、位置等。 如何打印日志 使用Logger类 使用方法&#xff1a; Logger log LoggerFactory.getLogger&#xff08;类名/类名…

MVCC实现原理

MVCC实现原理 主要依赖隐藏字段undo logundolog生成的记录链 Read View可见性规则三个全局属性具体的比较规则 MVCC的整体处理流程RC、RR级别下的InnoDB快照读有什么不同 主要依赖 mvcc的实现原理主要依赖于记录中的三个隐藏字段&#xff08;对用户来说是不可见的&#xff09;…

【Spring Cloud Alibaba】8.路由网关(Gateway)

文章目录 简介什么是 Spring Cloud Gateway功能介绍工作流程 开始搭建创建项目修改POM文件添加启动类添加配置文件启动项目测试 网关全局过滤创建全局过滤器测试 结尾 简介 接下来对服务消费者添加路由网关来实现统一访问接口&#xff0c;本操作先要完成之前的步骤&#xff0c…

API 自动化测试难点总结与分享

笔者是 API 管理工具的项目参与者之一&#xff0c;在日常工作中会经常遇到 API 自动化测试难点&#xff0c;我决定总结分享给大家&#xff1a; API 自动化测试的难点包括&#xff1a; 接口的参数组合较多&#xff0c;需要覆盖各种可能的情况。 接口的状态和数据关联较多&#…

DJ4-1 存储器的层次结构

目录 4.1.1 存储器的层次结构 1. 主存储器&#xff08;内存&#xff0c;主存&#xff0c;可执行存储器&#xff09; 2. 寄存器 3. 高速缓存 4. 磁盘缓存 存储器层次结构的特点 4.1.2 存储器管理的目的和功能 1. 主存储器的分配和管理 2. 提高主存储器的利用率 3. 扩…

基于ArcGIS Pro、Python、USLE、INVEST模型等多技术融合的生态系统服务构建生态安全格局

近年来&#xff0c;由于社会经济的快速发展和人口增长&#xff0c;社会活动对环境的压力不断增大&#xff0c;人地矛盾加剧。虽然全球各国在生态环境的建设和保护上已取得不少成果&#xff0c;但还是未从根本上转变生态环境的恶化趋势&#xff1b;生态破坏、环境退化、生物多样…

OceanMind海睿思入选“2023爱分析·智能制造最佳实践案例”

近日&#xff0c;中国领先的产业数字化研究与咨询机构 爱分析 发布了《2023爱分析智能制造最佳实践案例》&#xff0c;该奖项旨在肯定智能制造领域领先企业的数字化创新应用和最佳实践。 中新赛克海睿思凭借为星宇股份构建的“星宇车灯数据智能解决方案”入选智能制造最佳实践…

AWR1642毫米波雷达实测行人、自行车和汽车等目标

本文编辑 | 调皮哥的小助理 AWR1642因为最大中频带宽 固定只有5MHz&#xff0c;最大中频带宽是发射信号与回波信号混频之后得到的最大中频频率&#xff0c;即代表着最大的回波延迟时间。 因此根据雷达方程和目标最大探测距离公式&#xff0c;如下所示&#xff1a; 复采样&…

一文谈谈文心一言对比ChatGPT4.0的差距

对于想体验文心一言的朋友&#xff0c;可以进行申请尝试&#xff0c;快速入口 如果想体验ChatGPT的朋友&#xff0c;可以自行fq注册&#xff1b;但是由于现在限制注册并且不稳定&#xff0c;对于不会用梯子不想注册的朋友可以使用这个进行访问&#xff0c;快速入口 关于ChatG…

CTF之SSRF常见绕过

1.绕过localhost和127.0.0.1 当程序中限制了我们使用localhost和127.0.0.1时&#xff0c;便可以利用进制转换来绕过 http://0x7F.0.0.1 //16进制 http://0177.0.0.1 //8进制 http://2130706433 //10进制整数格式 http://0x7F000001 16进制整数格式 http://127.1 //省略模式 h…

【算法】C程序的运行速度测试

C语言程序的运行速度测试 代码随想录上提到了一点&#xff0c;即我们应该学会估计一个时间复杂度较高的算法&#xff0c;在机器上的运行速度。 如果题目给出的数据量级在高复杂度的算法中会超时&#xff0c;那就应该放弃使用这个代码&#xff0c;而想其他时间复杂度更优的解法…

QMS-云质说质量 - 9 我和我的客户投诉(1) - 逢年过节要祈祷

云质QMS原创 转载请注明来源 作者&#xff1a;王洪石 逢年过节都要祈祷 在某外资汽车零部件企业工作的那些年&#xff0c;无论在质量部还是项目部&#xff0c;都是成天和客户打交道&#xff0c;也经常面对各种各样的客户投诉。 尤其是当质量经理的那些年&#xff0c;每年都要被…