在线代码编辑器 CodeMirror 使用简介
2017-11-21 19:31
1076 查看
在线代码编辑器 CodeMirror 使用简介
CodeMirror是一款在线的支持语法高亮的代码编辑器 github源码特点:
支持100多种语言支持多语言混合
代码自动提示
代码折叠
键盘绑定事件
编辑模式 Vim,Emacs和Sublime Text
很多的方法和插件…
几十个demo可供参考
已经应用CodeMirror的产品
使用:
基本的用法
<!-- 引入codemirror 外部基本资源js css --> <link rel="stylesheet" href="http://codemirror.net/lib/codemirror.css"> <script src="http://codemirror.net/lib/codemirror.js"></script> <!-- 引入mode 此处为js mode--> <script src="http://codemirror.net/mode/javascript/javascript.js"></script> <body> <!-- 创建编辑区域1 --> <form> <textarea id="myTextarea"></textarea> </form> <!-- 创建编辑区域2 --> <div id="code"></div> </body>
推荐的使用方法
编辑器将会替换
textarea,和
textarea平级,自动把
textarea隐藏掉
(display: none)
// 创建实例 这种方法在options 里写value属性是没有用的,自3.0版本改掉了 // 对于生成实例的步骤,react用户注意,要在真实dom生成之后再调用 const myTextarea = document.getElementById('myTextarea') const editor = CodeMirror.fromTextArea(myTextarea, { lineNumbers: true, mode: 'javascript' // 设置mode 对应的也要这之前引入相应的js });
编辑器将被追加到
div里边
// 编辑器将被追加到div 里边 var myCodeMirror2 = CodeMirror(document.getElementById("code"), { lineNumbers: true, value: "function myScript(){return 100;}\n", mode: "javascript" });
编辑器将
替换元素
var myTextArea = document.getElementById("code"); var editor = CodeMirror(function(elt) { myTextArea.parentNode.replaceChild(elt, myTextArea); }, { value: 'select * from table6666', lineNumbers: true, });
更多场景,就要通过
options配置 和
eitor的方法去实现了
常用Configuration options 配置介绍
value: string | CodeMirror.Doc
编辑器的初始值(文本),可以是字符串或者CodeMirror文档对象
mode: string | object
通用的或者在
CodeMirror中使用的与
mode相关联的MIME,当不设置这个值的时候,会默认使用第一个载入的
mode定义文件。一般地,会使用关联的mime类型来设置这个值;除此之外,也可以使用一个带有name属性的对象来作为值
(如:{name: “javascript”, json: true})。可以通过访问
CodeMirror.modes和
CodeMirror.mimeModes`获取定义的mode和MIME
lineSeparator: string | null
明确指定编辑器使用的行分割符(换行符)。默认(值为
null)情况下,文档会被
CRLF(以及单独的CR, LF)分割,单独的LF会在所有的输出中用作换行符(如:
getValue)。当指定了换行字符串,行就只会被指定的串分割。
theme: string
主题样式,主题对应的样式类名为
.cm-s-[name],参考其他主题,也可以自定义主题样式
indentUnit: integer
缩进为多少个空格,默认为
2
smartIndent: boolean
换行的时候是否使用模式提供的上下文相关的缩进(或只是缩进与之前的行对其), 默认
true
tabSize: integer
一个tab有几个空格,默认是
4个
indentWithTabs: boolean
在缩进时,是否需要把
n*tab宽度个空格替换成
n个
tab字符,默认为
false
keyMap: string
配置快捷键图,编辑模式。默认
defaul,这是
codemirror.js本身定义的唯一键映射。其他选项参考key map
extraKeys: object
可以为编辑器绑定额外的键盘事件。
lineWrapping: boolean
当一行特别长的时候,是滚动还是换行。默认为
false(滚动)
lineNumbers: boolean
是否在编辑器左侧显示行号
firstLineNumber: interger
第一行的行号,默认为
1
lineNumberFormatter: function(line: integer) → string
自定义行号
fixedGutter: boolean
是否在内容水平滚动的时候,行号也跟着滚动,(默认为true)
readOnly: boolean
编辑器是否可以编辑
(默认false)
showCursorWhenSelecting: boolean
选中的时候,是否显示光标,默认
false
lineWiseCopyCut: boolean
在没有选择时进行复制或剪切,将复制或剪切光标所在的行
undoDepth: integer
编辑器存储的撤消级别的最大数量,默认
200次
autofocus: boolean
自动获取焦点
dragDrop: boolean
是否启用拖放功能,就是把文件拖进来自动打开。
allowDropFileTypes: array
设置可以拖放的文件类型
常用的可绑定的事件 Events
editor.on('change', (instance, change) => { // instance 指CodeMirror实例对象 // ..... do what you want })
CodeMirror 提供了很多的方法,这些方法允许客户端对各种情况做出不同的行为,这些事件可以通过
on和
off来绑定和解除绑定处理函数
change (instance: CodeMirror, changeObj: object)
编辑器发生改变的时候触发(不建议在
change事件中做过多的操作,比如
setState,否则会导致卡顿)
beforeChange (instance: CodeMirror, changeObj: object)
在更改之前触发,可以选择修改更改的内容或者取消更改,
changeObj提供了
cancel()和
update的方法
cursorActivity (instance: CodeMirror)
当改变、光标移动、选择的时候触发
keyHandled (instance: CodeMirror, name: string, event: Event)
快捷键映射
(key map)中的快捷键被处理
(handle)后触发
inputRead (instance: CodeMirror, changeObj: object)
当用户输入,或者粘贴时触发,(和
change区别:撤销,恢复不会触发)
viewportChange (instance: CodeMirror, from: number, to: number)
每当编辑器的视图窗口发生更改(由于滚动,编辑或其他因素)时触发
gutterClick (instance: CodeMirror, line: integer, gutter: string, clickEvent: Event)
当编辑区域的行号被点击时触发,
line是从
0开始的,
gutter为行号的
class名
gutterContextMenu (instance: CodeMirror, line: integer, gutter: string, contextMenu: Event: Event)
编辑器行号
(contextmenu)右键出现上下午菜单的时候触发
focus (instance: CodeMirror, event: Event)
编辑器获取到焦点的时候触发
blur (instance: CodeMirror, event: Event)
失去焦点时触发
scroll (instance: CodeMirror)
滚动的时候触发
optionChange (instance: CodeMirror, option: string)
当配置项别改变的时候触发
(setOption)
update (instance: CodeMirror)
当
CodeMirror更新其
DOM显示时触发
mousedown, dblclick, touchstart, contextmenu, keydown, keypress, keyup, cut, copy, paste, dragstart, dragenter, dragover, dragleave, drop (instance: CodeMirror, event: Event)
dom的原生事件
CodeMirror API
文档操作
editor.getValue() // 当前编辑器的content
getValue (?separator: string) → string
获取编辑器的内容,你可以传入一个特殊的字符串,去分割行,默认
'\n'。
setValue (content: string)
设置编辑器的内容,实例初始化的时候可以通过
option:value,或者写入
textarea里指定编辑器的内容。实例生成之后,通过这个方法去设置编辑器的内容。
getRange (from: {line, ch}, to: {line, ch}, ?separator: string) → string
获取编辑器指定位置的内容,可以传入特定的行分割符,
line第几行,
ch第几列,都是从
0开始
replaceRange (replacement: string, from: {line, ch}, to: {line, ch}, ?origin: string)
用给定的字符串替换或插入指定的地方
getLine (n: integer) → string
获取指定行的内容
(0 开始)
lineCount () → integer
获取编辑器一共有多少行
getLineHandle (num: integer) → LineHandle
获取指定行的实例对象
getLineNumber (handle: LineHandle) → integer
根据行的实例,获取行的行号
(0开始)
eachLine(f: (line: LineHandle)) 或者 (start: integer, end: integer, f: (line: LineHandle))
遍历整个文档,或者如果给出了开始和结束行号,则从开始到(不包括)结束的范围,并且为每一行调用
f,传递行句柄。这是访问一系列行处理程序比为每个行调用
getLineHandle更快的方法
光标和选择
getSelection (?lineSep: string) → string
获取选中的内容,可以传入一个行分割符默认
'\n',返回的是字符串。当有有多个选中的区域,他们之间的链接就是这个分割符
getSelections (?lineSep: string) → array
获取多个选中的内容,返回的是一个数组,其他同上。
replaceSelection (replacement: string, ?select: string)
用给定的字符串替换选中的。可选的
select当传入
'around'时,替换完成后会自动选中新插入的文本,
'start'时,替换完后光标在最开始的位置
replaceSelections(replacements: array, ?select: string)
用数组中的字符替换选中的内容,替换的数组的长度应该和选中的数组的长度保持一致
getCursor (?start: string) → {line, ch}
返回光标所在的位置
listSelections () → array<{anchor, head}>
返回当前被选中的
Range实例
somethingSelected () → boolean
当选中任何内容,将会返回
true
setSelection (anchor: {line, ch}, ?head: {line, ch}, ?options: object)
给定位置,设置选中的区域,如果
head没传,
head默认为
anchor。
options有以下选项:
scroll: boolean
是否将选中的区域滚动到可视范围。
origin: string
确定选择历史事件是否可以与前一个合并。具体:
Determines whether the selection history event may be merged with the previous one. When an origin starts with the character +, and the last recorded selection had the same origin and was similar (close in time, both collapsed or both non-collapsed), the new one will replace the old one. When it starts with *, it will always replace the previous event (if that had the same origin). Built-in motion uses the “+move” origin. User input uses the “+input” origin.
bias: number
确定选择端点落入原子范围内时应调整的方向(具体我也不清楚)
Determine the direction into which the selection endpoints should be adjusted when they fall inside an atomic range. Can be either -1 (backward) or 1 (forward). When not given, the bias will be based on the relative position of the old selection—the editor will try to move further away from that, to prevent getting stuck.
setCursor (pos: {line, ch}|number, ?ch: number, ?options: object)
设置光标位置。可以传参数
{line, ch}对象,也可以将这两个值作为两个参数传入。将在给定位置用一个空的选择来替换所有的选择,
options同
setSelection的
options参数
setSelections (ranges: array<{anchor, head}>, ?primary: integer, ?options: object)
设置一组新的选择。给定数组中至少有一个选择。当
primary是一个数字,它决定哪个选择是主要的。如果没有给出,则主索引从前一个选择中获取,如果前一个选择的范围小于新的范围,则将其设置为最后一个范围。
options同
setSelection的
options参数
addSelection (anchor: {line, ch}, ?head: {line, ch})
添加一个新的选择到现有的选择,并使其成为主要的选择
extendSelection (from: {line, ch}, ?to: {line, ch}, ?options: object)
与
setSelection类似。区别在于,当按下shift键或设置了extending标志时(指的是设置为true),只会移动head的位置,
anchor会被留在当前位置。参数
to是可选的,传此参数用于确保区域(
region,比如单词或段落)能被完整选择。当前有多个选区时,会清除掉主选区。参数
options同
setSelection
extendSelections (heads: array<{line, ch}>, ?options: object)
相当于一次执行所有选择的extendSelection
extendSelectionsBy(f: function(range: {anchor, head}) → {line, ch}), ?options: object)
将给定的函数应用于所有现有的选择,并调用
extendSelections
hasFocus() → boolean
编辑器当前是否有焦点
配置的设置方法
// 映射Tab键以插入空格而不是制表符 editor.setOption("extraKeys", { Tab: function(cm) { var spaces = Array(cm.getOption("indentUnit") + 1).join(" "); cm.replaceSelection(spaces); } });
setOption (option: string, value: any)
更改编辑器的配置。
option应该是一个选项的名称,
value应该是该选项的有效值
getOption (option: string) → any
检索此编辑器实例
option的值
setSize (width: number|string, height: number|string)
设置编辑器的
宽高
scrollTo(x: number, y: number)
主动让编辑器滚动
getScrollInfo () → {left, top, width, height, clientWidth, clientHeight}
获取表示当前滚动位置,可滚动区域的大小以及可见区域的大小(减号滚动条)的
{left,top,width,height,clientWidth,clientHeight}
getMode () → object
获取编辑器的模式对象。请注意,这不同于
getOption(“mode”)。当前返回的是模式实例化对象
isReadOnly() → boolean
返回编辑器当前是否允许编辑。
getWrapperElement () → Element
返回代表当前编辑器的
DOM
CodeMirror.fromTextArea(textArea: TextAreaElement, ?config: object),这个方法创建的实例有以下几个方法:
save ()
将编辑器的内容复制到
textarea中,这样表单中的textarea的值就会和编辑器同步,以方便表单验证
toTextArea ()
删除编辑器,并恢复原始文本区(内容与编辑器的当前内容保持一致)
getTextArea () → TextAreaElement
返回实例所基于的
textarea
CodeMirror提供了很多的快捷键去完成编写 具体参考
实际应用实例
CodeMirror在
mobx、
react中的应用demo
场景:编辑器支持可编辑,代码高亮,代码提示
// code.js 此处codemirror是npm包 import {Component} from 'react' import {observer} from 'mobx-react' // 如果是安装包的形式,这样引入 import CodeMirror from 'codemirror' import 'codemirror/lib/codemirror.css' import 'codemirror/' // 引入mode import 'codemirror/mode/sql/sql' // 引入代码提示 import 'codemirror/addon/hint/show-hint.css' import 'codemirror/addon/hint/show-hint' // 上边两个是定义提示的前提,下边定义自动提示是哪种模式,此处为sql import 'codemirror/addon/hint/sql-hint' // 引入keymap import 'codemirror/addon/comment/comment' import 'codemirror/keymap/sublime' @observer export default class Code extends Component { render() { return ( <form> <textarea ref={p => this.codeDom = p}> placeholder="code goes here..." > { value // 如果是异步获取的value,可以通过setValue赋值 } </textarea> </form> ) } componentDidMount() { this.editor = CodeMirror.fromTextArea(this.codeDom, { lineNumbers: true, keyMap: 'sublime', indentUnit: 4, tabSize: 4, mode: 'text/x-mysql', showCursorWhenSelecting: true, // 这是针对sql有自定义表和字段的,这样可以把自己的表和字段也放入提示里。如果数据是异步请求获取的,可以通过editor.setOption('hintOptions', data) hintOptions: { tables: { table1: [ 'col_A', 'col_B', 'col_C' ], table2: [ 'other_columns1', 'other_columns2' ], }, } }) // 将自动提示绑定到change事件上,这样输入的时候就可以看到联想的关键词 this.editor.on('change', (instance, change) => { // 自动补全的时候,也会触发change事件,所有坐下判断,以免死循环,正则是为了不让空格,换行之类的也提示 // 通过change对象你可以自定义一些规则去判断是否提示 if (change.origin !== 'complete' && /\w|\./g.test(change.text[0])) { instance.showHint() } }) } // 获取编辑器的内容,以便提交 getTextareaCode = () => this.editor.getValue() }
效果如下:
自动提示的时候,当只有一个匹配选项
CodeMirror会自动帮你选,这样会影响用户输入其他前几个字符一样的单词,导致无法编辑相应的词,所以应该让用户自己去选。改掉
源码
show-hint.js中的选中逻辑。
finishUpdate: function(data, first) { if (this.data) CodeMirror.signal(this.data, "update"); var picked = (this.widget && this.widget.picked) || (first && this.options.completeSingle); if (this.widget) this.widget.close(); if (data && this.data && isNewCompletion(this.data, data)) return; this.data = data; if (data && data.list.length) { // 将这几行注释掉 // if (picked && data.list.length == 1) { // this.pick(data, 0); // } else { this.widget = new Widget(this, data); CodeMirror.signal(data, "shown"); // } } }
CodeMirror提供了很多内置的
API,提高了可扩展性,可自定义
mode,可自定义
hint,等等,在此都不一一列举了。就整理这么多了,还有很多很多我没有涉及到的,欢迎补充,谢谢
^_^。
相关文章推荐
- 使用 CodeMirror 打造属于自己的在线代码编辑器
- ACE Editor在线代码编辑器简介及使用引导
- 使用 CodeMirror 打造属于自己的带高亮显示的在线代码编辑器
- 使用 CodeMirror 打造属于自己的在线代码编辑器
- CodeMirror在线代码编辑器安装和使用
- ACE Editor在线代码编辑器简介及使用引导
- ACE Editor在线代码编辑器简介及使用引导
- 在线代码编辑器 CODEMIRROR 配置说明
- Codemirror-开源在线代码编辑器
- 使用CodeMirror在浏览器中实现编辑器的代码高亮效果
- CodeMirror 在线代码编辑器
- 在线代码编辑器 CODEMIRROR 配置说明
- <转载>仅一行代码,使用浏览器打造一个在线编辑器
- SPAW Editor .NET Edition v.2乱用:使用代码调整编辑器高度
- FCKeditor在线编辑器的使用
- 很赞的在线的代码编辑器,支持多种语言彩色语法编辑,罕见精品
- 在线编辑器CuteEditor使用方法
- UEStudio '06-一款基于IDE的代码编辑器_简介
- [教程]使用google code在线代码托管服务管理你的项目源码
- 简单在线编辑器的使用