@@ -20,16 +20,24 @@ import { initMermaidRenderer, disposeMermaidRenderer } from './mermaid/mermaid-r
2020 */
2121export class InlineEditorManager implements vscode . Disposable {
2222 private readonly disposables : vscode . Disposable [ ] = [ ] ;
23+ private readonly providerDisposables : vscode . Disposable [ ] = [ ] ;
2324 private readonly decorator : Decorator ;
2425 private readonly parseCache : MarkdownParseCache ;
2526 private readonly linkClickHandler : LinkClickHandler ;
27+ private readonly markdownSelector : vscode . DocumentSelector ;
28+ private readonly hasProLicence : ( ( ) => boolean ) | undefined ;
29+ private providersRegistered = false ;
2630
2731 constructor (
2832 context : vscode . ExtensionContext ,
2933 markdownSelector : vscode . DocumentSelector ,
3034 notesRootPath ?: string ,
3135 isIgnored ?: ( relativePath : string ) => boolean ,
36+ hasProLicence ?: ( ) => boolean ,
3237 ) {
38+ this . markdownSelector = markdownSelector ;
39+ this . hasProLicence = hasProLicence ;
40+
3341 // Mermaid renderer needs context for webview
3442 initMermaidRenderer ( context ) ;
3543
@@ -44,40 +52,21 @@ export class InlineEditorManager implements vscode.Disposable {
4452 this . decorator . updateDiffViewDecorationSetting ( ! diffViewApplyDecorations ) ;
4553 this . decorator . setActiveEditor ( vscode . window . activeTextEditor ) ;
4654
47- // Check if inline editor is enabled
48- const inlineEditorEnabled = vscode . workspace
49- . getConfiguration ( 'as-notes.inlineEditor' )
50- . get < boolean > ( 'enabled' , true ) ;
51- if ( ! inlineEditorEnabled ) {
55+ // Link click handler (created once, enabled/disabled dynamically)
56+ this . linkClickHandler = new LinkClickHandler ( this . parseCache ) ;
57+
58+ // Initial state: start based on shouldBeActive(). The licence callback
59+ // may return false during startup if verification hasn't completed yet;
60+ // enterFullMode() calls refreshLicenceGate() immediately after creation
61+ // to correct the state once the licence is known.
62+ if ( ! this . shouldBeActive ( ) ) {
5263 this . decorator . toggleDecorations ( ) ; // starts enabled, so toggle to disable
64+ this . linkClickHandler . setEnabled ( false ) ;
65+ } else {
66+ this . linkClickHandler . setEnabled ( config . links . singleClickOpen ( ) ) ;
67+ this . registerProviders ( ) ;
5368 }
5469
55- // Link provider
56- const linkProvider = new MarkdownLinkProvider ( this . parseCache ) ;
57- this . disposables . push (
58- vscode . languages . registerDocumentLinkProvider ( markdownSelector , linkProvider ) ,
59- ) ;
60-
61- // Hover providers
62- this . disposables . push (
63- vscode . languages . registerHoverProvider (
64- markdownSelector ,
65- new MarkdownImageHoverProvider ( this . parseCache ) ,
66- ) ,
67- vscode . languages . registerHoverProvider (
68- markdownSelector ,
69- new MarkdownLinkHoverProvider ( this . parseCache ) ,
70- ) ,
71- vscode . languages . registerHoverProvider (
72- markdownSelector ,
73- new CodeBlockHoverProvider ( this . parseCache ) ,
74- ) ,
75- ) ;
76-
77- // Link click handler
78- this . linkClickHandler = new LinkClickHandler ( this . parseCache ) ;
79- this . linkClickHandler . setEnabled ( config . links . singleClickOpen ( ) ) ;
80-
8170 // Toggle command
8271 this . disposables . push (
8372 vscode . commands . registerCommand ( 'as-notes.toggleInlineEditor' , ( ) => {
@@ -142,13 +131,7 @@ export class InlineEditorManager implements vscode.Disposable {
142131 this . disposables . push (
143132 vscode . workspace . onDidChangeConfiguration ( ( e ) => {
144133 if ( e . affectsConfiguration ( 'as-notes.inlineEditor.enabled' ) ) {
145- const enabled = vscode . workspace
146- . getConfiguration ( 'as-notes.inlineEditor' )
147- . get < boolean > ( 'enabled' , true ) ;
148- const currentlyEnabled = this . decorator . isEnabled ( ) ;
149- if ( enabled !== currentlyEnabled ) {
150- this . decorator . toggleDecorations ( ) ;
151- }
134+ this . refreshLicenceGate ( ) ;
152135 }
153136 if ( e . affectsConfiguration ( 'as-notes.inlineEditor.defaultBehaviors.diffView.applyDecorations' ) ) {
154137 const apply = config . diffView . applyDecorations ( ) ;
@@ -187,6 +170,70 @@ export class InlineEditorManager implements vscode.Disposable {
187170 'codesmith.markdown-inline-editor-vscode' ,
188171 ] ;
189172
173+ /** Whether the inline editor should be active (setting enabled AND pro licence). */
174+ private shouldBeActive ( ) : boolean {
175+ const settingEnabled = vscode . workspace
176+ . getConfiguration ( 'as-notes.inlineEditor' )
177+ . get < boolean > ( 'enabled' , true ) ;
178+ return settingEnabled && ( ! this . hasProLicence || this . hasProLicence ( ) ) ;
179+ }
180+
181+ /** Register hover, link, and document-link providers. */
182+ private registerProviders ( ) : void {
183+ if ( this . providersRegistered ) { return ; }
184+ this . providersRegistered = true ;
185+
186+ const linkProvider = new MarkdownLinkProvider ( this . parseCache ) ;
187+ this . providerDisposables . push (
188+ vscode . languages . registerDocumentLinkProvider ( this . markdownSelector , linkProvider ) ,
189+ ) ;
190+ this . providerDisposables . push (
191+ vscode . languages . registerHoverProvider (
192+ this . markdownSelector ,
193+ new MarkdownImageHoverProvider ( this . parseCache ) ,
194+ ) ,
195+ vscode . languages . registerHoverProvider (
196+ this . markdownSelector ,
197+ new MarkdownLinkHoverProvider ( this . parseCache ) ,
198+ ) ,
199+ vscode . languages . registerHoverProvider (
200+ this . markdownSelector ,
201+ new CodeBlockHoverProvider ( this . parseCache ) ,
202+ ) ,
203+ ) ;
204+ }
205+
206+ /** Dispose hover, link, and document-link providers. */
207+ private disposeProviders ( ) : void {
208+ if ( ! this . providersRegistered ) { return ; }
209+ for ( const d of this . providerDisposables ) {
210+ d . dispose ( ) ;
211+ }
212+ this . providerDisposables . length = 0 ;
213+ this . providersRegistered = false ;
214+ }
215+
216+ /**
217+ * Re-evaluate whether the inline editor should be active based on the
218+ * current setting and licence state. Enables or disables decorations and
219+ * registers or disposes providers accordingly.
220+ *
221+ * Call this after licence state changes or when the enabled setting changes.
222+ */
223+ refreshLicenceGate ( ) : void {
224+ const active = this . shouldBeActive ( ) ;
225+
226+ if ( active && ! this . decorator . isEnabled ( ) ) {
227+ this . decorator . toggleDecorations ( ) ;
228+ this . linkClickHandler . setEnabled ( config . links . singleClickOpen ( ) ) ;
229+ this . registerProviders ( ) ;
230+ } else if ( ! active && this . decorator . isEnabled ( ) ) {
231+ this . decorator . toggleDecorations ( ) ;
232+ this . linkClickHandler . setEnabled ( false ) ;
233+ this . disposeProviders ( ) ;
234+ }
235+ }
236+
190237 private static warnConflictingExtensions ( ) : void {
191238 for ( const id of InlineEditorManager . CONFLICTING_EXTENSIONS ) {
192239 const ext = vscode . extensions . getExtension ( id ) ;
@@ -216,6 +263,7 @@ export class InlineEditorManager implements vscode.Disposable {
216263 for ( const d of this . disposables ) {
217264 d . dispose ( ) ;
218265 }
266+ this . disposeProviders ( ) ;
219267 this . decorator . dispose ( ) ;
220268 this . linkClickHandler . dispose ( ) ;
221269 disposeMermaidRenderer ( ) ;
0 commit comments