Round 29: Add 20 new Emacs features
ober
48124abd3b3af6506c3bf89a20df61fa42818573
--- a/docs/jemacs-vs-emacs.md +++ b/docs/jemacs-vs-emacs.md @@ -1686,6 +1686,26 @@ No remaining Tier 1 gaps. All core editing, completion, and navigation features | Describe key briefly | :orange_circle: | Show key's command | | Describe bindings | :orange_circle: | Show all key bindings | | Describe mode | :orange_circle: | Show current modes | +| Describe face | :orange_circle: | Show face/style at point | +| Describe char | :orange_circle: | Show character details at point | +| Describe syntax | :orange_circle: | Show syntax class of char at point | +| Describe categories | :orange_circle: | Show character categories | +| Apropos command | :orange_circle: | Search commands by pattern | +| Info/Emacs manual | :orange_circle: | Show jemacs manual reference | +| View echo area messages | :orange_circle: | Show message history | +| Toggle debug on error | :orange_circle: | Toggle debug-on-error | +| Toggle debug on quit | :orange_circle: | Toggle debug-on-quit | +| Profiler start | :orange_circle: | Start CPU profiler | +| Profiler stop | :orange_circle: | Stop CPU profiler | +| Profiler report | :orange_circle: | Show profiler report | +| Memory report | :orange_circle: | Show memory usage | +| Emacs uptime | :orange_circle: | Show session uptime | +| Emacs version | :orange_circle: | Show jemacs version | +| Emacs init time | :orange_circle: | Show init time | +| List packages | :orange_circle: | List available packages | +| Package install | :orange_circle: | Install package (placeholder) | +| Package delete | :orange_circle: | Delete package (placeholder) | +| Package refresh contents | :orange_circle: | Refresh packages (placeholder) | --- --- a/src/jerboa-emacs/editor-extra-final.ss +++ b/src/jerboa-emacs/editor-extra-final.ss @@ -8927,3 +8927,99 @@ "\n\nTotal: " (length sorted) " active minor modes\n"))) (editor-set-text ed text) (echo-message! echo (str (length sorted) " active modes")))) + +;; Round 29 batch 2: profiler-stop, profiler-report, memory-report, emacs-uptime, +;; emacs-version, emacs-init-time, list-packages, package-install, package-delete, +;; package-refresh-contents + +;; cmd-profiler-stop: Stop the CPU profiler +(def (cmd-profiler-stop app) + (let* ((echo (app-state-echo app)) + (start (hash-get (app-state-modes app) 'profiler-start-time))) + (if (not start) + (echo-message! echo "Profiler not running") + (let ((elapsed (- (time-second (current-time)) start))) + (hash-put! (app-state-modes app) 'profiler-elapsed elapsed) + (hash-remove! (app-state-modes app) 'profiler-start-time) + (echo-message! echo (str "Profiler stopped after " elapsed " seconds")))))) + +;; cmd-profiler-report: Show profiler report +(def (cmd-profiler-report app) + (let* ((buf (app-state-current-buffer app)) + (ed (buffer-editor buf)) + (echo (app-state-echo app)) + (elapsed (or (hash-get (app-state-modes app) 'profiler-elapsed) 0)) + (text (str "=== Profiler Report ===\n\n" + "Profile duration: " elapsed " seconds\n\n" + "(Detailed CPU profiling requires Chez Scheme's\n" + " profile-dump-data and related forms.\n" + " Use M-x profiler-start/stop to time sections.)\n"))) + (editor-set-text ed text) + (echo-message! echo "Profiler report"))) + +;; cmd-memory-report: Show memory usage information +(def (cmd-memory-report app) + (let* ((buf (app-state-current-buffer app)) + (ed (buffer-editor buf)) + (echo (app-state-echo app)) + (buffers (app-state-buffers app)) + (buf-count (length buffers)) + (total-chars (apply + (map (lambda (b) (editor-get-length (buffer-editor b))) buffers))) + (text (str "=== Memory Report ===\n\n" + "Buffers: " buf-count "\n" + "Total buffer text: " total-chars " characters\n" + "Estimated buffer memory: ~" (quotient (* total-chars 4) 1024) " KB\n\n" + "Chez Scheme heap:\n" + " (Use scheme's (statistics) for detailed GC info)\n"))) + (editor-set-text ed text) + (echo-message! echo "Memory report"))) + +;; cmd-emacs-uptime: Show how long jemacs has been running +(def (cmd-emacs-uptime app) + (let* ((echo (app-state-echo app)) + (start (or (hash-get (app-state-modes app) 'start-time) (time-second (current-time)))) + (now (time-second (current-time))) + (elapsed (- now start)) + (hours (quotient elapsed 3600)) + (minutes (quotient (remainder elapsed 3600) 60)) + (seconds (remainder elapsed 60))) + (echo-message! echo (str "Uptime: " hours "h " minutes "m " seconds "s")))) + +;; cmd-emacs-version: Show jemacs version +(def (cmd-emacs-version app) + (let* ((echo (app-state-echo app))) + (echo-message! echo "jemacs (jerboa-emacs) on Chez Scheme 10.x"))) + +;; cmd-emacs-init-time: Show initialization time +(def (cmd-emacs-init-time app) + (let* ((echo (app-state-echo app))) + (echo-message! echo "Init time: <not measured> (see startup log)"))) + +;; cmd-list-packages: List available packages/extensions +(def (cmd-list-packages app) + (let* ((buf (app-state-current-buffer app)) + (ed (buffer-editor buf)) + (echo (app-state-echo app)) + (text (str "=== Package List ===\n\n" + "jemacs does not yet have a package manager.\n\n" + "Built-in features are available via M-x.\n" + "Custom extensions can be added as .ss files\n" + "in the src/jerboa-emacs/ directory.\n\n" + "For Emacs packages, see: https://melpa.org\n"))) + (editor-set-text ed text) + (echo-message! echo "Package list (no package manager yet)"))) + +;; cmd-package-install: Install a package +(def (cmd-package-install app) + (let* ((echo (app-state-echo app))) + (echo-message! echo "Package manager not available. Add .ss files to src/ instead."))) + +;; cmd-package-delete: Delete a package +(def (cmd-package-delete app) + (let* ((echo (app-state-echo app))) + (echo-message! echo "Package manager not available."))) + +;; cmd-package-refresh-contents: Refresh package list +(def (cmd-package-refresh-contents app) + (let* ((echo (app-state-echo app))) + (echo-message! echo "Package manager not available."))) --- a/src/jerboa-emacs/editor-extra-modes.ss +++ b/src/jerboa-emacs/editor-extra-modes.ss @@ -9356,3 +9356,150 @@ (send-message ed SCI_SETREADONLY 1 0) (echo-message! echo "Compilation mode"))) +;; Round 29 batch 1: describe-face, describe-char, describe-syntax, describe-categories, +;; apropos-command, info-emacs-manual, view-echo-area-messages, toggle-debug-on-error, +;; toggle-debug-on-quit, profiler-start + +;; cmd-describe-face: Show information about face/style at point +(def (cmd-describe-face app) + (let* ((buf (app-state-current-buffer app)) + (ed (buffer-editor buf)) + (echo (app-state-echo app)) + (pos (editor-cursor-position ed)) + (style (send-message ed SCI_GETSTYLEAT pos 0))) + (echo-message! echo (str "Face at point: style " style)))) + +;; cmd-describe-char: Show detailed information about character at point +(def (cmd-describe-char app) + (let* ((buf (app-state-current-buffer app)) + (ed (buffer-editor buf)) + (echo (app-state-echo app)) + (pos (editor-cursor-position ed)) + (text (editor-get-text ed)) + (len (string-length text))) + (if (>= pos len) + (echo-message! echo "End of buffer") + (let* ((c (string-ref text pos)) + (code (char->integer c)) + (info (str "Character: " (if (char=? c #\space) "SPACE" (string c)) + "\n Unicode: U+" (let ((h (number->string code 16))) + (if (< (string-length h) 4) + (str (make-string (- 4 (string-length h)) #\0) h) h)) + "\n Decimal: " code + "\n Octal: " (number->string code 8) + "\n Category: " (cond + ((char-alphabetic? c) "letter") + ((char-numeric? c) "digit") + ((char-whitespace? c) "whitespace") + (else "other"))))) + (echo-message! echo info))))) + +;; cmd-describe-syntax: Show syntax table info for character at point +(def (cmd-describe-syntax app) + (let* ((buf (app-state-current-buffer app)) + (ed (buffer-editor buf)) + (echo (app-state-echo app)) + (pos (editor-cursor-position ed)) + (text (editor-get-text ed)) + (len (string-length text))) + (if (>= pos len) + (echo-message! echo "End of buffer") + (let* ((c (string-ref text pos)) + (syntax (cond + ((char-alphabetic? c) "word constituent") + ((char-numeric? c) "word constituent") + ((char-whitespace? c) "whitespace") + ((memv c '(#\( #\[ #\{)) "open paren") + ((memv c '(#\) #\] #\})) "close paren") + ((memv c '(#\" #\')) "string quote") + ((char=? c #\;) "comment start") + ((char=? c #\\) "escape") + (else "punctuation")))) + (echo-message! echo (str "Syntax of '" (string c) "': " syntax)))))) + +;; cmd-describe-categories: Show character categories +(def (cmd-describe-categories app) + (let* ((echo (app-state-echo app)) + (buf (app-state-current-buffer app)) + (ed (buffer-editor buf)) + (text (str "=== Character Categories ===\n\n" + "a - ASCII\n" + "l - Latin\n" + "g - Greek\n" + "c - Chinese/CJK\n" + "j - Japanese\n" + "k - Korean\n" + "h - Hebrew\n" + "r - Arabic\n" + ". - Base (all others)\n"))) + (editor-set-text ed text) + (echo-message! echo "Character categories listed"))) + +;; cmd-apropos-command: Search for commands matching pattern +(def (cmd-apropos-command app) + (let* ((echo (app-state-echo app)) + (buf (app-state-current-buffer app)) + (ed (buffer-editor buf)) + (pattern (echo-read-string echo "Apropos command: "))) + (if (or (not pattern) (string=? pattern "")) + (echo-message! echo "No pattern specified") + (let* ((cmds (hash-keys (app-state-commands app))) + (matches (filter (lambda (sym) (string-contains (symbol->string sym) pattern)) cmds)) + (sorted (sort string<? (map symbol->string matches))) + (text (str "=== Apropos Command: \"" pattern "\" ===\n\n" + (if (null? sorted) "No matches found.\n" + (str (string-join (map (lambda (s) (str " M-x " s)) sorted) "\n") + "\n\n" (length sorted) " commands\n"))))) + (editor-set-text ed text) + (echo-message! echo (str (length sorted) " commands matching \"" pattern "\"")))))) + +;; cmd-info-emacs-manual: Open the Emacs manual reference +(def (cmd-info-emacs-manual app) + (let* ((buf (app-state-current-buffer app)) + (ed (buffer-editor buf)) + (echo (app-state-echo app)) + (text (str "=== jemacs Manual ===\n\n" + "jemacs is a Chez Scheme Emacs-like editor.\n\n" + "For help:\n" + " C-h k Describe a key binding\n" + " C-h f Describe a function\n" + " M-x cheat-sheet Quick reference\n" + " M-x describe-bindings All key bindings\n" + " M-x apropos-command Search commands\n" + " M-x tutorial-mode Interactive tutorial\n\n" + "For GNU Emacs manual: https://www.gnu.org/software/emacs/manual/\n"))) + (editor-set-text ed text) + (echo-message! echo "jemacs manual"))) + +;; cmd-view-echo-area-messages: Show recent echo area messages +(def (cmd-view-echo-area-messages app) + (let* ((echo (app-state-echo app)) + (buf (app-state-current-buffer app)) + (ed (buffer-editor buf))) + (editor-set-text ed (str "=== *Messages* ===\n\n" + "(Echo area message history is not persisted yet.\n" + " Recent messages appear in the echo area at bottom.)\n")) + (echo-message! echo "Messages buffer"))) + +;; cmd-toggle-debug-on-error: Toggle debug-on-error mode +(def (cmd-toggle-debug-on-error app) + (let* ((echo (app-state-echo app))) + (toggle-mode! app 'debug-on-error) + (if (mode-enabled? app 'debug-on-error) + (echo-message! echo "Debug on error enabled") + (echo-message! echo "Debug on error disabled")))) + +;; cmd-toggle-debug-on-quit: Toggle debug-on-quit mode +(def (cmd-toggle-debug-on-quit app) + (let* ((echo (app-state-echo app))) + (toggle-mode! app 'debug-on-quit) + (if (mode-enabled? app 'debug-on-quit) + (echo-message! echo "Debug on quit enabled") + (echo-message! echo "Debug on quit disabled")))) + +;; cmd-profiler-start: Start the CPU profiler +(def (cmd-profiler-start app) + (let* ((echo (app-state-echo app))) + (hash-put! (app-state-modes app) 'profiler-start-time (time-second (current-time))) + (echo-message! echo "Profiler started"))) + --- a/src/jerboa-emacs/editor-extra-regs2.ss +++ b/src/jerboa-emacs/editor-extra-regs2.ss @@ -2052,4 +2052,25 @@ (register-command! 'describe-key-briefly cmd-describe-key-briefly) (register-command! 'describe-bindings cmd-describe-bindings) (register-command! 'describe-mode cmd-describe-mode) + ;; Round 29 + (register-command! 'describe-face cmd-describe-face) + (register-command! 'describe-char cmd-describe-char) + (register-command! 'describe-syntax cmd-describe-syntax) + (register-command! 'describe-categories cmd-describe-categories) + (register-command! 'apropos-command cmd-apropos-command) + (register-command! 'info-emacs-manual cmd-info-emacs-manual) + (register-command! 'view-echo-area-messages cmd-view-echo-area-messages) + (register-command! 'toggle-debug-on-error cmd-toggle-debug-on-error) + (register-command! 'toggle-debug-on-quit cmd-toggle-debug-on-quit) + (register-command! 'profiler-start cmd-profiler-start) + (register-command! 'profiler-stop cmd-profiler-stop) + (register-command! 'profiler-report cmd-profiler-report) + (register-command! 'memory-report cmd-memory-report) + (register-command! 'emacs-uptime cmd-emacs-uptime) + (register-command! 'emacs-version cmd-emacs-version) + (register-command! 'emacs-init-time cmd-emacs-init-time) + (register-command! 'list-packages cmd-list-packages) + (register-command! 'package-install cmd-package-install) + (register-command! 'package-delete cmd-package-delete) + (register-command! 'package-refresh-contents cmd-package-refresh-contents) )