Download layer-15-shell/shell.f90 from Snapkitty/sovereign-ide: direct link, hf CLI and curl.
- Browser
- Download file 7.35 kB
-
https://huggingface.co/Snapkitty/sovereign-ide/resolve/main/layer-15-shell/shell.f90
- Command line
-
hf download hf://Snapkitty/sovereign-ide/layer-15-shell/shell.f90
-
curl -L -o shell.f90 https://huggingface.co/Snapkitty/sovereign-ide/resolve/main/layer-15-shell/shell.f90
7.35 kB
| ! Layer 15 β Sovereign IDE Application Shell | |
| ! Session state, workspace, main event loop, BOB context slot | |
| ! Maps to: bob-ide, bob-orchestrator | |
| MODULE sovereign_shell | |
| USE iso_c_binding | |
| USE sovereign_runtime, ONLY: runtime_init, runtime_teardown, runtime_panic, str_intern | |
| IMPLICIT NONE | |
| PRIVATE | |
| ! ββ Workspace descriptor βββββββββββββββββββββββββββββββββββββββββββββββββ | |
| INTEGER, PARAMETER :: MAX_OPEN_FILES = 512 | |
| INTEGER, PARAMETER :: MAX_PANELS = 16 | |
| TYPE :: panel_t | |
| REAL :: x = 0.0, y = 0.0, w = 1.0, h = 1.0 | |
| INTEGER :: buffer_idx = 0 | |
| LOGICAL :: active = .FALSE. | |
| END TYPE panel_t | |
| TYPE :: workspace_t | |
| INTEGER(C_INT32_T) :: root_path_id = 0 | |
| INTEGER(C_INT32_T) :: open_files(MAX_OPEN_FILES) | |
| INTEGER :: open_count = 0 | |
| TYPE(panel_t) :: panels(MAX_PANELS) | |
| INTEGER :: panel_count = 1 | |
| INTEGER :: active_panel = 1 | |
| LOGICAL :: dirty = .FALSE. | |
| END TYPE workspace_t | |
| ! ββ Session state (WORM-sealed) ββββββββββββββββββββββββββββββββββββββββββ | |
| TYPE :: session_t | |
| TYPE(workspace_t) :: workspace | |
| INTEGER(C_INT64_T) :: frame_count = 0 | |
| LOGICAL :: bob_context_loaded = .FALSE. | |
| INTEGER(C_INT32_T) :: session_id = 0 | |
| LOGICAL :: running = .FALSE. | |
| END TYPE session_t | |
| TYPE(session_t), SAVE :: g_session | |
| PUBLIC :: shell_init | |
| PUBLIC :: shell_run | |
| PUBLIC :: shell_shutdown | |
| PUBLIC :: shell_open_file | |
| PUBLIC :: shell_close_file | |
| PUBLIC :: shell_split_panel | |
| PUBLIC :: shell_save_session | |
| PUBLIC :: shell_restore_session | |
| CONTAINS | |
| ! --------------------------------------------------------------------------- | |
| SUBROUTINE shell_init(workspace_root) | |
| CHARACTER(LEN=*), INTENT(IN) :: workspace_root | |
| CALL runtime_init() | |
| g_session%workspace%root_path_id = str_intern(workspace_root) | |
| g_session%workspace%panel_count = 1 | |
| g_session%workspace%active_panel = 1 | |
| g_session%workspace%panels(1)%active = .TRUE. | |
| g_session%running = .TRUE. | |
| g_session%frame_count = 0 | |
| WRITE(*,'(A,A)') '[shell] init workspace: ', TRIM(workspace_root) | |
| END SUBROUTINE shell_init | |
| ! --------------------------------------------------------------------------- | |
| ! Main event loop: poll β update β render β repeat | |
| SUBROUTINE shell_run() | |
| DO WHILE (g_session%running) | |
| g_session%frame_count = g_session%frame_count + 1 | |
| ! 1. Poll OS events (Layer 1 platform) | |
| ! TODO: CALL platform_poll_events() | |
| ! 2. Process input (Layer 2 GUI input dispatch) | |
| ! TODO: CALL gui_process_input() | |
| ! 3. Update all active layers | |
| ! TODO: CALL lsp_tick() β Layer 12 | |
| ! TODO: CALL dap_tick() β Layer 13 | |
| ! TODO: CALL ext_host_tick() β Layer 14 | |
| ! 4. Begin frame (Layer 2 GUI) | |
| ! TODO: CALL gui_begin_frame() | |
| ! 5. Render panels β text buffers β syntax highlighting | |
| ! TODO: CALL gui_render_panels() | |
| ! 6. End frame | |
| ! TODO: CALL gui_end_frame() | |
| ! 7. Auto-save session every 300 frames | |
| IF (MOD(g_session%frame_count, 300) == 0) CALL shell_save_session() | |
| ! Stub: exit after first frame for now | |
| g_session%running = .FALSE. | |
| END DO | |
| END SUBROUTINE shell_run | |
| ! --------------------------------------------------------------------------- | |
| SUBROUTINE shell_shutdown() | |
| CALL shell_save_session() | |
| ! Teardown in reverse order: 15 β 0 | |
| ! TODO: CALL ext_host_shutdown() β Layer 14 | |
| ! TODO: CALL dap_shutdown() β Layer 13 | |
| ! TODO: CALL lsp_shutdown() β Layer 12 | |
| ! TODO: CALL build_shutdown() β Layer 11 | |
| ! ... | |
| CALL runtime_teardown() | |
| WRITE(*,'(A,I0,A)') '[shell] shutdown after ', g_session%frame_count, ' frames' | |
| END SUBROUTINE shell_shutdown | |
| ! --------------------------------------------------------------------------- | |
| SUBROUTINE shell_open_file(path) | |
| CHARACTER(LEN=*), INTENT(IN) :: path | |
| INTEGER(C_INT32_T) :: fid | |
| IF (g_session%workspace%open_count >= MAX_OPEN_FILES) & | |
| CALL runtime_panic('shell_open_file: too many open files') | |
| fid = str_intern(path) | |
| g_session%workspace%open_count = g_session%workspace%open_count + 1 | |
| g_session%workspace%open_files(g_session%workspace%open_count) = fid | |
| g_session%workspace%dirty = .TRUE. | |
| WRITE(*,'(A,A)') '[shell] opened: ', TRIM(path) | |
| END SUBROUTINE shell_open_file | |
| ! --------------------------------------------------------------------------- | |
| SUBROUTINE shell_close_file(idx) | |
| INTEGER, INTENT(IN) :: idx | |
| INTEGER :: i | |
| IF (idx < 1 .OR. idx > g_session%workspace%open_count) RETURN | |
| DO i = idx, g_session%workspace%open_count - 1 | |
| g_session%workspace%open_files(i) = g_session%workspace%open_files(i+1) | |
| END DO | |
| g_session%workspace%open_count = g_session%workspace%open_count - 1 | |
| g_session%workspace%dirty = .TRUE. | |
| END SUBROUTINE shell_close_file | |
| ! --------------------------------------------------------------------------- | |
| SUBROUTINE shell_split_panel(direction) | |
| CHARACTER(LEN=*), INTENT(IN) :: direction | |
| INTEGER :: n | |
| n = g_session%workspace%panel_count | |
| IF (n >= MAX_PANELS) RETURN | |
| g_session%workspace%panel_count = n + 1 | |
| g_session%workspace%panels(n+1)%active = .TRUE. | |
| IF (direction == 'v') THEN | |
| g_session%workspace%panels(n)%w = g_session%workspace%panels(n)%w * 0.5 | |
| g_session%workspace%panels(n+1)%x = g_session%workspace%panels(n)%x + g_session%workspace%panels(n)%w | |
| g_session%workspace%panels(n+1)%w = g_session%workspace%panels(n)%w | |
| ELSE | |
| g_session%workspace%panels(n)%h = g_session%workspace%panels(n)%h * 0.5 | |
| g_session%workspace%panels(n+1)%y = g_session%workspace%panels(n)%y + g_session%workspace%panels(n)%h | |
| g_session%workspace%panels(n+1)%h = g_session%workspace%panels(n)%h | |
| END IF | |
| g_session%workspace%dirty = .TRUE. | |
| END SUBROUTINE shell_split_panel | |
| ! --------------------------------------------------------------------------- | |
| ! Session save: serialize workspace to WORM-sealed JSON | |
| SUBROUTINE shell_save_session() | |
| IF (.NOT. g_session%workspace%dirty) RETURN | |
| ! TODO: serialize workspace_t β JSON | |
| ! TODO: CALL bifrost_worm_append(session_json) β Layer 0 WORM | |
| g_session%workspace%dirty = .FALSE. | |
| WRITE(*,'(A,I0)') '[shell] session saved at frame ', g_session%frame_count | |
| END SUBROUTINE shell_save_session | |
| ! --------------------------------------------------------------------------- | |
| SUBROUTINE shell_restore_session(session_path) | |
| CHARACTER(LEN=*), INTENT(IN) :: session_path | |
| ! TODO: read WORM-sealed session file | |
| ! TODO: deserialize β workspace_t | |
| ! TODO: re-open all files (Layer 3 buffer restore) | |
| ! TODO: reconnect BOB context (Layer 14 ext_host_connect_bob) | |
| g_session%bob_context_loaded = .TRUE. | |
| WRITE(*,'(A,A)') '[shell] restored session: ', TRIM(session_path) | |
| END SUBROUTINE shell_restore_session | |
| END MODULE sovereign_shell | |