完成第一版
commit
0a55442dc4
|
@ -0,0 +1,19 @@
|
|||
*.min.js
|
||||
.httpserver
|
||||
index.html
|
||||
test.js
|
||||
.vscode
|
||||
node_modules/
|
||||
dist/
|
||||
*.sublime-project
|
||||
*.sublime-workspace
|
||||
package-lock.json
|
||||
|
||||
|
||||
._*
|
||||
|
||||
.Spotlight-V100
|
||||
.Trashes
|
||||
.DS_Store
|
||||
.AppleDouble
|
||||
.LSOverride
|
|
@ -0,0 +1,10 @@
|
|||
jsxBracketSameLine: true
|
||||
jsxSingleQuote: true
|
||||
semi: false
|
||||
singleQuote: true
|
||||
printWidth: 80
|
||||
useTabs: false
|
||||
tabWidth: 2
|
||||
trailingComma: none
|
||||
bracketSpacing: true
|
||||
arrowParens: avoid
|
|
@ -0,0 +1,21 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2018
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
|
@ -0,0 +1,34 @@
|
|||
## @bytedo/editor
|
||||
> 定制版的前端代码编辑器, 基于`CodeMirror 6.0`,提供`html,css,js, vue`的语法高亮和最基本的键盘快捷键。
|
||||
|
||||
|
||||
### 用法
|
||||
|
||||
```js
|
||||
// 或者从CDN地址中获取
|
||||
import { EditorView, minimalSetup, vue, js, css, html } from '@bytedo/editor'
|
||||
|
||||
|
||||
let view = new EditorView({
|
||||
doc: '', //默认显示的代码,
|
||||
extensions: minimalSetup(vue()), // 需要高亮什么文件, 就传什么进去
|
||||
parent: document.body // 创建的编辑器实例, 被包裹在哪个节点上
|
||||
})
|
||||
|
||||
|
||||
console.log(view.state.doc.toString()) // 获取编辑器的代码
|
||||
|
||||
```
|
||||
|
||||
### 支持的键盘快捷键
|
||||
|
||||
- `Alt + Left/Right` 将光标按单词边界移动
|
||||
- `Alt + Up/Down` 将当前行代码与`上一行/下一行`互换
|
||||
- `Alt + Shift + Up/Down` 将当前行代码在`上一行/下一行`中复制一份, 并将光标移动到`上一行/下一行`
|
||||
- `Alt + l` (在`macos`中是`Ctrl + l`) 选中当前行
|
||||
- `Alt + i` (在`macos`中是`Ctrl + i`) 按单词边界选中内容, 连续按则父级的块作用域选中
|
||||
- `Alt + /` (在`macos`中是`Ctrl + /`) 注释当前行
|
||||
- `Ctrl + Shift + k` (在`macos`中是`Cmd + Shift + k`) 删除当前行
|
||||
- `Ctrl + Shift + \` (在`macos`中是`Cmd + Shift + \`) 在成对的符号前后移动光标
|
||||
- `Tab` 增加缩进
|
||||
- `Shift + Tab` 减少缩进
|
|
@ -0,0 +1,176 @@
|
|||
import {
|
||||
EditorView,
|
||||
lineNumbers,
|
||||
drawSelection,
|
||||
keymap
|
||||
} from '@codemirror/view'
|
||||
import {
|
||||
history,
|
||||
defaultKeymap,
|
||||
standardKeymap,
|
||||
historyKeymap,
|
||||
indentWithTab
|
||||
} from '@codemirror/commands'
|
||||
import {
|
||||
foldGutter,
|
||||
indentOnInput,
|
||||
syntaxHighlighting,
|
||||
HighlightStyle
|
||||
} from '@codemirror/language'
|
||||
import { tags as t } from '@lezer/highlight'
|
||||
import { css } from '@codemirror/lang-css'
|
||||
import { javascript } from '@codemirror/lang-javascript'
|
||||
import { vue } from '@codemirror/lang-vue'
|
||||
import { html } from '@codemirror/lang-html'
|
||||
|
||||
const chalky = '#e5c07b',
|
||||
blue = '#0096ff',
|
||||
strings = '#53c659',
|
||||
whiskey = '#d19a66',
|
||||
darkBackground = '#f2f5fc',
|
||||
highlightBackground = '#80CBC440',
|
||||
foreground = '#546e7a', //
|
||||
background = '#fff',
|
||||
tooltipBackground = '#353a42',
|
||||
selection = '#80CBC440',
|
||||
cursor = '#35373b',
|
||||
keyword = '#ff5370',
|
||||
property = '#8796B0'
|
||||
|
||||
const onePlain = EditorView.theme({
|
||||
'&': {
|
||||
color: foreground,
|
||||
backgroundColor: background
|
||||
},
|
||||
|
||||
'.cm-content': {
|
||||
caretColor: cursor
|
||||
},
|
||||
|
||||
'.cm-cursor, .cm-dropCursor': { borderLeftColor: cursor },
|
||||
'&.cm-focused .cm-selectionBackground, .cm-selectionBackground, .cm-content ::selection':
|
||||
{ backgroundColor: selection },
|
||||
|
||||
'.cm-panels': { backgroundColor: darkBackground, color: foreground },
|
||||
'.cm-panels.cm-panels-top': { borderBottom: '2px solid black' },
|
||||
'.cm-panels.cm-panels-bottom': { borderTop: '2px solid black' },
|
||||
|
||||
'.cm-searchMatch': {
|
||||
backgroundColor: '#72a1ff59',
|
||||
outline: '1px solid #457dff'
|
||||
},
|
||||
'.cm-searchMatch.cm-searchMatch-selected': {
|
||||
backgroundColor: '#6199ff2f'
|
||||
},
|
||||
|
||||
'.cm-activeLine': { backgroundColor: '#6699ff0b' },
|
||||
'.cm-selectionMatch': { backgroundColor: '#aafe661a' },
|
||||
|
||||
'&.cm-focused .cm-matchingBracket, &.cm-focused .cm-nonmatchingBracket': {
|
||||
backgroundColor: '#bad0f847'
|
||||
},
|
||||
|
||||
'.cm-gutters': {
|
||||
backgroundColor: darkBackground,
|
||||
color: foreground,
|
||||
border: 'none'
|
||||
},
|
||||
|
||||
'.cm-activeLineGutter': {
|
||||
backgroundColor: highlightBackground
|
||||
},
|
||||
|
||||
'.cm-foldPlaceholder': {
|
||||
backgroundColor: 'transparent',
|
||||
border: 'none',
|
||||
color: '#ddd'
|
||||
},
|
||||
|
||||
'.cm-tooltip': {
|
||||
border: 'none',
|
||||
backgroundColor: tooltipBackground
|
||||
},
|
||||
'.cm-tooltip .cm-tooltip-arrow:before': {
|
||||
borderTopColor: 'transparent',
|
||||
borderBottomColor: 'transparent'
|
||||
},
|
||||
'.cm-tooltip .cm-tooltip-arrow:after': {
|
||||
borderTopColor: tooltipBackground,
|
||||
borderBottomColor: tooltipBackground
|
||||
},
|
||||
'.cm-tooltip-autocomplete': {
|
||||
'& > ul > li[aria-selected]': {
|
||||
backgroundColor: highlightBackground,
|
||||
color: foreground
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
const onePlainHighlight = HighlightStyle.define([
|
||||
{ tag: t.keyword, color: keyword },
|
||||
{
|
||||
tag: [t.name, t.deleted, t.character, t.propertyName, t.macroName],
|
||||
color: property,
|
||||
fontWeight: 'bold'
|
||||
},
|
||||
{
|
||||
tag: [t.attributeName],
|
||||
color: '#ffb62c'
|
||||
},
|
||||
{ tag: [t.function(t.variableName), t.labelName], color: blue },
|
||||
{ tag: [t.color, t.constant(t.name), t.standard(t.name)], color: whiskey },
|
||||
{ tag: [t.definition(t.name), t.separator], color: foreground },
|
||||
{ tag: [t.typeName], color: keyword },
|
||||
{ tag: [t.number, t.atom, t.bool], fontStyle: 'italic', color: '#7c4dff' },
|
||||
{
|
||||
tag: [t.className, t.namespace, t.self],
|
||||
fontStyle: 'italic',
|
||||
fontWeight: 'bold',
|
||||
color: '#ffb62c'
|
||||
},
|
||||
{
|
||||
tag: [t.changed, t.annotation, t.modifier],
|
||||
color: chalky
|
||||
},
|
||||
{
|
||||
tag: [
|
||||
t.operator,
|
||||
t.operatorKeyword,
|
||||
t.url,
|
||||
t.escape,
|
||||
t.regexp,
|
||||
t.link,
|
||||
t.special(t.string)
|
||||
],
|
||||
color: keyword
|
||||
},
|
||||
{ tag: [t.meta, t.comment], fontStyle: 'italic', color: '#b6d5e0' },
|
||||
{ tag: t.strong, fontWeight: 'bold' },
|
||||
{ tag: t.emphasis, fontStyle: 'italic' },
|
||||
{ tag: t.strikethrough, textDecoration: 'line-through' },
|
||||
{ tag: t.link, color: foreground, textDecoration: 'underline' },
|
||||
{ tag: t.heading, fontWeight: 'bold', color: property },
|
||||
{ tag: [t.special(t.variableName)], color: whiskey },
|
||||
{ tag: [t.processingInstruction, t.string, t.inserted], color: strings },
|
||||
{ tag: t.invalid, color: foreground }
|
||||
])
|
||||
|
||||
export function minimalSetup(...args) {
|
||||
return [
|
||||
lineNumbers(),
|
||||
foldGutter(),
|
||||
indentOnInput(),
|
||||
history(),
|
||||
drawSelection(),
|
||||
...args,
|
||||
[onePlain, syntaxHighlighting(onePlainHighlight)],
|
||||
keymap.of([
|
||||
...standardKeymap,
|
||||
...defaultKeymap,
|
||||
indentWithTab,
|
||||
...historyKeymap
|
||||
])
|
||||
]
|
||||
}
|
||||
|
||||
export { EditorView, css, html, javascript, vue }
|
|
@ -0,0 +1,24 @@
|
|||
{
|
||||
"name": "@bytedo/editor",
|
||||
"description": "定制版的前端代码编辑器, 基于`CodeMirror 6.0`",
|
||||
"version": "1.0.0",
|
||||
"type": "module",
|
||||
"main": "dist/index.js",
|
||||
"files": [
|
||||
"dist/*"
|
||||
],
|
||||
"devDependencies": {
|
||||
"@codemirror/commands": "^6.2.2",
|
||||
"@codemirror/lang-css": "^6.1.1",
|
||||
"@codemirror/lang-html": "^6.4.3",
|
||||
"@codemirror/lang-javascript": "^6.1.5",
|
||||
"@codemirror/lang-vue": "^0.1.1",
|
||||
"@codemirror/language": "^6.6.0",
|
||||
"@codemirror/view": "^6.9.4"
|
||||
},
|
||||
"scripts": {
|
||||
"start": "esbuild index.js --bundle --target=esnext --format=esm --outfile=dist/index.js --watch",
|
||||
"build": "esbuild index.js --minify --bundle --target=esnext --format=esm --outfile=dist/index.js"
|
||||
},
|
||||
"license": "MIT"
|
||||
}
|
Loading…
Reference in New Issue