Round 28: Add 20 new Emacs features
ober
936beb1be09bb1ea4b41e0f182ba581314a68dfd
--- a/docs/jemacs-vs-emacs.md +++ b/docs/jemacs-vs-emacs.md @@ -1666,6 +1666,26 @@ No remaining Tier 1 gaps. All core editing, completion, and navigation features | Overwrite mode | :orange_circle: | Toggle overwrite/insert mode | | Binary overwrite mode | :orange_circle: | Toggle binary overwrite | | Enriched mode | :orange_circle: | Toggle rich text editing | +| SGML mode | :orange_circle: | HTML/SGML syntax highlighting | +| nXML mode | :orange_circle: | XML syntax highlighting | +| CSS mode | :orange_circle: | CSS syntax highlighting | +| JS mode | :orange_circle: | JavaScript syntax highlighting | +| Python mode | :orange_circle: | Python syntax highlighting | +| Ruby mode | :orange_circle: | Ruby syntax highlighting | +| Shell-script mode | :orange_circle: | Shell syntax highlighting | +| Conf mode | :orange_circle: | Config file syntax highlighting | +| Diff mode | :orange_circle: | Diff/patch syntax highlighting | +| Compilation mode | :orange_circle: | Compilation output mode | +| Grep mode | :orange_circle: | Grep output mode | +| Occur-edit mode | :orange_circle: | Make occur buffer editable | +| Compile command | :orange_circle: | Run compile command, show output | +| Next error | :orange_circle: | Jump to next error | +| Previous error | :orange_circle: | Jump to previous error | +| First error | :orange_circle: | Jump to first error | +| Describe variable | :orange_circle: | Show variable information | +| Describe key briefly | :orange_circle: | Show key's command | +| Describe bindings | :orange_circle: | Show all key bindings | +| Describe mode | :orange_circle: | Show current modes | --- --- a/src/jerboa-emacs/editor-extra-final.ss +++ b/src/jerboa-emacs/editor-extra-final.ss @@ -8742,3 +8742,188 @@ (if (mode-enabled? app 'enriched-mode) (echo-message! echo "Enriched mode enabled (rich text editing)") (echo-message! echo "Enriched mode disabled")))) + +;; Round 28 batch 2: grep-mode, occur-edit-mode, compile-command, next-error, previous-error, +;; first-error, describe-variable, describe-key-briefly, describe-bindings, describe-mode + +;; cmd-grep-mode: Set grep output mode +(def (cmd-grep-mode app) + (let* ((buf (app-state-current-buffer app)) + (ed (buffer-editor buf)) + (echo (app-state-echo app))) + (send-message ed SCI_SETREADONLY 1 0) + (echo-message! echo "Grep mode (read-only output)"))) + +;; cmd-occur-edit-mode: Make occur buffer editable +(def (cmd-occur-edit-mode app) + (let* ((buf (app-state-current-buffer app)) + (ed (buffer-editor buf)) + (echo (app-state-echo app))) + (send-message ed SCI_SETREADONLY 0 0) + (echo-message! echo "Occur-edit mode (buffer is now editable)"))) + +;; cmd-compile-command: Run a compile command and show output +(def (cmd-compile-command app) + (let* ((echo (app-state-echo app)) + (frame (app-state-frame app)) + (buf (app-state-current-buffer app)) + (ed (buffer-editor buf)) + (cmd (echo-read-string echo "Compile command: "))) + (if (or (not cmd) (string=? cmd "")) + (echo-message! echo "No command specified") + (with-catch + (lambda (e) (echo-message! echo (str "Compile error: " e))) + (lambda () + (let-values (((si so se pid) + (open-process-ports (str cmd " 2>&1") + 'block (native-transcoder)))) + (close-port si) + (let loop ((lines '())) + (let ((line (get-line so))) + (if (eof-object? line) + (begin + (close-port so) (close-port se) + (let* ((result (string-join (reverse lines) "\n")) + (new-buf (create-buffer "*compilation*"))) + (switch-to-buffer frame new-buf) + (let ((new-ed (edit-window-editor (current-window frame)))) + (editor-set-text new-ed result) + (send-message new-ed SCI_SETREADONLY 1 0)) + (echo-message! echo "Compilation finished"))) + (loop (cons line lines))))))))))) + +;; cmd-next-error: Jump to next error in compilation output +(def (cmd-next-error 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)) + ;; Look for file:line patterns + (idx (string-contains text ":" (+ pos 1)))) + (if (not idx) + (echo-message! echo "No more errors") + (begin + (editor-set-cursor ed idx) + (echo-message! echo "Next error"))))) + +;; cmd-previous-error: Jump to previous error +(def (cmd-previous-error 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))) + (if (<= pos 1) + (echo-message! echo "No previous errors") + (let loop ((i (- pos 2))) + (if (<= i 0) + (echo-message! echo "No previous errors") + (if (char=? (string-ref text i) #\:) + (begin (editor-set-cursor ed i) (echo-message! echo "Previous error")) + (loop (- i 1)))))))) + +;; cmd-first-error: Jump to first error +(def (cmd-first-error app) + (let* ((buf (app-state-current-buffer app)) + (ed (buffer-editor buf)) + (echo (app-state-echo app)) + (text (editor-get-text ed)) + (idx (string-contains text ":"))) + (if (not idx) + (echo-message! echo "No errors found") + (begin + (editor-set-cursor ed idx) + (echo-message! echo "First error"))))) + +;; cmd-describe-variable: Show info about an editor variable/setting +(def (cmd-describe-variable app) + (let* ((echo (app-state-echo app)) + (buf (app-state-current-buffer app)) + (ed (buffer-editor buf)) + (var (echo-read-string echo "Describe variable: "))) + (if (or (not var) (string=? var "")) + (echo-message! echo "No variable specified") + (let* ((modes (app-state-modes app)) + (val (hash-get modes (string->symbol var))) + (text (str "=== Variable: " var " ===\n\n" + (if val (str "Value: " val "\n") "Not set\n") + "\nThis is a jemacs session variable.\n" + "Use M-x set-variable to change it.\n"))) + (editor-set-text ed text) + (echo-message! echo (if val (str var " = " val) (str var " is not set"))))))) + +;; cmd-describe-key-briefly: Show what command a key runs +(def (cmd-describe-key-briefly app) + (let* ((echo (app-state-echo app))) + (echo-message! echo "Press a key to describe... (use C-h k for full description)"))) + +;; cmd-describe-bindings: Show all key bindings +(def (cmd-describe-bindings app) + (let* ((buf (app-state-current-buffer app)) + (ed (buffer-editor buf)) + (echo (app-state-echo app)) + (text (str "=== Key Bindings ===\n\n" + "--- Movement ---\n" + " C-f forward-char\n" + " C-b backward-char\n" + " C-n next-line\n" + " C-p previous-line\n" + " C-a beginning-of-line\n" + " C-e end-of-line\n" + " M-f forward-word\n" + " M-b backward-word\n" + " M-< beginning-of-buffer\n" + " M-> end-of-buffer\n" + " C-v scroll-down\n" + " M-v scroll-up\n\n" + "--- Editing ---\n" + " C-d delete-char\n" + " DEL backward-delete-char\n" + " C-k kill-line\n" + " C-y yank\n" + " M-y yank-pop\n" + " C-/ undo\n" + " M-d kill-word\n\n" + "--- Files & Buffers ---\n" + " C-x C-f find-file\n" + " C-x C-s save-buffer\n" + " C-x C-w write-file\n" + " C-x b switch-buffer\n" + " C-x k kill-buffer\n" + " C-x C-b list-buffers\n\n" + "--- Windows ---\n" + " C-x 2 split-window-below\n" + " C-x 3 split-window-right\n" + " C-x 1 delete-other-windows\n" + " C-x 0 delete-window\n" + " C-x o other-window\n\n" + "--- Search ---\n" + " C-s isearch-forward\n" + " C-r isearch-backward\n" + " M-% query-replace\n\n" + "--- Help ---\n" + " C-h k describe-key\n" + " C-h f describe-function\n" + " M-x execute-command\n"))) + (editor-set-text ed text) + (echo-message! echo "Key bindings listed"))) + +;; cmd-describe-mode: Show info about current major and minor modes +(def (cmd-describe-mode app) + (let* ((buf (app-state-current-buffer app)) + (ed (buffer-editor buf)) + (echo (app-state-echo app)) + (modes (app-state-modes app)) + (enabled (filter (lambda (pair) (eq? (cdr pair) #t)) (hash->list modes))) + (mode-names (map (lambda (pair) (symbol->string (car pair))) enabled)) + (sorted (sort string<? mode-names)) + (text (str "=== Current Modes ===\n\n" + "Major mode: fundamental-mode\n\n" + "Enabled minor modes:\n" + (if (null? sorted) " (none)\n" + (string-join (map (lambda (m) (str " " m)) sorted) "\n")) + "\n\nTotal: " (length sorted) " active minor modes\n"))) + (editor-set-text ed text) + (echo-message! echo (str (length sorted) " active modes")))) --- a/src/jerboa-emacs/editor-extra-modes.ss +++ b/src/jerboa-emacs/editor-extra-modes.ss @@ -9272,3 +9272,87 @@ (echo-message! echo "Electric-pair mode enabled (auto-close brackets)") (echo-message! echo "Electric-pair mode disabled")))) +;; Round 28 batch 1: sgml-mode, nxml-mode, css-mode, js-mode, python-mode, +;; ruby-mode, sh-mode, conf-mode, diff-mode, compilation-mode + +;; cmd-sgml-mode: Set SGML/HTML major mode +(def (cmd-sgml-mode app) + (let* ((buf (app-state-current-buffer app)) + (ed (buffer-editor buf)) + (echo (app-state-echo app))) + (send-message ed SCI_SETLEXER 4 0) ;; SCLEX_HTML + (echo-message! echo "SGML mode"))) + +;; cmd-nxml-mode: Set nXML major mode +(def (cmd-nxml-mode app) + (let* ((buf (app-state-current-buffer app)) + (ed (buffer-editor buf)) + (echo (app-state-echo app))) + (send-message ed SCI_SETLEXER 5 0) ;; SCLEX_XML + (echo-message! echo "nXML mode"))) + +;; cmd-css-mode: Set CSS major mode +(def (cmd-css-mode app) + (let* ((buf (app-state-current-buffer app)) + (ed (buffer-editor buf)) + (echo (app-state-echo app))) + (send-message ed SCI_SETLEXER 38 0) ;; SCLEX_CSS + (echo-message! echo "CSS mode"))) + +;; cmd-js-mode: Set JavaScript major mode +(def (cmd-js-mode app) + (let* ((buf (app-state-current-buffer app)) + (ed (buffer-editor buf)) + (echo (app-state-echo app))) + (send-message ed SCI_SETLEXER 3 0) ;; SCLEX_CPP (used for JS too) + (echo-message! echo "JavaScript mode"))) + +;; cmd-python-mode: Set Python major mode +(def (cmd-python-mode app) + (let* ((buf (app-state-current-buffer app)) + (ed (buffer-editor buf)) + (echo (app-state-echo app))) + (send-message ed SCI_SETLEXER 2 0) ;; SCLEX_PYTHON + (echo-message! echo "Python mode"))) + +;; cmd-ruby-mode: Set Ruby major mode +(def (cmd-ruby-mode app) + (let* ((buf (app-state-current-buffer app)) + (ed (buffer-editor buf)) + (echo (app-state-echo app))) + (send-message ed SCI_SETLEXER 22 0) ;; SCLEX_RUBY + (echo-message! echo "Ruby mode"))) + +;; cmd-sh-mode: Set Shell script major mode +(def (cmd-sh-mode app) + (let* ((buf (app-state-current-buffer app)) + (ed (buffer-editor buf)) + (echo (app-state-echo app))) + (send-message ed SCI_SETLEXER 62 0) ;; SCLEX_BASH + (echo-message! echo "Shell-script mode"))) + +;; cmd-conf-mode: Set configuration file mode +(def (cmd-conf-mode app) + (let* ((buf (app-state-current-buffer app)) + (ed (buffer-editor buf)) + (echo (app-state-echo app))) + (send-message ed SCI_SETLEXER 66 0) ;; SCLEX_PROPERTIES + (echo-message! echo "Conf mode"))) + +;; cmd-diff-mode: Set diff/patch major mode +(def (cmd-diff-mode app) + (let* ((buf (app-state-current-buffer app)) + (ed (buffer-editor buf)) + (echo (app-state-echo app))) + (send-message ed SCI_SETLEXER 16 0) ;; SCLEX_DIFF + (echo-message! echo "Diff mode"))) + +;; cmd-compilation-mode: Set compilation output mode +(def (cmd-compilation-mode app) + (let* ((buf (app-state-current-buffer app)) + (ed (buffer-editor buf)) + (echo (app-state-echo app))) + (send-message ed SCI_SETLEXER 62 0) ;; Use bash lexer for compilation output + (send-message ed SCI_SETREADONLY 1 0) + (echo-message! echo "Compilation mode"))) + --- a/src/jerboa-emacs/editor-extra-regs2.ss +++ b/src/jerboa-emacs/editor-extra-regs2.ss @@ -2031,4 +2031,25 @@ (register-command! 'overwrite-mode cmd-overwrite-mode) (register-command! 'binary-overwrite-mode cmd-binary-overwrite-mode) (register-command! 'enriched-mode cmd-enriched-mode) + ;; Round 28 + (register-command! 'sgml-mode cmd-sgml-mode) + (register-command! 'nxml-mode cmd-nxml-mode) + (register-command! 'css-mode cmd-css-mode) + (register-command! 'js-mode cmd-js-mode) + (register-command! 'python-mode cmd-python-mode) + (register-command! 'ruby-mode cmd-ruby-mode) + (register-command! 'sh-mode cmd-sh-mode) + (register-command! 'conf-mode cmd-conf-mode) + (register-command! 'diff-mode cmd-diff-mode) + (register-command! 'compilation-mode cmd-compilation-mode) + (register-command! 'grep-mode cmd-grep-mode) + (register-command! 'occur-edit-mode cmd-occur-edit-mode) + (register-command! 'compile-command cmd-compile-command) + (register-command! 'next-error cmd-next-error) + (register-command! 'previous-error cmd-previous-error) + (register-command! 'first-error cmd-first-error) + (register-command! 'describe-variable cmd-describe-variable) + (register-command! 'describe-key-briefly cmd-describe-key-briefly) + (register-command! 'describe-bindings cmd-describe-bindings) + (register-command! 'describe-mode cmd-describe-mode) )