import * as vscode from 'vscode' ; import { WorkspaceFolder , DebugConfiguration , ProviderResult , CancellationToken } from 'vscode' ; import { DebugSessionClass } from './debugadapter' ; import * as Net from 'net' ; import { DecorationClass , Decoration } from './decoration' ; import { LogSocket , LogCustomCode , LogSocketCommands , Log } from './log' ; import { Utility } from './misc/utility' ; import { PackageInfo } from './whatsnew/packageinfo' ; import { WhatsNewView } from './whatsnew/whatsnewview' ; import { HelpProvider } from './help/helpprovider' ; import { GlobalStorage } from './globalstorage' ; import { Z80UnitTestRunner } from './z80unittests/z80unittestrunner' ; import { DiagnosticsHandler } from './diagnosticshandler' ; param context export function activate ( context ) { PackageInfo . Init ( context ) ; GlobalStorage . Init ( context ) ; DiagnosticsHandler . Init ( context ) ; const extPath = context . extensionPath ; Utility . setExtensionPath ( extPath ) ; const mjrMnrChanged = WhatsNewView . updateVersion ( context ) ; if ( mjrMnrChanged ) { new WhatsNewView ( ) ; } context . subscriptions . push ( vscode . commands . registerCommand ( "dezog.whatsNew" , ( ) => new WhatsNewView ( ) ) ) ; const helpProvider = new HelpProvider ( ) ; context . subscriptions . push ( vscode . window . registerWebviewViewProvider ( "dezog.helpview" , helpProvider , { webviewOptions : { retainContextWhenHidden : false } } ) ) ; context . subscriptions . push ( vscode . commands . registerCommand ( 'dezog.help' , ( ) => helpProvider . createHelpView ( ) ) ) ; const extension = PackageInfo . extension ; const packageJSON = extension . packageJSON ; const extensionBaseName = packageJSON . name ; const configuration = PackageInfo . getConfiguration ( ) ; configureLogging ( configuration ) ; context . subscriptions . push ( vscode . workspace . onDidChangeConfiguration ( event => { if ( event . affectsConfiguration ( extensionBaseName + '.logpanel' ) || event . affectsConfiguration ( extensionBaseName + '.socket.logpanel' ) || event . affectsConfiguration ( extensionBaseName + '.customcode.logpanel' ) ) { configureLogging ( configuration ) ; } if ( event . affectsConfiguration ( extensionBaseName + '.donated' ) ) { helpProvider . setMainHtml ( ) ; } } ) ) ; const version = process . version ; console . log ( version ) ; context . subscriptions . push ( vscode . debug . onDidTerminateDebugSession ( s => { console . log ( `terminated: ${ s . type } ${ s . name }` ) ; } ) ) ; context . subscriptions . push ( vscode . commands . registerCommand ( 'dezog.movePCtoCursor' , ( ) => { if ( ! vscode . debug . activeDebugSession ) return ; const editor = vscode . window . activeTextEditor ; if ( ! editor ) return ; const position = editor . selection . anchor ; const filename = editor . document . fileName ; vscode . debug . activeDebugSession . customRequest ( 'setPcToLine' , [ filename , position . line ] ) ; } ) ) ; context . subscriptions . push ( vscode . commands . registerCommand ( 'dezog.disassemblyAtCursor' , async ( ) => { if ( ! vscode . debug . activeDebugSession ) return ; const editor = vscode . window . activeTextEditor ; if ( ! editor ) return ; for ( const selection of editor . selections ) { let from = selection . anchor ; let to = selection . active ; const filename = editor . document . fileName ; if ( from . line > to . line ) { const tmp = from ; from = to ; to = tmp ; } const fromLine = from . line ; let toLine = to . line ; if ( toLine > fromLine ) { if ( to . character == 0 ) toLine -- ; } await vscode . debug . activeDebugSession . customRequest ( 'disassemblyAtCursor' , [ filename , fromLine , toLine ] ) ; } } ) ) ; context . subscriptions . push ( vscode . commands . registerCommand ( 'dezog.clearAllDecorations' , ( ) => { Decoration ?. clearAllDecorations ( ) ; } ) ) ; const configProvider = new DeZogConfigurationProvider ( ) ; context . subscriptions . push ( vscode . debug . registerDebugConfigurationProvider ( 'dezog' , configProvider ) ) ; const asmDocSelector = { scheme : 'file' } ; const inlineValuesProvider = new DeZogInlineValuesProvider ( ) ; context . subscriptions . push ( vscode . languages . registerInlineValuesProvider ( asmDocSelector , inlineValuesProvider ) ) ; DecorationClass . Initialize ( ) ; Z80UnitTestRunner . Init ( ) ; } /**
 * 'deactivate' is only called when vscode is terminated.
 */ export function deactivate ( ) { } /**
 * This debug inline values provider simply provides nothing.
 * This is to prevent that the default debug inline values provider is used instead,
 * which would show basically garbage.
 *
 * So for settings.json "debug.inlineValues":
 * - false: The inline provider is not called
 * - true/"auto": The inline provider is called but returns nothing.
 *
 * I'm not using the vscode approach for debug values but decorations instead because:
 * - The decorations implementation is ready and working fine. To change would give
 *   no advantage other than additional effort and bugs.
 * - vscode only shows the inline values for the currently debugged file.
 *   The decorations show them on all files, i.e. it is easier to follow where the
 *   instruction history came from.
 */ class DeZogInlineValuesProvider implements vscode . InlineValuesProvider { provideInlineValues ( document , viewPort , context , token ) { return undefined ; } } ; /**
 * Instantiates the ZesaruxDebugAdapter and sets up the
 * socket connection to it.
 */ class DeZogConfigurationProvider implements vscode . DebugConfigurationProvider { private _server ? : Net . Server ; /**
    * Instantiates DebugAdapter (DebugSessionClass) and sets up the
    * soccket connection to it.
    */ resolveDebugConfiguration ( folder , config , token ? ) { if ( ! this . _server ) { this . _server = Net . createServer ( socket => { const session = new DebugSessionClass ( ) ; session . setRunAsServer ( true ) ; session . start ( < NodeJS . ReadableStream > socket , socket ) ; } ) . listen ( 0 ) ; } const addrInfo = this . _server . address ( ) as Net . AddressInfo ; Utility . assert ( typeof addrInfo != 'string' ) ; config . debugServer = addrInfo . port ; return config ; } /**
     * End.
     */ dispose ( ) { if ( this . _server ) { this . _server . close ( ) ; } } } /**
 * Configures the logging from the settings.
 */ function configureLogging ( configuration ) { { const logToPanel = configuration . get < boolean > ( 'logpanel' ) ; const channelName = ( logToPanel ) ? "DeZog" : undefined ; const channelOut = ( channelName ) ? vscode . window . createOutputChannel ( channelName ) : undefined ; Log . init ( channelOut ) ; } { const logToPanel = configuration . get < boolean > ( 'customcode.logpanel' ) ; const channelName = ( logToPanel ) ? "DeZog Custom Code" : undefined ; const channelOut = ( channelName ) ? vscode . window . createOutputChannel ( channelName ) : undefined ; LogCustomCode . init ( channelOut ) ; } { const logToPanel = configuration . get < boolean > ( 'socket.logpanel' ) ; const channelName = ( logToPanel ) ? "DeZog Socket" : undefined ; const channelOut = ( channelName ) ? vscode . window . createOutputChannel ( channelName ) : undefined ; LogSocket . init ( channelOut ) ; } if ( false ) { const channelOut = vscode . window . createOutputChannel ( "DeZog Socket Commands" ) ; LogSocketCommands . init ( channelOut , undefined ) ; } }