Skip to content

Commit 0031566

Browse files
committed
start
1 parent cae1637 commit 0031566

File tree

1 file changed

+86
-1
lines changed

1 file changed

+86
-1
lines changed

chatgpt.el

Lines changed: 86 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
;; Maintainer: Shen, Jen-Chieh <[email protected]>
77
;; URL: https://github.com/emacs-openai/chatgpt
88
;; Version: 0.1.0
9-
;; Package-Requires: ((emacs "26.1") (openai "0.1.0"))
9+
;; Package-Requires: ((emacs "26.1") (openai "0.1.0") (ht "2.0"))
1010
;; Keywords: comm openai
1111

1212
;; This file is not part of GNU Emacs.
@@ -31,13 +31,98 @@
3131

3232
;;; Code:
3333

34+
(require 'comint)
35+
3436
(require 'openai)
37+
(require 'ht)
3538

3639
(defgroup chatgpt nil
3740
"Use ChatGPT inside Emacs."
3841
:prefix "chatgpt-"
3942
:group 'comm
4043
:link '(url-link :tag "Repository" "https://github.com/emacs-openai/chatgpt"))
4144

45+
(defconst chatgpt-buffer-name-format "*ChatGPT: <%s>*"
46+
"Name of the buffer to use for the `chatgpt' comint instance.")
47+
48+
(defvar chatgpt-instances (ht-create)
49+
"List of instances, each pair is consist of (index . buffer).")
50+
51+
;;
52+
;;; Util
53+
54+
(defun chatgpt--pop-to-buffer (buffer-or-name)
55+
""
56+
(pop-to-buffer buffer-or-name `((display-buffer-in-direction)
57+
(dedicated . t))))
58+
59+
;;
60+
;;; Core
61+
62+
(defun chatgpt--live-instances ()
63+
"Return a list of live instances."
64+
(let ((live-instances))
65+
(ht-map (lambda (index buffer)
66+
(when (get-buffer buffer)
67+
(push buffer live-instances)))
68+
chatgpt-instances)
69+
(reverse live-instances)))
70+
71+
(defun chatgpt--shown-instances ()
72+
"Return a list of live instances that are displayed on the screen."
73+
(let ((live-instances (chatgpt--live-instances))
74+
(shown-instances))
75+
(dolist (instance shown-instances)
76+
(when (get-buffer-window instance)
77+
(push instance shown-instances)))
78+
(reverse shown-instances)))
79+
80+
(defun chatgpt--new-index ()
81+
"Find killed instance before giving new index."
82+
(let ((target))
83+
(cl-some (lambda (index)
84+
(let ((buffer (ht-get chatgpt-instances index)))
85+
(unless (get-buffer buffer) ; if buffer is killed
86+
(setq target index)
87+
t)))
88+
(ht-keys chatgpt-instances))
89+
(unless target ; No killed instance?
90+
(setq target (ht-size chatgpt-instances))) ; Create a new one!
91+
target))
92+
93+
;;;###autoload
94+
(define-derived-mode chatgpt-mode comint-mode "ChatGPT"
95+
"Major mode for `chatgpt-mode'.
96+
97+
\\<chatgpt-mode-map>"
98+
(setq comint-prompt-regexp cassandra-prompt-regexp
99+
comint-prompt-read-only t))
100+
101+
;;;###autoload
102+
(defun chatgpt-new ()
103+
"Run a new instance of ChatGPT."
104+
(interactive)
105+
(let* ((new-index (chatgpt--new-index))
106+
(new-buffer-name (format chatgpt-buffer-name-format new-index)))
107+
(when (get-buffer new-buffer-name)
108+
(user-error "Internal Error: creating instance that already exists"))
109+
(ht-set chatgpt-instances new-index (get-buffer-create new-buffer-name))
110+
(with-current-buffer new-buffer-name
111+
(chatgpt-mode 1))
112+
(chatgpt--pop-to-buffer new-buffer-name)))
113+
114+
;;;###autoload
115+
(defun chatgpt ()
116+
"Start ChatGPT with existing instance, else create a new instance."
117+
(interactive)
118+
(let ((live-instances (chatgpt--live-instances))
119+
(shown-instances (chatgpt--shown-instances)))
120+
(cond (shown-instances
121+
(chatgpt--pop-to-buffer (nth 0 shown-instances)))
122+
(live-instances
123+
(chatgpt--pop-to-buffer (nth 0 shown-instances)))
124+
(t
125+
(chatgpt-new)))))
126+
42127
(provide 'chatgpt)
43128
;;; chatgpt.el ends here

0 commit comments

Comments
 (0)