11import * as os from 'os'
22import * as path from 'path'
3- import { commands , ExtensionContext , extensions , TextDocument , window , workspace } from 'vscode'
3+ import { commands , ExtensionContext , extensions , TextDocument , TextEditor , window , workspace } from 'vscode'
44import { AbbreviationFeature } from './abbreviation/AbbreviationFeature'
55import { AbbreviationView } from './abbreviationview'
66import { getDefaultLeanVersion } from './config'
@@ -20,11 +20,11 @@ import { LeanClientProvider } from './utils/clientProvider'
2020import { LeanConfigWatchService } from './utils/configwatchservice'
2121import { ElanCommandProvider } from './utils/elanCommands'
2222import { PATH , setProcessEnvPATH } from './utils/envPath'
23- import { onEventWhile , withoutReentrancy } from './utils/events'
24- import { ExtUri , extUriToCwdUri , FileUri } from './utils/exturi'
23+ import { combine , onEventWhile , withoutReentrancy } from './utils/events'
24+ import { ExtUri , extUriToCwdUri , FileUri , toExtUri } from './utils/exturi'
2525import { displayInternalErrorsIn } from './utils/internalErrors'
2626import { registerLeanCommandRunner } from './utils/leanCmdRunner'
27- import { lean , registerLeanEditorProvider } from './utils/leanEditorProvider'
27+ import { lean , registerLeanEditorProviders , text } from './utils/leanEditorProvider'
2828import { LeanInstaller } from './utils/leanInstaller'
2929import { ModuleTreeViewProvider } from './utils/moduleTreeViewProvider'
3030import {
@@ -41,24 +41,51 @@ async function setLeanFeatureSetActive(isActive: boolean) {
4141 await commands . executeCommand ( 'setContext' , 'lean4.isLeanFeatureSetActive' , isActive )
4242}
4343
44- async function findOpenLeanProjectUri ( ) : Promise < ExtUri | 'NoValidDocument' > {
45- const activeEditor = lean . activeLeanEditor
46- if ( activeEditor !== undefined ) {
47- const info = await findLeanProjectRootInfo ( activeEditor . documentExtUri )
48- if ( info . kind !== 'FileNotFound' ) {
49- return info . projectRootUri
50- }
44+ async function findInitialLeanProjectUri ( editor : TextEditor ) : Promise < ExtUri | undefined > {
45+ const uri = toExtUri ( editor . document . uri )
46+ if ( uri === undefined ) {
47+ return undefined
48+ }
49+ const info = await findLeanProjectRootInfo ( uri )
50+ if ( info . kind === 'FileNotFound' ) {
51+ return undefined
52+ }
53+ if ( editor . document . languageId !== 'lean4' && info . kind === 'Success' && info . toolchainUri === undefined ) {
54+ return undefined
5155 }
56+ return info . projectRootUri
57+ }
5258
59+ async function findActiveLeanProjectUri ( ) : Promise < ExtUri | undefined > {
60+ const activeEditor = window . activeTextEditor
61+ if ( activeEditor === undefined ) {
62+ return undefined
63+ }
64+ return await findInitialLeanProjectUri ( activeEditor )
65+ }
66+
67+ async function findVisibleLeanProjectUri ( ) : Promise < ExtUri | undefined > {
5368 // This happens if vscode starts with a lean file open
5469 // but the "Getting Started" page is active.
55- for ( const editor of lean . visibleLeanEditors ) {
56- const info = await findLeanProjectRootInfo ( editor . documentExtUri )
57- if ( info . kind !== 'FileNotFound' ) {
58- return info . projectRootUri
70+ for ( const editor of window . visibleTextEditors ) {
71+ const projectUri = await findInitialLeanProjectUri ( editor )
72+ if ( projectUri === undefined ) {
73+ continue
5974 }
75+ return projectUri
6076 }
77+ return undefined
78+ }
6179
80+ async function findOpenLeanProjectUri ( ) : Promise < ExtUri | 'NoValidDocument' > {
81+ const activeProjectUri = await findActiveLeanProjectUri ( )
82+ if ( activeProjectUri !== undefined ) {
83+ return activeProjectUri
84+ }
85+ const visibleProjectUri = await findVisibleLeanProjectUri ( )
86+ if ( visibleProjectUri !== undefined ) {
87+ return visibleProjectUri
88+ }
6289 return 'NoValidDocument'
6390}
6491
@@ -257,12 +284,23 @@ async function tryActivatingLean4Features(
257284 'No visible Lean document - cannot retry activating the extension. Please select a Lean document.' ,
258285 )
259286 }
287+ // We try activating the Lean features in two cases:
288+ // 1. When revealing a new editor with the `lean4` language ID (e.g.: switching tabs, opening a new Lean document, changing the language ID to `lean4`)
289+ // 2. When revealing a new editor in a Lean project that doesn't have the `lean4` language ID (e.g.: switching tabs, opening a new document)
290+ // These two events are disjoint, so combining them won't cause duplicate triggers.
291+ const combinedEvent = combine (
292+ lean . onDidRevealLeanEditor ,
293+ _ => true ,
294+ text . onDidRevealLeanEditor ,
295+ editor => editor . editor . document . languageId !== 'lean4' ,
296+ )
297+ context . subscriptions . push ( combinedEvent . disposable )
260298 context . subscriptions . push (
261299 onEventWhile (
262- lean . onDidRevealLeanEditor ,
263- withoutReentrancy ( 'Continue' , async editor => {
264- const info = await findLeanProjectRootInfo ( editor . documentExtUri )
265- if ( info . kind === 'FileNotFound' ) {
300+ combinedEvent . event ,
301+ withoutReentrancy ( 'Continue' , async leanEditor => {
302+ const projectUri = await findInitialLeanProjectUri ( leanEditor . editor )
303+ if ( projectUri === undefined ) {
266304 return 'Continue'
267305 }
268306 await tryActivatingLean4FeaturesInProject (
@@ -271,7 +309,7 @@ async function tryActivatingLean4Features(
271309 elanCommandProvider ,
272310 resolve ,
273311 d ,
274- info . projectRootUri ,
312+ projectUri ,
275313 )
276314 return 'Stop'
277315 } ) ,
@@ -281,7 +319,7 @@ async function tryActivatingLean4Features(
281319
282320export async function activate ( context : ExtensionContext ) : Promise < Exports > {
283321 await setLeanFeatureSetActive ( false )
284- registerLeanEditorProvider ( context )
322+ registerLeanEditorProviders ( context )
285323 await setStickyNotificationActiveButHidden ( false )
286324 context . subscriptions . push (
287325 commands . registerCommand ( 'lean4.redisplaySetupError' , async ( ) => displayActiveStickyNotification ( ) ) ,
0 commit comments