@type32/codemirror-rich-obsidian-editor 0.1.5 → 0.1.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -1
- package/dist/module.json +1 -1
- package/dist/runtime/assets/css/editor.css +1 -1
- package/dist/runtime/components/CodeEditor.client.d.vue.ts +35 -0
- package/dist/runtime/components/CodeEditor.client.vue +207 -0
- package/dist/runtime/components/CodeEditor.client.vue.d.ts +35 -0
- package/dist/runtime/components/Editor/ImageEmbedComponent.vue +1 -0
- package/dist/runtime/components/Editor/TestCustomCodeBlock.vue +1 -0
- package/dist/runtime/components/Editor.client.d.vue.ts +2 -2
- package/dist/runtime/components/Editor.client.vue +2 -3
- package/dist/runtime/components/Editor.client.vue.d.ts +2 -2
- package/dist/runtime/editor/plugins/codemirror-plugin-proses/proseCalloutPlugin.js +34 -3
- package/dist/runtime/editor/plugins/codemirror-plugin-proses/proseCodeBlockCodemirrorViewPlugin.js +34 -4
- package/dist/runtime/editor/plugins/codemirror-plugin-proses/proseInternalLinkCodemirrorViewPlugin.js +38 -4
- package/dist/runtime/editor/plugins/codemirror-widgets/proseCalloutWidget.d.ts +0 -2
- package/dist/runtime/editor/plugins/codemirror-widgets/proseCalloutWidget.js +8 -11
- package/dist/runtime/editor/plugins/codemirror-widgets/proseVueComponentEmbedWidget.d.ts +4 -1
- package/dist/runtime/editor/plugins/codemirror-widgets/proseVueComponentEmbedWidget.js +27 -1
- package/package.json +3 -1
package/README.md
CHANGED
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
- https://github.com/mgmeyers/obsidian-indentation-guides, for indentation guides
|
|
10
10
|
- Markdown-It
|
|
11
11
|
- https://github.com/thecodrr/alfaaz, for insanely fast word/line-counting functions
|
|
12
|
+
- https://github.com/yuri2peter/codemirror-ai-enhancer, for providing the simple AI completion editing experience
|
|
12
13
|
|
|
13
14
|
### Related References & Resources
|
|
14
15
|
- https://github.com/heavycircle/remark-obsidian, for mostly wiki link alias & highlights & callouts parsing
|
|
@@ -18,7 +19,7 @@
|
|
|
18
19
|
- https://github.com/nothingislost/obsidian-cm6-attributes
|
|
19
20
|
|
|
20
21
|
## Disclaimer
|
|
21
|
-
I have used Gemini 2.5 Pro in the process of developing this editor numerous times, so do expect errors or inconsistencies in some parts of the code.
|
|
22
|
+
I have used Gemini 2.5 Pro + Gemini 3 Pro Preview + Claude Sonnet 4.5 in the process of developing this editor numerous times, so do expect errors or inconsistencies in some parts of the code.
|
|
22
23
|
|
|
23
24
|
## Introduction
|
|
24
25
|
Do I even need an intro?
|
package/dist/module.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
@import url("https://fonts.cdnfonts.com/css/segoe-ui-variable-static-display");@import url("https://fonts.cdnfonts.com/css/sf-pro-display");@import "katex/dist/katex.min.css";@import "tailwindcss";@import "@nuxt/ui";@theme{--font-sans:"Public Sans","Inter","SF Pro Display","Segoe UI Variable Static Display",sans-serif;--font-mono:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;--font-editor:"Inter","SF Pro Display","Segoe UI Variable Static Display",var(--font-sans,sans-serif);--font-editor-code:"Google Sans Code","JetBrains Mono","Consolas",var(--font-mono,ui-monospace);--list-indent:1.5rem;--indent-level:0}.cm-content{@apply font-editor}.cm-content .cm-escape,.cm-content .cm-meta{@apply text-dimmed! no-underline!}.cm-content .cm-heading{text-decoration:none!important}.cm-content .cm-mono{@apply font-editor-code bg-muted px-1 rounded-lg border border-default text-toned!}.cm-content .cm-hashtag{@apply bg-gradient-to-t from-primary/20! to-primary/10! ring ring-primary/50! px-1.5 text-sm rounded-4xl text-primary! inline-flex}.cm-content .cm-hashtag .cm-heading{@apply text-primary!}.cm-content .cm-highlighted{@apply bg-primary/20 text-primary px-0.5 rounded-sm}.cm-content .cm-internal-link-display,.cm-content .cm-internal-link-path,.cm-content .cm-internal-link-subpath,.cm-content .cm-link{@apply text-primary! underline}.cm-content .cm-internal-link-display[data-type=internal-link],.cm-content .cm-internal-link-path[data-type=internal-link],.cm-content .cm-internal-link-subpath[data-type=internal-link],.cm-content .cm-link[data-type=internal-link]{@apply cursor-pointer}.cm-content .cm-clickable-link{@apply cursor-pointer}.cm-content .cm-unresolved-link .cm-internal-link-display,.cm-content .cm-unresolved-link .cm-internal-link-path,.cm-content .cm-unresolved-link .cm-internal-link-subpath,.cm-content .cm-unresolved-link .cm-link{@apply text-error/75! cursor-not-allowed}.cm-content .cm-codeblock,.cm-content .cm-line-codeblock-begin,.cm-content .cm-line-codeblock-end{@apply font-editor-code py-0 my-0 text-sm! font-semibold border-x border-x-default mx-2 px-3 bg-muted relative}.cm-content .cm-codeblock .cm-codeblock-flair-container,.cm-content .cm-line-codeblock-begin .cm-codeblock-flair-container,.cm-content .cm-line-codeblock-end .cm-codeblock-flair-container{@apply absolute top-2 right-2 overflow-visible z-10}.cm-content .cm-codeblock .cm-codeblock-flair-container .cm-codeblock-copy-button,.cm-content .cm-line-codeblock-begin .cm-codeblock-flair-container .cm-codeblock-copy-button,.cm-content .cm-line-codeblock-end .cm-codeblock-flair-container .cm-codeblock-copy-button{@apply rounded hover:bg-accented transition duration-200 cursor-pointer py-1.5 px-2 font-sans text-dimmed z-10}.cm-content .cm-codeblock .cm-mono,.cm-content .cm-line-codeblock-begin .cm-mono,.cm-content .cm-line-codeblock-end .cm-mono{@apply border-none bg-none text-default}.cm-content .cm-line-codeblock-content{@apply border-x border-x-accented}.cm-content .cm-line-codeblock-begin{@apply rounded-t-lg border-t border-x border-t-accented border-x-accented pt-1 px-1}.cm-content .cm-line-codeblock-end{@apply rounded-b-lg border-b border-x border-b-accented border-x-accented pb-1 px-1}.cm-content .cm-task-checkbox-wrapper{@apply size-4 mb-0.5 rounded-xl border border-default bg-default inline-flex items-center justify-center align-middle cursor-pointer}.cm-content .cm-task-checkbox-wrapper[data-checked=true]{@apply bg-primary border border-primary}.cm-content .cm-task-checkbox-wrapper[data-checked=true]:before{content:"✔";@apply text-xs text-inverted}.cm-content .cm-task-checkbox-wrapper[data-special]{@apply font-editor-code text-xs text-highlighted}.cm-content .cm-task-checked{@apply line-through text-dimmed}.cm-content .cm-tooltip{@apply rounded-lg bg-default/70 shadow-lg backdrop-blur-sm border border-default font-sans p-2}.cm-content .cm-tooltip ul{@apply grid grid-cols-1 font-sans}.cm-content .cm-tooltip ul li{@apply grid grid-cols-1 rounded font-sans gap-1}.cm-content .cm-tooltip ul li .cm-completionLabel{@apply mx-1 mt-1 text-toned}.cm-content .cm-tooltip ul li .cm-completionDetail{@apply text-xs font-editor-code bg-elevated w-fit rounded text-muted px-1 mb-1}.cm-content .cm-tooltip ul li[aria-selected=true]{@apply bg-accented/70 backdrop-blur-sm border border-accented}.cm-content .cm-fold-widget{@apply absolute -left-0.5 pt-1}.cm-content .cm-gutter,.cm-content .cm-gutters{@apply bg-transparent! border-none}.cm-content .cm-foldPlaceholder{@apply bg-accented! text-dimmed! border border-none ml-0.5 h-fit inline-flex items-center justify-center align-middle}.cm-content .cm-gutterElement{@apply inline-flex justify-center items-center}.cm-content .cm-heading-1{@apply text-4xl! text-highlighted scroll-mt-[calc(45px+var(--ui-header-height))]}.cm-content .cm-heading-2{@apply text-2xl! text-highlighted scroll-mt-[calc(45px+var(--ui-header-height))]}.cm-content .cm-heading-3{@apply text-xl! text-highlighted scroll-mt-[calc(45px+var(--ui-header-height))]}.cm-content .cm-heading-4{@apply text-lg! text-highlighted scroll-mt-[calc(45px+var(--ui-header-height))]}.cm-content .cm-quoteblock,.cm-content blockquote{@apply bg-muted border-accented ps-2 mx-2 before:ml-0.5 before:rounded-lg before:px-0.5 before:bg-accented before:py-1}.cm-content .cm-quoteblock.cm-quoteblock-single,.cm-content blockquote.cm-quoteblock-single{@apply rounded-lg py-2 before:py-0.5}.cm-content .cm-quoteblock.cm-quoteblock-start,.cm-content blockquote.cm-quoteblock-start{@apply rounded-t-lg pt-2 before:pt-0}.cm-content .cm-quoteblock.cm-quoteblock-end,.cm-content blockquote.cm-quoteblock-end{@apply rounded-b-lg pb-2 before:pb-0}.cm-content .cm-quoteblock .cm-formatting-quote.cm-meta,.cm-content blockquote .cm-formatting-quote.cm-meta{@apply invisible}.cm-content .cm-quoteblock .cm-formatting-quote-active.cm-meta,.cm-content blockquote .cm-formatting-quote-active.cm-meta{@apply visible!}.cm-content .cm-obsidian-bullet{@apply text-transparent}.cm-content .cm-obsidian-bullet .cm-meta{@apply invisible}.cm-content .cm-obsidian-bullet:before{content:"•";@apply text-dimmed absolute}.cm-content .callout,.cm-content .cm-callout-widget{@apply p-3 relative flex flex-col h-fit mx-2 my-2 rounded-xl border border-primary/20 from-primary/10 to-primary/20 bg-gradient-to-b}.cm-content .callout summary,.cm-content .cm-callout-widget summary{@apply inline-flex}.cm-content .callout .callout-title,.cm-content .cm-callout-widget .callout-title{@apply flex gap-1.5 items-center}.cm-content .callout .callout-title .callout-title-icon,.cm-content .cm-callout-widget .callout-title .callout-title-icon{@apply flex size-4 items-center justify-center fill-primary text-primary}.cm-content .callout .callout-title .callout-title-inner,.cm-content .cm-callout-widget .callout-title .callout-title-inner{@apply text-primary text-lg font-bold flex-grow}.cm-content .callout .callout-title .edit-block-button,.cm-content .cm-callout-widget .callout-title .edit-block-button{@apply rounded hover:bg-elevated transition duration-200 cursor-pointer p-1 font-sans right-0 top-0 text-dimmed}.cm-content .callout .callout-content,.cm-content .cm-callout-widget .callout-content{@apply flex flex-col gap-1}.cm-content .callout[data-callout=info],.cm-content .cm-callout-widget[data-callout=info]{@apply from-info/10 to-info/20 bg-gradient-to-b border-info/20}.cm-content .callout[data-callout=info] .callout-fold,.cm-content .cm-callout-widget[data-callout=info] .callout-fold{@apply text-info-400}.cm-content .callout[data-callout=info] .callout-title .callout-title-icon,.cm-content .callout[data-callout=info] .callout-title .callout-title-inner,.cm-content .cm-callout-widget[data-callout=info] .callout-title .callout-title-icon,.cm-content .cm-callout-widget[data-callout=info] .callout-title .callout-title-inner{@apply text-info}.cm-content .callout[data-callout=check],.cm-content .callout[data-callout=done],.cm-content .callout[data-callout=success],.cm-content .cm-callout-widget[data-callout=check],.cm-content .cm-callout-widget[data-callout=done],.cm-content .cm-callout-widget[data-callout=success]{@apply from-success/10 to-success/20 bg-gradient-to-b border-success/20}.cm-content .callout[data-callout=check] .callout-fold,.cm-content .callout[data-callout=done] .callout-fold,.cm-content .callout[data-callout=success] .callout-fold,.cm-content .cm-callout-widget[data-callout=check] .callout-fold,.cm-content .cm-callout-widget[data-callout=done] .callout-fold,.cm-content .cm-callout-widget[data-callout=success] .callout-fold{@apply text-success-400}.cm-content .callout[data-callout=check] .callout-title .callout-title-icon,.cm-content .callout[data-callout=check] .callout-title .callout-title-inner,.cm-content .callout[data-callout=done] .callout-title .callout-title-icon,.cm-content .callout[data-callout=done] .callout-title .callout-title-inner,.cm-content .callout[data-callout=success] .callout-title .callout-title-icon,.cm-content .callout[data-callout=success] .callout-title .callout-title-inner,.cm-content .cm-callout-widget[data-callout=check] .callout-title .callout-title-icon,.cm-content .cm-callout-widget[data-callout=check] .callout-title .callout-title-inner,.cm-content .cm-callout-widget[data-callout=done] .callout-title .callout-title-icon,.cm-content .cm-callout-widget[data-callout=done] .callout-title .callout-title-inner,.cm-content .cm-callout-widget[data-callout=success] .callout-title .callout-title-icon,.cm-content .cm-callout-widget[data-callout=success] .callout-title .callout-title-inner{@apply text-success}.cm-content .callout[data-callout=faq],.cm-content .callout[data-callout=help],.cm-content .callout[data-callout=question],.cm-content .callout[data-callout=warning],.cm-content .cm-callout-widget[data-callout=faq],.cm-content .cm-callout-widget[data-callout=help],.cm-content .cm-callout-widget[data-callout=question],.cm-content .cm-callout-widget[data-callout=warning]{@apply from-warning/10 to-warning/20 bg-gradient-to-b border-warning/20}.cm-content .callout[data-callout=faq] .callout-fold,.cm-content .callout[data-callout=help] .callout-fold,.cm-content .callout[data-callout=question] .callout-fold,.cm-content .callout[data-callout=warning] .callout-fold,.cm-content .cm-callout-widget[data-callout=faq] .callout-fold,.cm-content .cm-callout-widget[data-callout=help] .callout-fold,.cm-content .cm-callout-widget[data-callout=question] .callout-fold,.cm-content .cm-callout-widget[data-callout=warning] .callout-fold{@apply text-warning-400}.cm-content .callout[data-callout=faq] .callout-title .callout-title-icon,.cm-content .callout[data-callout=faq] .callout-title .callout-title-inner,.cm-content .callout[data-callout=help] .callout-title .callout-title-icon,.cm-content .callout[data-callout=help] .callout-title .callout-title-inner,.cm-content .callout[data-callout=question] .callout-title .callout-title-icon,.cm-content .callout[data-callout=question] .callout-title .callout-title-inner,.cm-content .callout[data-callout=warning] .callout-title .callout-title-icon,.cm-content .callout[data-callout=warning] .callout-title .callout-title-inner,.cm-content .cm-callout-widget[data-callout=faq] .callout-title .callout-title-icon,.cm-content .cm-callout-widget[data-callout=faq] .callout-title .callout-title-inner,.cm-content .cm-callout-widget[data-callout=help] .callout-title .callout-title-icon,.cm-content .cm-callout-widget[data-callout=help] .callout-title .callout-title-inner,.cm-content .cm-callout-widget[data-callout=question] .callout-title .callout-title-icon,.cm-content .cm-callout-widget[data-callout=question] .callout-title .callout-title-inner,.cm-content .cm-callout-widget[data-callout=warning] .callout-title .callout-title-icon,.cm-content .cm-callout-widget[data-callout=warning] .callout-title .callout-title-inner{@apply text-warning}.cm-content .callout[data-callout=bug],.cm-content .callout[data-callout=error],.cm-content .callout[data-callout=failure],.cm-content .cm-callout-widget[data-callout=bug],.cm-content .cm-callout-widget[data-callout=error],.cm-content .cm-callout-widget[data-callout=failure]{@apply from-error/10 to-error/20 bg-gradient-to-b border-error/20}.cm-content .callout[data-callout=bug] .callout-fold,.cm-content .callout[data-callout=error] .callout-fold,.cm-content .callout[data-callout=failure] .callout-fold,.cm-content .cm-callout-widget[data-callout=bug] .callout-fold,.cm-content .cm-callout-widget[data-callout=error] .callout-fold,.cm-content .cm-callout-widget[data-callout=failure] .callout-fold{@apply text-error-400}.cm-content .callout[data-callout=bug] .callout-title .callout-title-icon,.cm-content .callout[data-callout=bug] .callout-title .callout-title-inner,.cm-content .callout[data-callout=error] .callout-title .callout-title-icon,.cm-content .callout[data-callout=error] .callout-title .callout-title-inner,.cm-content .callout[data-callout=failure] .callout-title .callout-title-icon,.cm-content .callout[data-callout=failure] .callout-title .callout-title-inner,.cm-content .cm-callout-widget[data-callout=bug] .callout-title .callout-title-icon,.cm-content .cm-callout-widget[data-callout=bug] .callout-title .callout-title-inner,.cm-content .cm-callout-widget[data-callout=error] .callout-title .callout-title-icon,.cm-content .cm-callout-widget[data-callout=error] .callout-title .callout-title-inner,.cm-content .cm-callout-widget[data-callout=failure] .callout-title .callout-title-icon,.cm-content .cm-callout-widget[data-callout=failure] .callout-title .callout-title-inner{@apply text-error}.cm-content .callout[data-callout=example],.cm-content .callout[data-callout=highlight],.cm-content .callout[data-callout=tip],.cm-content .cm-callout-widget[data-callout=example],.cm-content .cm-callout-widget[data-callout=highlight],.cm-content .cm-callout-widget[data-callout=tip]{@apply from-secondary/10 to-secondary/20 bg-gradient-to-b border-secondary/20}.cm-content .callout[data-callout=example] .callout-fold,.cm-content .callout[data-callout=highlight] .callout-fold,.cm-content .callout[data-callout=tip] .callout-fold,.cm-content .cm-callout-widget[data-callout=example] .callout-fold,.cm-content .cm-callout-widget[data-callout=highlight] .callout-fold,.cm-content .cm-callout-widget[data-callout=tip] .callout-fold{@apply text-secondary}.cm-content .callout[data-callout=example] .callout-title .callout-title-icon,.cm-content .callout[data-callout=example] .callout-title .callout-title-inner,.cm-content .callout[data-callout=highlight] .callout-title .callout-title-icon,.cm-content .callout[data-callout=highlight] .callout-title .callout-title-inner,.cm-content .callout[data-callout=tip] .callout-title .callout-title-icon,.cm-content .callout[data-callout=tip] .callout-title .callout-title-inner,.cm-content .cm-callout-widget[data-callout=example] .callout-title .callout-title-icon,.cm-content .cm-callout-widget[data-callout=example] .callout-title .callout-title-inner,.cm-content .cm-callout-widget[data-callout=highlight] .callout-title .callout-title-icon,.cm-content .cm-callout-widget[data-callout=highlight] .callout-title .callout-title-inner,.cm-content .cm-callout-widget[data-callout=tip] .callout-title .callout-title-icon,.cm-content .cm-callout-widget[data-callout=tip] .callout-title .callout-title-inner{@apply text-secondary}.cm-content .callout[data-callout=neutral],.cm-content .callout[data-callout=quote],.cm-content .cm-callout-widget[data-callout=neutral],.cm-content .cm-callout-widget[data-callout=quote]{@apply from-accented/20 to-accented/30 bg-gradient-to-b border-accented/30}.cm-content .callout[data-callout=neutral] .callout-fold,.cm-content .callout[data-callout=quote] .callout-fold,.cm-content .cm-callout-widget[data-callout=neutral] .callout-fold,.cm-content .cm-callout-widget[data-callout=quote] .callout-fold{@apply text-highlighted}.cm-content .callout[data-callout=neutral] .callout-title .callout-title-icon,.cm-content .callout[data-callout=neutral] .callout-title .callout-title-inner,.cm-content .callout[data-callout=quote] .callout-title .callout-title-icon,.cm-content .callout[data-callout=quote] .callout-title .callout-title-inner,.cm-content .cm-callout-widget[data-callout=neutral] .callout-title .callout-title-icon,.cm-content .cm-callout-widget[data-callout=neutral] .callout-title .callout-title-inner,.cm-content .cm-callout-widget[data-callout=quote] .callout-title .callout-title-icon,.cm-content .cm-callout-widget[data-callout=quote] .callout-title .callout-title-inner{@apply text-highlighted}.cm-content .callout .callout-fold,.cm-content .cm-callout-widget .callout-fold{@apply rounded hover:bg-elevated transition duration-200 cursor-pointer text-primary font-sans text-center align-middle p-1 size-6}.cm-content .callout .callout-fold svg,.cm-content .cm-callout-widget .callout-fold svg{@apply transition-transform duration-300 ease-in-out w-full h-full}.cm-content .callout[open] .callout-fold svg,.cm-content .cm-callout-widget[open] .callout-fold svg{@apply transition-transform duration-300 ease-in-out rotate-90 w-full h-full}.cm-content .callout[data-fold-state=closed] .callout-content,.cm-content .cm-callout-widget[data-fold-state=closed] .callout-content{@apply max-h-0 opacity-0 p-0}.cm-content .callout[data-fold-state=open] .callout-content,.cm-content .cm-callout-widget[data-fold-state=open] .callout-content{@apply max-h-none opacity-100 py-1 mt-1}.cm-content .callout .edit-block-button,.cm-content .cm-callout-widget .edit-block-button{@apply rounded hover:bg-elevated transition duration-200 cursor-pointer p-1 font-sans text-dimmed}.cm-content .callout .editing-utils-container,.cm-content .cm-callout-widget .editing-utils-container{@apply top-2 right-2 font-sans text-dimmed absolute flex items-center justify-center gap-1 p-1}.cm-content details .callout-content{@apply -mt-11}.cm-content .cm-indent{min-width:var(--list-indent,1.5rem);@apply relative inline-block}.cm-content .cm-indent:before{@apply content-["\200B"] absolute top-0 bottom-0 w-1;@apply border-r border-r-muted;@apply left-[var(--indentation-guide-source-indent)]}.cm-content .cm-indent-group .cm-active-indent:before{@apply border-primary}.cm-content .cm-list-line .cm-indent:before{@apply top-0}.cm-content .cm-list-internal[style*="--indent-level"]{@apply border-primary;padding-inline-start:calc(var(--indent-level)*var(--list-indent));text-indent:calc(var(--indent-level)*var(--list-indent))}.cm-content .cm-indent-list-bullet:before{content:"•";@apply text-dimmed border-none absolute;left:1rem}.cm-content .cm-indent-list-bullet+.cm-obsidian-bullet{@apply hidden}.cm-content .cm-obsidian-hidden{@apply hidden}.cm-content .cm-hidden-latex{@apply hidden}.cm-content .cm-yaml-content,.cm-content .cm-yaml-marker{@apply font-editor-code text-muted px-1}.cm-content .cm-line.hr{@apply h-8 flex items-center}.cm-content .cm-line.hr:after{content:"";@apply block w-full h-px bg-accented}
|
|
1
|
+
@import url("https://fonts.cdnfonts.com/css/segoe-ui-variable-static-display");@import url("https://fonts.cdnfonts.com/css/sf-pro-display");@import "katex/dist/katex.min.css";@import "tailwindcss";@import "@nuxt/ui";@theme{--font-sans:"Public Sans","Inter","SF Pro Display","Segoe UI Variable Static Display",sans-serif;--font-mono:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;--font-editor:"Inter","SF Pro Display","Segoe UI Variable Static Display",var(--font-sans,sans-serif);--font-editor-code:"Google Sans Code","JetBrains Mono","Consolas",var(--font-mono,ui-monospace);--list-indent:1.5rem;--indent-level:0}.cm-code-editor{@apply font-editor-code}.cm-code-editor .cm-content,.cm-code-editor .cm-placeholder{@apply font-editor-code text-sm}.cm-code-editor .cm-editor{@apply bg-default}.cm-code-editor .cm-placeholder{@apply text-dimmed}.cm-code-editor .cm-gutters,.cm-code-editor .cm-gutters-before{@apply bg-default text-muted text-sm border-r border-r-accented font-editor-code}.cm-code-editor .cm-activeLineGutter{@apply bg-elevated}.cm-code-editor .cm-activeLine{@apply bg-muted}.cm-code-editor .cm-foldPlaceholder{@apply bg-elevated border border-default font-editor-code text-muted}.cm-rich-editor{@apply font-editor}.cm-rich-editor .cm-activeLine{@apply after:absolute after:left-0 after:border-primary after:border after:rounded-lg after:h-full after:top-0 -z-10 bg-inherit}.cm-rich-editor .cm-content{@apply font-editor}.cm-rich-editor .katex-display{@apply m-0 pointer-events-none}.cm-rich-editor .katex-display .katex,.cm-rich-editor .katex-display .katex-html{@apply pointer-events-none}.cm-rich-editor .cm-escape,.cm-rich-editor .cm-meta{@apply text-dimmed! no-underline!}.cm-rich-editor .cm-heading{text-decoration:none!important}.cm-rich-editor .cm-mono{@apply font-editor-code bg-muted px-1 rounded-lg border border-default text-toned!}.cm-rich-editor .cm-hashtag{@apply bg-gradient-to-t from-primary/20! to-primary/10! ring ring-primary/50! px-1.5 text-sm rounded-4xl text-primary! inline-flex}.cm-rich-editor .cm-hashtag .cm-heading{@apply text-primary!}.cm-rich-editor .cm-highlighted{@apply bg-primary/20 text-primary px-0.5 rounded-sm}.cm-rich-editor .cm-internal-link-display,.cm-rich-editor .cm-internal-link-path,.cm-rich-editor .cm-internal-link-subpath,.cm-rich-editor .cm-link{@apply text-primary! underline}.cm-rich-editor .cm-internal-link-display[data-type=internal-link],.cm-rich-editor .cm-internal-link-path[data-type=internal-link],.cm-rich-editor .cm-internal-link-subpath[data-type=internal-link],.cm-rich-editor .cm-link[data-type=internal-link]{@apply cursor-pointer}.cm-rich-editor .cm-clickable-link{@apply cursor-pointer}.cm-rich-editor .cm-unresolved-link .cm-internal-link-display,.cm-rich-editor .cm-unresolved-link .cm-internal-link-path,.cm-rich-editor .cm-unresolved-link .cm-internal-link-subpath,.cm-rich-editor .cm-unresolved-link .cm-link{@apply text-error/75! cursor-not-allowed}.cm-rich-editor .cm-codeblock,.cm-rich-editor .cm-line-codeblock-begin,.cm-rich-editor .cm-line-codeblock-end{@apply font-editor-code py-0 my-0 text-sm! font-semibold border-x border-x-default mx-2 px-3 bg-muted relative}.cm-rich-editor .cm-codeblock .cm-codeblock-flair-container,.cm-rich-editor .cm-line-codeblock-begin .cm-codeblock-flair-container,.cm-rich-editor .cm-line-codeblock-end .cm-codeblock-flair-container{@apply absolute top-2 right-2 overflow-visible z-10}.cm-rich-editor .cm-codeblock .cm-codeblock-flair-container .cm-codeblock-copy-button,.cm-rich-editor .cm-line-codeblock-begin .cm-codeblock-flair-container .cm-codeblock-copy-button,.cm-rich-editor .cm-line-codeblock-end .cm-codeblock-flair-container .cm-codeblock-copy-button{@apply rounded hover:bg-accented transition duration-200 cursor-pointer py-1.5 px-2 font-sans text-dimmed z-10}.cm-rich-editor .cm-codeblock .cm-mono,.cm-rich-editor .cm-line-codeblock-begin .cm-mono,.cm-rich-editor .cm-line-codeblock-end .cm-mono{@apply border-none bg-none text-default}.cm-rich-editor .cm-line-codeblock-content{@apply border-x border-x-accented}.cm-rich-editor .cm-line-codeblock-begin{@apply rounded-t-lg border-t border-x border-t-accented border-x-accented pt-1 px-1}.cm-rich-editor .cm-line-codeblock-end{@apply rounded-b-lg border-b border-x border-b-accented border-x-accented pb-1 px-1}.cm-rich-editor .cm-task-checkbox-wrapper{@apply size-4 mb-0.5 rounded-xl border border-default bg-default inline-flex items-center justify-center align-middle cursor-pointer}.cm-rich-editor .cm-task-checkbox-wrapper[data-checked=true]{@apply bg-primary border border-primary}.cm-rich-editor .cm-task-checkbox-wrapper[data-checked=true]:before{content:"✔";@apply text-xs text-inverted}.cm-rich-editor .cm-task-checkbox-wrapper[data-special]{@apply font-editor-code text-xs text-highlighted}.cm-rich-editor .cm-task-checked{@apply line-through text-dimmed}.cm-rich-editor .cm-tooltip{@apply rounded-lg bg-default/70 shadow-lg backdrop-blur-sm border border-default font-sans p-2}.cm-rich-editor .cm-tooltip ul{@apply grid grid-cols-1 font-sans}.cm-rich-editor .cm-tooltip ul li{@apply grid grid-cols-1 rounded font-sans gap-1}.cm-rich-editor .cm-tooltip ul li .cm-completionLabel{@apply mx-1 mt-1 text-toned}.cm-rich-editor .cm-tooltip ul li .cm-completionDetail{@apply text-xs font-editor-code bg-elevated w-fit rounded text-muted px-1 mb-1}.cm-rich-editor .cm-tooltip ul li[aria-selected=true]{@apply bg-accented/70 backdrop-blur-sm border border-accented}.cm-rich-editor .cm-fold-widget{@apply absolute -left-0.5 pt-1}.cm-rich-editor .cm-gutter,.cm-rich-editor .cm-gutters{@apply bg-transparent! border-none}.cm-rich-editor .cm-foldPlaceholder{@apply bg-accented! text-dimmed! border border-none ml-0.5 h-fit inline-flex items-center justify-center align-middle}.cm-rich-editor .cm-gutterElement{@apply inline-flex justify-center items-center}.cm-rich-editor .cm-heading-1{@apply text-4xl! text-highlighted scroll-mt-[calc(45px+var(--ui-header-height))]}.cm-rich-editor .cm-heading-2{@apply text-2xl! text-highlighted scroll-mt-[calc(45px+var(--ui-header-height))]}.cm-rich-editor .cm-heading-3{@apply text-xl! text-highlighted scroll-mt-[calc(45px+var(--ui-header-height))]}.cm-rich-editor .cm-heading-4{@apply text-lg! text-highlighted scroll-mt-[calc(45px+var(--ui-header-height))]}.cm-rich-editor .cm-quoteblock,.cm-rich-editor blockquote{@apply bg-muted border-accented ps-2 mx-2 before:ml-0.5 before:rounded-lg before:px-0.5 before:bg-accented before:py-1}.cm-rich-editor .cm-quoteblock.cm-quoteblock-single,.cm-rich-editor blockquote.cm-quoteblock-single{@apply rounded-lg py-2 before:py-0.5}.cm-rich-editor .cm-quoteblock.cm-quoteblock-start,.cm-rich-editor blockquote.cm-quoteblock-start{@apply rounded-t-lg pt-2 before:pt-0}.cm-rich-editor .cm-quoteblock.cm-quoteblock-end,.cm-rich-editor blockquote.cm-quoteblock-end{@apply rounded-b-lg pb-2 before:pb-0}.cm-rich-editor .cm-quoteblock .cm-formatting-quote.cm-meta,.cm-rich-editor blockquote .cm-formatting-quote.cm-meta{@apply invisible}.cm-rich-editor .cm-quoteblock .cm-formatting-quote-active.cm-meta,.cm-rich-editor blockquote .cm-formatting-quote-active.cm-meta{@apply visible!}.cm-rich-editor .cm-obsidian-bullet{@apply text-transparent}.cm-rich-editor .cm-obsidian-bullet .cm-meta{@apply invisible}.cm-rich-editor .cm-obsidian-bullet:before{content:"•";@apply text-dimmed absolute}.cm-rich-editor .callout,.cm-rich-editor .cm-callout-widget{@apply p-3 relative flex flex-col h-fit rounded-xl border border-primary/20 from-primary/10 to-primary/20 bg-gradient-to-b}.cm-rich-editor .callout summary,.cm-rich-editor .cm-callout-widget summary{@apply inline-flex}.cm-rich-editor .callout .callout-title,.cm-rich-editor .cm-callout-widget .callout-title{@apply flex gap-1.5 items-center}.cm-rich-editor .callout .callout-title .callout-title-icon,.cm-rich-editor .cm-callout-widget .callout-title .callout-title-icon{@apply flex size-4 items-center justify-center fill-primary text-primary}.cm-rich-editor .callout .callout-title .callout-title-inner,.cm-rich-editor .cm-callout-widget .callout-title .callout-title-inner{@apply text-primary text-lg font-bold flex-grow}.cm-rich-editor .callout .callout-title .edit-block-button,.cm-rich-editor .cm-callout-widget .callout-title .edit-block-button{@apply rounded hover:bg-elevated transition duration-200 cursor-pointer p-1 font-sans right-0 top-0 text-dimmed}.cm-rich-editor .callout .callout-content,.cm-rich-editor .cm-callout-widget .callout-content{@apply flex flex-col gap-1}.cm-rich-editor .callout[data-callout=info],.cm-rich-editor .cm-callout-widget[data-callout=info]{@apply from-info/10 to-info/20 bg-gradient-to-b border-info/20}.cm-rich-editor .callout[data-callout=info] .callout-fold,.cm-rich-editor .cm-callout-widget[data-callout=info] .callout-fold{@apply text-info-400}.cm-rich-editor .callout[data-callout=info] .callout-title .callout-title-icon,.cm-rich-editor .callout[data-callout=info] .callout-title .callout-title-inner,.cm-rich-editor .cm-callout-widget[data-callout=info] .callout-title .callout-title-icon,.cm-rich-editor .cm-callout-widget[data-callout=info] .callout-title .callout-title-inner{@apply text-info}.cm-rich-editor .callout[data-callout=check],.cm-rich-editor .callout[data-callout=done],.cm-rich-editor .callout[data-callout=success],.cm-rich-editor .cm-callout-widget[data-callout=check],.cm-rich-editor .cm-callout-widget[data-callout=done],.cm-rich-editor .cm-callout-widget[data-callout=success]{@apply from-success/10 to-success/20 bg-gradient-to-b border-success/20}.cm-rich-editor .callout[data-callout=check] .callout-fold,.cm-rich-editor .callout[data-callout=done] .callout-fold,.cm-rich-editor .callout[data-callout=success] .callout-fold,.cm-rich-editor .cm-callout-widget[data-callout=check] .callout-fold,.cm-rich-editor .cm-callout-widget[data-callout=done] .callout-fold,.cm-rich-editor .cm-callout-widget[data-callout=success] .callout-fold{@apply text-success-400}.cm-rich-editor .callout[data-callout=check] .callout-title .callout-title-icon,.cm-rich-editor .callout[data-callout=check] .callout-title .callout-title-inner,.cm-rich-editor .callout[data-callout=done] .callout-title .callout-title-icon,.cm-rich-editor .callout[data-callout=done] .callout-title .callout-title-inner,.cm-rich-editor .callout[data-callout=success] .callout-title .callout-title-icon,.cm-rich-editor .callout[data-callout=success] .callout-title .callout-title-inner,.cm-rich-editor .cm-callout-widget[data-callout=check] .callout-title .callout-title-icon,.cm-rich-editor .cm-callout-widget[data-callout=check] .callout-title .callout-title-inner,.cm-rich-editor .cm-callout-widget[data-callout=done] .callout-title .callout-title-icon,.cm-rich-editor .cm-callout-widget[data-callout=done] .callout-title .callout-title-inner,.cm-rich-editor .cm-callout-widget[data-callout=success] .callout-title .callout-title-icon,.cm-rich-editor .cm-callout-widget[data-callout=success] .callout-title .callout-title-inner{@apply text-success}.cm-rich-editor .callout[data-callout=faq],.cm-rich-editor .callout[data-callout=help],.cm-rich-editor .callout[data-callout=question],.cm-rich-editor .callout[data-callout=warning],.cm-rich-editor .cm-callout-widget[data-callout=faq],.cm-rich-editor .cm-callout-widget[data-callout=help],.cm-rich-editor .cm-callout-widget[data-callout=question],.cm-rich-editor .cm-callout-widget[data-callout=warning]{@apply from-warning/10 to-warning/20 bg-gradient-to-b border-warning/20}.cm-rich-editor .callout[data-callout=faq] .callout-fold,.cm-rich-editor .callout[data-callout=help] .callout-fold,.cm-rich-editor .callout[data-callout=question] .callout-fold,.cm-rich-editor .callout[data-callout=warning] .callout-fold,.cm-rich-editor .cm-callout-widget[data-callout=faq] .callout-fold,.cm-rich-editor .cm-callout-widget[data-callout=help] .callout-fold,.cm-rich-editor .cm-callout-widget[data-callout=question] .callout-fold,.cm-rich-editor .cm-callout-widget[data-callout=warning] .callout-fold{@apply text-warning-400}.cm-rich-editor .callout[data-callout=faq] .callout-title .callout-title-icon,.cm-rich-editor .callout[data-callout=faq] .callout-title .callout-title-inner,.cm-rich-editor .callout[data-callout=help] .callout-title .callout-title-icon,.cm-rich-editor .callout[data-callout=help] .callout-title .callout-title-inner,.cm-rich-editor .callout[data-callout=question] .callout-title .callout-title-icon,.cm-rich-editor .callout[data-callout=question] .callout-title .callout-title-inner,.cm-rich-editor .callout[data-callout=warning] .callout-title .callout-title-icon,.cm-rich-editor .callout[data-callout=warning] .callout-title .callout-title-inner,.cm-rich-editor .cm-callout-widget[data-callout=faq] .callout-title .callout-title-icon,.cm-rich-editor .cm-callout-widget[data-callout=faq] .callout-title .callout-title-inner,.cm-rich-editor .cm-callout-widget[data-callout=help] .callout-title .callout-title-icon,.cm-rich-editor .cm-callout-widget[data-callout=help] .callout-title .callout-title-inner,.cm-rich-editor .cm-callout-widget[data-callout=question] .callout-title .callout-title-icon,.cm-rich-editor .cm-callout-widget[data-callout=question] .callout-title .callout-title-inner,.cm-rich-editor .cm-callout-widget[data-callout=warning] .callout-title .callout-title-icon,.cm-rich-editor .cm-callout-widget[data-callout=warning] .callout-title .callout-title-inner{@apply text-warning}.cm-rich-editor .callout[data-callout=bug],.cm-rich-editor .callout[data-callout=error],.cm-rich-editor .callout[data-callout=failure],.cm-rich-editor .cm-callout-widget[data-callout=bug],.cm-rich-editor .cm-callout-widget[data-callout=error],.cm-rich-editor .cm-callout-widget[data-callout=failure]{@apply from-error/10 to-error/20 bg-gradient-to-b border-error/20}.cm-rich-editor .callout[data-callout=bug] .callout-fold,.cm-rich-editor .callout[data-callout=error] .callout-fold,.cm-rich-editor .callout[data-callout=failure] .callout-fold,.cm-rich-editor .cm-callout-widget[data-callout=bug] .callout-fold,.cm-rich-editor .cm-callout-widget[data-callout=error] .callout-fold,.cm-rich-editor .cm-callout-widget[data-callout=failure] .callout-fold{@apply text-error-400}.cm-rich-editor .callout[data-callout=bug] .callout-title .callout-title-icon,.cm-rich-editor .callout[data-callout=bug] .callout-title .callout-title-inner,.cm-rich-editor .callout[data-callout=error] .callout-title .callout-title-icon,.cm-rich-editor .callout[data-callout=error] .callout-title .callout-title-inner,.cm-rich-editor .callout[data-callout=failure] .callout-title .callout-title-icon,.cm-rich-editor .callout[data-callout=failure] .callout-title .callout-title-inner,.cm-rich-editor .cm-callout-widget[data-callout=bug] .callout-title .callout-title-icon,.cm-rich-editor .cm-callout-widget[data-callout=bug] .callout-title .callout-title-inner,.cm-rich-editor .cm-callout-widget[data-callout=error] .callout-title .callout-title-icon,.cm-rich-editor .cm-callout-widget[data-callout=error] .callout-title .callout-title-inner,.cm-rich-editor .cm-callout-widget[data-callout=failure] .callout-title .callout-title-icon,.cm-rich-editor .cm-callout-widget[data-callout=failure] .callout-title .callout-title-inner{@apply text-error}.cm-rich-editor .callout[data-callout=example],.cm-rich-editor .callout[data-callout=highlight],.cm-rich-editor .callout[data-callout=tip],.cm-rich-editor .cm-callout-widget[data-callout=example],.cm-rich-editor .cm-callout-widget[data-callout=highlight],.cm-rich-editor .cm-callout-widget[data-callout=tip]{@apply from-secondary/10 to-secondary/20 bg-gradient-to-b border-secondary/20}.cm-rich-editor .callout[data-callout=example] .callout-fold,.cm-rich-editor .callout[data-callout=highlight] .callout-fold,.cm-rich-editor .callout[data-callout=tip] .callout-fold,.cm-rich-editor .cm-callout-widget[data-callout=example] .callout-fold,.cm-rich-editor .cm-callout-widget[data-callout=highlight] .callout-fold,.cm-rich-editor .cm-callout-widget[data-callout=tip] .callout-fold{@apply text-secondary}.cm-rich-editor .callout[data-callout=example] .callout-title .callout-title-icon,.cm-rich-editor .callout[data-callout=example] .callout-title .callout-title-inner,.cm-rich-editor .callout[data-callout=highlight] .callout-title .callout-title-icon,.cm-rich-editor .callout[data-callout=highlight] .callout-title .callout-title-inner,.cm-rich-editor .callout[data-callout=tip] .callout-title .callout-title-icon,.cm-rich-editor .callout[data-callout=tip] .callout-title .callout-title-inner,.cm-rich-editor .cm-callout-widget[data-callout=example] .callout-title .callout-title-icon,.cm-rich-editor .cm-callout-widget[data-callout=example] .callout-title .callout-title-inner,.cm-rich-editor .cm-callout-widget[data-callout=highlight] .callout-title .callout-title-icon,.cm-rich-editor .cm-callout-widget[data-callout=highlight] .callout-title .callout-title-inner,.cm-rich-editor .cm-callout-widget[data-callout=tip] .callout-title .callout-title-icon,.cm-rich-editor .cm-callout-widget[data-callout=tip] .callout-title .callout-title-inner{@apply text-secondary}.cm-rich-editor .callout[data-callout=neutral],.cm-rich-editor .callout[data-callout=quote],.cm-rich-editor .cm-callout-widget[data-callout=neutral],.cm-rich-editor .cm-callout-widget[data-callout=quote]{@apply from-accented/20 to-accented/30 bg-gradient-to-b border-accented/30}.cm-rich-editor .callout[data-callout=neutral] .callout-fold,.cm-rich-editor .callout[data-callout=quote] .callout-fold,.cm-rich-editor .cm-callout-widget[data-callout=neutral] .callout-fold,.cm-rich-editor .cm-callout-widget[data-callout=quote] .callout-fold{@apply text-highlighted}.cm-rich-editor .callout[data-callout=neutral] .callout-title .callout-title-icon,.cm-rich-editor .callout[data-callout=neutral] .callout-title .callout-title-inner,.cm-rich-editor .callout[data-callout=quote] .callout-title .callout-title-icon,.cm-rich-editor .callout[data-callout=quote] .callout-title .callout-title-inner,.cm-rich-editor .cm-callout-widget[data-callout=neutral] .callout-title .callout-title-icon,.cm-rich-editor .cm-callout-widget[data-callout=neutral] .callout-title .callout-title-inner,.cm-rich-editor .cm-callout-widget[data-callout=quote] .callout-title .callout-title-icon,.cm-rich-editor .cm-callout-widget[data-callout=quote] .callout-title .callout-title-inner{@apply text-highlighted}.cm-rich-editor .callout .callout-fold,.cm-rich-editor .cm-callout-widget .callout-fold{@apply rounded hover:bg-elevated transition duration-200 cursor-pointer text-primary font-sans text-center align-middle p-1 size-6}.cm-rich-editor .callout .callout-fold svg,.cm-rich-editor .cm-callout-widget .callout-fold svg{@apply transition-transform duration-300 ease-in-out w-full h-full}.cm-rich-editor .callout[open] .callout-fold svg,.cm-rich-editor .cm-callout-widget[open] .callout-fold svg{@apply transition-transform duration-300 ease-in-out rotate-90 w-full h-full}.cm-rich-editor .callout[data-fold-state=closed] .callout-content,.cm-rich-editor .cm-callout-widget[data-fold-state=closed] .callout-content{@apply max-h-0 opacity-0 p-0}.cm-rich-editor .callout[data-fold-state=open] .callout-content,.cm-rich-editor .cm-callout-widget[data-fold-state=open] .callout-content{@apply max-h-none opacity-100 py-1 mt-1}.cm-rich-editor .callout .edit-block-button,.cm-rich-editor .cm-callout-widget .edit-block-button{@apply rounded hover:bg-elevated transition duration-200 cursor-pointer p-1 font-sans text-dimmed}.cm-rich-editor .callout .editing-utils-container,.cm-rich-editor .cm-callout-widget .editing-utils-container{@apply top-2 right-2 font-sans text-dimmed absolute flex items-center justify-center gap-1 p-1}.cm-rich-editor details .callout-content{@apply -mt-11}.cm-rich-editor .cm-indent{min-width:var(--list-indent,1.5rem);@apply relative inline-block}.cm-rich-editor .cm-indent:before{@apply content-["\200B"] absolute top-0 bottom-0 w-1;@apply border-r border-r-muted;@apply left-[var(--indentation-guide-source-indent)]}.cm-rich-editor .cm-indent-group .cm-active-indent:before{@apply border-primary}.cm-rich-editor .cm-list-line .cm-indent:before{@apply top-0}.cm-rich-editor .cm-list-internal[style*="--indent-level"]{@apply border-primary;padding-inline-start:calc(var(--indent-level)*var(--list-indent));text-indent:calc(var(--indent-level)*var(--list-indent))}.cm-rich-editor .cm-indent-list-bullet:before{content:"•";@apply text-dimmed border-none absolute;left:1rem}.cm-rich-editor .cm-indent-list-bullet+.cm-obsidian-bullet{@apply hidden}.cm-rich-editor .cm-obsidian-hidden{@apply hidden}.cm-rich-editor .cm-hidden-latex{@apply hidden}.cm-rich-editor .cm-yaml-content,.cm-rich-editor .cm-yaml-marker{@apply font-editor-code text-muted px-1}.cm-rich-editor .cm-line.hr{@apply h-8 flex items-center}.cm-rich-editor .cm-line.hr:after{content:"";@apply block w-full h-px bg-accented}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { EditorView } from '@codemirror/view';
|
|
2
|
+
import type { Extension } from '@codemirror/state';
|
|
3
|
+
import type { SearchOptions } from '#codemirror-rich-obsidian-editor/editor-types';
|
|
4
|
+
type __VLS_Props = {
|
|
5
|
+
class?: string;
|
|
6
|
+
language?: string;
|
|
7
|
+
bracketClosing?: boolean;
|
|
8
|
+
foldGutter?: boolean;
|
|
9
|
+
disabled?: boolean;
|
|
10
|
+
debug?: boolean;
|
|
11
|
+
searchOptions?: SearchOptions;
|
|
12
|
+
/**
|
|
13
|
+
* Custom theme for light mode. Defaults to Catppuccin Latte.
|
|
14
|
+
* Pass a CodeMirror Extension (e.g., from @codemirror/theme-one-dark)
|
|
15
|
+
*/
|
|
16
|
+
lightTheme?: Extension;
|
|
17
|
+
/**
|
|
18
|
+
* Custom theme for dark mode. Defaults to Catppuccin Mocha.
|
|
19
|
+
* Pass a CodeMirror Extension (e.g., from @codemirror/theme-one-dark)
|
|
20
|
+
*/
|
|
21
|
+
darkTheme?: Extension;
|
|
22
|
+
};
|
|
23
|
+
type __VLS_ModelProps = {
|
|
24
|
+
modelValue?: string;
|
|
25
|
+
};
|
|
26
|
+
type __VLS_PublicProps = __VLS_Props & __VLS_ModelProps;
|
|
27
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {
|
|
28
|
+
view: import("vue").ShallowRef<EditorView | undefined, EditorView | undefined>;
|
|
29
|
+
}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
30
|
+
"update:modelValue": (value: string | undefined) => any;
|
|
31
|
+
}, string, import("vue").PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
|
|
32
|
+
"onUpdate:modelValue"?: ((value: string | undefined) => any) | undefined;
|
|
33
|
+
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
34
|
+
declare const _default: typeof __VLS_export;
|
|
35
|
+
export default _default;
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
import CodeMirror from "vue-codemirror6";
|
|
3
|
+
import {
|
|
4
|
+
EditorView,
|
|
5
|
+
drawSelection,
|
|
6
|
+
rectangularSelection,
|
|
7
|
+
highlightActiveLine,
|
|
8
|
+
highlightActiveLineGutter,
|
|
9
|
+
lineNumbers,
|
|
10
|
+
highlightSpecialChars,
|
|
11
|
+
dropCursor,
|
|
12
|
+
crosshairCursor,
|
|
13
|
+
keymap
|
|
14
|
+
} from "@codemirror/view";
|
|
15
|
+
import { history, historyKeymap, defaultKeymap } from "@codemirror/commands";
|
|
16
|
+
import {
|
|
17
|
+
defaultHighlightStyle,
|
|
18
|
+
syntaxHighlighting,
|
|
19
|
+
indentOnInput,
|
|
20
|
+
foldGutter,
|
|
21
|
+
syntaxTree,
|
|
22
|
+
bracketMatching,
|
|
23
|
+
foldKeymap
|
|
24
|
+
} from "@codemirror/language";
|
|
25
|
+
import { Compartment, EditorState } from "@codemirror/state";
|
|
26
|
+
import {} from "@codemirror/language";
|
|
27
|
+
import { languages } from "@codemirror/language-data";
|
|
28
|
+
import { ref, shallowRef, onMounted, watch, computed } from "vue";
|
|
29
|
+
import { autocompletion, closeBrackets, closeBracketsKeymap, completionKeymap } from "@codemirror/autocomplete";
|
|
30
|
+
import { highlightSelectionMatches, searchKeymap } from "@codemirror/search";
|
|
31
|
+
import { lintKeymap } from "@codemirror/lint";
|
|
32
|
+
import { catppuccinLatte, catppuccinMocha } from "@catppuccin/codemirror";
|
|
33
|
+
const doc = defineModel({ type: String });
|
|
34
|
+
const props = defineProps({
|
|
35
|
+
class: { type: String, required: false },
|
|
36
|
+
language: { type: String, required: false },
|
|
37
|
+
bracketClosing: { type: Boolean, required: false },
|
|
38
|
+
foldGutter: { type: Boolean, required: false },
|
|
39
|
+
disabled: { type: Boolean, required: false },
|
|
40
|
+
debug: { type: Boolean, required: false },
|
|
41
|
+
searchOptions: { type: Object, required: false },
|
|
42
|
+
lightTheme: { type: [Object, Array], required: false },
|
|
43
|
+
darkTheme: { type: [Object, Array], required: false }
|
|
44
|
+
});
|
|
45
|
+
const emit = defineEmits([]);
|
|
46
|
+
const extensions = shallowRef([]);
|
|
47
|
+
const view = shallowRef();
|
|
48
|
+
const ast = ref([]);
|
|
49
|
+
const languageCompartment = new Compartment();
|
|
50
|
+
const themeCompartment = new Compartment();
|
|
51
|
+
const colorMode = useColorMode();
|
|
52
|
+
const isDark = computed(() => colorMode.value === "dark");
|
|
53
|
+
const currentTheme = computed(() => {
|
|
54
|
+
if (isDark.value) {
|
|
55
|
+
return props.darkTheme || catppuccinMocha;
|
|
56
|
+
}
|
|
57
|
+
return props.lightTheme || catppuccinLatte;
|
|
58
|
+
});
|
|
59
|
+
async function loadLanguage(languageName) {
|
|
60
|
+
if (!languageName) return null;
|
|
61
|
+
const lang = languages.find(
|
|
62
|
+
(l) => l.name.toLowerCase() === languageName.toLowerCase() || l.alias.map((a) => a.toLowerCase()).includes(languageName.toLowerCase())
|
|
63
|
+
);
|
|
64
|
+
if (lang) {
|
|
65
|
+
try {
|
|
66
|
+
return await lang.load();
|
|
67
|
+
} catch (e) {
|
|
68
|
+
console.warn(`Failed to load language: ${languageName}`, e);
|
|
69
|
+
return null;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
console.warn(`Language not found: ${languageName}`);
|
|
73
|
+
return null;
|
|
74
|
+
}
|
|
75
|
+
onMounted(async () => {
|
|
76
|
+
const initialLanguage = await loadLanguage(props.language);
|
|
77
|
+
extensions.value = [
|
|
78
|
+
lineNumbers(),
|
|
79
|
+
// A gutter with code folding markers
|
|
80
|
+
foldGutter(),
|
|
81
|
+
// Replace non-printable characters with placeholders
|
|
82
|
+
highlightSpecialChars(),
|
|
83
|
+
// The undo history
|
|
84
|
+
history(),
|
|
85
|
+
// Replace native cursor/selection with our own
|
|
86
|
+
drawSelection(),
|
|
87
|
+
// Show a drop cursor when dragging over the editor
|
|
88
|
+
dropCursor(),
|
|
89
|
+
// Allow multiple cursors/selections
|
|
90
|
+
EditorState.allowMultipleSelections.of(true),
|
|
91
|
+
// Re-indent lines when typing specific input
|
|
92
|
+
indentOnInput(),
|
|
93
|
+
// Theme compartment - switches between light and dark
|
|
94
|
+
themeCompartment.of(currentTheme.value),
|
|
95
|
+
// Highlight matching brackets near cursor
|
|
96
|
+
bracketMatching(),
|
|
97
|
+
// Automatically close brackets
|
|
98
|
+
closeBrackets(),
|
|
99
|
+
// Load the autocompletion system
|
|
100
|
+
autocompletion(),
|
|
101
|
+
// Allow alt-drag to select rectangular regions
|
|
102
|
+
rectangularSelection(),
|
|
103
|
+
// Change the cursor to a crosshair when holding alt
|
|
104
|
+
crosshairCursor(),
|
|
105
|
+
// Style the current line specially
|
|
106
|
+
highlightActiveLine(),
|
|
107
|
+
// Style the gutter for current line specially
|
|
108
|
+
highlightActiveLineGutter(),
|
|
109
|
+
// Highlight text that matches the selected text
|
|
110
|
+
highlightSelectionMatches(),
|
|
111
|
+
// Language support compartment (can be reconfigured)
|
|
112
|
+
languageCompartment.of(initialLanguage || []),
|
|
113
|
+
keymap.of([
|
|
114
|
+
// Closed-brackets aware backspace
|
|
115
|
+
...closeBracketsKeymap,
|
|
116
|
+
// A large set of basic bindings
|
|
117
|
+
...defaultKeymap,
|
|
118
|
+
// Search-related keys
|
|
119
|
+
...searchKeymap,
|
|
120
|
+
// Redo/undo keys
|
|
121
|
+
...historyKeymap,
|
|
122
|
+
// Code folding bindings
|
|
123
|
+
...foldKeymap,
|
|
124
|
+
// Autocompletion keys
|
|
125
|
+
...completionKeymap,
|
|
126
|
+
// Keys related to the linter system
|
|
127
|
+
...lintKeymap
|
|
128
|
+
]),
|
|
129
|
+
EditorView.editable.of(!props.disabled)
|
|
130
|
+
];
|
|
131
|
+
});
|
|
132
|
+
watch(
|
|
133
|
+
() => props.language,
|
|
134
|
+
async (newLanguage) => {
|
|
135
|
+
if (view.value) {
|
|
136
|
+
const languageSupport = await loadLanguage(newLanguage);
|
|
137
|
+
view.value.dispatch({
|
|
138
|
+
effects: languageCompartment.reconfigure(languageSupport || [])
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
);
|
|
143
|
+
watch(
|
|
144
|
+
currentTheme,
|
|
145
|
+
(newTheme) => {
|
|
146
|
+
if (view.value) {
|
|
147
|
+
view.value.dispatch({
|
|
148
|
+
effects: themeCompartment.reconfigure(newTheme)
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
);
|
|
153
|
+
function handleReady(payload) {
|
|
154
|
+
view.value = payload.view;
|
|
155
|
+
}
|
|
156
|
+
function iterate() {
|
|
157
|
+
ast.value = [];
|
|
158
|
+
try {
|
|
159
|
+
view.value?.state?.tree.iterate({
|
|
160
|
+
from: 0,
|
|
161
|
+
to: view.value.state.doc.length,
|
|
162
|
+
//@ts-ignore
|
|
163
|
+
enter(node) {
|
|
164
|
+
ast.value.push(`Node: ${node.name}, From: ${node.from}, To: ${node.to}, Text: "${view.value?.state.doc.sliceString(node.from, node.to)}"`);
|
|
165
|
+
}
|
|
166
|
+
});
|
|
167
|
+
} catch (e) {
|
|
168
|
+
console.log(e);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
defineExpose({
|
|
172
|
+
view
|
|
173
|
+
});
|
|
174
|
+
</script>
|
|
175
|
+
|
|
176
|
+
<template>
|
|
177
|
+
<div :class="props.class ? props.class : 'w-full h-full overflow-visible'">
|
|
178
|
+
<ClientOnly class="overflow-visible">
|
|
179
|
+
<div class="w-full cm-code-editor overflow-visible">
|
|
180
|
+
<CodeMirror
|
|
181
|
+
v-model="doc"
|
|
182
|
+
placeholder="Your code here..."
|
|
183
|
+
:autofocus="true"
|
|
184
|
+
:indent-with-tab="true"
|
|
185
|
+
:tab-size="4"
|
|
186
|
+
:tab="true"
|
|
187
|
+
:indent-unit="' '"
|
|
188
|
+
:extensions="extensions"
|
|
189
|
+
@ready="handleReady"
|
|
190
|
+
class="w-full h-full cm-code-editor overflow-visible"
|
|
191
|
+
:disabled="props.disabled"
|
|
192
|
+
:readonly="props.disabled"
|
|
193
|
+
/>
|
|
194
|
+
</div>
|
|
195
|
+
<template v-if="props.debug">
|
|
196
|
+
<UButton label="Iterate AST" @click="iterate" />
|
|
197
|
+
<div class="grid grid-cols-1 gap-2 py-2 w-full">
|
|
198
|
+
<div v-for="(content, index) in ast" :key="index">{{ content }}</div>
|
|
199
|
+
</div>
|
|
200
|
+
</template>
|
|
201
|
+
</ClientOnly>
|
|
202
|
+
</div>
|
|
203
|
+
</template>
|
|
204
|
+
|
|
205
|
+
<style>
|
|
206
|
+
@reference "../assets/css/editor.css";.cm-cursor{@apply border-l-primary! border-l-[1.8px]! rounded-lg!}.cm-selectionBackground{@apply bg-primary/30! z-[150]}.cm-selectionLayer{@apply z-[150]!;pointer-events:none}div[contenteditable=true]:focus{@apply outline-none border-none h-full shadow-none}.cm-focused{@apply outline-none!}.cm-placeholder{@apply font-editor text-muted}.cm-activeLine{@apply bg-none! border-l-primary border-l-4 relative -left-1 content-[""] mask-no-clip overflow-visible}
|
|
207
|
+
</style>
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { EditorView } from '@codemirror/view';
|
|
2
|
+
import type { Extension } from '@codemirror/state';
|
|
3
|
+
import type { SearchOptions } from '#codemirror-rich-obsidian-editor/editor-types';
|
|
4
|
+
type __VLS_Props = {
|
|
5
|
+
class?: string;
|
|
6
|
+
language?: string;
|
|
7
|
+
bracketClosing?: boolean;
|
|
8
|
+
foldGutter?: boolean;
|
|
9
|
+
disabled?: boolean;
|
|
10
|
+
debug?: boolean;
|
|
11
|
+
searchOptions?: SearchOptions;
|
|
12
|
+
/**
|
|
13
|
+
* Custom theme for light mode. Defaults to Catppuccin Latte.
|
|
14
|
+
* Pass a CodeMirror Extension (e.g., from @codemirror/theme-one-dark)
|
|
15
|
+
*/
|
|
16
|
+
lightTheme?: Extension;
|
|
17
|
+
/**
|
|
18
|
+
* Custom theme for dark mode. Defaults to Catppuccin Mocha.
|
|
19
|
+
* Pass a CodeMirror Extension (e.g., from @codemirror/theme-one-dark)
|
|
20
|
+
*/
|
|
21
|
+
darkTheme?: Extension;
|
|
22
|
+
};
|
|
23
|
+
type __VLS_ModelProps = {
|
|
24
|
+
modelValue?: string;
|
|
25
|
+
};
|
|
26
|
+
type __VLS_PublicProps = __VLS_Props & __VLS_ModelProps;
|
|
27
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {
|
|
28
|
+
view: import("vue").ShallowRef<EditorView | undefined, EditorView | undefined>;
|
|
29
|
+
}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
30
|
+
"update:modelValue": (value: string | undefined) => any;
|
|
31
|
+
}, string, import("vue").PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
|
|
32
|
+
"onUpdate:modelValue"?: ((value: string | undefined) => any) | undefined;
|
|
33
|
+
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
34
|
+
declare const _default: typeof __VLS_export;
|
|
35
|
+
export default _default;
|
|
@@ -17,13 +17,13 @@ type __VLS_PublicProps = __VLS_Props & __VLS_ModelProps;
|
|
|
17
17
|
declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {
|
|
18
18
|
view: import("vue").ShallowRef<EditorView | undefined, EditorView | undefined>;
|
|
19
19
|
}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
20
|
+
"update:modelValue": (value: string | undefined) => any;
|
|
20
21
|
"internal-link-click": (detail: InternalLinkClickDetail) => any;
|
|
21
22
|
"external-link-click": (detail: ExternalLinkClickDetail) => any;
|
|
22
|
-
"update:modelValue": (value: string | undefined) => any;
|
|
23
23
|
}, string, import("vue").PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
|
|
24
|
+
"onUpdate:modelValue"?: ((value: string | undefined) => any) | undefined;
|
|
24
25
|
"onInternal-link-click"?: ((detail: InternalLinkClickDetail) => any) | undefined;
|
|
25
26
|
"onExternal-link-click"?: ((detail: ExternalLinkClickDetail) => any) | undefined;
|
|
26
|
-
"onUpdate:modelValue"?: ((value: string | undefined) => any) | undefined;
|
|
27
27
|
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
28
28
|
declare const _default: typeof __VLS_export;
|
|
29
29
|
export default _default;
|
|
@@ -52,7 +52,6 @@ async function loadLanguage(info) {
|
|
|
52
52
|
if (lang) {
|
|
53
53
|
return await lang.load();
|
|
54
54
|
}
|
|
55
|
-
throw new Error(`Language ${info} not found`);
|
|
56
55
|
}
|
|
57
56
|
onMounted(() => {
|
|
58
57
|
const wysiwygPlugin = wysiwyg({
|
|
@@ -177,7 +176,7 @@ defineExpose({
|
|
|
177
176
|
<template>
|
|
178
177
|
<div :class="props.class ? props.class : 'w-full h-full overflow-visible'" ref="editorElement">
|
|
179
178
|
<ClientOnly class="overflow-visible">
|
|
180
|
-
<div class="w-full cm-
|
|
179
|
+
<div class="w-full cm-rich-editor overflow-visible">
|
|
181
180
|
<CodeMirror
|
|
182
181
|
v-model="doc"
|
|
183
182
|
placeholder="Start typing your markdown content here..."
|
|
@@ -191,7 +190,7 @@ defineExpose({
|
|
|
191
190
|
@change="log('change', $event)"
|
|
192
191
|
@focus="log('focus', $event)"
|
|
193
192
|
@blur="log('blur', $event)"
|
|
194
|
-
class="w-full h-full cm-
|
|
193
|
+
class="w-full h-full cm-rich-editor overflow-visible"
|
|
195
194
|
:disabled="props.disabled"
|
|
196
195
|
:readonly="props.disabled"
|
|
197
196
|
/>
|
|
@@ -17,13 +17,13 @@ type __VLS_PublicProps = __VLS_Props & __VLS_ModelProps;
|
|
|
17
17
|
declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {
|
|
18
18
|
view: import("vue").ShallowRef<EditorView | undefined, EditorView | undefined>;
|
|
19
19
|
}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
20
|
+
"update:modelValue": (value: string | undefined) => any;
|
|
20
21
|
"internal-link-click": (detail: InternalLinkClickDetail) => any;
|
|
21
22
|
"external-link-click": (detail: ExternalLinkClickDetail) => any;
|
|
22
|
-
"update:modelValue": (value: string | undefined) => any;
|
|
23
23
|
}, string, import("vue").PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
|
|
24
|
+
"onUpdate:modelValue"?: ((value: string | undefined) => any) | undefined;
|
|
24
25
|
"onInternal-link-click"?: ((detail: InternalLinkClickDetail) => any) | undefined;
|
|
25
26
|
"onExternal-link-click"?: ((detail: ExternalLinkClickDetail) => any) | undefined;
|
|
26
|
-
"onUpdate:modelValue"?: ((value: string | undefined) => any) | undefined;
|
|
27
27
|
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
28
28
|
declare const _default: typeof __VLS_export;
|
|
29
29
|
export default _default;
|
|
@@ -9,6 +9,26 @@ function isNodeRangeActive(state, nodeFrom, nodeTo) {
|
|
|
9
9
|
}
|
|
10
10
|
return Math.max(nodeFrom, cursor.from) < Math.min(nodeTo, cursor.to);
|
|
11
11
|
}
|
|
12
|
+
function getCalloutBlockquoteRanges(state) {
|
|
13
|
+
const ranges = [];
|
|
14
|
+
syntaxTree(state).iterate({
|
|
15
|
+
enter(node) {
|
|
16
|
+
if (node.name === "Blockquote") {
|
|
17
|
+
const calloutNode = getCalloutNode(node.node);
|
|
18
|
+
if (calloutNode && node.node.parent?.name !== "Blockquote") {
|
|
19
|
+
ranges.push({ from: node.from, to: node.to });
|
|
20
|
+
return false;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
return ranges;
|
|
26
|
+
}
|
|
27
|
+
function isCursorInAnyRange(cursor, ranges) {
|
|
28
|
+
return ranges.some(
|
|
29
|
+
(range) => cursor.from >= range.from && cursor.from <= range.to || cursor.to >= range.from && cursor.to <= range.to || cursor.from <= range.from && cursor.to >= range.to
|
|
30
|
+
);
|
|
31
|
+
}
|
|
12
32
|
function getCalloutNode(blockquoteNode) {
|
|
13
33
|
let calloutNode = null;
|
|
14
34
|
let found = false;
|
|
@@ -53,11 +73,22 @@ export const proseCalloutPlugin = StateField.define({
|
|
|
53
73
|
create(state) {
|
|
54
74
|
return RangeSet.of(buildCalloutWidgetDecorations(state), true);
|
|
55
75
|
},
|
|
56
|
-
update(
|
|
57
|
-
if (tr.docChanged
|
|
76
|
+
update(oldDecorations, tr) {
|
|
77
|
+
if (tr.docChanged) {
|
|
58
78
|
return RangeSet.of(buildCalloutWidgetDecorations(tr.state), true);
|
|
59
79
|
}
|
|
60
|
-
|
|
80
|
+
if (tr.selection) {
|
|
81
|
+
const oldCursor = tr.startState.selection.main;
|
|
82
|
+
const newCursor = tr.state.selection.main;
|
|
83
|
+
const calloutRanges = getCalloutBlockquoteRanges(tr.state);
|
|
84
|
+
const wasInCallout = isCursorInAnyRange(oldCursor, calloutRanges);
|
|
85
|
+
const isInCallout = isCursorInAnyRange(newCursor, calloutRanges);
|
|
86
|
+
if (wasInCallout !== isInCallout) {
|
|
87
|
+
return RangeSet.of(buildCalloutWidgetDecorations(tr.state), true);
|
|
88
|
+
}
|
|
89
|
+
return oldDecorations;
|
|
90
|
+
}
|
|
91
|
+
return oldDecorations.map(tr.changes);
|
|
61
92
|
},
|
|
62
93
|
provide: (f) => EditorView.decorations.from(f)
|
|
63
94
|
});
|
package/dist/runtime/editor/plugins/codemirror-plugin-proses/proseCodeBlockCodemirrorViewPlugin.js
CHANGED
|
@@ -5,6 +5,23 @@ import { EndFenceWidget, LanguageFlairWidget } from "../codemirror-widgets/prose
|
|
|
5
5
|
import { specialCodeBlockMapFacet } from "../specialCodeBlockMappingConfig.js";
|
|
6
6
|
import { ProseVueComponentEmbedWidget } from "../codemirror-widgets/proseVueComponentEmbedWidget.js";
|
|
7
7
|
import { cursorSelectionCoveredNode, isNodeRangeActive, toCursorNodePositions } from "../../utility/tools.js";
|
|
8
|
+
function getFencedCodeRanges(state) {
|
|
9
|
+
const ranges = [];
|
|
10
|
+
syntaxTree(state).iterate({
|
|
11
|
+
enter(node) {
|
|
12
|
+
if (node.name === "FencedCode") {
|
|
13
|
+
ranges.push({ from: node.from, to: node.to });
|
|
14
|
+
return false;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
return ranges;
|
|
19
|
+
}
|
|
20
|
+
function isCursorInAnyRange(cursor, ranges) {
|
|
21
|
+
return ranges.some(
|
|
22
|
+
(range) => cursor.from >= range.from && cursor.from <= range.to || cursor.to >= range.from && cursor.to <= range.to || cursor.from <= range.from && cursor.to >= range.to
|
|
23
|
+
);
|
|
24
|
+
}
|
|
8
25
|
function buildCodeBlockDecorations(state) {
|
|
9
26
|
const decorations = [];
|
|
10
27
|
const specialCodeBlocks = state.facet(specialCodeBlockMapFacet);
|
|
@@ -39,7 +56,9 @@ function buildCodeBlockDecorations(state) {
|
|
|
39
56
|
widget: new ProseVueComponentEmbedWidget(
|
|
40
57
|
specialMapping.component,
|
|
41
58
|
{ codeContent: codeText },
|
|
42
|
-
node.from
|
|
59
|
+
node.from,
|
|
60
|
+
node.from,
|
|
61
|
+
node.to
|
|
43
62
|
),
|
|
44
63
|
block: true
|
|
45
64
|
}).range(node.from, node.to)
|
|
@@ -88,11 +107,22 @@ export const proseCodeBlockCodemirrorViewPlugin = StateField.define({
|
|
|
88
107
|
create(state) {
|
|
89
108
|
return RangeSet.of(buildCodeBlockDecorations(state), true);
|
|
90
109
|
},
|
|
91
|
-
update(
|
|
92
|
-
if (tr.docChanged
|
|
110
|
+
update(oldDecorations, tr) {
|
|
111
|
+
if (tr.docChanged) {
|
|
93
112
|
return RangeSet.of(buildCodeBlockDecorations(tr.state), true);
|
|
94
113
|
}
|
|
95
|
-
|
|
114
|
+
if (tr.selection) {
|
|
115
|
+
const oldCursor = tr.startState.selection.main;
|
|
116
|
+
const newCursor = tr.state.selection.main;
|
|
117
|
+
const codeBlockRanges = getFencedCodeRanges(tr.state);
|
|
118
|
+
const wasInCodeBlock = isCursorInAnyRange(oldCursor, codeBlockRanges);
|
|
119
|
+
const isInCodeBlock = isCursorInAnyRange(newCursor, codeBlockRanges);
|
|
120
|
+
if (wasInCodeBlock !== isInCodeBlock) {
|
|
121
|
+
return RangeSet.of(buildCodeBlockDecorations(tr.state), true);
|
|
122
|
+
}
|
|
123
|
+
return oldDecorations;
|
|
124
|
+
}
|
|
125
|
+
return oldDecorations.map(tr.changes);
|
|
96
126
|
},
|
|
97
127
|
provide: (f) => EditorView.decorations.from(f)
|
|
98
128
|
});
|
|
@@ -4,6 +4,23 @@ import { syntaxTree } from "@codemirror/language";
|
|
|
4
4
|
import { internalLinkMapFacet } from "../linkMappingConfig.js";
|
|
5
5
|
import { ProseVueComponentEmbedWidget } from "../codemirror-widgets/proseVueComponentEmbedWidget.js";
|
|
6
6
|
import { cursorSelectionCoveredNode, toCursorNodePositions, isNodeRangeActive } from "../../utility/tools.js";
|
|
7
|
+
function getEmbedAndInternalLinkRanges(state) {
|
|
8
|
+
const ranges = [];
|
|
9
|
+
syntaxTree(state).iterate({
|
|
10
|
+
enter(node) {
|
|
11
|
+
if (node.name === "Embed" || node.name === "InternalLink") {
|
|
12
|
+
ranges.push({ from: node.from, to: node.to });
|
|
13
|
+
return false;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
});
|
|
17
|
+
return ranges;
|
|
18
|
+
}
|
|
19
|
+
function isCursorInAnyRange(cursor, ranges) {
|
|
20
|
+
return ranges.some(
|
|
21
|
+
(range) => cursor.from >= range.from && cursor.from <= range.to || cursor.to >= range.from && cursor.to <= range.to || cursor.from <= range.from && cursor.to >= range.to
|
|
22
|
+
);
|
|
23
|
+
}
|
|
7
24
|
function buildInternalLinkDecorations(state) {
|
|
8
25
|
const decorations = [];
|
|
9
26
|
const linkMap = state.facet(internalLinkMapFacet);
|
|
@@ -25,7 +42,13 @@ function buildInternalLinkDecorations(state) {
|
|
|
25
42
|
props.display = state.doc.sliceString(displayNode.from, displayNode.to);
|
|
26
43
|
}
|
|
27
44
|
widgets.push(Decoration.widget({
|
|
28
|
-
widget: new ProseVueComponentEmbedWidget(
|
|
45
|
+
widget: new ProseVueComponentEmbedWidget(
|
|
46
|
+
linkInfo.embedComponent,
|
|
47
|
+
linkInfo?.componentProps ? { ...linkInfo?.componentProps, ...props } : props,
|
|
48
|
+
node.from,
|
|
49
|
+
node.from,
|
|
50
|
+
node.to
|
|
51
|
+
),
|
|
29
52
|
block: true,
|
|
30
53
|
side: 1
|
|
31
54
|
}).range(line.to));
|
|
@@ -98,11 +121,22 @@ export const proseInternalLinkCodemirrorViewPlugin = StateField.define({
|
|
|
98
121
|
create(state) {
|
|
99
122
|
return RangeSet.of(buildInternalLinkDecorations(state), true);
|
|
100
123
|
},
|
|
101
|
-
update(
|
|
102
|
-
if (tr.docChanged
|
|
124
|
+
update(oldDecorations, tr) {
|
|
125
|
+
if (tr.docChanged) {
|
|
103
126
|
return RangeSet.of(buildInternalLinkDecorations(tr.state), true);
|
|
104
127
|
}
|
|
105
|
-
|
|
128
|
+
if (tr.selection) {
|
|
129
|
+
const oldCursor = tr.startState.selection.main;
|
|
130
|
+
const newCursor = tr.state.selection.main;
|
|
131
|
+
const linkRanges = getEmbedAndInternalLinkRanges(tr.state);
|
|
132
|
+
const wasInLink = isCursorInAnyRange(oldCursor, linkRanges);
|
|
133
|
+
const isInLink = isCursorInAnyRange(newCursor, linkRanges);
|
|
134
|
+
if (wasInLink !== isInLink) {
|
|
135
|
+
return RangeSet.of(buildInternalLinkDecorations(tr.state), true);
|
|
136
|
+
}
|
|
137
|
+
return oldDecorations;
|
|
138
|
+
}
|
|
139
|
+
return oldDecorations.map(tr.changes);
|
|
106
140
|
},
|
|
107
141
|
provide: (f) => EditorView.decorations.from(f)
|
|
108
142
|
});
|
|
@@ -3,10 +3,8 @@ import type { EditorView } from '@codemirror/view';
|
|
|
3
3
|
export declare class CalloutWidget extends WidgetType {
|
|
4
4
|
private sourceNodeFrom;
|
|
5
5
|
private sourceNodeTo;
|
|
6
|
-
private rawContent;
|
|
7
6
|
constructor(sourceNodeFrom: number, sourceNodeTo: number);
|
|
8
7
|
private findParentBlockquote;
|
|
9
|
-
private extractDetails;
|
|
10
8
|
toDOM(view: EditorView): HTMLElement;
|
|
11
9
|
eq(other: CalloutWidget): boolean;
|
|
12
10
|
ignoreEvent(event: Event): boolean;
|
|
@@ -9,7 +9,6 @@ export class CalloutWidget extends WidgetType {
|
|
|
9
9
|
this.sourceNodeFrom = sourceNodeFrom;
|
|
10
10
|
this.sourceNodeTo = sourceNodeTo;
|
|
11
11
|
}
|
|
12
|
-
rawContent = "";
|
|
13
12
|
findParentBlockquote(node) {
|
|
14
13
|
let current = node;
|
|
15
14
|
while (current) {
|
|
@@ -20,17 +19,15 @@ export class CalloutWidget extends WidgetType {
|
|
|
20
19
|
}
|
|
21
20
|
return null;
|
|
22
21
|
}
|
|
23
|
-
|
|
22
|
+
toDOM(view) {
|
|
24
23
|
const state = view.state;
|
|
25
24
|
const calloutNode = syntaxTree(state).resolve(this.sourceNodeFrom, 1);
|
|
26
25
|
const parentBlockquote = this.findParentBlockquote(calloutNode);
|
|
26
|
+
let rawContent = "";
|
|
27
27
|
if (parentBlockquote) {
|
|
28
|
-
|
|
28
|
+
rawContent = view.state.doc.sliceString(parentBlockquote.from, parentBlockquote.to);
|
|
29
29
|
}
|
|
30
|
-
|
|
31
|
-
toDOM(view) {
|
|
32
|
-
this.extractDetails(view);
|
|
33
|
-
const renderedHtml = md.render(this.rawContent);
|
|
30
|
+
const renderedHtml = md.render(rawContent);
|
|
34
31
|
const tempDiv = document.createElement("div");
|
|
35
32
|
tempDiv.innerHTML = renderedHtml;
|
|
36
33
|
const calloutEl = tempDiv.querySelector(".callout");
|
|
@@ -52,9 +49,9 @@ export class CalloutWidget extends WidgetType {
|
|
|
52
49
|
};
|
|
53
50
|
editButton.onclick = (e) => {
|
|
54
51
|
e.stopPropagation();
|
|
55
|
-
const
|
|
56
|
-
if (
|
|
57
|
-
view.dispatch({ selection: { anchor:
|
|
52
|
+
const parentBlockquote2 = this.findParentBlockquote(syntaxTree(view.state).resolve(this.sourceNodeFrom, 1));
|
|
53
|
+
if (parentBlockquote2) {
|
|
54
|
+
view.dispatch({ selection: { anchor: parentBlockquote2.from } });
|
|
58
55
|
view.focus();
|
|
59
56
|
}
|
|
60
57
|
};
|
|
@@ -73,7 +70,7 @@ export class CalloutWidget extends WidgetType {
|
|
|
73
70
|
return calloutEl;
|
|
74
71
|
}
|
|
75
72
|
eq(other) {
|
|
76
|
-
return other.sourceNodeFrom === this.sourceNodeFrom && other.sourceNodeTo === this.sourceNodeTo
|
|
73
|
+
return other.sourceNodeFrom === this.sourceNodeFrom && other.sourceNodeTo === this.sourceNodeTo;
|
|
77
74
|
}
|
|
78
75
|
ignoreEvent(event) {
|
|
79
76
|
if (event.type === "click" || event.type === "mousedown") {
|
|
@@ -4,9 +4,12 @@ export declare class ProseVueComponentEmbedWidget extends WidgetType {
|
|
|
4
4
|
readonly component: Component;
|
|
5
5
|
readonly props: Record<string, any>;
|
|
6
6
|
readonly pos: number;
|
|
7
|
+
readonly nodeFrom: number;
|
|
8
|
+
readonly nodeTo: number;
|
|
7
9
|
private app;
|
|
8
|
-
constructor(component: Component, props: Record<string, any>, pos: number);
|
|
10
|
+
constructor(component: Component, props: Record<string, any>, pos: number, nodeFrom: number, nodeTo: number);
|
|
9
11
|
toDOM(view: EditorView): HTMLDivElement;
|
|
10
12
|
destroy(): void;
|
|
13
|
+
eq(other: ProseVueComponentEmbedWidget): boolean;
|
|
11
14
|
ignoreEvent(event: Event): boolean;
|
|
12
15
|
}
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import { WidgetType } from "@codemirror/view";
|
|
2
2
|
import { createApp } from "vue";
|
|
3
3
|
export class ProseVueComponentEmbedWidget extends WidgetType {
|
|
4
|
-
constructor(component, props, pos) {
|
|
4
|
+
constructor(component, props, pos, nodeFrom, nodeTo) {
|
|
5
5
|
super();
|
|
6
6
|
this.component = component;
|
|
7
7
|
this.props = props;
|
|
8
8
|
this.pos = pos;
|
|
9
|
+
this.nodeFrom = nodeFrom;
|
|
10
|
+
this.nodeTo = nodeTo;
|
|
9
11
|
}
|
|
10
12
|
app = null;
|
|
11
13
|
toDOM(view) {
|
|
@@ -26,6 +28,30 @@ export class ProseVueComponentEmbedWidget extends WidgetType {
|
|
|
26
28
|
this.app.unmount();
|
|
27
29
|
}
|
|
28
30
|
}
|
|
31
|
+
eq(other) {
|
|
32
|
+
if (this.component !== other.component) return false;
|
|
33
|
+
if (this.nodeFrom !== other.nodeFrom || this.nodeTo !== other.nodeTo) return false;
|
|
34
|
+
const thisKeys = Object.keys(this.props);
|
|
35
|
+
const otherKeys = Object.keys(other.props);
|
|
36
|
+
if (thisKeys.length !== otherKeys.length) return false;
|
|
37
|
+
for (const key of thisKeys) {
|
|
38
|
+
if (this.props[key] !== other.props[key]) {
|
|
39
|
+
if (typeof this.props[key] === "object" && typeof other.props[key] === "object") {
|
|
40
|
+
if (key === "linkData") {
|
|
41
|
+
const thisLink = this.props[key];
|
|
42
|
+
const otherLink = other.props[key];
|
|
43
|
+
if (thisLink?.referenceId !== otherLink?.referenceId) return false;
|
|
44
|
+
if (thisLink?.name !== otherLink?.name) return false;
|
|
45
|
+
if (thisLink?.filePath !== otherLink?.filePath) return false;
|
|
46
|
+
continue;
|
|
47
|
+
}
|
|
48
|
+
return false;
|
|
49
|
+
}
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return true;
|
|
54
|
+
}
|
|
29
55
|
ignoreEvent(event) {
|
|
30
56
|
return event instanceof MouseEvent;
|
|
31
57
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@type32/codemirror-rich-obsidian-editor",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.6",
|
|
4
4
|
"description": "OFM Editor Component for Nuxt.",
|
|
5
5
|
"repository": "Type-32/codemirror-rich-obsidian",
|
|
6
6
|
"license": "MIT",
|
|
@@ -35,12 +35,14 @@
|
|
|
35
35
|
"test:types": "bunx vue-tsc --noEmit && cd playground && bunx vue-tsc --noEmit"
|
|
36
36
|
},
|
|
37
37
|
"dependencies": {
|
|
38
|
+
"@catppuccin/codemirror": "^1.0.1",
|
|
38
39
|
"@codemirror/autocomplete": "^6.20.0",
|
|
39
40
|
"@codemirror/lang-json": "^6.0.2",
|
|
40
41
|
"@codemirror/lang-markdown": "^6.5.0",
|
|
41
42
|
"@codemirror/lang-yaml": "^6.1.2",
|
|
42
43
|
"@codemirror/language": "^6.12.1",
|
|
43
44
|
"@codemirror/language-data": "^6.5.2",
|
|
45
|
+
"@codemirror/theme-one-dark": "^6.1.3",
|
|
44
46
|
"@hsorby/vue3-katex": "0.6.0-rc.7",
|
|
45
47
|
"@lezer/markdown": "^1.6.3",
|
|
46
48
|
"@nuxt/image": "2.0.0",
|