finish setting up coloring

This commit is contained in:
2026-01-09 14:42:25 -05:00
parent de7e28648b
commit 9006d5b801
2 changed files with 59 additions and 20 deletions

1
.gitignore vendored
View File

@@ -10,3 +10,4 @@ eshell
parinfer-rust parinfer-rust
.mc-lists.el .mc-lists.el
codex-sessions codex-sessions
codex-sessions-history

View File

@@ -63,6 +63,12 @@
:type 'string :type 'string
:group 'codex) :group 'codex)
(defcustom codex-sessions-history-dir
(concat (file-name-parent-directory user-init-file) "codex-sessions-history/")
"Directory where Codex session histories are stored."
:type 'directory
:group 'codex)
(defvar codex--session-id nil) (defvar codex--session-id nil)
(defvar codex-mode-map (defvar codex-mode-map
@@ -75,16 +81,54 @@
map) map)
"Keymap for `codex-mode'.") "Keymap for `codex-mode'.")
(defconst codex--font-lock-keywords
'(("^---$" . 'codex-prompt-delimiter-face)
("^User:$" . 'codex-user-prompt-face)
("^Codex:$" . 'codex-assistant-prompt-face)))
(define-derived-mode codex-mode fundamental-mode "Codex" (define-derived-mode codex-mode fundamental-mode "Codex"
"Major mode for chatting with Codex." "Major mode for chatting with Codex."
(setq-local buffer-read-only nil) (setq-local buffer-read-only nil)
(setq-local truncate-lines (not codex-wrap-lines)) (setq-local truncate-lines (not codex-wrap-lines))
(setq-local font-lock-defaults '(codex--font-lock-keywords))
(setq-local codex--busy nil)) (setq-local codex--busy nil))
(defvar-local codex--prompt-start nil) (defvar-local codex--prompt-start nil)
(defun codex--propertize-label (text face) (defun codex--ensure-history-dir ()
(propertize text 'face face 'rear-nonsticky '(face))) (make-directory codex-sessions-history-dir t))
(defun codex--history-file ()
(when (and codex--session-id (not (string-empty-p codex--session-id)))
(expand-file-name codex--session-id codex-sessions-history-dir)))
(defun codex--set-prompt-start-from-buffer ()
(let* ((haystack (buffer-string))
(needle "---\nUser:\n")
(index (cl-search needle haystack :from-end t)))
(when index
(setq codex--prompt-start (copy-marker (+ (length needle) index)))
t)))
(defun codex--save-session-history ()
(with-codex-buffer
(let ((history-file (codex--history-file)))
(when history-file
(codex--ensure-history-dir)
(write-region (point-min) (point-max) history-file nil 'silent)))))
(defun codex--load-session-history ()
(with-codex-buffer
(let ((history-file (codex--history-file)))
(setq codex--prompt-start nil)
(erase-buffer)
(if (and history-file (file-exists-p history-file))
(progn
(insert-file-contents history-file)
(goto-char (point-max))
(unless (codex--set-prompt-start-from-buffer)
(user-prompt)))
(user-prompt)))))
(defun list->hash-set (list &optional test) (defun list->hash-set (list &optional test)
"Return a hash table whose keys are the elements of LIST." "Return a hash table whose keys are the elements of LIST."
@@ -98,22 +142,23 @@
(defun prompt-delimiter () (defun prompt-delimiter ()
(newline) (newline)
(insert (codex--propertize-label "---" 'codex-prompt-delimiter-face)) (insert "---")
(newline)) (newline))
(defun user-prompt () (defun user-prompt ()
(prompt-delimiter) (prompt-delimiter)
(insert (codex--propertize-label "User:" 'codex-user-prompt-face)) (insert "User:")
(newline) (newline)
(setq codex--prompt-start (point-marker))) (setq codex--prompt-start (point-marker)))
(defun codex--write-to-chat (msg) (defun codex--write-to-chat (msg)
(with-codex-buffer (with-codex-buffer
(newline) (newline)
(insert (codex--propertize-label "Codex:" 'codex-assistant-prompt-face)) (insert "Codex:")
(newline) (newline)
(insert msg) (insert msg)
(user-prompt))) (user-prompt)
(codex--save-session-history)))
(defun codex--parse-session-id (jsons) (defun codex--parse-session-id (jsons)
(let ((thread-started-message (let ((thread-started-message
@@ -185,12 +230,8 @@
(marker-position codex--prompt-start)))) (marker-position codex--prompt-start))))
;; fallback in case we somehow lost where our user prompt starts ;; fallback in case we somehow lost where our user prompt starts
(unless prompt-start (unless prompt-start
(let* ((haystack (buffer-string)) (when (codex--set-prompt-start-from-buffer)
(needle "---\nUser:\n") (setq prompt-start (marker-position codex--prompt-start))))
(index (cl-search needle haystack :from-end t)))
(when index
(setq prompt-start (+ (length needle) index))
(setq codex--prompt-start (copy-marker prompt-start)))))
(unless prompt-start (unless prompt-start
(error "No current prompt start")) (error "No current prompt start"))
(buffer-substring-no-properties prompt-start (point-max))))) (buffer-substring-no-properties prompt-start (point-max)))))
@@ -203,6 +244,7 @@
(error "Prompt is empty!") (error "Prompt is empty!")
(newline) (newline)
(insert "---") (insert "---")
(codex--save-session-history)
(codex--send prompt))))) (codex--send prompt)))))
;;;###autoload ;;;###autoload
@@ -216,7 +258,7 @@
(pop-to-buffer buf) (pop-to-buffer buf)
(unless (derived-mode-p 'codex-mode) (unless (derived-mode-p 'codex-mode)
(codex-mode)) (codex-mode))
(user-prompt) (codex--load-session-history)
(goto-char (point-max))))) (goto-char (point-max)))))
(defun codex--read-sessions-file () (defun codex--read-sessions-file ()
@@ -240,13 +282,9 @@
(interactive (interactive
(list (completing-read "Session: " (cons '("New") (codex--read-sessions-file))))) (list (completing-read "Session: " (cons '("New") (codex--read-sessions-file)))))
(let ((session-id (cdr (assoc new-session (codex--read-sessions-file))))) (let ((session-id (cdr (assoc new-session (codex--read-sessions-file)))))
(codex--save-session-history)
(setf codex--session-id session-id) (setf codex--session-id session-id)
(with-codex-buffer (codex--load-session-history)))
(prompt-delimiter)
(if session-id
(insert (concat "Switching to session " session-id))
(insert "Switching to new session"))
(user-prompt))))
(defun codex-rename-current-session (name) (defun codex-rename-current-session (name)
(interactive "sNew name: ") (interactive "sNew name: ")