1
0

Helios-Workspace.st 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404
  1. Smalltalk current createPackage: 'Helios-Workspace'!
  2. Object subclass: #HLCodeModel
  3. instanceVariableNames: 'announcer environment receiver'
  4. package: 'Helios-Workspace'!
  5. !HLCodeModel methodsFor: 'accessing'!
  6. announcer
  7. ^ announcer ifNil: [ announcer := Announcer new ]
  8. !
  9. environment
  10. ^ environment ifNil: [ HLManager current environment ]
  11. !
  12. environment: anEnvironment
  13. environment := anEnvironment
  14. !
  15. receiver
  16. ^ receiver ifNil: [ receiver := self defaultReceiver ]
  17. !
  18. receiver: anObject
  19. receiver := anObject
  20. ! !
  21. !HLCodeModel methodsFor: 'actions'!
  22. doIt: someCode
  23. ^ self environment eval: someCode on: self receiver
  24. !
  25. subscribe: aWidget
  26. aWidget subscribeTo: self announcer
  27. ! !
  28. !HLCodeModel methodsFor: 'defaults'!
  29. defaultReceiver
  30. ^ DoIt new
  31. ! !
  32. !HLCodeModel class methodsFor: 'actions'!
  33. on: anEnvironment
  34. ^ self new
  35. environment: anEnvironment;
  36. yourself
  37. ! !
  38. HLWidget subclass: #HLCodeWidget
  39. instanceVariableNames: 'model wrapper code editor'
  40. package: 'Helios-Workspace'!
  41. !HLCodeWidget methodsFor: 'accessing'!
  42. announcer
  43. ^ self model announcer
  44. !
  45. contents
  46. ^ editor getValue
  47. !
  48. contents: aString
  49. editor setValue: aString
  50. !
  51. currentLine
  52. ^editor getLine: (editor getCursor line)
  53. !
  54. currentLineOrSelection
  55. ^editor somethingSelected
  56. ifFalse: [ self currentLine ]
  57. ifTrue: [ self selection ]
  58. !
  59. model
  60. ^ model ifNil: [
  61. self model: HLCodeModel new.
  62. model ]
  63. !
  64. model: aModel
  65. model := aModel
  66. !
  67. receiver
  68. ^ self model receiver
  69. !
  70. receiver: anObject
  71. self model receiver: anObject
  72. !
  73. selection
  74. ^editor getSelection
  75. !
  76. selectionEnd
  77. ^code element selectionEnd
  78. !
  79. selectionEnd: anInteger
  80. code element selectionEnd: anInteger
  81. !
  82. selectionStart
  83. ^code element selectionStart
  84. !
  85. selectionStart: anInteger
  86. code element selectionStart: anInteger
  87. ! !
  88. !HLCodeWidget methodsFor: 'actions'!
  89. clear
  90. self contents: ''
  91. !
  92. doIt
  93. | result |
  94. self announcer announce: (HLDoItRequested on: model).
  95. result:= model doIt: self currentLineOrSelection.
  96. self announcer announce: (HLDoItExecuted on: model).
  97. ^ result
  98. !
  99. editor
  100. ^editor
  101. !
  102. focus
  103. self editor focus
  104. !
  105. inspectIt
  106. | newInspector |
  107. self announcer announce: (HLInspectItRequested on: model).
  108. newInspector := self makeInspectorOn: self doIt.
  109. newInspector open
  110. !
  111. makeInspectorOn: anObject
  112. ^ HLInspector new
  113. inspect: anObject;
  114. yourself
  115. !
  116. observeWrapper
  117. wrapper onKeyDown: [ :e | self onKeyDown: e ]
  118. !
  119. print: aString
  120. | start stop currentLine |
  121. currentLine := (editor getCursor: false) line.
  122. start := HashedCollection new.
  123. start at: 'line' put: currentLine.
  124. start at: 'ch' put: (editor getCursor: false) ch.
  125. (editor getSelection) ifEmpty: [
  126. "select current line if selection is empty"
  127. start at: 'ch' put: (editor getLine: currentLine) size.
  128. editor setSelection: #{'line' -> currentLine. 'ch' -> 0} end: start.
  129. ].
  130. stop := HashedCollection new.
  131. stop at: 'line' put: currentLine.
  132. stop at: 'ch' put: ((start at: 'ch') + aString size + 2).
  133. editor replaceSelection: (editor getSelection, ' ', aString, ' ').
  134. editor setCursor: (editor getCursor: true).
  135. editor setSelection: stop end: start
  136. !
  137. printIt
  138. | result |
  139. result:= self doIt.
  140. self announcer announce: (HLPrintItRequested on: model).
  141. self print: result printString.
  142. self focus.
  143. !
  144. setEditorOn: aTextarea
  145. <self['@editor'] = CodeMirror.fromTextArea(aTextarea, {
  146. theme: 'amber',
  147. lineNumbers: true,
  148. enterMode: 'flat',
  149. indentWithTabs: true,
  150. indentUnit: 4,
  151. matchBrackets: true,
  152. electricChars: false
  153. })>
  154. ! !
  155. !HLCodeWidget methodsFor: 'reactions'!
  156. onDoIt
  157. self doIt
  158. !
  159. onInspectIt
  160. self inspectIt
  161. !
  162. onKeyDown: anEvent
  163. <if(anEvent.ctrlKey) {
  164. if(anEvent.keyCode === 80) { //ctrl+p
  165. self._onPrintIt();
  166. anEvent.preventDefault();
  167. return false;
  168. }
  169. if(anEvent.keyCode === 68) { //ctrl+d
  170. self._onDoIt();
  171. anEvent.preventDefault();
  172. return false;
  173. }
  174. if(anEvent.keyCode === 73) { //ctrl+i
  175. self._onInspectIt();
  176. anEvent.preventDefault();
  177. return false;
  178. }
  179. }>
  180. !
  181. onPrintIt
  182. self printIt
  183. ! !
  184. !HLCodeWidget methodsFor: 'rendering'!
  185. renderContentOn: html
  186. code := html textarea.
  187. self setEditorOn: code element.
  188. self observeWrapper
  189. ! !
  190. !HLCodeWidget class methodsFor: 'initialization'!
  191. initialize
  192. super initialize.
  193. self setupCodeMirror
  194. !
  195. setupCodeMirror
  196. < CodeMirror.keyMap.default.fallthrough = ["basic"] >
  197. ! !
  198. HLCodeWidget subclass: #HLSourceCodeWidget
  199. instanceVariableNames: ''
  200. package: 'Helios-Workspace'!
  201. !HLSourceCodeWidget methodsFor: 'reactions'!
  202. onKeyDown: anEvent
  203. (super onKeyDown: anEvent) ifFalse: [ ^ false ].
  204. anEvent ctrlKey ifTrue: [
  205. anEvent keyCode = 83 ifTrue: [
  206. self onSave.
  207. anEvent preventDefault.
  208. ^ false ] ]
  209. !
  210. onSave
  211. ! !
  212. HLWidget subclass: #HLWorkspace
  213. instanceVariableNames: 'model codeWidget'
  214. package: 'Helios-Workspace'!
  215. !HLWorkspace methodsFor: 'accessing'!
  216. codeWidget
  217. ^ codeWidget ifNil: [
  218. codeWidget := HLCodeWidget new
  219. model: self model code;
  220. yourself ]
  221. !
  222. model
  223. ^ model ifNil: [
  224. self model: HLWorkspaceModel new.
  225. model ]
  226. !
  227. model: aModel
  228. model := aModel.
  229. self codeWidget model: aModel code.
  230. self observeCodeWidget.
  231. ! !
  232. !HLWorkspace methodsFor: 'actions'!
  233. observeCodeWidget
  234. ! !
  235. !HLWorkspace methodsFor: 'reactions'!
  236. onDoIt
  237. !
  238. onInspectIt
  239. !
  240. onPrintIt
  241. ! !
  242. !HLWorkspace methodsFor: 'rendering'!
  243. renderContentOn: html
  244. html with: self codeWidget
  245. ! !
  246. !HLWorkspace class methodsFor: 'accessing'!
  247. tabLabel
  248. ^ 'Workspace'
  249. !
  250. tabPriority
  251. ^ 10
  252. ! !
  253. !HLWorkspace class methodsFor: 'testing'!
  254. canBeOpenAsTab
  255. ^ true
  256. ! !
  257. Object subclass: #HLWorkspaceModel
  258. instanceVariableNames: 'announcer environment code'
  259. package: 'Helios-Workspace'!
  260. !HLWorkspaceModel methodsFor: 'accessing'!
  261. announcer
  262. ^ announcer ifNil: [ announcer := Announcer new ]
  263. !
  264. code
  265. "Answers the code model working for this workspace model"
  266. ^ code ifNil:[ HLCodeModel on: self environment ]
  267. !
  268. environment
  269. ^ environment ifNil: [ HLManager current environment ]
  270. !
  271. environment: anEnvironment
  272. environment := anEnvironment
  273. ! !
  274. !HLWorkspaceModel methodsFor: 'reactions'!
  275. onKeyDown: anEvent
  276. <if(anEvent.ctrlKey) {
  277. if(anEvent.keyCode === 80) { //ctrl+p
  278. self._printIt();
  279. anEvent.preventDefault();
  280. return false;
  281. }
  282. if(anEvent.keyCode === 68) { //ctrl+d
  283. self._doIt();
  284. anEvent.preventDefault();
  285. return false;
  286. }
  287. if(anEvent.keyCode === 73) { //ctrl+i
  288. self._inspectIt();
  289. anEvent.preventDefault();
  290. return false;
  291. }
  292. }>
  293. ! !
  294. !HLWorkspaceModel class methodsFor: 'actions'!
  295. on: anEnvironment
  296. ^ self new
  297. environment: anEnvironment;
  298. yourself
  299. ! !