Helios-Workspace.st 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865
  1. Smalltalk createPackage: 'Helios-Workspace'!
  2. (Smalltalk packageAt: 'Helios-Workspace' ifAbsent: [ self error: 'Package not created: Helios-Workspace' ]) imports: {'codeMirrorLib' -> 'codemirror/lib/codemirror'. 'codemirror/addon/hint/show-hint'. 'codemirror/mode/smalltalk/smalltalk'}!
  3. Object subclass: #HLCodeModel
  4. slots: {#announcer. #environment. #receiver}
  5. package: 'Helios-Workspace'!
  6. !HLCodeModel methodsFor: 'accessing'!
  7. announcer
  8. ^ announcer ifNil: [ announcer := Announcer new ]
  9. !
  10. environment
  11. ^ environment ifNil: [ HLManager current environment ]
  12. !
  13. environment: anEnvironment
  14. environment := anEnvironment
  15. !
  16. receiver
  17. ^ receiver ifNil: [ receiver := self defaultReceiver ]
  18. !
  19. receiver: anObject
  20. receiver := anObject
  21. ! !
  22. !HLCodeModel methodsFor: 'actions'!
  23. browse: anObject
  24. anObject browse
  25. !
  26. doIt: aString
  27. "Evaluate aString in the receiver's `environment`.
  28. Note: Catch any error and handle it manually, bypassing
  29. boot.js behavior to avoid the browser default action on
  30. ctrl+d/ctrl+p.
  31. See https://lolg.it/amber/amber/issues/882"
  32. ^ [ self environment evaluate: aString for: self receiver ]
  33. tryCatch: [ :e |
  34. ErrorHandler handleError: e.
  35. nil ]
  36. !
  37. inspect: anObject
  38. self environment inspect: anObject
  39. ! !
  40. !HLCodeModel methodsFor: 'defaults'!
  41. defaultReceiver
  42. ^ self environment doItReceiver
  43. ! !
  44. !HLCodeModel class methodsFor: 'actions'!
  45. on: anEnvironment
  46. ^ self new
  47. environment: anEnvironment;
  48. yourself
  49. ! !
  50. HLWidget subclass: #HLCodeWidget
  51. slots: {#model. #wrapper. #code. #editor. #state}
  52. package: 'Helios-Workspace'!
  53. !HLCodeWidget methodsFor: 'accessing'!
  54. announcer
  55. ^ self model announcer
  56. !
  57. contents
  58. ^ editor getValue
  59. !
  60. contents: aString
  61. editor setValue: aString.
  62. state ifNotNil: [ self updateState ]
  63. !
  64. currentLine
  65. ^editor getLine: (editor getCursor line)
  66. !
  67. currentLineOrSelection
  68. ^editor somethingSelected
  69. ifFalse: [ self currentLine ]
  70. ifTrue: [ self selection ]
  71. !
  72. editorOptions
  73. ^ #{
  74. 'theme' -> ('helios.editorTheme' settingValueIfAbsent: 'default').
  75. 'mode' -> 'text/x-stsrc'.
  76. 'inputStyle' -> 'contenteditable'.
  77. 'lineNumbers' -> true.
  78. 'enterMode' -> 'flat'.
  79. 'indentWithTabs' -> true.
  80. 'indentUnit' -> 4.
  81. 'matchBrackets' -> true.
  82. 'electricChars' -> false.
  83. 'keyMap' -> 'Amber'.
  84. 'extraKeys' -> (HashedCollection with: ('helios.completionKey' settingValueIfAbsent: 'Shift-Space') -> 'autocomplete')
  85. }
  86. !
  87. model
  88. ^ model ifNil: [ model := HLCodeModel new ]
  89. !
  90. model: aModel
  91. model := aModel
  92. !
  93. receiver
  94. ^ self model receiver
  95. !
  96. receiver: anObject
  97. self model receiver: anObject
  98. !
  99. selection
  100. ^editor getSelection
  101. !
  102. selectionEnd
  103. ^ code asDomNode selectionEnd
  104. !
  105. selectionEnd: anInteger
  106. code asDomNode selectionEnd: anInteger
  107. !
  108. selectionStart
  109. ^ code asDomNode selectionStart
  110. !
  111. selectionStart: anInteger
  112. code asDomNode selectionStart: anInteger
  113. ! !
  114. !HLCodeWidget methodsFor: 'actions'!
  115. browseIt
  116. | result |
  117. result := [ self doIt ] on: Error do: [ :exception |
  118. ^ ErrorHandler handleError: exception ].
  119. self model browse: result
  120. !
  121. clear
  122. self contents: ''
  123. !
  124. configureEditor
  125. self editor at: 'amberCodeWidget' put: self.
  126. self editor on: 'change' do: [ self onChange ].
  127. self wrapper asJQuery on: 'mousedown' in: '.CodeMirror pre' do: [ :event | | position node |
  128. (event at: 'ctrlKey') ifTrue: [
  129. position := self editor coordsChar: #{
  130. 'left' -> event clientX.
  131. 'top' -> event clientY
  132. }.
  133. self onCtrlClickAt: (position line @ position ch) + 1.
  134. event preventDefault ] ]
  135. !
  136. doIt
  137. | result |
  138. result := self model doIt: self currentLineOrSelection.
  139. self model announcer announce: (HLDoItExecuted on: model).
  140. ^ result
  141. !
  142. editor
  143. ^ editor
  144. !
  145. focus
  146. editor focus
  147. !
  148. inspectIt
  149. self model inspect: self doIt
  150. !
  151. navigateTo: aString
  152. Finder findString: aString
  153. !
  154. navigateToReference: aString
  155. (HLReferences openAsTab)
  156. search: aString
  157. !
  158. print: aString
  159. | start stop currentLine |
  160. currentLine := (editor getCursor: false) line.
  161. start := HashedCollection new.
  162. start at: 'line' put: currentLine.
  163. start at: 'ch' put: (editor getCursor: false) ch.
  164. (editor getSelection) ifEmpty: [
  165. "select current line if selection is empty"
  166. start at: 'ch' put: (editor getLine: currentLine) size.
  167. editor setSelection: #{'line' -> currentLine. 'ch' -> 0} end: start.
  168. ].
  169. stop := HashedCollection new.
  170. stop at: 'line' put: currentLine.
  171. stop at: 'ch' put: ((start at: 'ch') + aString size + 2).
  172. editor replaceSelection: (editor getSelection, ' ', aString, ' ').
  173. editor setCursor: (editor getCursor: true).
  174. editor setSelection: stop end: start
  175. !
  176. printIt
  177. self print: self doIt printString
  178. !
  179. saveIt
  180. "I do not do anything"
  181. !
  182. setEditorOn: aTextarea
  183. editor := codeMirrorLib provided fromTextArea: aTextarea options: self editorOptions
  184. ! !
  185. !HLCodeWidget methodsFor: 'hints'!
  186. messageHintFor: anEditor token: aToken
  187. ^ (Smalltalk core allSelectors asArray
  188. select: [ :each | each includesSubString: aToken string ])
  189. reject: [ :each | each = aToken string ]
  190. !
  191. variableHintFor: anEditor token: aToken
  192. | variables classNames pseudoVariables |
  193. variables := (anEditor display wrapper asJQuery find: 'span.cm-variable') get
  194. collect: [ :each | each asJQuery html ].
  195. classNames := Smalltalk classes collect: [ :each | each name ].
  196. pseudoVariables := Smalltalk pseudoVariableNames.
  197. ^ ((variables, classNames, pseudoVariables) asSet asArray sort
  198. select: [ :each | each includesSubString: aToken string ])
  199. reject: [ :each | each = aToken string ]
  200. ! !
  201. !HLCodeWidget methodsFor: 'reactions'!
  202. onChange
  203. self updateState
  204. !
  205. onCtrlClickAt: aPoint
  206. | ast node |
  207. ast := [ Smalltalk parse: self editor getValue ]
  208. on: Error
  209. do: [ :error | ^ self ].
  210. node := ast
  211. navigationNodeAt: aPoint
  212. ifAbsent: [ ^ nil ].
  213. self navigateTo: node navigationLink
  214. !
  215. onInspectIt
  216. self inspectIt
  217. !
  218. onPrintIt
  219. self printIt
  220. !
  221. onSaveIt
  222. "I do not do anything"
  223. ! !
  224. !HLCodeWidget methodsFor: 'rendering'!
  225. renderButtonsOn: html
  226. html button
  227. class: 'button';
  228. with: 'DoIt';
  229. onClick: [ self doIt ].
  230. html button
  231. class: 'button';
  232. with: 'PrintIt';
  233. onClick: [ self printIt ].
  234. html button
  235. class: 'button';
  236. with: 'InspectIt';
  237. onClick: [ self inspectIt ].
  238. html button
  239. class: 'button';
  240. with: 'BrowseIt';
  241. onClick: [ self browseIt ]
  242. !
  243. renderContentOn: html
  244. html div class: 'editor'; with: [
  245. code := html textarea ].
  246. state := html div class: 'state'.
  247. html div
  248. class: 'buttons_bar';
  249. with: [ self renderButtonsOn: html ].
  250. self
  251. setEditorOn: code asDomNode;
  252. configureEditor;
  253. updateState
  254. ! !
  255. !HLCodeWidget methodsFor: 'testing'!
  256. canHaveFocus
  257. ^ true
  258. !
  259. hasFocus
  260. ^ code asJQuery is: ':active'
  261. !
  262. hasModification
  263. ^ false
  264. ! !
  265. !HLCodeWidget methodsFor: 'updating'!
  266. updateState
  267. self hasModification
  268. ifTrue: [ state asJQuery addClass: 'modified' ]
  269. ifFalse: [ state asJQuery removeClass: 'modified' ]
  270. ! !
  271. !HLCodeWidget class methodsFor: 'accessing'!
  272. keyMap
  273. ^ HLManager current keyBinder systemIsMac
  274. ifTrue: [ self macKeyMap ]
  275. ifFalse: [ self pcKeyMap ]
  276. !
  277. macKeyMap
  278. ^ #{
  279. 'Alt-Backspace' -> 'delWordBefore'.
  280. 'Alt-Delete' -> 'delWordAfter'.
  281. 'Alt-Left' -> 'goWordLeft'.
  282. 'Alt-Right' -> 'goWordRight'.
  283. 'Cmd-A' -> 'selectAll'.
  284. 'Cmd-Alt-F' -> 'replace'.
  285. 'Cmd-D' -> 'doIt'.
  286. 'Cmd-B' -> 'browseIt'.
  287. 'Cmd-Down' -> 'goDocEnd'.
  288. 'Cmd-End' -> 'goDocEnd'.
  289. 'Cmd-F' -> 'find'.
  290. 'Cmd-G' -> 'findNext'.
  291. 'Cmd-I' -> 'inspectIt'.
  292. 'Cmd-Left' -> 'goLineStart'.
  293. 'Cmd-P' -> 'printIt'.
  294. 'Cmd-Right' -> 'goLineEnd'.
  295. 'Cmd-S' -> 'saveIt'.
  296. 'Cmd-Up' -> 'goDocStart'.
  297. 'Cmd-Y' -> 'redo'.
  298. 'Cmd-Z' -> 'undo'.
  299. 'Cmd-[' -> 'indentLess'.
  300. 'Cmd-]' -> 'indentMore'.
  301. 'Ctrl-Alt-Backspace' -> 'delWordAfter'.
  302. 'Shift-Cmd-Alt-F' -> 'replaceAll'.
  303. 'Shift-Cmd-G' -> 'findPrev'.
  304. 'Shift-Cmd-Z' -> 'redo'.
  305. 'fallthrough' -> { 'basic'. 'emacsy' }
  306. }
  307. !
  308. pcKeyMap
  309. ^ #{
  310. 'Alt-Left' -> 'goLineStart'.
  311. 'Alt-Right' -> 'goLineEnd'.
  312. 'Alt-Up' -> 'goDocStart'.
  313. 'Ctrl-A' -> 'selectAll'.
  314. 'Ctrl-Backspace' -> 'delWordBefore'.
  315. 'Ctrl-D' -> 'doIt'.
  316. 'Ctrl-B' -> 'browseIt'.
  317. 'Ctrl-Delete' -> 'delWordAfter'.
  318. 'Ctrl-Down' -> 'goDocEnd'.
  319. 'Ctrl-End' -> 'goDocEnd'.
  320. 'Ctrl-F' -> 'find'.
  321. 'Ctrl-G' -> 'findNext'.
  322. 'Ctrl-I' -> 'inspectIt'.
  323. 'Ctrl-Home' -> 'goDocStart'.
  324. 'Ctrl-Left' -> 'goWordLeft'.
  325. 'Ctrl-P' -> 'printIt'.
  326. 'Ctrl-Right' -> 'goWordRight'.
  327. 'Ctrl-S' -> 'saveIt'.
  328. 'Ctrl-Y' -> 'redo'.
  329. 'Ctrl-Z' -> 'undo'.
  330. 'Ctrl-[' -> 'indentLess'.
  331. 'Ctrl-]' -> 'indentMore'.
  332. 'Shift-Ctrl-F' -> 'replace'.
  333. 'Shift-Ctrl-G' -> 'findPrev'.
  334. 'Shift-Ctrl-R' -> 'replaceAll'.
  335. 'Shift-Ctrl-Z' -> 'redo'.
  336. 'fallthrough' -> #('basic')
  337. }
  338. ! !
  339. !HLCodeWidget class methodsFor: 'hints'!
  340. hintFor: anEditor options: options
  341. | cursor token completions |
  342. cursor := anEditor getCursor.
  343. token := anEditor getTokenAt: cursor.
  344. token at: 'state' put: ((codeMirrorLib basicAt: 'innerMode')
  345. value: anEditor getMode value: (token at: 'state')) state.
  346. completions := token type = 'variable'
  347. ifTrue: [ HLCodeWidget variableHintFor: anEditor token: token ]
  348. ifFalse: [ HLCodeWidget messageHintFor: anEditor token: token ].
  349. ^ #{
  350. 'list' -> completions.
  351. 'from' -> ((codeMirrorLib basicAt: 'Pos') value: cursor line value: token end).
  352. 'to' -> ((codeMirrorLib basicAt: 'Pos') value: cursor line value: token start)
  353. }
  354. !
  355. messageHintFor: anEditor token: aToken
  356. ^ (anEditor at: 'amberCodeWidget')
  357. messageHintFor: anEditor token: aToken
  358. !
  359. variableHintFor: anEditor token: aToken
  360. ^ (anEditor at: 'amberCodeWidget')
  361. variableHintFor: anEditor token: aToken
  362. ! !
  363. !HLCodeWidget class methodsFor: 'initialization'!
  364. initialize
  365. super initialize.
  366. self
  367. setupCodeMirror;
  368. setupCommands;
  369. setupKeyMaps.
  370. !
  371. setupCodeMirror
  372. <inlineJS: '
  373. codeMirrorLib.keyMap["default"].fallthrough = ["basic"];
  374. codeMirrorLib.commands.autocomplete = function(cm) {
  375. codeMirrorLib.showHint(cm, $self._hintFor_options_.bind($self));
  376. }
  377. '>
  378. !
  379. setupCommands
  380. (codeMirrorLib basicAt: 'commands')
  381. at: 'doIt' put: [ :cm | cm amberCodeWidget doIt ];
  382. at: 'inspectIt' put: [ :cm | cm amberCodeWidget inspectIt ];
  383. at: 'printIt' put: [ :cm | cm amberCodeWidget printIt ];
  384. at: 'saveIt' put: [ :cm | cm amberCodeWidget saveIt ];
  385. at: 'browseIt' put: [ :cm | cm amberCodeWidget browseIt ]
  386. !
  387. setupKeyMaps
  388. <inlineJS: 'codeMirrorLib.keyMap["Amber"] = $self._keyMap()'>
  389. ! !
  390. HLCodeWidget subclass: #HLNavigationCodeWidget
  391. slots: {#methodContents}
  392. package: 'Helios-Workspace'!
  393. !HLNavigationCodeWidget methodsFor: 'accessing'!
  394. configureEditor
  395. super configureEditor.
  396. self contents: self methodContents
  397. !
  398. contents: aString
  399. self methodContents: aString.
  400. super contents: aString
  401. !
  402. methodContents
  403. ^ methodContents ifNil: [ '' ]
  404. !
  405. methodContents: aString
  406. ^ methodContents := aString
  407. !
  408. previous
  409. "for browser lists widget"
  410. !
  411. previous: aWidget
  412. "for browser lists widget"
  413. ! !
  414. !HLNavigationCodeWidget methodsFor: 'testing'!
  415. hasModification
  416. ^ (self methodContents = self contents) not
  417. ! !
  418. !HLNavigationCodeWidget class methodsFor: 'instance creation'!
  419. on: aBrowserModel
  420. ^ self new
  421. browserModel: aBrowserModel;
  422. yourself
  423. ! !
  424. !HLNavigationCodeWidget class methodsFor: 'testing'!
  425. canBeOpenAsTab
  426. ^ false
  427. ! !
  428. HLNavigationCodeWidget subclass: #HLBrowserCodeWidget
  429. slots: {#browserModel}
  430. package: 'Helios-Workspace'!
  431. !HLBrowserCodeWidget methodsFor: 'accessing'!
  432. browserModel
  433. ^ browserModel
  434. !
  435. browserModel: aBrowserModel
  436. browserModel := aBrowserModel.
  437. self
  438. observeSystem;
  439. observeBrowserModel
  440. ! !
  441. !HLBrowserCodeWidget methodsFor: 'actions'!
  442. observeBrowserModel
  443. self browserModel announcer
  444. on: HLSaveSourceCode
  445. send: #onSaveIt
  446. to: self;
  447. on: HLShowInstanceToggled
  448. send: #onShowInstanceToggled
  449. to: self;
  450. on: HLSourceCodeSaved
  451. send: #onSourceCodeSaved
  452. to: self;
  453. on: HLAboutToChange
  454. send: #onBrowserAboutToChange:
  455. to: self;
  456. on: HLParseErrorRaised
  457. send: #onParseError:
  458. to: self;
  459. on: HLCompileErrorRaised
  460. send: #onCompileError:
  461. to: self;
  462. on: HLUnknownVariableErrorRaised
  463. send: #onUnknownVariableError:
  464. to: self;
  465. on: HLInstVarAdded
  466. send: #onInstVarAdded
  467. to: self;
  468. on: HLMethodSelected
  469. send: #onMethodSelected:
  470. to: self;
  471. on: HLClassSelected
  472. send: #onClassSelected:
  473. to: self;
  474. on: HLPackageSelected
  475. send: #onPackageSelected:
  476. to: self;
  477. on: HLProtocolSelected
  478. send: #onProtocolSelected:
  479. to: self;
  480. on: HLSourceCodeFocusRequested
  481. send: #onSourceCodeFocusRequested
  482. to: self;
  483. on: HLShowTemplate
  484. send: #onShowTemplate:
  485. to: self
  486. !
  487. observeSystem
  488. self browserModel systemAnnouncer
  489. on: MethodModified
  490. send: #onMethodModified:
  491. to: self
  492. !
  493. refresh
  494. self hasModification ifTrue: [ ^ self ].
  495. self hasFocus ifTrue: [ ^ self ].
  496. self contents: self browserModel selectedMethod source
  497. !
  498. renderButtonsOn: html
  499. html button
  500. class: 'button';
  501. with: 'SaveIt';
  502. onClick: [ self saveIt ].
  503. super renderButtonsOn: html
  504. !
  505. saveIt
  506. self browserModel saveSourceCode
  507. !
  508. unregister
  509. super unregsiter.
  510. self browserModel announcer unsubscribe: self.
  511. self browserModel systemAnnouncer unsubscribe: self
  512. ! !
  513. !HLBrowserCodeWidget methodsFor: 'reactions'!
  514. onBrowserAboutToChange: anAnnouncement
  515. | block |
  516. block := anAnnouncement actionBlock.
  517. self hasModification
  518. ifTrue: [
  519. self
  520. confirm: 'Changes have not been saved. Do you want to discard these changes?'
  521. ifTrue: [
  522. "Don't ask twice"
  523. self methodContents: self contents.
  524. block value ].
  525. HLChangeForbidden signal ]
  526. !
  527. onClassSelected: anAnnouncement
  528. | class |
  529. class:= anAnnouncement item.
  530. class ifNil: [ ^ self contents: '' ].
  531. self contents: class definition
  532. !
  533. onCompileError: anAnnouncement
  534. Terminal alert: anAnnouncement error messageText
  535. !
  536. onInstVarAdded
  537. self browserModel save: self contents
  538. !
  539. onMethodModified: anAnnouncement
  540. | method |
  541. method := anAnnouncement method.
  542. self browserModel selectedClass = method methodClass ifFalse: [ ^ self ].
  543. self browserModel selectedMethod ifNil: [ ^ self ].
  544. self browserModel selectedMethod selector = method selector ifFalse: [ ^ self ].
  545. self refresh
  546. !
  547. onMethodSelected: anAnnouncement
  548. | method |
  549. method := anAnnouncement item.
  550. method ifNil: [ ^ self contents: '' ].
  551. self contents: method source
  552. !
  553. onPackageSelected: anAnnouncement
  554. | package |
  555. package := anAnnouncement item.
  556. package ifNil: [ ^ self contents: '' ].
  557. self contents: package definition
  558. !
  559. onParseError: anAnnouncement
  560. | lineIndex newContents |
  561. lineIndex := 1.
  562. self contents: (String streamContents: [ :stream |
  563. self contents linesDo: [ :each |
  564. lineIndex = anAnnouncement line
  565. ifTrue: [
  566. stream
  567. nextPutAll: (each copyFrom: 1 to: anAnnouncement column);
  568. nextPutAll: '<- ';
  569. nextPutAll: anAnnouncement message;
  570. nextPutAll: ' ';
  571. nextPutAll: (each copyFrom: anAnnouncement column + 1 to: each size) ]
  572. ifFalse: [ stream nextPutAll: each ].
  573. stream nextPutAll: String cr.
  574. lineIndex := lineIndex + 1 ] ])
  575. !
  576. onProtocolSelected: anAnnouncement
  577. self browserModel selectedClass ifNil: [ ^ self contents: '' ].
  578. self contents: self browserModel selectedClass definition
  579. !
  580. onSaveIt
  581. self browserModel save: self contents
  582. !
  583. onShowInstanceToggled
  584. self browserModel selectedClass ifNil: [ ^ self contents: '' ].
  585. self contents: self browserModel selectedClass definition
  586. !
  587. onShowTemplate: anAnnouncement
  588. self contents: anAnnouncement template
  589. !
  590. onSourceCodeFocusRequested
  591. self focus
  592. !
  593. onSourceCodeSaved
  594. self methodContents: self contents.
  595. self updateState
  596. !
  597. onUnknownVariableError: anAnnouncement
  598. | error |
  599. error := anAnnouncement error.
  600. self
  601. confirm: (String streamContents: [ :stream |
  602. stream
  603. nextPutAll: error messageText;
  604. nextPutAll: String cr;
  605. nextPutAll: 'Would you like to define an instance variable?' ])
  606. ifTrue: [
  607. self browserModel addInstVarNamed: error variableName ]
  608. ! !
  609. !HLBrowserCodeWidget class methodsFor: 'instance creation'!
  610. on: aBrowserModel
  611. ^ self new
  612. browserModel: aBrowserModel;
  613. yourself
  614. ! !
  615. !HLBrowserCodeWidget class methodsFor: 'testing'!
  616. canBeOpenAsTab
  617. ^ false
  618. ! !
  619. HLWidget subclass: #HLWorkspace
  620. slots: {#codeWidget. #transcript}
  621. package: 'Helios-Workspace'!
  622. !HLWorkspace methodsFor: 'accessing'!
  623. codeWidget
  624. ^ codeWidget ifNil: [ codeWidget := HLCodeWidget new ]
  625. !
  626. transcript
  627. ^ transcript ifNil: [ transcript := HLTranscript new ]
  628. ! !
  629. !HLWorkspace methodsFor: 'actions'!
  630. focus
  631. ^ self codeWidget focus
  632. !
  633. unregister
  634. super unregister.
  635. self transcript unregister
  636. ! !
  637. !HLWorkspace methodsFor: 'rendering'!
  638. renderContentOn: html
  639. html with: (HLContainer with: (HLHorizontalSplitter
  640. with: self codeWidget
  641. with: [ :canvas | self renderTranscriptOn: canvas ]))
  642. !
  643. renderTranscriptOn: html
  644. html div
  645. class: 'transcript-container';
  646. with: [
  647. html div
  648. class: 'list-label';
  649. with: 'Transcript'.
  650. self transcript renderOn: html ]
  651. ! !
  652. !HLWorkspace methodsFor: 'testing'!
  653. canHaveFocus
  654. ^ true
  655. ! !
  656. !HLWorkspace class methodsFor: 'accessing'!
  657. tabClass
  658. ^ 'workspace'
  659. !
  660. tabLabel
  661. ^ 'Workspace'
  662. !
  663. tabPriority
  664. ^ 10
  665. ! !
  666. !HLWorkspace class methodsFor: 'testing'!
  667. canBeOpenAsTab
  668. ^ true
  669. ! !