A complete rewrite of simple console
..that is not using `TerminalView`. The original (previous) implementation
had various problems that were hard to fix, namely loosing some
stream output in some cases.
New (current) implementation uses custom console view (1VDBSimpleDebuggerConsoleView`)
based on `TextCollector` rather than `TerminalView`. The resulting code is
much much simpler, it does not use internal pipes nor REPL / pipe reader processes.
Whole REPL runs completely in UI process.
"
jv:vdb - Visual / VM Debugger
Copyright (C) 2015-now Jan Vrany
This software is licensed under 'Creative Commons Attribution-NonCommercial 4.0 International License'
You may find a full license text in LICENSE.txt or at http://creativecommons.org/licenses/by-nc/4.0/
"
"{ Package: 'jv:vdb' }"
"{ NameSpace: Smalltalk }"
VDBAbstractApplication subclass:#VDBSourceApplication
instanceVariableNames:'frameHolder sourceFileHolder sourceStringHolder sourceView'
classVariableNames:''
poolDictionaries:''
category:'VDB-UI-Source'
!
!VDBSourceApplication class methodsFor:'documentation'!
copyright
"
jv:vdb - Visual / VM Debugger
Copyright (C) 2015-now Jan Vrany
This software is licensed under 'Creative Commons Attribution-NonCommercial 4.0 International License'
You may find a full license text in LICENSE.txt or at http://creativecommons.org/licenses/by-nc/4.0/
"
! !
!VDBSourceApplication class methodsFor:'interface specs'!
windowSpec
"This resource specification was automatically generated
by the UIPainter of ST/X."
"Do not manually edit this!! If it is corrupted,
the UIPainter may not be able to read the specification."
"
UIPainter new openOnClass:VDBSourceApplication andSelector:#windowSpec
VDBSourceApplication new openInterface:#windowSpec
VDBSourceApplication open
"
<resource: #canvas>
^
#(FullSpec
name: windowSpec
window:
(WindowSpec
label: 'Source View'
name: 'Source View'
min: (Point 10 10)
bounds: (Rectangle 0 0 300 300)
)
component:
(SpecCollection
collection: (
(NonScrollableArbitraryComponentSpec
name: 'SourceView'
layout: (LayoutFrame 0 0 0 0 0 1 0 1)
model: sourceStringHolder
component: sourceView
)
)
)
)
! !
!VDBSourceApplication class methodsFor:'plugIn spec'!
aspectSelectors
"This resource specification was automatically generated
by the UIPainter of ST/X."
"Do not manually edit this. If it is corrupted,
the UIPainter may not be able to read the specification."
"Return a description of exported aspects;
these can be connected to aspects of an embedding application
(if this app is embedded in a subCanvas)."
^ #(
#debuggerHolder
#frameHolder
).
! !
!VDBSourceApplication methodsFor:'aspects'!
frameHolder
"return/create the 'frameHolder' value holder (automatically generated)"
frameHolder isNil ifTrue:[
frameHolder := ValueHolder new.
frameHolder addDependent:self.
].
^ frameHolder
!
frameHolder:something
"set the 'frameHolder' value holder (automatically generated)"
|oldValue newValue|
frameHolder notNil ifTrue:[
oldValue := frameHolder value.
frameHolder removeDependent:self.
].
frameHolder := something.
frameHolder notNil ifTrue:[
frameHolder addDependent:self.
].
newValue := frameHolder value.
oldValue ~~ newValue ifTrue:[
self update:#value with:newValue from:frameHolder.
].
!
sourceFileHolder
"return/create the 'sourceFileHolder' value holder (automatically generated)"
sourceFileHolder isNil ifTrue:[
sourceFileHolder := ValueHolder new.
sourceFileHolder addDependent:self.
].
^ sourceFileHolder
!
sourceFileHolder:something
"set the 'sourceFileHolder' value holder (automatically generated)"
|oldValue newValue|
sourceFileHolder notNil ifTrue:[
oldValue := sourceFileHolder value.
sourceFileHolder removeDependent:self.
].
sourceFileHolder := something.
sourceFileHolder notNil ifTrue:[
sourceFileHolder addDependent:self.
].
newValue := sourceFileHolder value.
oldValue ~~ newValue ifTrue:[
self update:#value with:newValue from:sourceFileHolder.
].
!
sourceStringHolder
"return/create the 'sourceStringHolder' value holder (automatically generated)"
sourceStringHolder isNil ifTrue:[
sourceStringHolder := ValueHolder new.
sourceStringHolder addDependent:self.
].
^ sourceStringHolder
!
sourceStringHolder:something
"set the 'sourceStringHolder' value holder (automatically generated)"
|oldValue newValue|
sourceStringHolder notNil ifTrue:[
oldValue := sourceStringHolder value.
sourceStringHolder removeDependent:self.
].
sourceStringHolder := something.
sourceStringHolder notNil ifTrue:[
sourceStringHolder addDependent:self.
].
newValue := sourceStringHolder value.
oldValue ~~ newValue ifTrue:[
self update:#value with:newValue from:sourceStringHolder.
].
!
sourceView
sourceView isNil ifTrue:[
sourceView := Tools::CodeView2 new.
sourceView font: self textFont.
sourceView compilerClass: (VDBEvaluator new setDebugger: debugger).
sourceView readOnly: true.
sourceView services: #()
].
^ sourceView
"Created: / 21-09-2014 / 01:42:25 / Jan Vrany <jan.vrany@fit.cvut.cz>"
"Modified: / 20-08-2018 / 11:03:09 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !
!VDBSourceApplication methodsFor:'change & update'!
update:aspect with:param from:sender
"Invoked when an object that I depend upon sends a change notification."
sender == frameHolder ifTrue:[
self updateSourceFile.
^ self.
].
sender == sourceFileHolder ifTrue:[
self updateSourceString.
^ self.
].
super update:aspect with:param from:sender
"Modified: / 02-10-2018 / 10:50:19 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!
updateCurrentLine
| frame file |
frame := frameHolder value.
file := sourceFileHolder value.
(frame notNil and:[file notNil]) ifTrue:[
| line |
line := frame line.
line notNil ifTrue:[
sourceView selectLine:line.
sourceView makeSelectionVisible.
^ self.
]
].
sourceView unselect
"Created: / 02-10-2018 / 11:03:17 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!
updateSourceFile
| frame |
frame := frameHolder value.
frame notNil ifTrue:[
| file |
file := frame file.
file notNil ifTrue:[ file := file asFilename ].
file notNil ifTrue:[
self sourceFileHolder value: file.
] ifFalse:[
"/ If file is nil, this means that it is either unknown (no
"/ debug info) or it cannot be resolved. If the latter, a
"/ help text is shown, see #updateSourceString.
"/
"/ Therefore, here we force an update to make sure that
"/ help text is regenerated.
self sourceFileHolder
setValue: file;
changed: #value
]
].
"Created: / 01-02-2018 / 15:16:24 / Jan Vrany <jan.vrany@fit.cvut.cz>"
"Modified: / 16-01-2019 / 23:55:47 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!
updateSourceString
| source file |
source := nil.
file := sourceFileHolder value.
(file notNil and:[file exists]) ifTrue:[
source := file contents asString.
] ifFalse:[
"/ We have no source. As a courtesy to the user, display some info
"/ on what's the problem and
| frame |
frame := self frameHolder value.
source := Text streamContents:[ :info |
| frameFile frameFullname |
info emphasis: #color -> (UserPreferences current codeViewTheme ? UserPreferences current) commentColor.
info nextPutAll: '//' ; cr.
info nextPutAll: '// '; nextPutAll: (resources string: 'No source available :-('); cr.
info nextPutAll: '//' ; cr.
frameFile := frame propertyAt: #file.
frameFullname := frame propertyAt: #fullname.
(frameFile isNil and:[ frameFullname notNil ]) ifTrue:[
info nextPutAll: '// '; nextPutLine: (resources string: 'Source file reference missing (no debug info?)').
] ifFalse:[
info nextPutAll: '// '; nextPutLine: (resources string: 'Source file cannot be resolved:').
info nextPutAll: '// '; cr.
frameFile notNil ifTrue:[
info nextPutAll: '// '; nextPutLine: frameFile.
].
frameFullname notNil ifTrue:[
info nextPutAll: '// '; nextPutLine: frameFullname.
].
info nextPutAll: '// '; cr.
info nextPutAll: '// '; nextPutLine: (resources string: 'Configured source directories:').
debugger directories do:[:each |
info nextPutAll: '// '; nextPutLine: each.
].
info nextPutAll: '// '; cr.
info nextPutAll: '// '; nextPutLine: (resources string: 'See also:').
info nextPutAll: '// [1]: https://sourceware.org/gdb/onlinedocs/gdb/Source-Path.html'.
].
]
].
self sourceStringHolder value:source.
self updateCurrentLine.
^ self.
"Modified: / 07-10-2018 / 20:47:42 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !
!VDBSourceApplication methodsFor:'change & update-delayed'!
delayedUpdateCurrentLine
self updateCurrentLine
"Created: / 02-10-2018 / 11:04:10 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !
!VDBSourceApplication methodsFor:'event handling'!
onStoppedEvent: aGDBStoppedEvent
self enqueueDelayedUpdate: #delayedUpdateCurrentLine
"Created: / 01-02-2018 / 15:23:46 / Jan Vrany <jan.vrany@fit.cvut.cz>"
"Modified: / 02-10-2018 / 11:04:21 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !
!VDBSourceApplication methodsFor:'initialization & release'!
subscribe
"Register for debugger events. To be overrided by subclasses"
debugger announcer
when: GDBStoppedEvent send: #onStoppedEvent: to: self.
sourceView notNil ifTrue:[
sourceView compilerClass setDebugger: debugger.
].
"Created: / 01-02-2018 / 15:18:23 / Jan Vrany <jan.vrany@fit.cvut.cz>"
"Modified: / 21-03-2018 / 22:18:07 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !
!VDBSourceApplication class methodsFor:'documentation'!
version_HG
^ '$Changeset: <not expanded> $'
! !