codemirror6教程

codemirror6教程

两个概念

编辑器视图

视图用于展示文本的,在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.support

if(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>

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
CodeMirror 是一个用 JavaScript 编写的基于浏览器的代码编辑器。它支持超过 100 种语言和文件格式,包括 HTML、CSS、JavaScript、Python 等。CodeMirror 不仅具有语法高亮和自动代码补全等常见的代码编辑器功能,还支持多光标编辑、搜索替换、折叠代码块等高级功能。以下是 CodeMirror 的使用教程。 ## 安装 可以通过以下方式来安装 CodeMirror: ### 下载文件 从 CodeMirror 的官方网站 https://codemirror.net/ 下载最新版本的 CodeMirror 文件,然后将 `codemirror.js`、`codemirror.css` 和 `theme` 目录下的样式文件复制到你的项目中。 ### 使用 npm 安装 如果你使用 npm 管理你的项目依赖,可以通过以下命令来安装 CodeMirror: ``` npm install codemirror ``` ## 基本使用 ### HTML 在 HTML 文件中,你需要引入 CodeMirror 的 CSS 和 JavaScript 文件,并创建一个 `textarea` 元素或一个 `div` 元素来显示代码编辑器。 ```html <!DOCTYPE html> <html> <head> <link rel="stylesheet" href="path/to/codemirror.css"> <script src="path/to/codemirror.js"></script> </head> <body> <textarea id="myTextarea"></textarea> <script> var myTextarea = document.getElementById("myTextarea"); var editor = CodeMirror.fromTextArea(myTextarea, { lineNumbers: true }); </script> </body> </html> ``` ### JavaScriptJavaScript 文件中,你可以使用 `CodeMirror` 构造函数来创建一个代码编辑器。 ```javascript var editor = CodeMirror(document.body, { value: "function myScript(){return 100;}\n", mode: "javascript", lineNumbers: true }); ``` ## 高级功能 ### 自动代码补全 CodeMirror 支持自动代码补全功能,你可以通过以下方式来启用它: ```javascript var editor = CodeMirror(document.body, { mode: "javascript", lineNumbers: true, extraKeys: { "Ctrl-Space": "autocomplete" }, hintOptions: { completeSingle: false } }); ``` ### 多光标编辑 CodeMirror 支持多光标编辑功能,你可以通过以下方式来启用它: ```javascript var editor = CodeMirror(document.body, { mode: "javascript", lineNumbers: true, extraKeys: { "Ctrl-Alt-Click": function(cm, event) { var pos = event.target.getBoundingClientRect(); var coords = { left: (pos.left + pos.right) / 2, top: (pos.top + pos.bottom) / 2 }; cm.setCursor(cm.coordsChar(coords)); cm.setSelection(cm.getCursor("start"), cm.getCursor("end")); } } }); ``` ### 搜索替换 CodeMirror 支持搜索替换功能,你可以通过以下方式来启用它: ```javascript var editor = CodeMirror(document.body, { mode: "javascript", lineNumbers: true, extraKeys: { "Ctrl-F": "findPersistent", "Shift-Ctrl-F": "replace" } }); ``` ### 折叠代码块 CodeMirror 支持折叠代码块功能,你可以通过以下方式来启用它: ```javascript var editor = CodeMirror(document.body, { mode: "javascript", lineNumbers: true, foldGutter: true, gutters: ["CodeMirror-linenumbers", "CodeMirror-foldgutter"] }); ``` ## 总结 CodeMirror 是一个功能强大的浏览器端代码编辑器,它支持多种语言和文件格式,具有语法高亮、自动代码补全、多光标编辑、搜索替换、折叠代码块等高级功能。以上是 CodeMirror 的使用教程,希望对你有所帮助。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值