@@ -7,7 +7,8 @@ import { summary } from 'itertools-ts/es';
77import type { TFile } from 'obsidian' ;
88import { Component , editorLivePreviewField } from 'obsidian' ;
99import type { InlineFieldType } from 'packages/core/src/config/APIConfigs' ;
10- import { Cm6_Util , MB_WidgetType } from 'packages/obsidian/src/cm6/Cm6_Util' ;
10+ import type { MB_WidgetSpec } from 'packages/obsidian/src/cm6/Cm6_Util' ;
11+ import { Cm6_Util , MB_WidgetType } from 'packages/obsidian/src/cm6/Cm6_Util' ;
1112import type MetaBindPlugin from 'packages/obsidian/src/main' ;
1213
1314// eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -68,6 +69,7 @@ export function createMarkdownRenderChildWidgetEditorPlugin(plugin: MetaBindPlug
6869 */
6970 updateWidgets ( view : EditorView ) : void {
7071 // remove all decorations that are not visible and call unload manually
72+ // this is needed because otherwise some decorations are not unloaded correctly
7173 this . decorations = this . decorations . update ( {
7274 filter : ( fromA , toA , decoration ) => {
7375 const inVisibleRange = summary . anyMatch ( view . visibleRanges , range =>
@@ -76,11 +78,12 @@ export function createMarkdownRenderChildWidgetEditorPlugin(plugin: MetaBindPlug
7678
7779 if ( inVisibleRange ) {
7880 return true ;
79- }
81+ } else {
82+ const spec = decoration . spec as MB_WidgetSpec ;
8083
81- // eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access
82- decoration . spec . mb_unload ?. ( ) ;
83- return false ;
84+ spec . mb_unload ?. ( ) ;
85+ return false ;
86+ }
8487 } ,
8588 } ) ;
8689
@@ -135,17 +138,13 @@ export function createMarkdownRenderChildWidgetEditorPlugin(plugin: MetaBindPlug
135138 filterFrom : from ,
136139 filterTo : to ,
137140 filter : ( _from , _to , decoration ) => {
138- if ( widgetTypeToKeep ) {
139- // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-assignment
140- const widgetType = decoration . spec . mb_widgetType ;
141+ const spec = decoration . spec as MB_WidgetSpec ;
141142
142- if ( widgetType === widgetTypeToKeep ) {
143- return true ;
144- }
143+ if ( widgetTypeToKeep && spec . mb_widgetType === widgetTypeToKeep ) {
144+ return true ;
145145 }
146146
147- // eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access
148- decoration . spec . mb_unload ?.( ) ;
147+ spec . mb_unload ?.( ) ;
149148 return false ;
150149 } ,
151150 } ) ;
@@ -171,11 +170,12 @@ export function createMarkdownRenderChildWidgetEditorPlugin(plugin: MetaBindPlug
171170 const from = node . from - 1 ;
172171 const to = node . to + 1 ;
173172
174- // check if the decoration already exists and only add it if it does not exist
173+ // we check if there already is a decoration of the same type in the range
175174 if ( Cm6_Util . existsDecorationOfTypeBetween ( this . decorations , widgetType , from , to ) ) {
176175 return ;
177176 }
178177
178+ // we can only render widgets if we have a current file
179179 const currentFile = Cm6_Util . getCurrentFile ( view ) ;
180180 if ( ! currentFile ) {
181181 return ;
@@ -189,6 +189,7 @@ export function createMarkdownRenderChildWidgetEditorPlugin(plugin: MetaBindPlug
189189 currentFile ,
190190 ) ;
191191 const newDecorations = Array . isArray ( newDecoration ) ? newDecoration : [ newDecoration ] ;
192+ // the render widget function might return an empty array if the widget is not supposed to be rendered
192193 if ( newDecorations . length === 0 ) {
193194 return ;
194195 }
@@ -221,15 +222,22 @@ export function createMarkdownRenderChildWidgetEditorPlugin(plugin: MetaBindPlug
221222 // node is inline code
222223 if ( props . has ( 'inline-code' ) && ! props . has ( 'formatting' ) ) {
223224 // check for selection or cursor overlap
224- const selection = view . state . selection ;
225- const hasSelectionOverlap = Cm6_Util . checkSelectionOverlap ( selection , node . from - 1 , node . to + 1 ) ;
225+ const hasSelectionOverlap = Cm6_Util . checkSelectionOverlap (
226+ view . state . selection ,
227+ node . from - 1 ,
228+ node . to + 1 ,
229+ ) ;
226230 const content = this . readNode ( view , node . from , node . to ) ;
227231 const isLivePreview = this . isLivePreview ( view . state ) ;
232+ // if we are in live preview mode, we only render the widget if there is no selection overlap
233+ // otherwise the user has it's cursor within the bounds of the code for the field and we do syntax highlighting
234+ // if we are not in live preview, so in source mode, we always do syntax highlighting
235+ const shouldRenderField = ! hasSelectionOverlap && isLivePreview ;
228236
229237 return {
230- shouldRender : ! hasSelectionOverlap && isLivePreview ,
231- shouldHighlight :
232- ( hasSelectionOverlap || ! isLivePreview ) && plugin . settings . enableSyntaxHighlighting ,
238+ shouldRender : shouldRenderField ,
239+ // we need to also check that the user has highlighting enabled in the settings
240+ shouldHighlight : ! shouldRenderField && plugin . settings . enableSyntaxHighlighting ,
233241 content : content . content ,
234242 widgetType : content . widgetType ,
235243 } ;
0 commit comments