Round 14: Add 20 new features (color conversion, JSON tools, git utilities)
ober
6ac123971b3e86cac92e3ee1451b26b94bcc1480
--- a/docs/jemacs-vs-emacs.md +++ b/docs/jemacs-vs-emacs.md @@ -1386,6 +1386,26 @@ No remaining Tier 1 gaps. All core editing, completion, and navigation features | Copy line number | :orange_circle: | Copy current line number to kill ring | | Rename file and buffer | :orange_circle: | Rename file on disk and update buffer | | Sudo edit | :orange_circle: | Re-open file with sudo privileges | +| Insert date header | :orange_circle: | Insert formatted date/time header at point | +| Highlight phrase | :orange_circle: | Highlight all occurrences of a phrase (indicator overlay) | +| Unhighlight all | :orange_circle: | Clear all phrase highlights | +| Widen buffer | :orange_circle: | Remove narrowing, show full buffer | +| Move region up | :orange_circle: | Move selected lines up | +| Move region down | :orange_circle: | Move selected lines down | +| JSON to YAML | :orange_circle: | Convert JSON to YAML via Python | +| YAML to JSON | :orange_circle: | Convert YAML to JSON via Python | +| CSV to JSON | :orange_circle: | Convert CSV to JSON via Python | +| JSON to CSV | :orange_circle: | Convert JSON array to CSV via Python | +| Hex to RGB | :orange_circle: | Convert hex color (#FF8800) to rgb() format | +| RGB to hex | :orange_circle: | Convert rgb() color to hex format | +| Unix timestamp | :orange_circle: | Insert/convert Unix timestamps (now, from-date, to-date) | +| Format JSON | :orange_circle: | Pretty-print JSON via python3 json.tool | +| Minify JSON | :orange_circle: | Compact JSON to single line | +| File info | :orange_circle: | Show file size, permissions, owner, type, line count | +| Git contributors | :orange_circle: | Show top contributors via git shortlog | +| Git file history | :orange_circle: | Show git log for current file | +| Copy git branch | :orange_circle: | Copy current git branch name to kill ring | +| Eval and replace | :orange_circle: | Evaluate selection as shell/bc expression, replace with result | --- --- a/src/jerboa-emacs/editor-extra-final.ss +++ b/src/jerboa-emacs/editor-extra-final.ss @@ -5584,3 +5584,349 @@ (editor-goto-pos ed 0) (echo-message! echo (str "Opened with sudo: " file)))) (loop (cons line lines))))))))))) + +;; ===== Round 14 Batch 2 ===== + +;; --- Feature 1: Hex to RGB --- + +(def (cmd-hex-to-rgb app) + "Convert a hex color code at point or in selection to RGB format." + (let* ((echo (app-state-echo app)) + (frame (app-state-frame app)) + (win (current-window frame)) + (ed (edit-window-editor win)) + (start (send-message ed SCI_GETSELECTIONSTART 0 0)) + (end (send-message ed SCI_GETSELECTIONEND 0 0))) + (if (= start end) + (echo-message! echo "No selection — select a hex color like #FF8800") + (let* ((text (editor-get-text-range ed start end)) + (hex (if (and (> (string-length text) 0) (char=? (string-ref text 0) #\#)) + (substring text 1 (string-length text)) + text))) + (if (not (= (string-length hex) 6)) + (echo-message! echo "Invalid hex color — expected 6 hex digits") + (with-catch + (lambda (e) (echo-message! echo (str "Parse error: " e))) + (lambda () + (let* ((r (string->number (substring hex 0 2) 16)) + (g (string->number (substring hex 2 4) 16)) + (b (string->number (substring hex 4 6) 16)) + (rgb (str "rgb(" r ", " g ", " b ")"))) + (send-message ed SCI_DELETERANGE start (- end start)) + (send-message ed SCI_INSERTTEXT start rgb) + (echo-message! echo (str "Converted to: " rgb)))))))))) + +;; --- Feature 2: RGB to Hex --- + +(def (cmd-rgb-to-hex app) + "Convert an RGB color at point or in selection to hex format." + (let* ((echo (app-state-echo app)) + (frame (app-state-frame app)) + (win (current-window frame)) + (ed (edit-window-editor win)) + (start (send-message ed SCI_GETSELECTIONSTART 0 0)) + (end (send-message ed SCI_GETSELECTIONEND 0 0))) + (if (= start end) + (echo-message! echo "No selection — select an rgb(...) value") + (let* ((text (editor-get-text-range ed start end)) + (nums (with-catch + (lambda (e) #f) + (lambda () + (let-values (((si so se pid) + (open-process-ports + (str "echo " (shell-quote text) + " | grep -oP '\\d+' | head -3") + 'block (native-transcoder)))) + (close-port si) + (let loop ((vals '())) + (let ((line (get-line so))) + (if (eof-object? line) + (begin (close-port so) (close-port se) (reverse vals)) + (loop (cons (string->number (string-trim line)) vals)))))))))) + (if (or (not nums) (not (= (length nums) 3))) + (echo-message! echo "Could not parse RGB values") + (let* ((r (car nums)) (g (cadr nums)) (b (caddr nums)) + (hex (str "#" + (if (< r 16) "0" "") (number->string r 16) + (if (< g 16) "0" "") (number->string g 16) + (if (< b 16) "0" "") (number->string b 16)))) + (send-message ed SCI_DELETERANGE start (- end start)) + (send-message ed SCI_INSERTTEXT start (string-upcase hex)) + (echo-message! echo (str "Converted to: " (string-upcase hex))))))))) + +;; --- Feature 3: Unix Timestamp --- + +(def (cmd-unix-timestamp app) + "Insert or convert a Unix timestamp at point." + (let* ((echo (app-state-echo app)) + (frame (app-state-frame app)) + (win (current-window frame)) + (ed (edit-window-editor win)) + (row (tui-rows)) (width (tui-cols)) + (choice (echo-read-string echo "Timestamp [now/from-date/to-date]: " row width))) + (when (and choice (not (string-empty? choice))) + (let ((cmd (string-trim choice))) + (cond + ((string=? cmd "now") + (let ((ts (number->string (time-second (current-time))))) + (send-message ed SCI_INSERTTEXT -1 ts) + (echo-message! echo (str "Inserted timestamp: " ts)))) + ((string=? cmd "from-date") + (let* ((date-str (echo-read-string echo "Date (YYYY-MM-DD HH:MM:SS): " row width))) + (when (and date-str (not (string-empty? date-str))) + (with-catch + (lambda (e) (echo-message! echo (str "Error: " e))) + (lambda () + (let-values (((si so se pid) + (open-process-ports + (str "date -d " (shell-quote (string-trim date-str)) " +%s") + 'block (native-transcoder)))) + (close-port si) + (let ((ts (get-line so))) + (close-port so) (close-port se) + (when (not (eof-object? ts)) + (send-message ed SCI_INSERTTEXT -1 (string-trim ts)) + (echo-message! echo (str "Timestamp: " (string-trim ts))))))))))) + ((string=? cmd "to-date") + (let* ((ts-str (echo-read-string echo "Unix timestamp: " row width))) + (when (and ts-str (not (string-empty? ts-str))) + (with-catch + (lambda (e) (echo-message! echo (str "Error: " e))) + (lambda () + (let-values (((si so se pid) + (open-process-ports + (str "date -d @" (string-trim ts-str)) + 'block (native-transcoder)))) + (close-port si) + (let ((date (get-line so))) + (close-port so) (close-port se) + (when (not (eof-object? date)) + (send-message ed SCI_INSERTTEXT -1 (string-trim date)) + (echo-message! echo (str "Date: " (string-trim date))))))))))) + (else (echo-message! echo "Unknown option. Use: now, from-date, to-date"))))))) + +;; --- Feature 4: Format JSON --- + +(def (cmd-format-json app) + "Pretty-print JSON in the current buffer or selection." + (let* ((echo (app-state-echo app)) + (frame (app-state-frame app)) + (win (current-window frame)) + (ed (edit-window-editor win)) + (start (send-message ed SCI_GETSELECTIONSTART 0 0)) + (end (send-message ed SCI_GETSELECTIONEND 0 0)) + (has-sel (not (= start end))) + (text (if has-sel + (editor-get-text-range ed start end) + (editor-get-text ed)))) + (with-catch + (lambda (e) (echo-message! echo (str "JSON format error: " e))) + (lambda () + (let-values (((si so se pid) + (open-process-ports "python3 -m json.tool" + 'block (native-transcoder)))) + (put-string si text) + (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"))) + (if has-sel + (begin + (send-message ed SCI_DELETERANGE start (- end start)) + (send-message ed SCI_INSERTTEXT start result)) + (begin + (editor-set-text ed result) + (editor-goto-pos ed 0))) + (echo-message! echo "JSON formatted"))) + (loop (cons line lines)))))))))) + +;; --- Feature 5: Minify JSON --- + +(def (cmd-minify-json app) + "Minify JSON in the current buffer or selection." + (let* ((echo (app-state-echo app)) + (frame (app-state-frame app)) + (win (current-window frame)) + (ed (edit-window-editor win)) + (start (send-message ed SCI_GETSELECTIONSTART 0 0)) + (end (send-message ed SCI_GETSELECTIONEND 0 0)) + (has-sel (not (= start end))) + (text (if has-sel + (editor-get-text-range ed start end) + (editor-get-text ed)))) + (with-catch + (lambda (e) (echo-message! echo (str "JSON minify error: " e))) + (lambda () + (let-values (((si so se pid) + (open-process-ports + "python3 -c 'import sys,json; print(json.dumps(json.load(sys.stdin),separators=(\",\",\":\")))')" + 'block (native-transcoder)))) + (put-string si text) + (close-port si) + (let ((result (get-line so))) + (close-port so) (close-port se) + (when (not (eof-object? result)) + (let ((minified (string-trim result))) + (if has-sel + (begin + (send-message ed SCI_DELETERANGE start (- end start)) + (send-message ed SCI_INSERTTEXT start minified)) + (begin + (editor-set-text ed minified) + (editor-goto-pos ed 0))) + (echo-message! echo (str "JSON minified (" (string-length minified) " chars)")))))))))) + +;; --- Feature 6: File Info --- + +(def (cmd-file-info app) + "Show detailed information about the current file." + (let* ((echo (app-state-echo app)) + (frame (app-state-frame app)) + (win (current-window frame)) + (ed (edit-window-editor win)) + (buf (edit-window-buffer win)) + (file (buffer-file buf))) + (if (not file) + (echo-message! echo "No file associated with buffer") + (with-catch + (lambda (e) (echo-message! echo (str "file-info error: " e))) + (lambda () + (let-values (((si so se pid) + (open-process-ports + (str "stat --printf='Size: %s bytes\\nModified: %y\\nPermissions: %A\\nOwner: %U:%G\\n' " + (shell-quote file) + " && file --brief " (shell-quote file) + " && wc -l < " (shell-quote file)) + '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) + (echo-message! echo (string-join (reverse lines) " | "))) + (loop (cons (string-trim line) lines))))))))))) + +;; --- Feature 7: Git Contributors --- + +(def (cmd-git-contributors app) + "Show top contributors for the current repository." + (let* ((echo (app-state-echo app)) + (frame (app-state-frame app)) + (win (current-window frame)) + (ed (edit-window-editor win))) + (with-catch + (lambda (e) (echo-message! echo (str "git error: " e))) + (lambda () + (let-values (((si so se pid) + (open-process-ports + "git shortlog -sn --all | head -20" + '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"))) + (when (not (string-empty? result)) + (let* ((new-buf (create-buffer "*git-contributors*"))) + (switch-to-buffer (app-state-frame app) new-buf) + (let ((new-ed (edit-window-editor (current-window (app-state-frame app))))) + (editor-set-text new-ed (str "=== Git Contributors ===\n\n" result "\n"))) + (echo-message! echo "Git contributors loaded"))))) + (loop (cons line lines)))))))))) + +;; --- Feature 8: Git File History --- + +(def (cmd-git-file-history app) + "Show the git log for the current file." + (let* ((echo (app-state-echo app)) + (frame (app-state-frame app)) + (win (current-window frame)) + (buf (edit-window-buffer win)) + (file (buffer-file buf))) + (if (not file) + (echo-message! echo "No file associated with buffer") + (with-catch + (lambda (e) (echo-message! echo (str "git error: " e))) + (lambda () + (let-values (((si so se pid) + (open-process-ports + (str "git log --oneline -30 -- " (shell-quote file)) + '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"))) + (if (string-empty? result) + (echo-message! echo "No git history for this file") + (let* ((new-buf (create-buffer "*git-file-history*"))) + (switch-to-buffer (app-state-frame app) new-buf) + (let ((new-ed (edit-window-editor (current-window (app-state-frame app))))) + (editor-set-text new-ed (str "=== Git History: " file " ===\n\n" result "\n"))) + (echo-message! echo "Git file history loaded"))))) + (loop (cons line lines))))))))))) + +;; --- Feature 9: Copy Git Branch --- + +(def (cmd-copy-git-branch app) + "Copy the current git branch name to the kill ring." + (let* ((echo (app-state-echo app))) + (with-catch + (lambda (e) (echo-message! echo (str "git error: " e))) + (lambda () + (let-values (((si so se pid) + (open-process-ports "git rev-parse --abbrev-ref HEAD" + 'block (native-transcoder)))) + (close-port si) + (let ((branch (get-line so))) + (close-port so) (close-port se) + (if (eof-object? branch) + (echo-message! echo "Not in a git repository") + (let ((name (string-trim branch))) + (let* ((frame (app-state-frame app)) + (win (current-window frame)) + (ed (edit-window-editor win))) + (send-message ed SCI_COPYTEXT (string-length name) name) + (echo-message! echo (str "Copied branch: " name))))))))))) + +;; --- Feature 10: Eval and Replace --- + +(def (cmd-eval-and-replace app) + "Evaluate the selected text as a shell expression and replace with result." + (let* ((echo (app-state-echo app)) + (frame (app-state-frame app)) + (win (current-window frame)) + (ed (edit-window-editor win)) + (start (send-message ed SCI_GETSELECTIONSTART 0 0)) + (end (send-message ed SCI_GETSELECTIONEND 0 0))) + (if (= start end) + (echo-message! echo "No selection — select an expression to evaluate") + (let ((text (editor-get-text-range ed start end))) + (with-catch + (lambda (e) (echo-message! echo (str "Eval error: " e))) + (lambda () + (let-values (((si so se pid) + (open-process-ports (str "echo " (shell-quote text) " | bc -l 2>/dev/null || eval " (shell-quote text)) + '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"))) + (if (string-empty? result) + (echo-message! echo "No output from evaluation") + (begin + (send-message ed SCI_DELETERANGE start (- end start)) + (send-message ed SCI_INSERTTEXT start result) + (echo-message! echo (str "Replaced with: " result)))))) + (loop (cons line lines)))))))))))) --- a/src/jerboa-emacs/editor-extra-modes.ss +++ b/src/jerboa-emacs/editor-extra-modes.ss @@ -5922,3 +5922,227 @@ (wrapped (str open-char text close-char))) (editor-replace-selection ed wrapped) (echo-message! echo "Region wrapped"))))))) + +;; ===== Round 14 Batch 1 ===== + +;; --- Feature 1: Insert Date Header --- + +(def (cmd-insert-date-header app) + "Insert a date header comment (e.g., for changelog entries)." + (let* ((echo (app-state-echo app)) + (frame (app-state-frame app)) + (win (current-window frame)) + (ed (edit-window-editor win)) + (user (or (getenv "USER") "unknown")) + (now (time-second (current-time))) + (header (str "## " now " - " user "\n\n"))) + (editor-insert-text ed header) + (echo-message! echo "Date header inserted"))) + +;; --- Feature 2: Highlight Phrase --- + +(def *highlight-phrases* '()) + +(def (cmd-highlight-phrase app) + "Highlight all occurrences of a phrase in the current buffer." + (let* ((echo (app-state-echo app)) + (frame (app-state-frame app)) + (win (current-window frame)) + (ed (edit-window-editor win)) + (row (tui-rows)) (width (tui-cols)) + (phrase (echo-read-string echo "Highlight phrase: " row width))) + (when (and phrase (not (string-empty? phrase))) + (set! *highlight-phrases* (cons phrase *highlight-phrases*)) + ;; Use indicator 17 for phrase highlighting + (send-message ed SCI_INDICSETSTYLE 17 6) ;; INDIC_BOX + (send-message ed SCI_INDICSETFORE 17 #xFF8000) ;; orange + (send-message ed SCI_SETINDICATORCURRENT 17 0) + (let* ((len (send-message ed SCI_GETLENGTH 0 0)) + (text (editor-get-text ed len)) + (plen (string-length phrase)) + (count (let loop ((pos 0) (n 0)) + (let ((found (string-contains (substring text pos (string-length text)) phrase))) + (if (not found) n + (let ((abs-pos (+ pos found))) + (send-message ed SCI_INDICATORFILLRANGE abs-pos plen) + (loop (+ abs-pos plen) (+ n 1)))))))) + (echo-message! echo (str "Highlighted " count " occurrences of \"" phrase "\"")))))) + +;; --- Feature 3: Unhighlight All --- + +(def (cmd-unhighlight-all app) + "Remove all phrase highlights." + (let* ((echo (app-state-echo app)) + (frame (app-state-frame app)) + (win (current-window frame)) + (ed (edit-window-editor win)) + (len (send-message ed SCI_GETLENGTH 0 0))) + (send-message ed SCI_SETINDICATORCURRENT 17 0) + (send-message ed SCI_INDICATORCLEARRANGE 0 len) + (set! *highlight-phrases* '()) + (echo-message! echo "All highlights cleared"))) + +;; --- Feature 4: Widen Buffer --- + +(def (cmd-widen-buffer app) + "Remove narrowing — show the entire buffer content." + (let ((echo (app-state-echo app))) + ;; In Scintilla, there's no native narrowing, so this is a no-op/informational + (echo-message! echo "Buffer widened (no narrowing active)"))) + +;; --- Feature 5: Move Region Up --- + +(def (cmd-move-region-up app) + "Move the selected lines up by one line." + (let* ((echo (app-state-echo app)) + (frame (app-state-frame app)) + (win (current-window frame)) + (ed (edit-window-editor win)) + (sel-start (send-message ed SCI_GETSELECTIONSTART 0 0)) + (sel-end (send-message ed SCI_GETSELECTIONEND 0 0)) + (start-line (send-message ed SCI_LINEFROMPOSITION sel-start 0)) + (end-line (send-message ed SCI_LINEFROMPOSITION sel-end 0))) + (if (= start-line 0) + (echo-message! echo "Already at top") + (begin + (send-message ed SCI_MOVESELECTEDLINESUP 0 0) + (echo-message! echo "Moved up"))))) + +;; --- Feature 6: Move Region Down --- + +(def (cmd-move-region-down app) + "Move the selected lines down by one line." + (let* ((echo (app-state-echo app)) + (frame (app-state-frame app)) + (win (current-window frame)) + (ed (edit-window-editor win))) + (send-message ed SCI_MOVESELECTEDLINESDOWN 0 0) + (echo-message! echo "Moved down"))) + +;; --- Feature 7: JSON to YAML --- + +(def (cmd-json-to-yaml app) + "Convert JSON buffer content to YAML." + (let* ((echo (app-state-echo app)) + (frame (app-state-frame app)) + (win (current-window frame)) + (ed (edit-window-editor win)) + (len (send-message ed SCI_GETLENGTH 0 0)) + (text (editor-get-text ed len))) + (when (and text (> (string-length text) 0)) + (with-catch + (lambda (e) (echo-message! echo (str "Conversion error: " e))) + (lambda () + (let-values (((p-stdin p-stdout p-stderr pid) + (open-process-ports + "python3 -c 'import sys,json,yaml;yaml.dump(json.load(sys.stdin),sys.stdout,default_flow_style=False)' 2>/dev/null" + 'block (native-transcoder)))) + (display text p-stdin) + (close-port p-stdin) + (let loop ((lines '())) + (let ((line (get-line p-stdout))) + (if (eof-object? line) + (begin + (close-port p-stdout) (close-port p-stderr) + (let ((yaml (string-join (reverse lines) "\n"))) + (when (> (string-length yaml) 0) + (editor-set-text ed yaml) + (editor-goto-pos ed 0) + (echo-message! echo "Converted to YAML")))) + (loop (cons line lines))))))))))) + +;; --- Feature 8: YAML to JSON --- + +(def (cmd-yaml-to-json app) + "Convert YAML buffer content to JSON." + (let* ((echo (app-state-echo app)) + (frame (app-state-frame app)) + (win (current-window frame)) + (ed (edit-window-editor win)) + (len (send-message ed SCI_GETLENGTH 0 0)) + (text (editor-get-text ed len))) + (when (and text (> (string-length text) 0)) + (with-catch + (lambda (e) (echo-message! echo (str "Conversion error: " e))) + (lambda () + (let-values (((p-stdin p-stdout p-stderr pid) + (open-process-ports + "python3 -c 'import sys,json,yaml;json.dump(yaml.safe_load(sys.stdin),sys.stdout,indent=2)' 2>/dev/null" + 'block (native-transcoder)))) + (display text p-stdin) + (close-port p-stdin) + (let loop ((lines '())) + (let ((line (get-line p-stdout))) + (if (eof-object? line) + (begin + (close-port p-stdout) (close-port p-stderr) + (let ((json (string-join (reverse lines) "\n"))) + (when (> (string-length json) 0) + (editor-set-text ed json) + (editor-goto-pos ed 0) + (echo-message! echo "Converted to JSON")))) + (loop (cons line lines))))))))))) + +;; --- Feature 9: CSV to JSON --- + +(def (cmd-csv-to-json app) + "Convert CSV buffer content to JSON." + (let* ((echo (app-state-echo app)) + (frame (app-state-frame app)) + (win (current-window frame)) + (ed (edit-window-editor win)) + (len (send-message ed SCI_GETLENGTH 0 0)) + (text (editor-get-text ed len))) + (when (and text (> (string-length text) 0)) + (with-catch + (lambda (e) (echo-message! echo (str "Conversion error: " e))) + (lambda () + (let-values (((p-stdin p-stdout p-stderr pid) + (open-process-ports + "python3 -c 'import sys,csv,json;r=csv.DictReader(sys.stdin);json.dump(list(r),sys.stdout,indent=2)'" + 'block (native-transcoder)))) + (display text p-stdin) + (close-port p-stdin) + (let loop ((lines '())) + (let ((line (get-line p-stdout))) + (if (eof-object? line) + (begin + (close-port p-stdout) (close-port p-stderr) + (let ((json (string-join (reverse lines) "\n"))) + (when (> (string-length json) 0) + (editor-set-text ed json) + (editor-goto-pos ed 0) + (echo-message! echo "Converted to JSON")))) + (loop (cons line lines))))))))))) + +;; --- Feature 10: JSON to CSV --- + +(def (cmd-json-to-csv app) + "Convert JSON array of objects to CSV." + (let* ((echo (app-state-echo app)) + (frame (app-state-frame app)) + (win (current-window frame)) + (ed (edit-window-editor win)) + (len (send-message ed SCI_GETLENGTH 0 0)) + (text (editor-get-text ed len))) + (when (and text (> (string-length text) 0)) + (with-catch + (lambda (e) (echo-message! echo (str "Conversion error: " e))) + (lambda () + (let-values (((p-stdin p-stdout p-stderr pid) + (open-process-ports + "python3 -c 'import sys,csv,json;d=json.load(sys.stdin);w=csv.DictWriter(sys.stdout,d[0].keys());w.writeheader();w.writerows(d)' 2>/dev/null" + 'block (native-transcoder)))) + (display text p-stdin) + (close-port p-stdin) + (let loop ((lines '())) + (let ((line (get-line p-stdout))) + (if (eof-object? line) + (begin + (close-port p-stdout) (close-port p-stderr) + (let ((csv (string-join (reverse lines) "\n"))) + (when (> (string-length csv) 0) + (editor-set-text ed csv) + (editor-goto-pos ed 0) + (echo-message! echo "Converted to CSV")))) + (loop (cons line lines))))))))))) --- a/src/jerboa-emacs/editor-extra-regs2.ss +++ b/src/jerboa-emacs/editor-extra-regs2.ss @@ -1725,4 +1725,26 @@ (register-command! 'copy-line-number cmd-copy-line-number) (register-command! 'rename-file-and-buffer cmd-rename-file-and-buffer) (register-command! 'sudo-edit cmd-sudo-edit) + ;; Round 14 batch 1: insert-date-header, highlight-phrase, unhighlight-all, widen-buffer, move-region-up, move-region-down, json-to-yaml, yaml-to-json, csv-to-json, json-to-csv + (register-command! 'insert-date-header cmd-insert-date-header) + (register-command! 'highlight-phrase cmd-highlight-phrase) + (register-command! 'unhighlight-all cmd-unhighlight-all) + (register-command! 'widen-buffer cmd-widen-buffer) + (register-command! 'move-region-up cmd-move-region-up) + (register-command! 'move-region-down cmd-move-region-down) + (register-command! 'json-to-yaml cmd-json-to-yaml) + (register-command! 'yaml-to-json cmd-yaml-to-json) + (register-command! 'csv-to-json cmd-csv-to-json) + (register-command! 'json-to-csv cmd-json-to-csv) + ;; Round 14 batch 2: hex-to-rgb, rgb-to-hex, unix-timestamp, format-json, minify-json, file-info, git-contributors, git-file-history, copy-git-branch, eval-and-replace + (register-command! 'hex-to-rgb cmd-hex-to-rgb) + (register-command! 'rgb-to-hex cmd-rgb-to-hex) + (register-command! 'unix-timestamp cmd-unix-timestamp) + (register-command! 'format-json cmd-format-json) + (register-command! 'minify-json cmd-minify-json) + (register-command! 'file-info cmd-file-info) + (register-command! 'git-contributors cmd-git-contributors) + (register-command! 'git-file-history cmd-git-file-history) + (register-command! 'copy-git-branch cmd-copy-git-branch) + (register-command! 'eval-and-replace cmd-eval-and-replace) )