The Meta-Environment API
00001 #ifndef __EDITING__ 00002 #define __EDITING__ 00003 00004 #include <editor-manager.idef> 00005 #include <editor-plugin.idef> 00006 #include <structure-editor.idef> 00007 00008 #include <module-manager.tb> 00009 #include <io-utils.tb> 00010 #include <config-utils.tb> 00011 #include <editor-error-display.tb> 00012 #include <text-utils.tb> 00013 00014 /** 00015 * Starts an editor without a language for structure editing. 00016 */ 00017 process EditAnonymousLocation(Path: str, Area: term) is 00018 let 00019 AlreadyExists: bool, 00020 EditorType: term, 00021 Offset: int, 00022 Line: int, 00023 Column: int, 00024 Sid: session-id 00025 in 00026 Edit(Path, Sid?) 00027 . EditorType := quote(anonymous-editor) 00028 . EditText(Sid, EditorType, AlreadyExists?) 00029 . 00030 if equal(AlreadyExists, false) then 00031 snd-msg(te-set-selection(Sid, Area)) 00032 . 00033 ( 00034 MenuSelected(Sid, EditorType) 00035 + 00036 rec-msg(te-mouse-click-at-offset(Sid, Offset?)) 00037 + 00038 rec-msg(te-mouse-click-at-line-column(Sid, Line?, Column?)) 00039 + 00040 rec-msg(te-contents-changed(Sid)) 00041 ) 00042 * 00043 EditorDisconnected(Sid) 00044 . DeleteSession(Sid) 00045 else 00046 snd-msg(te-set-selection(Sid, Area)) 00047 fi 00048 endlet 00049 00050 process DisplayMessage(EditorId : session-id, Message : str) is 00051 snd-msg(te-display-message(EditorId, Message)) 00052 00053 process GetModuleId(Sid: session-id, ModuleId: module-id?) is 00054 snd-msg(em-get-moduleid(Sid)) 00055 . 00056 ( 00057 rec-msg(em-moduleid(Sid, ModuleId?)) 00058 + 00059 rec-msg(em-no-such-session(Sid)) 00060 . printf("FIX ME: PushActiveModule: No such session\n") 00061 . ModuleId := UNDEFINED 00062 + 00063 rec-msg(em-session-not-bound(Sid)) 00064 . printf("FIX ME: PushActiveModule: Session not bound\n") 00065 . ModuleId := UNDEFINED 00066 ) 00067 00068 process GetFocus(Sid: session-id, Tree: term?) is 00069 let 00070 Registered: bool 00071 in 00072 IsStructureEditorRegistered(Sid, Registered?) 00073 . 00074 if equal(Registered, true) then 00075 snd-msg(se-get-cursor(Sid)) 00076 . 00077 ( 00078 rec-msg(se-cursor(Sid, Tree?)) 00079 + 00080 rec-msg(se-no-cursor(Sid)) 00081 . Tree := UNDEFINED 00082 ) 00083 else 00084 Tree := UNDEFINED 00085 fi 00086 endlet 00087 00088 process ReplaceFocus(Sid: session-id, Tree: term) is 00089 let 00090 Text: str, 00091 Filename: str, 00092 Error: str 00093 in 00094 snd-msg(unparse(Tree)) 00095 . rec-msg(unparsed-text(Text?)) 00096 . snd-msg(te-set-contents(Sid, Text)) 00097 . UpdateTextRepository(Sid) 00098 . SE-UpdateTree(Sid, Tree) 00099 . snd-msg(te-clear-focus(Sid)) 00100 endlet 00101 00102 process GetPath(Sid: session-id, Path: str?) is 00103 snd-msg(em-get-path(Sid)) 00104 . rec-msg(em-path(Sid, Path?)) 00105 00106 process Edit(Path: str, Sid: session-id?) is 00107 let 00108 TooBig: bool 00109 in 00110 CheckFileSize(Path, TooBig?) 00111 . 00112 if equal(TooBig, true) then 00113 Sid := UNDEFINED 00114 else 00115 snd-msg(em-create-session(Path)) 00116 . rec-msg(em-session(Path, Sid?)) 00117 fi 00118 endlet 00119 00120 process IsStructureEditorRegistered(Sid: session-id, Registered: bool?) is 00121 snd-msg(em-is-editor-registered(Sid, structure)) 00122 . 00123 ( 00124 rec-msg(em-editor-registered(Sid, structure)) 00125 . Registered := true 00126 + 00127 rec-msg(em-editor-not-registered(Sid, structure)) 00128 . Registered := false 00129 ) 00130 00131 process IsTextEditorRegistered(Sid: session-id, Registered: bool?) is 00132 snd-msg(em-is-editor-registered(Sid, text)) 00133 . 00134 ( 00135 rec-msg(em-editor-registered(Sid, text)) 00136 . Registered := true 00137 + 00138 rec-msg(em-editor-not-registered(Sid, text)) 00139 . Registered := false 00140 ) 00141 00142 /** 00143 * This is the basic utility for constructing a new editor. Call it 00144 * to start an fresh editor process, or to bring an existing editor 00145 * to the front. 00146 */ 00147 process EditText(Sid: session-id, Type: term, AlreadyExists: bool?) is 00148 let 00149 Path: str, 00150 Categories: list 00151 in 00152 IsTextEditorRegistered(Sid, AlreadyExists?) 00153 . 00154 if equal(AlreadyExists, true) then 00155 snd-msg(te-editor-to-front(Sid)) 00156 else 00157 snd-msg(em-register-editor(Sid, text)) 00158 . GetPath(Sid, Path?) 00159 . snd-msg(te-edit-text(Sid, Path)) 00160 . SetEditActions(Sid, Type) 00161 . snd-msg(get-text-categories) 00162 . rec-msg(text-categories(Categories?)) 00163 . snd-msg(te-register-text-categories(Sid, Categories)) 00164 fi 00165 endlet 00166 00167 process SetEditActions(Sid: session-id, Type: term) is 00168 let 00169 Events: list 00170 in 00171 snd-msg(cm-get-events(Type)) 00172 . rec-msg(cm-events(Events?)) 00173 . snd-msg(te-add-actions(Sid, Events)) 00174 endlet 00175 00176 process SE-UpdateTree(Sid: session-id, Tree: term) is 00177 let 00178 Registered: bool, 00179 Slices: list 00180 in 00181 if not-equal(Tree, UNDEFINED) then 00182 IsStructureEditorRegistered(Sid, Registered?) 00183 . 00184 if equal(Registered, true) then 00185 snd-msg(se-update(Sid, Tree)) 00186 else 00187 snd-msg(em-register-editor(Sid, structure)) 00188 . snd-msg(se-create(Sid, Tree)) 00189 fi 00190 . AddJob("Highlighting") 00191 . snd-msg(se-get-tree-slices(Sid)) 00192 . 00193 ( 00194 rec-msg(se-tree-slices(Sid, Slices?)) 00195 . JobDone("Highlighting") 00196 . snd-msg(te-highlight-slices(Sid, Slices)) 00197 + 00198 rec-msg(se-no-tree-slices(Sid)) 00199 ) 00200 else 00201 tau 00202 fi 00203 endlet 00204 00205 process SynchronizeFocus(Sid: session-id) is 00206 let 00207 Focus: term, 00208 Sortname: str 00209 in 00210 snd-msg(se-get-sort-at-cursor(Sid)) 00211 . 00212 ( 00213 rec-msg(se-sort-at-cursor(Sid, Sortname?)) 00214 . snd-msg(se-get-focus-at-cursor(Sid)) 00215 . rec-msg(se-focus-at-cursor(Sid, Focus?)) 00216 . snd-msg(te-set-focus(Sid, Focus)) 00217 . snd-msg(te-display-message(Sid, Sortname)) 00218 + 00219 rec-msg(se-no-cursor(Sid)) 00220 ) 00221 endlet 00222 00223 process GetFocusSort(Sid: session-id, Sort: str?) is 00224 Sort := "" 00225 . snd-msg(se-get-sort-at-cursor(Sid)) 00226 . 00227 ( 00228 rec-msg(se-sort-at-cursor(Sid, Sort?)) 00229 + 00230 rec-msg(se-no-cursor(Sid)) 00231 ) 00232 00233 process UpdateTextRepository(Sid: session-id) is 00234 let 00235 Contents: str, 00236 ModuleId: module-id, 00237 Path: str 00238 in 00239 snd-msg(te-get-contents(Sid)) 00240 . rec-msg(te-contents(Sid, Contents?)) 00241 . GetPath(Sid, Path?) 00242 . PutCachedValue(TEXT_REPOSITORY, Path, Contents) 00243 endlet 00244 00245 /** 00246 * Default handler that an editor may use in its event loop 00247 * for dealing with menu's 00248 */ 00249 process MenuSelected(Sid: session-id, EditorType: term) is 00250 let 00251 Event: term, 00252 Pid: int 00253 in 00254 rec-msg(te-event(Sid, Event?)) 00255 . create(AsyncMenuSelected(Sid, EditorType, Event), Pid?) 00256 endlet 00257 00258 process AsyncMenuSelected(Sid: session-id, EditorType: term, Event: term) is 00259 let 00260 Action: str, 00261 ModuleId: module-id, 00262 Sort: str 00263 in 00264 snd-msg(em-request-transaction(Sid)) 00265 . 00266 ( 00267 rec-msg(em-no-transaction(Sid)) 00268 + 00269 rec-msg(em-transaction-started(Sid)) 00270 . GetModuleId(Sid, ModuleId?) 00271 . GetFocusSort(Sid, Sort?) 00272 . snd-msg(cm-get-action(EditorType, Sort, Event)) 00273 . rec-msg(cm-action(Action?)) 00274 . UpdateTextRepository(Sid) 00275 . 00276 ( 00277 printf("Warning: process %s was not found\n", Action) 00278 +> 00279 Action(Sid, EditorType, Sort) 00280 +> 00281 Action(Sid) 00282 ) 00283 . snd-msg(em-end-transaction(Sid)) 00284 ) 00285 endlet 00286 00287 /** 00288 * Default handler that an editor may use in its event loop 00289 * for dealing with mouse clicks 00290 */ 00291 process MouseClicked(Sid: session-id) is 00292 let 00293 Column: int, 00294 Line: int, 00295 Offset: int, 00296 Pid: int, 00297 Registered: bool 00298 in 00299 ( 00300 rec-msg(te-mouse-click-at-offset(Sid, Offset?)) 00301 . create(OffsetHandler(Sid, Offset), Pid?) 00302 + 00303 rec-msg(te-mouse-click-at-line-column(Sid, Line?, Column?)) 00304 . create(LineColumnHandler(Sid, Line, Column), Pid?) 00305 ) 00306 . snd-msg(em-request-transaction(Sid)) 00307 . 00308 ( 00309 rec-msg(em-no-transaction(Sid)) 00310 + 00311 rec-msg(em-transaction-started(Sid)) 00312 . IsStructureEditorRegistered(Sid, Registered?) 00313 . 00314 if equal(Registered, true) then 00315 snd-msg(handle-mouse-event(Pid)) 00316 . SynchronizeFocus(Sid) 00317 else 00318 tau 00319 fi 00320 . snd-msg(em-end-transaction(Sid)) 00321 ) 00322 endlet 00323 00324 /** 00325 * Default handler that an editor may use for synchronizing 00326 * with the structure editor 00327 */ 00328 process OffsetHandler(Sid: session-id, Offset: int) is 00329 let 00330 Pid: int 00331 in 00332 Pid := process-id 00333 . rec-msg(handle-mouse-event(Pid)) 00334 . snd-msg(se-set-cursor-at-offset(Sid, Offset)) 00335 endlet 00336 00337 process LineColumnHandler(Sid: session-id, Line: int, Column: int) is 00338 let 00339 Pid: int 00340 in 00341 Pid := process-id 00342 . rec-msg(handle-mouse-event(Pid)) 00343 . snd-msg(se-set-cursor-at-line-column(Sid, Line, Column)) 00344 endlet 00345 00346 process EditorDisconnected(Sid: session-id) is 00347 ( 00348 rec-msg(te-text-editor-disconnected(Sid)) 00349 + 00350 rec-msg(kill-editor(Sid)) 00351 ) 00352 00353 process DeleteTextEditor(Sid: session-id) is 00354 snd-msg(te-kill-text-editor(Sid)) 00355 . snd-msg(em-unregister-editor(Sid, text)) 00356 00357 process DeleteStructureEditor(Sid: session-id) is 00358 let 00359 Registered: bool 00360 in 00361 snd-msg(se-delete(Sid)) 00362 endlet 00363 00364 process DeleteSession(Sid: session-id) is 00365 let 00366 Registered: bool 00367 in 00368 snd-msg(em-request-transaction(Sid)) 00369 . 00370 ( 00371 rec-msg(em-no-transaction(Sid)) 00372 + 00373 rec-msg(em-transaction-started(Sid)) 00374 . IsTextEditorRegistered(Sid, Registered?) 00375 . 00376 if equal(Registered, true) then 00377 DeleteTextEditor(Sid) 00378 else 00379 tau 00380 fi 00381 . IsStructureEditorRegistered(Sid, Registered?) 00382 . 00383 if equal(Registered, true) then 00384 DeleteStructureEditor(Sid) 00385 else 00386 tau 00387 fi 00388 . snd-msg(em-delete-session(Sid)) 00389 . snd-msg(em-end-transaction(Sid)) 00390 ) 00391 endlet 00392 00393 process DeleteSessions(ModuleId: module-id) is 00394 let 00395 Sid: session-id, 00396 Sids: list 00397 in 00398 snd-msg(em-get-sessions-by-moduleid(ModuleId)) 00399 . 00400 ( 00401 rec-msg(em-sessions(ModuleId, Sids?)) 00402 . 00403 ( 00404 if not-equal(Sids, []) then 00405 Sid := first(Sids) 00406 . DeleteSession(Sid) 00407 . Sids := next(Sids) 00408 fi 00409 ) 00410 * 00411 if equal(Sids, []) then 00412 tau 00413 fi 00414 + 00415 rec-msg(em-no-such-session(ModuleId)) 00416 ) 00417 endlet 00418 00419 process GetModuleByPath(Path: str, ModuleId: module-id?) is 00420 let 00421 Sid: session-id 00422 in 00423 GetEditorByPath(Path, Sid?) 00424 . 00425 if not-equal(Sid, UNDEFINED) then 00426 snd-msg(em-get-moduleid(Sid)) 00427 . rec-msg(em-moduleid(Sid, ModuleId?)) 00428 else 00429 ModuleId := UNDEFINED 00430 fi 00431 endlet 00432 00433 process GetEditorByPath(Path: str, Sid: session-id?) is 00434 snd-msg(em-get-session-by-path(Path)) 00435 . 00436 ( 00437 rec-msg(em-session(Path, Sid?)) 00438 + 00439 rec-msg(em-no-such-session(Path)) 00440 . Sid := UNDEFINED 00441 ) 00442 00443 process CheckFileSize(Path: str, TooBig: bool?) is 00444 let 00445 Size: int 00446 in 00447 snd-msg(io-get-file-size(Path)) 00448 . rec-msg(io-file-size(Path, Size?)) 00449 . 00450 if less(Size, 1048576) then 00451 TooBig := false 00452 else 00453 TooBig := true 00454 fi 00455 endlet 00456 00457 process CheckSanity(Path: str, RequestedModuleId: module-id, Valid: bool?) is 00458 let 00459 Available: bool, 00460 CurrentModuleId: module-id 00461 in 00462 GetModuleByPath(Path, CurrentModuleId?) 00463 . 00464 if equal(CurrentModuleId, UNDEFINED) then 00465 Valid := true 00466 else 00467 Valid := equal(CurrentModuleId, RequestedModuleId) 00468 fi 00469 endlet 00470 00471 process MoveCursorLeftAction(EditorId : session-id) is 00472 MoveCursor(EditorId, left) 00473 00474 process MoveCursorRightAction(EditorId : session-id) is 00475 MoveCursor(EditorId, right) 00476 00477 process MoveCursorUpAction(EditorId : session-id) is 00478 MoveCursor(EditorId, up) 00479 00480 process MoveCursorDownAction(EditorId : session-id) is 00481 MoveCursor(EditorId, down) 00482 00483 process MoveCursor(Sid: session-id, Direction: term) is 00484 let 00485 Registered: bool 00486 in 00487 IsStructureEditorRegistered(Sid, Registered?) 00488 . 00489 if equal(Registered, true) then 00490 snd-msg(se-move-cursor(Sid, Direction)) 00491 . SynchronizeFocus(Sid) 00492 else 00493 tau 00494 fi 00495 endlet 00496 00497 /** 00498 * This process is the default function to call when you 00499 * want to start an editor for a location. It uses the 00500 * configuration manager to find out if for certain files 00501 * (based on the extension) a specialized editor process 00502 * has been registered. If not it starts an editor without 00503 * parsing/structure editing capabilities. If an editor 00504 * is already open for that file, it will not create a 00505 * new editor. 00506 */ 00507 process EditLocation(Location: term) is 00508 let 00509 Extension: str, 00510 EditorAction: str, 00511 Filename: str, 00512 Path: str, 00513 Prefix: str, 00514 Sid: session-id, 00515 Area: area 00516 in 00517 snd-msg(get-location-filename(Location)) 00518 . rec-msg(location-filename(Path?)) 00519 . snd-msg(has-location-area(Location)) 00520 . 00521 ( 00522 rec-msg(location-has-area(Location)) 00523 . snd-msg(get-location-area(Location)) 00524 . rec-msg(location-area(Area?)) 00525 + 00526 rec-msg(location-has-no-area(Location)) 00527 . Area := quote(area(0,0,0,0,0,0)) 00528 ) 00529 . snd-msg(em-get-session-by-path(Path)) 00530 . 00531 ( 00532 rec-msg(em-session(Path, Sid?)) 00533 . snd-msg(te-editor-to-front(Sid)) 00534 . snd-msg(te-set-selection(Sid, Area)) 00535 . GoToEditorArea(Sid, Area) 00536 + 00537 rec-msg(em-no-such-session(Path)) 00538 . SplitFilename(Path, Filename?, Prefix?, Extension?) 00539 . snd-msg(cm-get-extension-editor(Extension)) 00540 . 00541 ( 00542 rec-msg(cm-extension-editor(Extension, EditorAction?)) 00543 . 00544 ( 00545 EditAnonymousLocation(Path, Area) 00546 +> 00547 EditorAction(Path, Area) 00548 ) 00549 + 00550 rec-msg(cm-no-extension-editor(Extension)) 00551 . EditAnonymousLocation(Path, Area) 00552 ) 00553 ) 00554 endlet 00555 00556 process ShowOriginAction(EditorId : session-id) is 00557 let 00558 Origin: term 00559 in 00560 GetFocusOrigin(EditorId, Origin?) 00561 . 00562 if equal(Origin, no-origin) then 00563 DisplayMessage(EditorId, "No origin information available") 00564 else 00565 ShowAreaAction("Origin", Origin) 00566 fi 00567 endlet 00568 00569 process ShowAreaAction(Message : str, Location : term) is 00570 EditLocation(Location) 00571 00572 process ShowFeedbackLocation(Location : term) is 00573 EditLocation(Location) 00574 00575 process ShowSubjectHandler(Subject: term) is 00576 let 00577 Pid: int, 00578 Sid: session-id 00579 in 00580 Pid := process-id 00581 . 00582 ( 00583 rec-msg(session(Pid, Sid?)) 00584 . ShowSubject(Sid, Subject) 00585 + 00586 rec-msg(no-such-session(Pid)) 00587 ) 00588 endlet 00589 00590 process ShowErrorHandler(Location: term) is 00591 let 00592 Pid: int, 00593 Sid: session-id 00594 in 00595 Pid := process-id 00596 . 00597 ( 00598 rec-msg(session(Pid, Sid?)) 00599 . ShowLocation(Sid, Location) 00600 + 00601 rec-msg(no-such-session(Pid)) 00602 ) 00603 endlet 00604 00605 process CleanupEditTerm(Sid: session-id) is 00606 TODO("Dit werkt dus niet!\n") 00607 00608 process GetFocusOrigin(EditorId : session-id, Origin: term?) is 00609 let 00610 Cursor : term 00611 in 00612 snd-msg(se-get-cursor(EditorId)) 00613 . rec-msg(se-cursor(EditorId, Cursor?)) 00614 . snd-msg(pa-get-origin(Cursor)) 00615 . 00616 ( 00617 rec-msg(pa-origin(Origin?)) 00618 + 00619 rec-msg(pa-no-origin) 00620 . Origin := no-origin 00621 ) 00622 endlet 00623 00624 process EditorPopup(Sid : session-id, EditorType: term, FocusSort: term) is 00625 let 00626 MenuList : list 00627 in 00628 snd-msg(cm-get-events(EditorType, FocusSort)) 00629 . rec-msg(cm-events(MenuList?)) 00630 . snd-msg(te-show-popup(Sid, MenuList)) 00631 endlet 00632 00633 #endif /* __EDITING__ */