codemirror6教程

news/2024/4/20 4:32:37/文章来源:https://blog.csdn.net/qq_43203949/article/details/128107891

codemirror6教程

文章目录

  • codemirror6教程
      • 两个概念
        • 编辑器视图
        • 编辑器状态
      • 安装Codemirror6
      • EditorState
        • 创建
      • EditorView
        • 创建
      • Compartment
        • 创建
        • 给编辑器动态的注入插件
        • 巧妙的封装
      • 插件
        • 基础插件(basicSetup)
        • 代码高亮插件
          • 静态高亮
          • 动态高亮
      • 在vue中的使用

两个概念

编辑器视图

视图用于展示文本的,在codemirror6中文本信息的展示使用的是EditorView这个类

编辑器状态

在codemirror6中,文本信息放到了EditorState这个类,EditorState可以展示在EditorView之上,改变EditorView里面的文本,可以更改页面上的文本展示。

安装Codemirror6

npm install codemirror

EditorState

编辑器状态,描述当前编辑器使用的插件,文本等信息

创建

import {EditorState,type Extension} from "@codemirror/state"
//创建编辑器状态
let state = EditorState.create({doc: str,  //这是文本extensions:this.codemirrorPlugin  //传入的插件数组
})

EditorView

编辑器视图,编辑器的展现

创建

let view = new EditorView({state:state, //编辑器状态,编辑器视图创建时初始化的状态parent:element //挂载的dom,可以通过parent挂载到指定的div块
})

Compartment

  • 一个特殊的插件类,也叫隔层,用于封装真正的插件,当插件传入EditorState后,我们是无法直接动态改变里面的插件的,如果要改变里面的插件,就需要用到Compartment封装插件。
  • Compartment就像一个隔箱一样,里面装插件
  • Compartment使用场景:用户需要根据选择的语言,动态更改语法高亮。(通过Compartment去修改编辑器的高亮插件)

创建

import {Compartment} from "@codemirror/state"
import { javascript } from '@codemirror/lang-javascript'
import {EditorState,Extension} from "@codemirror/state"const compartment = new Compartment()let state = EditorState.create({doc: "hello!!!",  //这是文本extensions:[compartment.of(javascript())  //]  //传入的插件数组
})//判断当前编辑器中是否存在当前的compartment封装过的插件
//当flag为真时,当前编辑器存在当前的compartment封装过的插件
let flag = compartment.get(view.state)

给编辑器动态的注入插件

import {EditorState,Extension, Compartment,StateEffect} from "@codemirror/state"
import {EditorView} from "@codemirror/view"
import {basicSetup} from "codemirror"
import { javascript } from '@codemirror/lang-javascript'
import {java} from '@codemirror/lang-java'let state = EditorState.create({doc: "hello!!!",  //这是文本extensions:[basicSetup]  //传入的插件数组
})
let view = new EditorView({state:state, //编辑器状态,编辑器视图创建时初始化的状态parent:element //挂载的dom,可以通过parent挂载到指定的div块
})
let compartment = new Compartment()// inject,向编辑器注入插件(如果在EditorState创建时传入,可以忽略这一步)
view.dispatch({ //通过dispatch发送事务effects: StateEffect.appendConfig.of(compartment.of(javascript())) 
})// reconfigure,向编辑器修改某个插件
view.dispatch({ effects: compartment.reconfigure(java()) 
}) 

巧妙的封装

通过createEditorCompartment()函数,我们就可以巧妙地封装插件

import {EditorState,type Extension, Compartment,StateEffect} from "@codemirror/state"
import {EditorView} from "@codemirror/view"
import { javascript } from '@codemirror/lang-javascript'
import {java} from '@codemirror/lang-java'
/*** 创建一个compartment,并和对其修改的run函数* @param view * @returns */// https://codemirror.net/examples/config/// https://github.com/uiwjs/react-codemirror/blob/22cc81971a/src/useCodeMirror.ts#L144// https://gist.github.com/s-cork/e7104bace090702f6acbc3004228f2cb
const createEditorCompartment = () => {const compartment = new Compartment()const run = (extension: Extension,view: EditorView) => {if(compartment.get(view.state)){//动态地重新配置插件view.dispatch({ effects: compartment.reconfigure(extension) }) // reconfigure}else{//向编辑器注入某一个插件view.dispatch({ effects: StateEffect.appendConfig.of(compartment.of(extension)) })// inject}}return { compartment, run }
}//使用
let {compartment, run} = createEditorCompartment()
//注入
run(javascript(),view)
//修改
run(java(),view)

插件

基础插件(basicSetup)

basicSetup提供了基础的插件功能,如:行数,折叠,历史记录,选择高亮,快捷键映射

import {basicSetup} from "codemirror"
EditorState.create({doc: str,  //这是文本extensions:[basicSetup]  //传入的插件数组
})

basicSetup的源码

const basicSetup = (() => [view.lineNumbers(),  //行数view.highlightActiveLineGutter(),view.highlightSpecialChars(),commands.history(), //历史插件language.foldGutter(), //折叠view.drawSelection(),view.dropCursor(),state.EditorState.allowMultipleSelections.of(true), //复数选择(编辑器查找替换功能会用到)language.indentOnInput(),language.syntaxHighlighting(language.defaultHighlightStyle, { fallback: true }),language.bracketMatching(),autocomplete.closeBrackets(),autocomplete.autocompletion(),  //语法提示view.rectangularSelection(),view.crosshairCursor(),view.highlightActiveLine(),  //激活行高亮插件search.highlightSelectionMatches(),  //选择匹配高亮view.keymap.of([   //一些快捷键映射...autocomplete.closeBracketsKeymap,...commands.defaultKeymap,...search.searchKeymap,...commands.historyKeymap,...language.foldKeymap,...autocomplete.completionKeymap,...lint.lintKeymap])
])();

代码高亮插件

静态高亮

如果只是高亮个别代表代码,可以通过加载不同的高亮包去高亮代码

import { javascript } from '@codemirror/lang-javascript'EditorState.create({doc: str,  //这是文本extensions:[javascript()]  //传入的插件数组
})
动态高亮

如果需要动态加载高亮,需要引用包加载,其中languageDescription.support指向的是高亮插件,只有当语言包加载了后languageDescription.support才不为空

//语言包描述
import {LanguageDescription} from "@codemirror/language"
//语言包
import {languages} from "@codemirror/language-data"//根据语言名称匹配语言描述信息
const languageDescription = LanguageDescription.matchLanguageName(languages, "java", true);
//语言高亮插件支持
let support = languageDescription.supportif(support){//已经加载//跟新语言高亮插件支持//...........
}else{//去加载并跟新languageDescription.load().then(s=>{//s是语言高亮插件//...........})
}

加载完语言包,还有一个重要的步骤,替换编辑器视图中的语言包,结合上面的Compartment,我们就可以很轻松的对高亮插件进行注入和修改。

//语言包描述
import {LanguageDescription} from "@codemirror/language"
//语言包
import {languages} from "@codemirror/language-data"/*** 创建一个compartment,并和对其修改的run函数* @param view * @returns */// https://codemirror.net/examples/config/// https://github.com/uiwjs/react-codemirror/blob/22cc81971a/src/useCodeMirror.ts#L144// https://gist.github.com/s-cork/e7104bace090702f6acbc3004228f2cb
const createEditorCompartment = () => {const compartment = new Compartment()const run = (extension: Extension,view: EditorView) => {if(compartment.get(view.state)){//动态地重新配置插件view.dispatch({ effects: compartment.reconfigure(extension) }) // reconfigure}else{//向编辑器注入某一个插件view.dispatch({ effects: StateEffect.appendConfig.of(compartment.of(extension)) })// inject}}return { compartment, run }
}let state = EditorState.create({doc: "hello!!!",  //这是文本extensions:[basicSetup]  //传入的插件数组
})
let view = new EditorView({state:state, //编辑器状态,编辑器视图创建时初始化的状态parent:element //挂载的dom,可以通过parent挂载到指定的div块
})
//根据语言名称匹配语言描述信息
const languageDescription = LanguageDescription.matchLanguageName(languages, "java", true);
//注入Java高亮插件
languageDescription.load().then(support=>{run(support,view)
})

在vue中的使用

<template><div id="editor"></div>
</template><script lang="ts" setup>
import {onMounted} from 'vue'
import {EditorState,Extension, Compartment,StateEffect} from "@codemirror/state"
import {EditorView} from "@codemirror/view"
import {basicSetup} from "codemirror"/*** 创建一个compartment,并和对其修改的run函数* @param view * @returns */// https://codemirror.net/examples/config/// https://github.com/uiwjs/react-codemirror/blob/22cc81971a/src/useCodeMirror.ts#L144// https://gist.github.com/s-cork/e7104bace090702f6acbc3004228f2cb
const createEditorCompartment = () => {const compartment = new Compartment()const run = (extension: Extension,view: EditorView) => {if(compartment.get(view.state)){//动态地重新配置插件view.dispatch({ effects: compartment.reconfigure(extension) }) // reconfigure}else{//向编辑器注入某一个插件view.dispatch({ effects: StateEffect.appendConfig.of(compartment.of(extension)) })// inject}}return { compartment, run }
}//动态语言包函数
let {compartment, run } = createEditorCompartment()
let editor = null
const updateLang = (lang:string) => {//根据语言名称匹配语言描述信息const languageDescription = LanguageDescription.matchLanguageName(languages, "java", true);//注入高亮插件languageDescription.load().then(support=>{run(support,editor)})
}//挂载
onMounted(() => {let element = document.getElementById("editor")let state = EditorState.create({doc: "hello!!!",  //这是文本extensions:[basicSetup]  //传入的插件数组})let view = new EditorView({state:state, //编辑器状态,编辑器视图创建时初始化的状态parent:element //挂载的dom,可以通过parent挂载到指定的div块})editor = view
})</script>

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

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

视频编解码 - RTP 与 RTCP

目录 RTP 实时传输协议 RTCP协议 将H264 RTP打包 RTP 实时传输协议 音视频数据传输&#xff0c;先将原始数据经过编码压缩后&#xff0c;将码流打包成一个个RTP包&#xff0c;再将码流传输到接收端。 打包的作用 接收端要正确地使用这些音视频编码数据&#xff0c;不仅仅需…

JaVers:自动化数据审计

在开发应用程序时&#xff0c;我们经常需要存储有关数据如何随时间变化的信息。此信息可用于更轻松地调试应用程序并满足设计要求。在本文中&#xff0c;我们将讨论 JaVers 工具&#xff0c;该工具允许您通过记录数据库实体状态的更改来自动执行此过程。 Javers如何工作&#x…

vue Router

Vue项目各文件含义 1.src文件夹 是我们真正敲代码的文件夹&#xff0c; 2.assets放静态资源 3.components放组件 4.App.vue主组件 5.main.js项目的入口文件 Vue Router 在router/index.js路由文件中配置路由&#xff0c;设置路由跳转规则 import Vue from vue import Vu…

android Framework 中用到了哪些跨进程通信方式?

文章目录Linux 有哪些跨进程的通信方式&#xff1f;管道本地 Socket共享内存信号Linux 有哪些跨进程的通信方式&#xff1f; Binder 机制是Android基于Linux的一种独特的IPC机制。我们常用的AMS&#xff0c;PMS 等都是通过Binder机制来完成跨进程通信的&#xff0c;那么除了Bin…

【并发】深入理解Java线程的底层原理

线程基础知识 线程与进程 进程 操作系统会以进程为单位&#xff0c;分配系统资源&#xff08;CPU时间片、内存等资源&#xff09;&#xff0c;进程是资源分配的最小单位。 当一个程序被运行&#xff0c;从磁盘加载这个程序的代码至内存&#xff0c;这时就开启了一个进程。 线…

使用 Mason 创建自己的 Flutter brick

使用 Mason 创建自己的 Flutter brick 原文 https://medium.com/gytworkz/create-your-own-flutter-brick-using-mason-7abc70d0324e 前言 谁不喜欢用最少的努力完成大部分事情呢&#xff1f;我当然知道! &#xff01;Mason 帮我完成了几个简单的步骤。 在本文中&#xff0c;我…

Redis——》数据类型:List(列表)

推荐链接&#xff1a; 总结——》【Java】 总结——》【Mysql】 总结——》【Redis】 总结——》【Spring】 总结——》【SpringBoot】 总结——》【MyBatis、MyBatis-Plus】 Redis——》数据类型&#xff1a;List&#xff08;列表&#xff09;一、简介…

复现黑客在后门中藏匿后门

PHP实现在后门中藏匿后门 在攻击渗透的时候会传入shell后门方便进行远控。其中的后门包括多种类型&#xff0c;大马是功能最全的直接提供了可视化的界面方便攻击者进行提权、扫描、上传等一系列的操作。 但有很多hacker不讲武德&#xff0c;在写好的大马中藏入自己的后门&…

VBA Regex 正则表达式应用介绍

. VBA正则表达式介绍 正则表达式或 RegEx 用于在字符串中查找特定的字符。 本文将展示一个 VBA RegEx 示例,并演示为什么在 VBA 中使用正则表达式如此强大。 正则表达式是一个比较大的话题,关于这方面的书很多。 同时也是一个让许多人感到害怕的话题,因为它的语法比较神秘和…

C++入门笔记

C 入门笔记Functions in CC header Files下面主要是我学习C的一个笔记&#xff0c;记录学习中遇到的一些重点事项。下面是视频的连接https://www.bilibili.com/video/BV1Ay4y1i7Z6/?p10&spm_id_from333.1007.top_right_bar_window_history.content.click&vd_sourcee6e…

记录--两行CSS让页面提升了近7倍渲染性能!

这里给大家分享我在网上总结出来的一些知识&#xff0c;希望对大家有所帮助 前言 对于前端人员来讲&#xff0c;最令人头疼的应该就是页面性能了&#xff0c;当用户在访问一个页面时&#xff0c;总是希望它能够快速呈现在眼前并且是可交互状态。如果页面加载过慢&#xff0c;你…

第四章. Pandas进阶—时间序列

第四章. Pandas进阶 4.9 时间序列 1.重采样&#xff08;resample&#xff09; 在Pandas中&#xff0c;对时间序列频率的调整称为重采样&#xff0c;即时间序列从一个频率转换到另一个频率的过程&#xff0c;由周统计变成月统计 1).语法&#xff1a; 4.8章 第4点 已介绍过&…

MySQL数据库行级锁之间隙锁、临键锁

间隙锁 默认情况下&#xff0c;InnoDB在 REPEATABLE READ事务隔离级别运行&#xff0c;InnoDB使用 next-key 锁进行搜索和索引扫描&#xff0c;以防止幻读。 索引上的等值查询(唯一索引)&#xff0c;给不存在的记录加锁时, 优化为间隙锁 。索引上的等值查询(非唯一普通索引)&…

如果把网络原理倒过来看,从无到有,一切如此清晰(下)

人生若只如初见。 前言 当我在台灯下&#xff0c;听着远隔17年前五月天的歌&#xff0c;而在数日后&#xff0c;我的文字也会纵使相隔万里远的来到你的屏幕前&#xff0c;就觉得这一切妙不可言。 OSI 网络七层模型 《如果把网络原理倒过来看&#xff0c;从无到有&#xff0c…

Seal库官方示例(二):encoders.cpp解析

补充一个常用的SIMD操作原理 图片来自的Hang Shao的文章。 完整代码 这个代码主要功能是编码明文&#xff0c;使得能够使用更加完整的明文多项式&#xff08;前一个只用到了一个多项式的常量&#xff09;&#xff0c;也就是SIMD操作。主要包含了两个部分&#xff0c;一个是BG…

HLS + ffmpeg 实现动态码流视频服务

一、简介 如下图&#xff0c;包含三部分&#xff0c;右边一列为边缘节点&#xff1b;中间一列代表数据中心&#xff1b;左边一列是项目为客户提供的一系列web管理工具&#xff1a; 具体来说在我们项目中有一堆边缘节点&#xff0c;每个节点上部署一台强大的GPU服务器及N个网络…

精彩回顾 | 苏州农商银行新一代云原生信息科技架构体系实践

11月18日&#xff0c;2022年第五届中国金融科技产业大会暨第四届中新&#xff08;苏州&#xff09;数字金融应用博览会“基础软件与云原生系统软件”分论坛成功举办。该论坛由由中国计算机学会CTO CLUB&#xff08;苏州&#xff09;承办&#xff0c;江苏省金融科技云原生融合创…

目标检测数据标注项目分析-产品缺陷检测

什么是生产过程中的产品缺陷检测? 生产过程中的缺陷检测是保证产品质量的重要环节。及时发现故障或缺陷&#xff0c;并采取适当的措施&#xff0c;我们可以降低运行和质量相关的风险。但在一般视觉系统中&#xff0c;每个缺陷都必须经过检查及预处理才能被检测到&#xff0c;…

javaSE - Arrays - 数组的定义与使用

一、数组基本用法 1.1、什么是数组 数组本质上就是让我们能 “批量” 创建相同类型的变量 也可以说是存储一组相同数据类型的数据的集合 如: 如果需要表示两个数据, 那么直接创建两个变量即可 int a; int b 如果需要表示五个数据, 那么可以创建五个变量 int a1; int a2; int …

[附源码]Python计算机毕业设计Django的4s店车辆管理系统

项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等等。 环境需要 1.运行环境&#xff1a;最好是python3.7.7&#xff0c;…