Helios-Workspace.st 6.9 KB

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