├── .commitlintrc.js ├── .editorconfig ├── .eslintcache ├── .eslintignore ├── .eslintrc-auto-import.json ├── .eslintrc.cjs ├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.yml │ └── feature_request.md └── workflows │ └── release.yml ├── .gitignore ├── .npmrc ├── .nvmrc ├── .prettierrc.json ├── CHANGELOG.md ├── LICENSE ├── README.md ├── bower.json ├── build └── plugins │ ├── custom │ ├── InjectCss.js │ └── InjectCss.ts │ ├── index.js │ └── index.ts ├── docs ├── .vitepress │ ├── config.mts │ └── theme │ │ ├── index.ts │ │ └── styles │ │ └── index.css ├── demo │ ├── examples │ │ ├── Interactive │ │ │ ├── components │ │ │ │ ├── Example.vue │ │ │ │ ├── LangSelect.vue │ │ │ │ └── Layout.vue │ │ │ ├── config │ │ │ │ ├── lang.ts │ │ │ │ ├── langOptions.ts │ │ │ │ ├── theme.ts │ │ │ │ └── themeOptions.ts │ │ │ ├── demo.vue │ │ │ ├── index.vue │ │ │ ├── store.ts │ │ │ ├── template.pug │ │ │ ├── types │ │ │ │ └── index.ts │ │ │ └── utils.ts │ │ ├── components │ │ │ ├── BashBlock.vue │ │ │ ├── Example.vue │ │ │ ├── IconCode.vue │ │ │ └── IconCopy.vue │ │ ├── index.vue │ │ ├── lang │ │ │ └── js.vue │ │ ├── lint │ │ │ ├── index.vue │ │ │ ├── jsLint.vue │ │ │ └── jsonLint.vue │ │ └── utils.ts │ ├── home.vue │ ├── index.vue │ ├── log │ │ ├── fclog.vue │ │ └── index.vue │ └── mergeDemo.vue ├── example │ ├── codeLint.md │ └── index.md ├── guide │ ├── events.md │ ├── getting-started.md │ ├── lang.md │ ├── prepattern │ │ ├── log.md │ │ └── merge.md │ ├── props.md │ ├── supplementary │ │ ├── custom-theme.md │ │ ├── instance.md │ │ └── static-properties.md │ └── typescript │ │ └── Support.md ├── img │ ├── createMarkLink.jpg │ ├── createTitle.jpg │ ├── error-time.jpg │ ├── error.jpg │ ├── info-time.jpg │ ├── info.jpg │ ├── warning-time.jpg │ └── warning.jpg ├── index.md ├── package.json └── zh-CN │ ├── example │ ├── codeLint.md │ └── index.md │ ├── guide │ ├── events.md │ ├── getting-started.md │ ├── lang.md │ ├── prepattern │ │ ├── log.md │ │ └── merge.md │ ├── props.md │ ├── supplementary │ │ ├── custom-theme.md │ │ ├── instance.md │ │ └── static-properties.md │ └── typescript │ │ └── Support.md │ └── index.md ├── index.html ├── package.json ├── packages ├── index.ts └── src │ ├── components │ ├── index.vue │ └── presetMode │ │ ├── Merge │ │ └── index.vue │ │ ├── default │ │ └── index.vue │ │ └── log │ │ ├── config.ts │ │ ├── index.vue │ │ ├── languages │ │ ├── fcLog │ │ │ └── index.ts │ │ └── simpleLog │ │ │ └── index.ts │ │ └── utils.ts │ ├── config │ └── index.ts │ ├── hooks │ ├── useEvents.ts │ └── useViewControl.ts │ ├── sourceLib │ └── index.ts │ ├── style │ └── index.css │ └── types │ ├── index.d.ts │ └── props.ts ├── playground ├── App.vue ├── demo │ ├── javascript.vue │ ├── json.vue │ ├── merge.vue │ ├── placeholder.vue │ └── theme.vue ├── main.ts └── router │ └── index.ts ├── pnpm-lock.yaml ├── scripts ├── deploy-docs.sh ├── release.ts └── releaseUtils.ts ├── tsconfig.json ├── types ├── auto-imports.d.ts ├── global.d.ts ├── module.d.ts └── vite-env.d.ts ├── uno.config.ts └── vite.config.ts /.commitlintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: ['@commitlint/config-conventional'], 3 | rules: { 4 | 'type-enum': [ 5 | 2, 6 | 'always', 7 | ['init', 'build', 'ci', 'chore', 'docs', 'feat', 'fix', 'perf', 'refactor', 'revert', 'style', 'test'], 8 | ], 9 | }, 10 | }; 11 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig is awesome: https://EditorConfig.org 2 | 3 | # top-most EditorConfig file 4 | root = true 5 | 6 | [*] # 表示所有文件都要遵循 7 | indent_style = space # 缩进风格,可选配置有space和tab 8 | indent_size = 2 # 缩进大小 9 | end_of_line = lf # 换行符,可选配置有lf、cr和crlf 10 | charset = utf-8 # 编码格式,通常都是选utf-8 11 | trim_trailing_whitespace = true # 去除多余的空格 12 | insert_final_newline = true # 在尾部插入一行 13 | 14 | [*.md] # 表示仅 md 文件适用 15 | insert_final_newline = false # 在尾部插入一行 16 | trim_trailing_whitespace = false # 去除多余的空格 17 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | auto-imports.d.ts 2 | node_modules 3 | dist 4 | components.d.ts 5 | /types 6 | .gitignore 7 | -------------------------------------------------------------------------------- /.eslintrc-auto-import.json: -------------------------------------------------------------------------------- 1 | { 2 | "globals": { 3 | "Component": true, 4 | "ComponentPublicInstance": true, 5 | "ComputedRef": true, 6 | "EffectScope": true, 7 | "ExtractDefaultPropTypes": true, 8 | "ExtractPropTypes": true, 9 | "ExtractPublicPropTypes": true, 10 | "InjectionKey": true, 11 | "PropType": true, 12 | "Ref": true, 13 | "VNode": true, 14 | "WritableComputedRef": true, 15 | "computed": true, 16 | "createApp": true, 17 | "customRef": true, 18 | "defineAsyncComponent": true, 19 | "defineComponent": true, 20 | "effectScope": true, 21 | "getCurrentInstance": true, 22 | "getCurrentScope": true, 23 | "h": true, 24 | "inject": true, 25 | "isProxy": true, 26 | "isReactive": true, 27 | "isReadonly": true, 28 | "isRef": true, 29 | "markRaw": true, 30 | "nextTick": true, 31 | "onActivated": true, 32 | "onBeforeMount": true, 33 | "onBeforeRouteLeave": true, 34 | "onBeforeRouteUpdate": true, 35 | "onBeforeUnmount": true, 36 | "onBeforeUpdate": true, 37 | "onDeactivated": true, 38 | "onErrorCaptured": true, 39 | "onMounted": true, 40 | "onRenderTracked": true, 41 | "onRenderTriggered": true, 42 | "onScopeDispose": true, 43 | "onServerPrefetch": true, 44 | "onUnmounted": true, 45 | "onUpdated": true, 46 | "onWatcherCleanup": true, 47 | "provide": true, 48 | "reactive": true, 49 | "readonly": true, 50 | "ref": true, 51 | "resolveComponent": true, 52 | "shallowReactive": true, 53 | "shallowReadonly": true, 54 | "shallowRef": true, 55 | "toRaw": true, 56 | "toRef": true, 57 | "toRefs": true, 58 | "toValue": true, 59 | "triggerRef": true, 60 | "unref": true, 61 | "useAttrs": true, 62 | "useCssModule": true, 63 | "useCssVars": true, 64 | "useId": true, 65 | "useLink": true, 66 | "useModel": true, 67 | "useRoute": true, 68 | "useRouter": true, 69 | "useSlots": true, 70 | "useTemplateRef": true, 71 | "watch": true, 72 | "watchEffect": true, 73 | "watchPostEffect": true, 74 | "watchSyncEffect": true 75 | } 76 | } -------------------------------------------------------------------------------- /.eslintrc.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | env: { 3 | browser: true, 4 | es2021: true, 5 | node: true, 6 | }, 7 | extends: [ 8 | "plugin:vue/vue3-essential", 9 | "eslint:recommended", 10 | "@vue/eslint-config-typescript", 11 | "@vue/typescript/recommended", 12 | "@vue/prettier", 13 | "./.eslintrc-auto-import.json", 14 | ], 15 | parser: "vue-eslint-parser", 16 | parserOptions: { 17 | parser: "@typescript-eslint/parser", 18 | ecmaVersion: 2020, 19 | sourceType: "module", 20 | jsxPragma: "React", 21 | ecmaFeatures: { 22 | jsx: true, 23 | tsx: true, 24 | }, 25 | }, 26 | rules: { 27 | "@typescript-eslint/no-explicit-any": "off", 28 | "no-debugger": "off", 29 | "@typescript-eslint/explicit-module-boundary-types": "off", 30 | "@typescript-eslint/ban-types": "off", 31 | "@typescript-eslint/ban-ts-comment": "off", 32 | "@typescript-eslint/no-empty-function": "off", 33 | "@typescript-eslint/no-non-null-assertion": "off", 34 | "@typescript-eslint/no-unused-vars": [ 35 | "warn", 36 | { 37 | argsIgnorePattern: "^_", 38 | varsIgnorePattern: "^_", 39 | }, 40 | ], 41 | "no-unused-vars": [ 42 | "warn", 43 | { 44 | argsIgnorePattern: "^_", 45 | varsIgnorePattern: "^_", 46 | }, 47 | ], 48 | 49 | "vue/html-self-closing": [ 50 | "error", 51 | { 52 | html: { 53 | void: "always", 54 | normal: "always", 55 | component: "always", 56 | }, 57 | svg: "always", 58 | math: "always", 59 | }, 60 | ], 61 | "linebreak-style": 0, // 强制使用一致的换行风格 62 | "max-len": 0, // 强制一行的最大长度 63 | // // Prettier 64 | "prettier/prettier": [ 65 | "error", 66 | { 67 | endOfLine: "auto", 68 | semi: true, 69 | trailingComma: "es5", 70 | }, 71 | ], 72 | // Vue 73 | "vue/require-default-prop": "off", 74 | "vue/require-explicit-emits": "off", 75 | "vue/multi-word-component-names": "off", 76 | quotes: ["error", "double"], 77 | "no-console": "off", 78 | "import/no-unresolved": "off", 79 | "import/extensions": "off", 80 | "import/no-extraneous-dependencies": "off", 81 | "no-restricted-syntax": "off", 82 | "no-unused-expressions": "off", 83 | "no-plusplus": "off", 84 | "no-underscore-dangle": "off", 85 | // "@typescript-eslint/ban-ts-comment": "off", 86 | // "vue/multi-word-component-names": "off", 87 | // "@typescript-eslint/no-explicit-any": ["off"], 88 | "import/prefer-default-export": "off", 89 | }, 90 | overrides: [ 91 | { 92 | files: ["*.vue"], 93 | rules: { 94 | "no-undef": "off", 95 | }, 96 | }, 97 | ], 98 | }; 99 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.yml: -------------------------------------------------------------------------------- 1 | name: "\U0001F41E Bug report" 2 | description: Report an issue with codemirror-editor-vue3 3 | labels: [pending triage] 4 | body: 5 | - type: markdown 6 | attributes: 7 | value: | 8 | Thanks for taking the time to fill out this bug report! 9 | - type: textarea 10 | id: bug-description 11 | attributes: 12 | label: Describe the bug 13 | description: A clear and concise description of what the bug is. 14 | placeholder: Bug description 15 | validations: 16 | required: true 17 | - type: textarea 18 | id: Reproduction-steps 19 | attributes: 20 | label: Steps to reproduce 21 | description: Please provide any reproduction steps that may need to be described. 22 | placeholder: Reproduction steps 23 | validations: 24 | required: true 25 | - type: textarea 26 | id: package-info 27 | attributes: 28 | label: Package Info 29 | description: 30 | Copy the output of the command `npm list vue typescript codemirror codemirror-editor-vue3 --depth=0 --binaries 31 | --browsers` 32 | render: shell 33 | placeholder: package versions 34 | validations: 35 | required: true 36 | - type: checkboxes 37 | id: checkboxes 38 | attributes: 39 | label: Validations 40 | description: Before submitting the issue, please make sure you do the following 41 | options: 42 | - label: Is it the latest version? 43 | required: true 44 | - label: Read the [docs](https://rennzhang.github.io/codemirror-editor-vue3/guide/getting-started). 45 | required: true 46 | - label: 47 | Check that there isn't [already an issue](https://github.com/RennCheung/codemirror-editor-vue3/issues?q=) 48 | that reports the same bug to avoid creating a duplicate. 49 | required: true 50 | - label: 51 | The provided reproduction is a [minimal reproducible 52 | example](https://stackoverflow.com/help/minimal-reproducible-example) of the bug. 53 | required: false 54 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Create Release 2 | 3 | on: 4 | push: 5 | tags: 6 | - v* 7 | 8 | jobs: 9 | build: 10 | name: Create Release 11 | runs-on: ubuntu-latest 12 | steps: 13 | - name: Checkout code 14 | uses: actions/checkout@master 15 | 16 | - name: Create Release for Tag 17 | id: release_tag 18 | uses: yyx990803/release-tag@master 19 | env: 20 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 21 | with: 22 | tag_name: ${{ github.ref }} 23 | body: | 24 | Please refer to [CHANGELOG.md](https://github.com/RennCheung/codemirror-editor-vue3/blob/main/CHANGELOG.md) for details. 25 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | /dist/ 3 | /docs/.vitepress/dist 4 | */.DS_Store 5 | # Editor directories and files 6 | .idea 7 | .vscode 8 | .DS_Store 9 | docs/.vitepress/dist/ 10 | docs/.vitepress/cache/ 11 | types/auto-imports.d.ts 12 | docs/auto-imports.d.ts 13 | docs/components.d.ts 14 | -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | unsafe-perm=true 2 | registry = https://registry.npmjs.org/ 3 | -------------------------------------------------------------------------------- /.nvmrc: -------------------------------------------------------------------------------- 1 | 20.14.0 2 | -------------------------------------------------------------------------------- /.prettierrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "bracketSpacing": true, 3 | "htmlWhitespaceSensitivity": "css", 4 | "insertPragma": false, 5 | "printWidth": 120, 6 | "arrowParens": "always", 7 | "proseWrap": "always", 8 | "quoteProps": "as-needed", 9 | "requirePragma": false, 10 | "semi": true, 11 | "singleQuote": false, 12 | "tabWidth": 2, 13 | "trailingComma": "es5", 14 | "useTabs": false, 15 | "endOfLine": "auto", 16 | 17 | "overrides": [ 18 | { 19 | "files": "*.html", 20 | "options": { 21 | "parser": "html" 22 | } 23 | } 24 | ] 25 | } 26 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (C) 2021 by RennCheung and others 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "codemirror-editor-vue3", 3 | "description": "CodeMirror component for Vue3", 4 | "main": "./dist/codemirror-editor-vue3.js", 5 | "author": { 6 | "name": "zhangren", 7 | "email": "906155099@qq.com" 8 | }, 9 | "license": "MIT", 10 | "keywords": [ 11 | "codemirror-editor-vue3", 12 | "vue3 codemirror", 13 | "codemirror", 14 | "vue3", 15 | "log" 16 | ], 17 | "moduleType": [], 18 | "ignore": [ 19 | "**/.*", 20 | "node_modules", 21 | "bower_components", 22 | "test", 23 | "tests" 24 | ] 25 | } -------------------------------------------------------------------------------- /build/plugins/custom/InjectCss.js: -------------------------------------------------------------------------------- 1 | import fs from "fs"; 2 | import { resolve } from "path"; 3 | const fileRegex = /\.(css)$/; 4 | const injectCode = (code) => `function styleInject(css,ref){if(ref===void 0){ref={}}var insertAt=ref.insertAt;if(!css||typeof document==="undefined"){return}var head=document.head||document.getElementsByTagName("head")[0];var style=document.createElement("style");style.type="text/css";if(insertAt==="top"){if(head.firstChild){head.insertBefore(style,head.firstChild)}else{head.appendChild(style)}}else{head.appendChild(style)}if(style.styleSheet){style.styleSheet.cssText=css}else{style.appendChild(document.createTextNode(css))}};styleInject(\`${code}\`)`; 5 | const template = 'console.warn("__INJECT__")'; 6 | let viteConfig; 7 | const css = []; 8 | const libInjectCss = () => ({ 9 | name: "lib-inject-css", 10 | apply: "build", 11 | configResolved(resolvedConfig) { 12 | viteConfig = resolvedConfig; 13 | }, 14 | transform(code, id) { 15 | if (fileRegex.test(id)) { 16 | css.push(code); 17 | return { 18 | code: "", 19 | }; 20 | } 21 | if ( 22 | // @ts-ignore 23 | id.includes("packages/index.ts")) { 24 | return { 25 | code: `${code} 26 | ${template}`, 27 | }; 28 | } 29 | return null; 30 | }, 31 | async writeBundle(_, bundle) { 32 | for (const file of Object.entries(bundle)) { 33 | const { root } = viteConfig; 34 | const outDir = viteConfig.build.outDir || "dist"; 35 | const fileName = file[0]; 36 | const filePath = resolve(root, outDir, fileName); 37 | try { 38 | let data = fs.readFileSync(filePath, { 39 | encoding: "utf8", 40 | }); 41 | if (data.includes(template)) { 42 | data = data.replace(template, injectCode(css.join("\n"))); 43 | } 44 | fs.writeFileSync(filePath, data); 45 | } 46 | catch (e) { 47 | console.error(e); 48 | } 49 | } 50 | }, 51 | }); 52 | export default libInjectCss; 53 | -------------------------------------------------------------------------------- /build/plugins/custom/InjectCss.ts: -------------------------------------------------------------------------------- 1 | import fs from "fs"; 2 | import { resolve } from "path"; 3 | import type { ResolvedConfig, PluginOption } from "vite"; 4 | 5 | const fileRegex = /\.(css)$/; 6 | 7 | const injectCode = (code: string) => `function styleInject(css,ref){if(ref===void 0){ref={}}var insertAt=ref.insertAt;if(!css||typeof document==="undefined"){return}var head=document.head||document.getElementsByTagName("head")[0];var style=document.createElement("style");style.type="text/css";if(insertAt==="top"){if(head.firstChild){head.insertBefore(style,head.firstChild)}else{head.appendChild(style)}}else{head.appendChild(style)}if(style.styleSheet){style.styleSheet.cssText=css}else{style.appendChild(document.createTextNode(css))}};styleInject(\`${code}\`)`; 8 | const template = 'console.warn("__INJECT__")'; 9 | 10 | let viteConfig: ResolvedConfig; 11 | const css: string[] = []; 12 | 13 | const libInjectCss = (): PluginOption => ({ 14 | name: "lib-inject-css", 15 | 16 | apply: "build", 17 | 18 | configResolved(resolvedConfig: ResolvedConfig) { 19 | viteConfig = resolvedConfig; 20 | }, 21 | 22 | transform(code: string, id: string) { 23 | if (fileRegex.test(id)) { 24 | css.push(code); 25 | return { 26 | code: "", 27 | }; 28 | } 29 | if ( 30 | // @ts-ignore 31 | id.includes("packages/index.ts") 32 | ) { 33 | return { 34 | code: `${code} 35 | ${template}`, 36 | }; 37 | } 38 | return null; 39 | }, 40 | 41 | async writeBundle(_: any, bundle: any) { 42 | for (const file of Object.entries(bundle)) { 43 | const { root } = viteConfig; 44 | const outDir: string = viteConfig.build.outDir || "dist"; 45 | const fileName: string = file[0]; 46 | const filePath: string = resolve(root, outDir, fileName); 47 | 48 | try { 49 | let data: string = fs.readFileSync(filePath, { 50 | encoding: "utf8", 51 | }); 52 | 53 | if (data.includes(template)) { 54 | data = data.replace(template, injectCode(css.join("\n"))); 55 | } 56 | 57 | fs.writeFileSync(filePath, data); 58 | } catch (e) { 59 | console.error(e); 60 | } 61 | } 62 | }, 63 | }); 64 | 65 | export default libInjectCss; 66 | -------------------------------------------------------------------------------- /build/plugins/index.js: -------------------------------------------------------------------------------- 1 | import vue from "@vitejs/plugin-vue"; 2 | import vueJsx from "@vitejs/plugin-vue-jsx"; 3 | import AutoImport from "unplugin-auto-import/vite"; 4 | import dts from "vite-plugin-dts"; 5 | import Pages from "vite-plugin-pages"; 6 | import UnoCSS from "unocss/vite"; 7 | import libInjectCss from "./custom/InjectCss"; 8 | export default [ 9 | vue(), 10 | vueJsx(), 11 | AutoImport({ 12 | dts: "./types/auto-imports.d.ts", 13 | imports: ["vue", "vue-router"], 14 | eslintrc: { 15 | enabled: true, // Default `false` 16 | filepath: "./.eslintrc-auto-import.json", // Default `./.eslintrc-auto-import.json` 17 | globalsPropValue: true, // Default `true`, (true | false | 'readonly' | 'readable' | 'writable' | 'writeable') 18 | }, 19 | // Generate corresponding .eslintrc-auto-import.json file. 20 | // eslint globals Docs - https://eslint.org/docs/user-guide/configuring/language-options#specifying-globals 21 | }), 22 | dts(), 23 | libInjectCss(), 24 | Pages({ 25 | dirs: [ 26 | { 27 | dir: "playground/demo", 28 | baseRoute: "demo", 29 | }, 30 | ], 31 | exclude: ["playground/demo/index.vue"], 32 | }), 33 | UnoCSS(), 34 | ]; 35 | -------------------------------------------------------------------------------- /build/plugins/index.ts: -------------------------------------------------------------------------------- 1 | import vue from "@vitejs/plugin-vue"; 2 | import vueJsx from "@vitejs/plugin-vue-jsx"; 3 | import AutoImport from "unplugin-auto-import/vite"; 4 | import dts from "vite-plugin-dts"; 5 | import Pages from "vite-plugin-pages"; 6 | import UnoCSS from "unocss/vite"; 7 | 8 | import libInjectCss from "./custom/InjectCss"; 9 | 10 | export default [ 11 | vue(), 12 | vueJsx(), 13 | AutoImport({ 14 | dts: "./types/auto-imports.d.ts", 15 | imports: ["vue", "vue-router"], 16 | eslintrc: { 17 | enabled: true, // Default `false` 18 | filepath: "./.eslintrc-auto-import.json", // Default `./.eslintrc-auto-import.json` 19 | globalsPropValue: true, // Default `true`, (true | false | 'readonly' | 'readable' | 'writable' | 'writeable') 20 | }, 21 | // Generate corresponding .eslintrc-auto-import.json file. 22 | // eslint globals Docs - https://eslint.org/docs/user-guide/configuring/language-options#specifying-globals 23 | }), 24 | dts(), 25 | libInjectCss(), 26 | Pages({ 27 | dirs: [ 28 | { 29 | dir: "playground/demo", 30 | baseRoute: "demo", 31 | }, 32 | ], 33 | exclude: ["playground/demo/index.vue"], 34 | }), 35 | UnoCSS(), 36 | ]; 37 | -------------------------------------------------------------------------------- /docs/.vitepress/config.mts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from "vitepress"; 2 | import { resolve } from "path"; 3 | import UnoCSS from "unocss/vite"; 4 | import AutoImport from "unplugin-auto-import/vite"; 5 | import Components from "unplugin-vue-components/vite"; 6 | import { ElementPlusResolver } from "unplugin-vue-components/resolvers"; 7 | 8 | function pathResolve(dir: string) { 9 | return resolve(process.cwd(), ".", dir); 10 | } 11 | 12 | const base = process.env.NODE_ENV == "production" ? "/codemirror-editor-vue3/" : "/"; 13 | const routeMap = { 14 | en: "", 15 | zh: "/zh-CN", 16 | }; 17 | const getNav = (lang: "en" | "zh") => { 18 | const isEn = lang == "en"; 19 | const route = routeMap[lang]; 20 | return [ 21 | { 22 | text: isEn ? "Guide" : "入门", 23 | link: `${route}/guide/getting-started`, 24 | activeMatch: "/guide/g", 25 | }, 26 | { 27 | text: isEn ? "More Example" : "更多案例", 28 | link: `${route}/example/index`, 29 | activeMatch: "/example/g", 30 | }, 31 | { 32 | text: isEn ? "Changelog" : "更新日志", 33 | link: "https://github.com/RennCheung/codemirror-editor-vue3/blob/main/CHANGELOG.md", 34 | }, 35 | ]; 36 | }; 37 | 38 | function getGuideSidebar(lang: "en" | "zh") { 39 | const isEn = lang == "en"; 40 | 41 | const route = routeMap[lang]; 42 | return [ 43 | { 44 | text: isEn ? "Introduction" : "介绍", 45 | collapsed: false, 46 | items: [ 47 | { 48 | text: isEn ? "Getting Started" : "入门指南", 49 | link: `${route}/guide/getting-started`, 50 | }, 51 | { 52 | text: isEn ? "Component Props" : "组件属性", 53 | link: `${route}/guide/props`, 54 | }, 55 | { 56 | text: isEn ? "Component Events" : "组件事件", 57 | link: `${route}/guide/events`, 58 | }, 59 | { 60 | text: isEn ? "Language Modes" : "语言高亮", 61 | link: `${route}/guide/lang`, 62 | }, 63 | ], 64 | }, 65 | { 66 | text: isEn ? "prepattern" : "预置模式", 67 | items: [ 68 | { 69 | text: isEn ? "merge(diff) mode" : "merge(diff) 模式", 70 | link: `${route}/guide/prepattern/merge`, 71 | }, 72 | { 73 | text: isEn ? "log mode" : "log 模式", 74 | link: `${route}/guide/prepattern/log`, 75 | }, 76 | ], 77 | }, 78 | { 79 | text: isEn ? "Supplementary Instruction" : "补充说明", 80 | items: [ 81 | { 82 | text: isEn ? "CodeMirror Static properties" : "CodeMirror 静态属性", 83 | link: `${route}/guide/supplementary/static-properties`, 84 | }, 85 | { 86 | text: isEn ? "Get instance object" : "获取实例对象", 87 | link: `${route}/guide/supplementary/instance`, 88 | }, 89 | // 自定义主题 90 | { 91 | text: isEn ? "Custom Theme" : "自定义主题", 92 | link: `${route}/guide/supplementary/custom-theme`, 93 | }, 94 | ], 95 | }, 96 | { 97 | text: isEn ? "Typescript Support" : "Typescript 支持", 98 | link: `${route}/guide/typescript/Support`, 99 | }, 100 | // { 101 | // text: "更多案例", 102 | // link: "/more/index", 103 | // }, 104 | ]; 105 | } 106 | function getExampleSidebar(lang: "en" | "zh") { 107 | const isEn = lang == "en"; 108 | 109 | const route = routeMap[lang]; 110 | return [ 111 | { 112 | text: isEn ? "Examples" : "示例", 113 | collapsed: false, 114 | items: [ 115 | { 116 | text: isEn ? "Basic Examples" : "基础示例", 117 | link: `${route}/example/index`, 118 | }, 119 | { 120 | text: "Code Syntax Check", 121 | link: `${route}/example/codeLint`, 122 | }, 123 | ], 124 | }, 125 | ]; 126 | } 127 | export default defineConfig({ 128 | base, 129 | title: "codemirror-editor-vue3", 130 | description: "CodeMirror component for Vue3", 131 | lastUpdated: true, 132 | cleanUrls: true, 133 | ignoreDeadLinks: [ 134 | // 自定义函数,忽略所有包含 "example "的链接 135 | (url) => { 136 | return url.toLowerCase().includes("/example"); 137 | }, 138 | ], 139 | vite: { 140 | build: {}, 141 | plugins: [ 142 | UnoCSS(), 143 | AutoImport({ 144 | resolvers: [ElementPlusResolver()], 145 | }), 146 | Components({ 147 | resolvers: [ElementPlusResolver()], 148 | }), 149 | ], 150 | resolve: { 151 | alias: [ 152 | { 153 | find: "codemirror-editor-vue3", 154 | replacement: `${pathResolve("packages/index.ts")}`, 155 | }, 156 | ], 157 | }, 158 | }, 159 | 160 | locales: { 161 | root: { 162 | label: "English", 163 | lang: "en", 164 | themeConfig: { 165 | lastUpdatedText: "Last update time", 166 | nav: getNav("en"), 167 | sidebar: { 168 | "/guide": getGuideSidebar("en"), 169 | "/example": getExampleSidebar("en"), 170 | }, 171 | }, 172 | }, 173 | "zh-CN": { 174 | label: "简体中文", 175 | lang: "zh-CN", 176 | themeConfig: { 177 | lastUpdatedText: "最近更新时间", 178 | nav: getNav("zh"), 179 | sidebar: { 180 | "/zh-CN/guide": getGuideSidebar("zh"), 181 | "/zh-CN/example": getExampleSidebar("zh"), 182 | }, 183 | }, 184 | }, 185 | }, 186 | head: [ 187 | ["link", { rel: "icon", href: "https://codemirror.net/favicon.ico" }], 188 | ["meta", { name: "theme-color", content: "#3c8772" }], 189 | ], 190 | themeConfig: { 191 | editLink: { 192 | pattern: "https://github.com/RennCheung/codemirror-editor-vue3/edit/main/docs/:path", 193 | text: "Edit this page on GitHub", 194 | }, 195 | socialLinks: [ 196 | { 197 | icon: "github", 198 | link: "https://github.com/RennCheung/codemirror-editor-vue3", 199 | }, 200 | ], 201 | 202 | footer: { 203 | message: "Released under the MIT License.", 204 | copyright: "Copyright © 2021-present Renn Cheung", 205 | }, 206 | search: { 207 | provider: "local", 208 | options: { 209 | locales: { 210 | "zh-CN": { 211 | translations: { 212 | button: { 213 | buttonText: "搜索文档", 214 | buttonAriaLabel: "搜索文档", 215 | }, 216 | modal: { 217 | noResultsText: "无法找到相关结果", 218 | resetButtonTitle: "清除查询条件", 219 | footer: { 220 | selectText: "选择", 221 | navigateText: "切换", 222 | }, 223 | }, 224 | }, 225 | }, 226 | }, 227 | }, 228 | }, 229 | 230 | // algolia: { 231 | // appId: "TIA2QKB31F", 232 | // apiKey: "57dd54cc00e988117cc8b741128f5089", 233 | // indexName: "codemirror-editor-vue3" 234 | // } 235 | }, 236 | }); 237 | -------------------------------------------------------------------------------- /docs/.vitepress/theme/index.ts: -------------------------------------------------------------------------------- 1 | import theme from "vitepress/dist/client/theme-default/index.js"; 2 | import "./styles/index.css"; 3 | import "virtual:uno.css"; 4 | 5 | export default { 6 | ...theme, 7 | }; 8 | -------------------------------------------------------------------------------- /docs/.vitepress/theme/styles/index.css: -------------------------------------------------------------------------------- 1 | .vp-doc p > a { 2 | margin-right: 8px; 3 | display: inline-block; 4 | } 5 | 6 | .VPDoc:not(.has-aside) .container .content { 7 | width: 100%; 8 | max-width: 100% !important; 9 | } 10 | 11 | .VPHomeHero .main .name, 12 | .VPHomeHero .main .tagline { 13 | width: 100%; 14 | max-width: 100%; 15 | } 16 | -------------------------------------------------------------------------------- /docs/demo/examples/Interactive/components/Example.vue: -------------------------------------------------------------------------------- 1 | 20 | 21 | 58 | 59 | 116 | -------------------------------------------------------------------------------- /docs/demo/examples/Interactive/components/LangSelect.vue: -------------------------------------------------------------------------------- 1 | 22 | 23 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /docs/demo/examples/Interactive/components/Layout.vue: -------------------------------------------------------------------------------- 1 | 65 | 66 | 111 | 116 | -------------------------------------------------------------------------------- /docs/demo/examples/Interactive/config/lang.ts: -------------------------------------------------------------------------------- 1 | // 引入 codemirror 所有语言包 2 | import "codemirror/mode/javascript/javascript"; 3 | import "codemirror/mode/css/css"; 4 | import "codemirror/mode/htmlmixed/htmlmixed"; 5 | import "codemirror/mode/vue/vue"; 6 | import "codemirror/mode/markdown/markdown"; 7 | import "codemirror/mode/jsx/jsx"; 8 | import "codemirror/mode/sass/sass"; 9 | import "codemirror/mode/php/php"; 10 | import "codemirror/mode/python/python"; 11 | import "codemirror/mode/go/go"; 12 | import "codemirror/mode/ruby/ruby"; 13 | import "codemirror/mode/sql/sql"; 14 | // yaml 15 | import "codemirror/mode/yaml/yaml"; 16 | 17 | // java 18 | import "codemirror/mode/clike/clike"; 19 | // go 20 | import "codemirror/mode/go/go"; 21 | // php 22 | import "codemirror/mode/php/php"; 23 | // python 24 | import "codemirror/mode/python/python"; 25 | // ruby 26 | import "codemirror/mode/ruby/ruby"; 27 | // sql 28 | import "codemirror/mode/sql/sql"; 29 | // shell 30 | import "codemirror/mode/shell/shell"; 31 | -------------------------------------------------------------------------------- /docs/demo/examples/Interactive/config/theme.ts: -------------------------------------------------------------------------------- 1 | import "codemirror/theme/dracula.css"; 2 | import "codemirror/theme/3024-day.css"; 3 | import "codemirror/theme/3024-night.css"; 4 | import "codemirror/theme/abbott.css"; 5 | import "codemirror/theme/abcdef.css"; 6 | import "codemirror/theme/ambiance.css"; 7 | import "codemirror/theme/ayu-dark.css"; 8 | import "codemirror/theme/ayu-mirage.css"; 9 | import "codemirror/theme/base16-dark.css"; 10 | import "codemirror/theme/base16-light.css"; 11 | import "codemirror/theme/bespin.css"; 12 | import "codemirror/theme/blackboard.css"; 13 | import "codemirror/theme/cobalt.css"; 14 | import "codemirror/theme/colorforth.css"; 15 | import "codemirror/theme/darcula.css"; 16 | import "codemirror/theme/dracula.css"; 17 | import "codemirror/theme/duotone-dark.css"; 18 | import "codemirror/theme/duotone-light.css"; 19 | import "codemirror/theme/eclipse.css"; 20 | import "codemirror/theme/elegant.css"; 21 | import "codemirror/theme/erlang-dark.css"; 22 | import "codemirror/theme/gruvbox-dark.css"; 23 | import "codemirror/theme/hopscotch.css"; 24 | import "codemirror/theme/icecoder.css"; 25 | import "codemirror/theme/idea.css"; 26 | import "codemirror/theme/isotope.css"; 27 | import "codemirror/theme/juejin.css"; 28 | import "codemirror/theme/lesser-dark.css"; 29 | import "codemirror/theme/liquibyte.css"; 30 | import "codemirror/theme/lucario.css"; 31 | import "codemirror/theme/material.css"; 32 | import "codemirror/theme/material-darker.css"; 33 | import "codemirror/theme/material-palenight.css"; 34 | import "codemirror/theme/material-ocean.css"; 35 | import "codemirror/theme/mbo.css"; 36 | import "codemirror/theme/mdn-like.css"; 37 | import "codemirror/theme/midnight.css"; 38 | import "codemirror/theme/monokai.css"; 39 | import "codemirror/theme/moxer.css"; 40 | import "codemirror/theme/neat.css"; 41 | import "codemirror/theme/neo.css"; 42 | import "codemirror/theme/night.css"; 43 | import "codemirror/theme/nord.css"; 44 | import "codemirror/theme/oceanic-next.css"; 45 | import "codemirror/theme/panda-syntax.css"; 46 | import "codemirror/theme/paraiso-dark.css"; 47 | import "codemirror/theme/paraiso-light.css"; 48 | import "codemirror/theme/pastel-on-dark.css"; 49 | import "codemirror/theme/railscasts.css"; 50 | import "codemirror/theme/rubyblue.css"; 51 | import "codemirror/theme/seti.css"; 52 | import "codemirror/theme/shadowfox.css"; 53 | import "codemirror/theme/solarized.css"; 54 | import "codemirror/theme/the-matrix.css"; 55 | import "codemirror/theme/tomorrow-night-bright.css"; 56 | import "codemirror/theme/tomorrow-night-eighties.css"; 57 | import "codemirror/theme/ttcn.css"; 58 | import "codemirror/theme/twilight.css"; 59 | import "codemirror/theme/vibrant-ink.css"; 60 | import "codemirror/theme/xq-dark.css"; 61 | import "codemirror/theme/xq-light.css"; 62 | import "codemirror/theme/yeti.css"; 63 | import "codemirror/theme/yonce.css"; 64 | import "codemirror/theme/zenburn.css"; 65 | -------------------------------------------------------------------------------- /docs/demo/examples/Interactive/demo.vue: -------------------------------------------------------------------------------- 1 | 14 | 74 | 81 | -------------------------------------------------------------------------------- /docs/demo/examples/Interactive/index.vue: -------------------------------------------------------------------------------- 1 | 17 | 18 | 61 | 62 | 67 | -------------------------------------------------------------------------------- /docs/demo/examples/Interactive/store.ts: -------------------------------------------------------------------------------- 1 | import { useData } from "vitepress"; 2 | import { LANG_OPTIONS, DEFAULT_LANG_OPT } from "./config/langOptions"; 3 | import { reactive, watch, onMounted } from "vue"; 4 | export const store = reactive({ 5 | height: "400px" as string | number, 6 | width: "100%", 7 | lineHeight: "20px", 8 | fontSize: "13px", 9 | border: true, 10 | readOnly: false, 11 | theme: "default", 12 | themePath: "", 13 | lang: DEFAULT_LANG_OPT.value, 14 | langPath: DEFAULT_LANG_OPT.langPath, 15 | code: DEFAULT_LANG_OPT.code, 16 | }); 17 | 18 | export const useStore = () => { 19 | const { isDark } = useData(); 20 | 21 | watch( 22 | isDark, 23 | (val) => { 24 | store.theme = val ? "dracula" : "default"; 25 | store.themePath = val ? "codemirror/theme/dracula.css" : ""; 26 | }, 27 | { immediate: true, deep: true } 28 | ); 29 | 30 | watch( 31 | () => store.lang, 32 | (val) => { 33 | if (val == "langConfig") return; 34 | const langOpt = LANG_OPTIONS.find((opt) => opt.value === val); 35 | if (langOpt) { 36 | store.langPath = langOpt.langPath; 37 | store.code = langOpt.code; 38 | } 39 | }, 40 | { immediate: true } 41 | ); 42 | 43 | onMounted(() => { 44 | // 读取 url 中的 lang参数 45 | const url = new URL(window.location.href); 46 | const lang = url.searchParams.get("lang"); 47 | if (lang) { 48 | const langOpt = LANG_OPTIONS.find((opt) => opt.label === lang); 49 | if (langOpt) { 50 | store.lang = langOpt.value; 51 | } 52 | } 53 | console.log("url lang", lang, store); 54 | }); 55 | return store; 56 | }; 57 | 58 | export default store; 59 | -------------------------------------------------------------------------------- /docs/demo/examples/Interactive/template.pug: -------------------------------------------------------------------------------- 1 | 12 | 39 | 44 | -------------------------------------------------------------------------------- /docs/demo/examples/Interactive/types/index.ts: -------------------------------------------------------------------------------- 1 | export type LangOption = { 2 | value: string; 3 | label: string; 4 | code: string; 5 | langPath: string; 6 | disabled?: boolean; 7 | }; 8 | 9 | export type LayoutState = { 10 | height: string; 11 | width: string; 12 | lineHeight: string; 13 | fontSize: string; 14 | }; 15 | 16 | export type ThemeOption = { 17 | value: string; 18 | label: string; 19 | filePath: string; 20 | }; 21 | -------------------------------------------------------------------------------- /docs/demo/examples/Interactive/utils.ts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rennzhang/codemirror-editor-vue3/c45b54c864ee0c19512720d717d986423822bb09/docs/demo/examples/Interactive/utils.ts -------------------------------------------------------------------------------- /docs/demo/examples/components/BashBlock.vue: -------------------------------------------------------------------------------- 1 | 36 | 37 | 51 | 52 | 58 | -------------------------------------------------------------------------------- /docs/demo/examples/components/Example.vue: -------------------------------------------------------------------------------- 1 | 31 | 32 | 78 | 79 | 131 | -------------------------------------------------------------------------------- /docs/demo/examples/components/IconCode.vue: -------------------------------------------------------------------------------- 1 | 15 | 16 | 21 | -------------------------------------------------------------------------------- /docs/demo/examples/components/IconCopy.vue: -------------------------------------------------------------------------------- 1 | 17 | 18 | 23 | -------------------------------------------------------------------------------- /docs/demo/examples/index.vue: -------------------------------------------------------------------------------- 1 | 12 | 13 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /docs/demo/examples/lang/js.vue: -------------------------------------------------------------------------------- 1 | 12 | 57 | 62 | -------------------------------------------------------------------------------- /docs/demo/examples/lint/index.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /docs/demo/examples/lint/jsLint.vue: -------------------------------------------------------------------------------- 1 | 12 | 60 | 65 | -------------------------------------------------------------------------------- /docs/demo/examples/lint/jsonLint.vue: -------------------------------------------------------------------------------- 1 | 12 | 87 | 92 | -------------------------------------------------------------------------------- /docs/demo/examples/utils.ts: -------------------------------------------------------------------------------- 1 | export function pathResolve(dir: string) { 2 | return import.meta.glob(`.${dir}`)[dir]; 3 | } 4 | export default ""; 5 | -------------------------------------------------------------------------------- /docs/demo/home.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 13 | -------------------------------------------------------------------------------- /docs/demo/index.vue: -------------------------------------------------------------------------------- 1 | 13 | 14 | 46 | -------------------------------------------------------------------------------- /docs/demo/log/fclog.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 34 | -------------------------------------------------------------------------------- /docs/demo/log/index.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 51 | -------------------------------------------------------------------------------- /docs/demo/mergeDemo.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 56 | -------------------------------------------------------------------------------- /docs/example/codeLint.md: -------------------------------------------------------------------------------- 1 | --- 2 | aside: false 3 | --- 4 | 5 | # Code syntax check 6 | 7 | ::: tip Here are some examples of code syntax checking(code lint), currently supported for js, json. 8 | 9 | Click on the blue font below to see the effect. ::: 10 | 11 | 12 | 13 | 31 | -------------------------------------------------------------------------------- /docs/example/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | aside: false 3 | --- 4 | 5 | # Example 6 | 7 | More cases are being updated... 8 | 9 | # Interactive Example 10 | 11 | ::: tip You can get rich examples through the following configurations. 12 | 13 | ::: 14 | 15 | 16 | 17 | 35 | -------------------------------------------------------------------------------- /docs/guide/events.md: -------------------------------------------------------------------------------- 1 | # Component Events 2 | 3 | > The following three are only the events encapsulated by this component. Please refer to more events 4 | > [Codemirror Events](./events#codemirror-events) 5 | 6 | | event name | description | params | 7 | | ---------- | :---------------------------------: | :------------------------------------ | 8 | | `change` | value or instance changes | `(value: string, cm: Editor) => void` | 9 | | `input` | input | `(value: string) => void` | 10 | | `ready` | The Codemirror component is mounted | `(cm: Editor) => void;` | 11 | 12 | the case: 13 | 14 | ```vue 15 | 26 | 52 | 53 | ``` 54 | 55 | ::: warning tip 56 | 57 | change events in the merge mode are different, Case code: 58 | 59 | ::: details 60 | 61 | ```vue 62 | 71 | 94 | 95 | ``` 96 | 97 | ::: 98 | 99 | ## Codemirror Events 100 | 101 | ::: tip 102 | 103 | The following events are official events of Codemirror5. You can refer to the official documents for details 104 | [Codemirror Event](https://codemirror.net/doc/manual.html#events),You can use this component to bind events directly 105 | through components, for example: 106 | 107 | ::: 108 | 109 | ```vue {8-10} 110 | 121 | ``` 122 | 123 | > All event names are as follows: 124 | 125 | - `changes` 126 | - `scroll` 127 | - `beforeChange` 128 | - `cursorActivity` 129 | - `keyHandled` 130 | - `inputRead` 131 | - `electricInput` 132 | - `beforeSelectionChange` 133 | - `viewportChange` 134 | - `swapDoc` 135 | - `gutterClick` 136 | - `gutterContextMenu` 137 | - `focus` 138 | - `blur` 139 | - `refresh` 140 | - `optionChange` 141 | - `scrollCursorIntoView` 142 | - `update` 143 | -------------------------------------------------------------------------------- /docs/guide/getting-started.md: -------------------------------------------------------------------------------- 1 | [![GitHub stars](https://img.shields.io/github/stars/RennCheung/codemirror-editor-vue3)](https://github.com/RennCheung/codemirror-editor-vue3/stargazers) 2 | [![npm downloads](https://img.shields.io/npm/dt/codemirror-editor-vue3)](https://www.npmjs.com/package/codemirror-editor-vue3) 3 | [![GitHub issues](https://img.shields.io/github/issues/RennCheung/codemirror-editor-vue3)](https://github.com/RennCheung/codemirror-editor-vue3/issues) 4 | [![GitHub forks](https://img.shields.io/github/forks/RennCheung/codemirror-editor-vue3)](https://github.com/RennCheung/codemirror-editor-vue3/network) 5 | [![GitHub last commit](https://img.shields.io/github/last-commit/RennCheung/codemirror-editor-vue3)](https://github.com/RennCheung/codemirror-editor-vue3) 6 | [![license](https://img.shields.io/github/license/RennCheung/codemirror-editor-vue3)](https://github.com/RennCheung/codemirror-editor-vue3) 7 | 8 | ## Introduction 9 | 10 | The codemirror component of vue3. This component is developed based on [Codemirror 5](http://codemirror.net/5/) and only 11 | vue3 is supported. 12 | 13 | In addition to the officially supported modes, the log output presentation mode is added, out of the box, but not 14 | necessarily suitable for all scenarios. 15 | 16 | ## Install 17 | 18 | ::: code-group 19 | 20 | ```bash [npm] 21 | npm install codemirror-editor-vue3 codemirror@^5 -S 22 | ``` 23 | 24 | ```bash [yarn] 25 | yarn add codemirror-editor-vue3 codemirror@">=5.64.0 <6" 26 | ``` 27 | 28 | ```bash [pnpm] 29 | pnpm i codemirror-editor-vue3 codemirror@^5 -S 30 | ``` 31 | 32 | ::: 33 | 34 | ::: details Typescript Support 35 | 36 | If your project requires Typescript support, you will also need to install the type dependency. 37 | 38 | ::: code-group 39 | 40 | ```bash [npm] 41 | npm install @types/codemirror -D 42 | ``` 43 | 44 | ```bash [yarn] 45 | yarn add @types/codemirror 46 | ``` 47 | 48 | ```bash [pnpm] 49 | pnpm i @types/codemirror -D 50 | ``` 51 | 52 | ::: 53 | 54 | ## Register global component 55 | 56 | ::: warning 57 | 58 | It is not recommended to register components globally. This will cause the type prompt on the template to not be 59 | retrieved correctly. 60 | 61 | ::: 62 | 63 | ::: code-group 64 | 65 | ```js [main.js] 66 | import { createApp } from "vue"; 67 | import App from "./App.vue"; 68 | import { InstallCodeMirror } from "codemirror-editor-vue3"; // [!code ++] 69 | 70 | const app = createApp(App); 71 | app.use(InstallCodeMirror); // [!code ++] 72 | app.mount("#app"); 73 | ``` 74 | 75 | ::: 76 | 77 | The global registered component name is Codemirror or you can customize a component name, for example: 78 | 79 | ::: code-group 80 | 81 | ```js [main.js] 82 | // .... 83 | app.use(InstallCodeMirror, { componentName: "customName" }); // [!code ++] 84 | ``` 85 | 86 | ::: 87 | 88 | ## Use in components 89 | 90 | This is a commonly used javascript language case. 91 | 92 | 93 | 94 | Specific code is as follows: 95 | 96 | ::: code-group 97 | 98 | ```vue [index.vue] 99 | 113 | 175 | ``` 176 | 177 | ```vue [index.vue(ts setup)] 178 | 192 | 243 | ``` 244 | 245 | ::: 246 | 247 | 263 | -------------------------------------------------------------------------------- /docs/guide/lang.md: -------------------------------------------------------------------------------- 1 | # Language Modes 2 | 3 | > Multiple language modes can be supported through 4 | > configuration,[Click to view all supported languages in codemirror5](https://codemirror.net/5/mode/index.html) 5 | 6 | ## View the case 7 | 8 | > You can click on the following link to view corresponding language cases 9 | 10 | - [javascript](/example?lang=javascript) 11 | - [json](/example?lang=json) 12 | - [css](/example?lang=css) 13 | - [html](/example?lang=html) 14 | - [apl](/example?lang=apl) 15 | - [yaml](/example?lang=yaml) 16 | 17 | More cases are gradually being added, and you can also refer to the following configuration methods to achieve more 18 | language modes. 19 | 20 | ## Language Configuration 21 | 22 | Just set `mode` in options and introduce the corresponding language pack. Multiple language modes can be supported 23 | through configuration. [Click to view all supported languages in codemirror5](https://codemirror.net/5/mode/index.html) 24 | 25 | ```vue {8,19} 26 | 30 | 55 | ``` 56 | -------------------------------------------------------------------------------- /docs/guide/prepattern/log.md: -------------------------------------------------------------------------------- 1 | # Log mode 2 | 3 | Based on the log modes derived from services, there are common log modes and custom log modes, as follows: 4 | 5 | ## Simple log mode(`mode: "log"`) 6 | 7 | > By default, words that start with a capital letter are shown in red 8 | 9 | 10 | 11 | ::: details Click to view the code 12 | 13 | ```vue 14 | 17 | 18 | 59 | ``` 60 | 61 | ::: 62 | 63 | ## Custom log mode(`mode: "fclog"`) 64 | 65 | 66 | 67 | ::: details Click to view the code 68 | 69 | ```vue 70 | 74 | 75 | 104 | ``` 105 | 106 | ::: 107 | 108 | ## Log mode method description 109 | 110 | | name | description | params | case | 111 | | ---------------- | :-----------------------------------------------------------------: | :------------------------------------------------------------------------------------------------ | :---------------------------------------------------------------------------------: | 112 | | `createLinkMark` | Create a clickable link (a tag), such as download the complete logs | support all a tag attributes, such as: `{ href: "/target-link", download: "", target: "_blank" }` | ![](../../img/createMarkLink.jpg) | 113 | | `createLogMark` | Flags the output type of the log | (text: string, type: `'info' \| 'warning' \| 'error'`) => void | ![](../../img/info.jpg)![](../../img/warning.jpg)![](../../img/error.jpg) | 114 | | `getLogMark` | Gets the text of the current tag and returns an array of nodes | `(value: string) => [{start: number, end: number ,node: HTMLElement}]` | - | 115 | | `createTitle` | Create a title | `(value: string, symbolLength?: number = 15, symbol?:string = "=") => string` | ![](../../img/createTitle.jpg) | 116 | | `createLog` | **Only used in fclog mode**, create log text with time and type | (text: string, type: `'info' \| 'warning' \| 'error'`) => void | ![](../../img/info.jpg)![](../../img/warning-time.jpg)![](../../img/error-time.jpg) | 117 | 118 | 139 | -------------------------------------------------------------------------------- /docs/guide/prepattern/merge.md: -------------------------------------------------------------------------------- 1 | # Merge Mode 2 | 3 | ::: tip 4 | 5 | merge pattern-related dependencies are already introduced within the component; you only need to import the language 6 | pattern and style files that you need to use. 7 | 8 | ::: 9 | 10 | ## introduce 11 | 12 | The merge mode works with the [diff-match-patch](https://github.com/JackuB/diff-match-patch) plug-in(Only 6.3k after 13 | compression), For better out-of-the-box, this dependency is automatically introduced when you install 14 | `codemirror-editor-vue3`. 15 | 16 | 17 | 18 | 34 | 35 | :::details Click to view the code 36 | 37 | ```vue 38 | 41 | 42 | 87 | ``` 88 | 89 | ::: 90 | -------------------------------------------------------------------------------- /docs/guide/props.md: -------------------------------------------------------------------------------- 1 | # Component Props 2 | 3 | [cm_config_url]: https://codemirror.net/doc/manual.html#config 4 | [cm_editor_type_url]: https://codemirror.net/doc/manual.html#config 5 | [default_options_url]: https://github.com/RennCheung/codemirror-editor-vue3/blob/main/packages/src/config/index.ts#L68 6 | 7 | | name | description | type | default | 8 | | ------------------- | :---------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------- | :------------------------------------: | 9 | | **value(v-model)** | Editor content | `string` | "" | 10 | | **options** | [Configuration options of codemirror5][cm_config_url] | [EditorConfiguration][cm_editor_type_url] | [DEFAULT_OPTIONS][default_options_url] | 11 | | **placeholder** | Editor placeholder content to introduce codemirror related files | `string` | "" | 12 | | **border** | Whether to display editor borders | `boolean` | `false` | 13 | | **width** | width | `string` | `100% ` | 14 | | **height** | height | `string` | `100% ` | 15 | | **original-style** | Using the original style, disable the second modification of the style for this component (but does not affect width, height, and border) | ` boolean` | `false` | 16 | | **KeepCursorInEnd** | Always keep the mouse position on the last line | `boolean` | `false` | 17 | | **merge** | merge mode, can also be used as diff pattern | `boolean` | `false` | 18 | | _name_ | Name, which is passed to the textarea inside the component(This is useless🙃) | `string` | - | 19 | -------------------------------------------------------------------------------- /docs/guide/supplementary/custom-theme.md: -------------------------------------------------------------------------------- 1 | # Custom Theme 2 | 3 | CodeMirror editor supports custom themes, allowing you to create your own theme using CSS variables and styles. This 4 | guide will show you how to create and use custom themes. 5 | 6 | ## Basic Usage 7 | 8 | To use a custom theme, you need to: 9 | 10 | 1. Define theme CSS variables and styles 11 | 2. Set the theme name in the editor instance 12 | 13 | Here's a complete example (theme code from [catppuccin/codemirror](https://github.com/catppuccin/codemirror)): 14 | 15 | ```vue 16 | 29 | 30 | 75 | 76 | 203 | ``` 204 | 205 | ## Theme Variables 206 | 207 | In custom themes, you can use the following CSS variables to control different element styles: 208 | 209 | - `--bg0`: Background color 210 | - `--bg1`: Secondary background color 211 | - `--bg4`: Line number color 212 | - `--fg`: Primary text color 213 | - `--fg3`: Secondary text color 214 | - `--gray`: Gray text 215 | - `--blue`: Blue highlight 216 | - `--yellow`: Yellow highlight 217 | - `--aqua`: Aqua highlight 218 | - `--orange`: Orange highlight 219 | - `--primary-bg`: Primary background color 220 | - `--current-line`: Current line background color 221 | - `--selection`: Selected text background color 222 | - `--atom`: Atomic element color 223 | - `--cursor`: Cursor color 224 | - `--keyword`: Keyword color 225 | - `--operator`: Operator color 226 | - `--number`: Number color 227 | - `--definition`: Definition color 228 | - `--string`: String color 229 | 230 | ## Using Custom Theme 231 | 232 | To use a custom theme, you need to: 233 | 234 | 1. Define theme-related CSS styles in your component 235 | 2. Set the theme name in the `onReady` callback: 236 | 237 | ```typescript 238 | onReady(cm: Editor) { 239 | cm.setOption("theme", "your-theme-name"); 240 | } 241 | ``` 242 | 243 | Note: The theme name should match the CSS class name `cm-s-your-theme-name`. 244 | 245 | ## Best Practices 246 | 247 | 1. Use CSS variables to manage theme colors for easier maintenance and modification 248 | 2. Add appropriate namespaces to theme classes to avoid style conflicts 249 | 3. Ensure theme styles cover all necessary CodeMirror elements 250 | 4. Test syntax highlighting effects in different language modes 251 | 5. Consider adding dark/light theme switching support 252 | -------------------------------------------------------------------------------- /docs/guide/supplementary/instance.md: -------------------------------------------------------------------------------- 1 | ::: tip Gets an instance object of the codemirror editor to perform a series of operations on the editor content, such 2 | as select, insert, collapse, and so on. ::: 3 | 4 | ## Obtained from the component ref 5 | 6 | Get the component first, then get the instance object in the component, and pay attention to the lifecycle. 7 | 8 | ```vue 9 | 19 | 20 | 60 | ``` 61 | 62 | ## Get it through the hook function 63 | 64 | You can get instance objects in 'change' and 'ready'. 65 | 66 | ```vue 67 | 78 | 79 | 118 | ``` 119 | -------------------------------------------------------------------------------- /docs/guide/supplementary/static-properties.md: -------------------------------------------------------------------------------- 1 | # CodeMirror Static properties 2 | 3 | Sometimes we need to use some of the static properties provided by the CodeMirror object itself, such as printing the 4 | default properties of CodeMirror. All properties can be found in the official 5 | [documentation](https://codemirror.net/5/doc/manual.html#api_static) 6 | 7 | ```vue 8 | 11 | 31 | ``` 32 | -------------------------------------------------------------------------------- /docs/guide/typescript/Support.md: -------------------------------------------------------------------------------- 1 | # Typescript Support 2 | 3 | ## Prepare 4 | 5 | - Make sure your project supports Typescript 6 | - It is recommended to install [volar](https://marketplace.visualstudio.com/items?itemName=johnsoncodehk.volar) for 7 | better template prompts 8 | - Installation dependency [@types/codemirror](https://www.npmjs.com/package/@types/codemirror) 9 | 10 | ::: code-group 11 | 12 | ```bash [npm] 13 | npm install @types/codemirror -D 14 | ``` 15 | 16 | ```bash [yarn] 17 | yarn add @types/codemirror 18 | ``` 19 | 20 | ```bash [pnpm] 21 | pnpm i @types/codemirror -D 22 | ``` 23 | 24 | ::: 25 | 26 | ## Case 27 | 28 | ```vue 29 | 33 | 34 | 76 | ``` 77 | -------------------------------------------------------------------------------- /docs/img/createMarkLink.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rennzhang/codemirror-editor-vue3/c45b54c864ee0c19512720d717d986423822bb09/docs/img/createMarkLink.jpg -------------------------------------------------------------------------------- /docs/img/createTitle.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rennzhang/codemirror-editor-vue3/c45b54c864ee0c19512720d717d986423822bb09/docs/img/createTitle.jpg -------------------------------------------------------------------------------- /docs/img/error-time.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rennzhang/codemirror-editor-vue3/c45b54c864ee0c19512720d717d986423822bb09/docs/img/error-time.jpg -------------------------------------------------------------------------------- /docs/img/error.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rennzhang/codemirror-editor-vue3/c45b54c864ee0c19512720d717d986423822bb09/docs/img/error.jpg -------------------------------------------------------------------------------- /docs/img/info-time.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rennzhang/codemirror-editor-vue3/c45b54c864ee0c19512720d717d986423822bb09/docs/img/info-time.jpg -------------------------------------------------------------------------------- /docs/img/info.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rennzhang/codemirror-editor-vue3/c45b54c864ee0c19512720d717d986423822bb09/docs/img/info.jpg -------------------------------------------------------------------------------- /docs/img/warning-time.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rennzhang/codemirror-editor-vue3/c45b54c864ee0c19512720d717d986423822bb09/docs/img/warning-time.jpg -------------------------------------------------------------------------------- /docs/img/warning.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rennzhang/codemirror-editor-vue3/c45b54c864ee0c19512720d717d986423822bb09/docs/img/warning.jpg -------------------------------------------------------------------------------- /docs/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: home 3 | 4 | title: codemirror-editor-vue3 5 | titleTemplate: codemirror-editor-vue3 6 | 7 | hero: 8 | name: codemirror-editor-vue3 9 | tagline: CodeMirror component for Vue3, very easy to use codeMirror. 10 | actions: 11 | - theme: brand 12 | text: Get Started 13 | link: /guide/getting-started 14 | - theme: alt 15 | text: View on GitHub 16 | link: https://github.com/RennCheung/codemirror-editor-vue3 17 | --- 18 | 19 | 20 | 21 | 37 | -------------------------------------------------------------------------------- /docs/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "name": "codemirror-editor-vue3-docs" 4 | } 5 | -------------------------------------------------------------------------------- /docs/zh-CN/example/codeLint.md: -------------------------------------------------------------------------------- 1 | --- 2 | aside: false 3 | --- 4 | 5 | # 代码语法检查 6 | 7 | ::: tip下面是一些代码语法检查的案例,目前支持 js、json等。 8 | 9 | 可以点击下面蓝色字体查看效果 ::: 10 | 11 | 12 | 13 | 31 | -------------------------------------------------------------------------------- /docs/zh-CN/example/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | aside: false 3 | --- 4 | 5 | # 交互案例 6 | 7 | ::: tip通过下面的各项配置,你可以得到丰富的案例 8 | 9 | ::: 10 | 11 | 12 | 13 | 31 | -------------------------------------------------------------------------------- /docs/zh-CN/guide/events.md: -------------------------------------------------------------------------------- 1 | # 组件事件 2 | 3 | > 以下三种仅是本组件封装的事件,更多事件请查阅 [Codemirror Events](./events#codemirror-events) 4 | 5 | | 事件名称 | 说明 | 参数 | 6 | | -------- | :----------------: | :------------------------------------ | 7 | | `change` | `值`或者`实例`改变 | `(value: string, cm: Editor) => void` | 8 | | `input` | input | `(value: string) => void` | 9 | | `ready` | 组件加载完成 | `(cm: Editor) => void;` | 10 | 11 | 示例: 12 | 13 | ```vue 14 | 25 | 51 | 52 | ``` 53 | 54 | ::: warning 注意 `merge(diff)` 模式下 `change` 事件有所不同, 示例: 55 | 56 | ::: details 57 | 58 | ```vue 59 | 68 | 90 | ``` 91 | 92 | ::: 93 | 94 | ## Codemirror 自身事件 95 | 96 | ::: tip 97 | 98 | 以下事件为 Codemirror5 官方自身事件,具体内容可以查阅官方文档 99 | [Codemirror Event](https://codemirror.net/doc/manual.html#events),使用本插件时可以直接通过组件绑定事件,例如: 100 | 101 | ::: 102 | 103 | ```vue {8-10} 104 | 115 | ``` 116 | 117 | > 所有事件名称如下: 118 | 119 | - `changes` 120 | - `scroll` 121 | - `beforeChange` 122 | - `cursorActivity` 123 | - `keyHandled` 124 | - `inputRead` 125 | - `electricInput` 126 | - `beforeSelectionChange` 127 | - `viewportChange` 128 | - `swapDoc` 129 | - `gutterClick` 130 | - `gutterContextMenu` 131 | - `focus` 132 | - `blur` 133 | - `refresh` 134 | - `optionChange` 135 | - `scrollCursorIntoView` 136 | - `update` 137 | -------------------------------------------------------------------------------- /docs/zh-CN/guide/getting-started.md: -------------------------------------------------------------------------------- 1 | [![GitHub stars](https://img.shields.io/github/stars/RennCheung/codemirror-editor-vue3)](https://github.com/RennCheung/codemirror-editor-vue3/stargazers) 2 | [![npm downloads](https://img.shields.io/npm/dt/codemirror-editor-vue3)](https://www.npmjs.com/package/codemirror-editor-vue3) 3 | [![GitHub issues](https://img.shields.io/github/issues/RennCheung/codemirror-editor-vue3)](https://github.com/RennCheung/codemirror-editor-vue3/issues) 4 | [![GitHub forks](https://img.shields.io/github/forks/RennCheung/codemirror-editor-vue3)](https://github.com/RennCheung/codemirror-editor-vue3/network) 5 | [![GitHub last commit](https://img.shields.io/github/last-commit/RennCheung/codemirror-editor-vue3)](https://github.com/RennCheung/codemirror-editor-vue3) 6 | [![license](https://img.shields.io/github/license/RennCheung/codemirror-editor-vue3)](https://github.com/RennCheung/codemirror-editor-vue3) 7 | 8 | ## 简介 9 | 10 | Codemirror 的 vue3 组件。 基于 [Codemirror 5](http://codemirror.net/5/)开发,仅支持 vue3. 11 | 12 | 除了 Codemirror 官方支持的模式外,还增加了开箱即用的日志输出模式,但不一定适用于所有场景。 13 | 14 | ## 安装 15 | 16 | ::: code-group 17 | 18 | ```bash [npm] 19 | npm install codemirror-editor-vue3 codemirror@^5 -S 20 | ``` 21 | 22 | ```bash [yarn] 23 | yarn add codemirror-editor-vue3 codemirror@">=5.64.0 <6" 24 | ``` 25 | 26 | ```bash [pnpm] 27 | pnpm i codemirror-editor-vue3 codemirror@^5 -S 28 | ``` 29 | 30 | ::: 31 | 32 | ::: details 使用 Typescript 33 | 34 | 如果你的项目需要支持 Typescript,那还需要安装对应的类型包. 35 | 36 | ::: code-group 37 | 38 | ```bash [npm] 39 | npm install @types/codemirror -D 40 | ``` 41 | 42 | ```bash [yarn] 43 | yarn add @types/codemirror 44 | ``` 45 | 46 | ```bash [pnpm] 47 | pnpm i @types/codemirror -D 48 | ``` 49 | 50 | ::: 51 | 52 | ## 注册全局组件 53 | 54 | ::: warning 55 | 56 | 提示不建议全局注册组件,这会导致无法正确获取模板上的类型提示。 57 | 58 | ::: 59 | 60 | ::: code-group 61 | 62 | ```js [main.js] 63 | import { createApp } from "vue"; 64 | import App from "./App.vue"; 65 | import { InstallCodeMirror } from "codemirror-editor-vue3"; // [!code ++] 66 | 67 | const app = createApp(App); 68 | app.use(InstallCodeMirror); // [!code ++] 69 | app.mount("#app"); 70 | ``` 71 | 72 | ::: 73 | 74 | 全局注册组件名称是`Codemirror`,也可以自定义一个组件名称,例如: 75 | 76 | ::: code-group 77 | 78 | ```js [main.js] 79 | // .... 80 | app.use(InstallCodeMirror, { componentName: "customName" }); // [!code ++] 81 | ``` 82 | 83 | ::: 84 | 85 | --- 86 | 87 | ## 在组件中使用 88 | 89 | 这是一个常用的 javascript 语言的案例。 90 | 91 | 92 | 93 | 具体代码如下: 94 | 95 | ::: code-group 96 | 97 | ```vue [index.vue] 98 | 112 | 174 | ``` 175 | 176 | ```vue [index.vue(ts setup)] 177 | 191 | 242 | ``` 243 | 244 | ::: 245 | 246 | 262 | -------------------------------------------------------------------------------- /docs/zh-CN/guide/lang.md: -------------------------------------------------------------------------------- 1 | # 语言模式 2 | 3 | > 通过配置可支持多种语言模式,[点击查看 codemirror5 所有已支持的语言](https://codemirror.net/5/mode/index.html) 4 | 5 | ## 查看案例 6 | 7 | > 可以点击以下链接查看对应语言案例 8 | 9 | - [javascript](/zh-CN/example?lang=javascript) 10 | - [json](/zh-CN/example?lang=json) 11 | - [css](/zh-CN/example?lang=css) 12 | - [html](/zh-CN/example?lang=html) 13 | - [apl](/zh-CN/example?lang=apl) 14 | - [yaml](/zh-CN/example?lang=yaml) 15 | 16 | 更多案例陆续添加中,也可以参考下面的配置方法实现更多语言模式 17 | 18 | ## 语言配置 19 | 20 | 在 options 中设置 `mode`,并引入对应的语言包即可,通过配置可支持多种语言模式, 21 | [点击查看 codemirror5 所有已支持的语言](https://codemirror.net/5/mode/index.html) 22 | 23 | ```vue {8,19} 24 | 28 | 53 | ``` 54 | -------------------------------------------------------------------------------- /docs/zh-CN/guide/prepattern/log.md: -------------------------------------------------------------------------------- 1 | # 日志模式 2 | 3 | 根据业务衍生的日志模式,分为普通日志模式和自定义日志模式,如下: 4 | 5 | ## 简单日志模式(`mode: "log"`) 6 | 7 | > 默认情况下,首字母大写的单词会显示为红色 8 | 9 | 10 | 11 | :::details 点击查看代码 12 | 13 | ```vue 14 | 17 | 18 | 59 | ``` 60 | 61 | ::: 62 | 63 | ## 自定义日志模式(`mode: "fclog"`) 64 | 65 | 66 | 67 | :::details 点击查看代码 68 | 69 | ```vue 70 | 74 | 75 | 104 | ``` 105 | 106 | ::: 107 | 108 | ## 日志模式方法说明 109 | 110 | | 名称 | 说明 | 参数 | 案例 | 111 | | ---------------- | :-------------------------------------------------------: | :---------------------------------------------------------------------------------- | :------------------------------------------------------------------------------------------: | 112 | | `createLinkMark` | 创建一个可点击的连接(a 标签),如下载完整日志 | 支持所有 a 标签属性,如:`{ href: "/target-link", download: "", target: "_blank" }` | ![](../../../img/createMarkLink.jpg) | 113 | | `createLogMark` | 标记日志的输出类型 | (text: string, type: `'info' \| 'warning' \| 'error'`) => void | ![](../../../img/info.jpg)![](../../../img/warning.jpg)![](../../../img/error.jpg) | 114 | | `getLogMark` | 获取当前标记的文本,返回节点数组 | `(value: string) => [{start: number, end: number ,node: HTMLElement}]` | - | 115 | | `createTitle` | 创建标题 | `(value: string, symbolLength?: number = 15, symbol?:string = "=") => string` | ![](../../../img/createTitle.jpg) | 116 | | `createLog` | **仅在 fclog 模式下使用**,创建带有时间以及类型的日志文本 | (text: string, type: `'info' \| 'warning' \| 'error'`) => void | ![](../../../img/info.jpg)![](../../../img/warning-time.jpg)![](../../../img/error-time.jpg) | 117 | 118 | 139 | -------------------------------------------------------------------------------- /docs/zh-CN/guide/prepattern/merge.md: -------------------------------------------------------------------------------- 1 | # merge 模式 2 | 3 | ::: tip 4 | 5 | 组件内部已经引入 merge 模式相关依赖,只需要引入需要使用的语言模式和样式文件即可。 6 | 7 | ::: 8 | 9 | ## 说明 10 | 11 | merge 模式需要配合[diff-match-patch](https://github.com/JackuB/diff-match-patch)插件使用(压缩后只占用 6.3k),为了更好 12 | 的开箱即用,安装`codemirror-editor-vue3`时会自动引入该依赖 13 | 14 | 15 | 16 | 32 | 33 | :::details 点击查看代码 34 | 35 | ```vue 36 | 39 | 40 | 85 | ``` 86 | 87 | ::: 88 | -------------------------------------------------------------------------------- /docs/zh-CN/guide/props.md: -------------------------------------------------------------------------------- 1 | # 组件 Props 2 | 3 | [cm_config_url]: https://codemirror.net/doc/manual.html#config 4 | [cm_editor_type_url]: https://codemirror.net/doc/manual.html#config 5 | [default_options_url]: https://github.com/RennCheung/codemirror-editor-vue3/blob/main/packages/src/config/index.ts#L68 6 | 7 | | 名称 | 说明 | 类型 | 默认值 | 8 | | ------------------- | :----------------------------------------------------------------: | :---------------------------------------- | :------------------------------------: | 9 | | **value(v-model)** | 编辑器内容 | `string` | "" | 10 | | **options** | [codemirror5的配置项][cm_config_url] | [EditorConfiguration][cm_editor_type_url] | [DEFAULT_OPTIONS][default_options_url] | 11 | | **placeholder** | 编辑器占位内容,需引入 codemirror 相关文件 | `string` | "" | 12 | | **border** | 边框 | `boolean` | `false` | 13 | | **width** | 宽度 | `string` | `100% ` | 14 | | **height** | 高度 | `string` | `100% ` | 15 | | **original-style** | 使用原始样式,禁用此组件二次修改的样式(`但不影响宽度、高度和边框`) | ` boolean` | `false` | 16 | | **KeepCursorInEnd** | 始终保持鼠标位置在最后一行 | `boolean` | `false` | 17 | | **merge** | `merge` 模式,也可作为 diff 模式 | `boolean` | `false` | 18 | | _name_ | 名称,将传给给组件内部的 textarea(没什么用🙃) | `string` | - | 19 | -------------------------------------------------------------------------------- /docs/zh-CN/guide/supplementary/custom-theme.md: -------------------------------------------------------------------------------- 1 | # 自定义主题 2 | 3 | CodeMirror 编辑器支持自定义主题,你可以通过 CSS 变量和样式来创建自己的主题。本文将介绍如何创建和使用自定义主题。 4 | 5 | ## 基本用法 6 | 7 | 要使用自定义主题,你需要: 8 | 9 | 1. 定义主题的 CSS 变量和样式 10 | 2. 在编辑器实例中设置主题名称 11 | 12 | 以下是一个完整的示例(主题代码来自 [catppuccin/codemirror](https://github.com/catppuccin/codemirror)): 13 | 14 | ```vue 15 | 28 | 29 | 74 | 75 | 202 | ``` 203 | 204 | ## 主题变量说明 205 | 206 | 在自定义主题中,你可以使用以下 CSS 变量来控制不同元素的样式: 207 | 208 | - `--bg0`: 背景色 209 | - `--bg1`: 次要背景色 210 | - `--bg4`: 行号颜色 211 | - `--fg`: 主要文本颜色 212 | - `--fg3`: 次要文本颜色 213 | - `--gray`: 灰色文本 214 | - `--blue`: 蓝色高亮 215 | - `--yellow`: 黄色高亮 216 | - `--aqua`: 青色高亮 217 | - `--orange`: 橙色高亮 218 | - `--primary-bg`: 主背景色 219 | - `--current-line`: 当前行背景色 220 | - `--selection`: 选中文本背景色 221 | - `--atom`: 原子元素颜色 222 | - `--cursor`: 光标颜色 223 | - `--keyword`: 关键字颜色 224 | - `--operator`: 运算符颜色 225 | - `--number`: 数字颜色 226 | - `--definition`: 定义颜色 227 | - `--string`: 字符串颜色 228 | 229 | ## 使用自定义主题 230 | 231 | 要使用自定义主题,你需要: 232 | 233 | 1. 在组件中定义主题相关的 CSS 样式 234 | 2. 在 `onReady` 回调中设置主题名称: 235 | 236 | ```typescript 237 | onReady(cm: Editor) { 238 | cm.setOption("theme", "your-theme-name"); 239 | } 240 | ``` 241 | 242 | 注意:主题名称应该与 CSS 类名中的 `cm-s-your-theme-name` 保持一致。 243 | 244 | ## 最佳实践 245 | 246 | 1. 使用 CSS 变量来管理主题颜色,便于统一管理和修改 247 | 2. 为主题类添加适当的命名空间,避免样式冲突 248 | 3. 确保主题样式覆盖所有必要的 CodeMirror 元素 249 | 4. 测试不同语言模式下的语法高亮效果 250 | 5. 考虑添加暗色/亮色主题切换支持 251 | -------------------------------------------------------------------------------- /docs/zh-CN/guide/supplementary/instance.md: -------------------------------------------------------------------------------- 1 | ::: tip 获取 codemirror editor 的实例对象,从而对编辑器内容进行一系列的操作,比如选中、插入、折叠等等。::: 2 | 3 | ## 通过组件 ref 获取 4 | 5 | 先获取组件,再获取组件中的实例对象,需要注意生命周期。 6 | 7 | ```vue 8 | 18 | 19 | 59 | ``` 60 | 61 | ## 通过钩子函数获取 62 | 63 | 可以在`change`和`ready`中拿到实例对象 64 | 65 | ```vue 66 | 77 | 78 | 117 | ``` 118 | -------------------------------------------------------------------------------- /docs/zh-CN/guide/supplementary/static-properties.md: -------------------------------------------------------------------------------- 1 | # CodeMirror Static properties 2 | 3 | 有时候我们需要使用 `CodeMirror` 对象本身提供的一些`静态属性`,例如打印 CodeMirror 的默认属性,更多属性请查 4 | 阅[官方文档](https://codemirror.net/5/doc/manual.html#api_static) 5 | 6 | ```vue 7 | 10 | 30 | ``` 31 | -------------------------------------------------------------------------------- /docs/zh-CN/guide/typescript/Support.md: -------------------------------------------------------------------------------- 1 | # Typescript Support 2 | 3 | ## 前置工作 4 | 5 | - 确保你的项目支持 ts 6 | - 推荐安装 [volar](https://marketplace.visualstudio.com/items?itemName=johnsoncodehk.volar) 获取更好的模板提示 7 | - 安装依赖 [@types/codemirror](https://www.npmjs.com/package/@types/codemirror) 8 | 9 | ::: code-group 10 | 11 | ```bash [npm] 12 | npm install @types/codemirror -D 13 | ``` 14 | 15 | ```bash [yarn] 16 | yarn add @types/codemirror 17 | ``` 18 | 19 | ```bash [pnpm] 20 | pnpm i @types/codemirror -D 21 | ``` 22 | 23 | ::: 24 | 25 | ## 案例 26 | 27 | ```vue 28 | 32 | 33 | 75 | ``` 76 | -------------------------------------------------------------------------------- /docs/zh-CN/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: home 3 | 4 | title: codemirror-editor-vue3 5 | titleTemplate: codemirror-editor-vue3 6 | 7 | hero: 8 | name: codemirror-editor-vue3 9 | tagline: CodeMirror 的 vue3 组件, 开箱即用. 10 | actions: 11 | - theme: brand 12 | text: 入门指南 13 | link: /zh-CN/guide/getting-started 14 | - theme: alt 15 | text: View on GitHub 16 | link: https://github.com/RennCheung/codemirror-editor-vue3 17 | --- 18 | 19 | 20 | 21 | 37 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Vite App 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "codemirror-editor-vue3", 3 | "description": "CodeMirror component for Vue3", 4 | "version": "2.8.0", 5 | "license": "MIT", 6 | "files": [ 7 | "dist" 8 | ], 9 | "type": "module", 10 | "types": "./dist/packages/index.d.ts", 11 | "main": "./dist/codemirror-editor-vue3.umd.cjs", 12 | "module": "./dist/codemirror-editor-vue3.js", 13 | "exports": { 14 | ".": { 15 | "import": "./dist/codemirror-editor-vue3.js", 16 | "require": "./dist/codemirror-editor-vue3.umd.cjs", 17 | "types": "./dist/packages/index.d.ts" 18 | } 19 | }, 20 | "private": false, 21 | "author": { 22 | "name": "RennCheung", 23 | "email": "906155099@qq.com" 24 | }, 25 | "homepage": "https://rennzhang.github.io/codemirror-editor-vue3/", 26 | "unpkg": "dist/codemirror-editor-vue3.js", 27 | "jsnext:main": "dist/codemirror-editor-vue3.js", 28 | "jspm": { 29 | "main": "dist/codemirror-editor-vue3.js", 30 | "registry": "npm", 31 | "format": "esm" 32 | }, 33 | "repository": { 34 | "type": "git", 35 | "url": "git+https://github.com/rennzhang/codemirror-editor-vue3.git" 36 | }, 37 | "keywords": [ 38 | "codemirror-editor-vue3", 39 | "vue3 codemirror", 40 | "codemirror", 41 | "vue3", 42 | "log mode", 43 | "log" 44 | ], 45 | "scripts": { 46 | "dev": "vite", 47 | "build": "vite build", 48 | "docs-dev": "vitepress dev docs --open", 49 | "docs-build": "vitepress build docs", 50 | "docs-serve": "vitepress serve docs", 51 | "deploy-docs": "bash scripts/deploy-docs.sh", 52 | "release": "node --import tsx scripts/release.ts", 53 | "changelog": "conventional-changelog -p angular -i CHANGELOG.md -s", 54 | "lint:eslint": "eslint --cache --max-warnings 0 \"{docs,packages,tests,types}/**/*.{vue,js,jsx,ts,tsx}\" --fix", 55 | "lint:prettier": "prettier --write \"{docs,packages,tests,types}/**/*.{vue,js,jsx,ts,tsx,json,css,less,scss,html,md}\"", 56 | "lint": "pnpm lint:eslint && pnpm lint:prettier", 57 | "tsc": "tsc", 58 | "prepublishOnly": "npm run build" 59 | }, 60 | "dependencies": { 61 | "codemirror": "^5", 62 | "diff-match-patch": "^1.0.5" 63 | }, 64 | "peerDependencies": { 65 | "codemirror": "^5", 66 | "diff-match-patch": "^1.0.5", 67 | "vue": "^3.x" 68 | }, 69 | "devDependencies": { 70 | "@unocss/transformer-directives": "^0.58.8", 71 | "@wdns/vue-code-block": "^2.3.2", 72 | "unplugin-vue-components": "^0.26.0", 73 | "element-plus": "^2.6.3", 74 | "jsonlint-mod": "^1.7.6", 75 | "@commitlint/cli": "^16.1.0", 76 | "@commitlint/config-conventional": "^16.0.0", 77 | "@types/codemirror": "^5.60.15", 78 | "@types/diff-match-patch": "^1.0.32", 79 | "@types/jshint": "^2.12.4", 80 | "@types/node": "^16.11.13", 81 | "@typescript-eslint/eslint-plugin": "7.13.0", 82 | "@typescript-eslint/parser": "7.13.0", 83 | "@vitejs/plugin-vue": "^5.0.4", 84 | "@vitejs/plugin-vue-jsx": "^3.1.0", 85 | "@vue/cli-plugin-typescript": "~4.5.15", 86 | "@vue/eslint-config-prettier": "9.0.0", 87 | "@vue/eslint-config-typescript": "13.0.0", 88 | "@vueuse/core": "^10.9.0", 89 | "chalk": "^4.1.2", 90 | "conventional-changelog-cli": "^2.0.31", 91 | "dedent": "^0.7.0", 92 | "diff-match-patch": "^1.0.5", 93 | "enquirer": "^2.3.6", 94 | "eslint": "8.57.0", 95 | "eslint-plugin-import": "^2.27.5", 96 | "eslint-plugin-prettier": "^5.1.3", 97 | "eslint-plugin-vue": "^9.9.0", 98 | "execa": "^7.0.0", 99 | "jshint": "^2.13.6", 100 | "less": "^4.1.3", 101 | "lint-staged": "^10.2.10", 102 | "minimist": "^1.2.6", 103 | "picocolors": "^1.0.0", 104 | "prettier": "3.2.5", 105 | "prompts": "^2.4.2", 106 | "semver": "^7.3.5", 107 | "tsx": "^3.12.3", 108 | "typescript": "^5.4.5", 109 | "unocss": "^0.58.8", 110 | "unplugin-auto-import": "^0.15.0", 111 | "vite": "^5.2.6", 112 | "vite-plugin-dts": "^3.9.1", 113 | "vite-plugin-pages": "^0.32.0", 114 | "vite-plugin-windicss": "^1.8.10", 115 | "vitepress": "^1.0.1", 116 | "vue": "^3.4.21", 117 | "vue-router": "^4.1.6", 118 | "vue-tsc": "^2.0.21", 119 | "windicss": "^3.5.6", 120 | "yorkie-pnpm": "^2.0.1" 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /packages/index.ts: -------------------------------------------------------------------------------- 1 | import type { App } from "vue"; 2 | import type { EditorConfiguration, Editor } from "codemirror"; 3 | import VueCodemirror from "./src/components/index.vue"; 4 | import "./src/style/index.css"; 5 | import _CodeMirror from "./src/sourceLib"; 6 | 7 | interface CmComp { 8 | cminstance: Editor; 9 | resize: (width?: string | number | null, height?: string | number | null) => void; 10 | refresh: () => void; 11 | destroy: () => void; 12 | } 13 | export type CmComponentRef = CmComp | null; 14 | declare interface InstallConfig { 15 | options: EditorConfiguration; 16 | componentName: string; 17 | } 18 | 19 | const install = (app: App, config?: InstallConfig) => { 20 | if (config) { 21 | if (config.options) { 22 | VueCodemirror.props.globalOptions.default = () => config.options; 23 | } 24 | } 25 | 26 | app.component(config?.componentName || "Codemirror", VueCodemirror); 27 | return app; 28 | }; 29 | 30 | const CodeMirror = window.CodeMirror || _CodeMirror; 31 | /** 32 | * Use global components. 33 | * @example 34 | * import { createApp } from "vue"; 35 | * const app = createApp(App); 36 | * app.use(InstallCodeMirror, { componentName: "customCodemirrorComponentName" }); 37 | */ 38 | const GlobalCmComponent = install; 39 | const InstallCodeMirror = install; 40 | 41 | export * from "./src/components/presetMode/log/utils"; 42 | 43 | export { CodeMirror, GlobalCmComponent, InstallCodeMirror, VueCodemirror }; 44 | export default VueCodemirror; 45 | -------------------------------------------------------------------------------- /packages/src/components/index.vue: -------------------------------------------------------------------------------- 1 | 30 | 31 | 244 | -------------------------------------------------------------------------------- /packages/src/components/presetMode/Merge/index.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /packages/src/components/presetMode/default/index.vue: -------------------------------------------------------------------------------- 1 |