mirror of
https://github.com/pestctrl/emacs-config.git
synced 2026-02-16 16:24:18 +00:00
169 lines
5.9 KiB
EmacsLisp
169 lines
5.9 KiB
EmacsLisp
;; This buffer is for text that is not saved, and for Lisp evaluation.
|
|
;; To create a file, visit it with C-x C-f and enter text in its buffer.
|
|
(require 'cl)
|
|
|
|
(defvar self-chat-num 0)
|
|
(defvar self-chat-characters nil)
|
|
(defvar self-chat-random-list nil)
|
|
(defvar self-chat-last nil)
|
|
(defvar self-chat-last2 nil)
|
|
(defvar self-chat-highlights nil)
|
|
(defvar self-chat-alist nil)
|
|
|
|
(define-derived-mode self-chat-mode fundamental-mode "self-chat"
|
|
"This is a mode where I become crazy and talk to myself."
|
|
(setq font-lock-defaults '(self-chat-highlights))
|
|
(olivetti-mode 1))
|
|
|
|
(defun self-chat-buffer ()
|
|
(interactive)
|
|
(--> (let ((org-time-was-given t))
|
|
(org-read-date t nil ""))
|
|
(format "*self-chat-%s*"
|
|
it)
|
|
(get-buffer-create it)
|
|
(switch-to-buffer it))
|
|
(self-chat-mode))
|
|
|
|
(modify-syntax-entry ?\" " " self-chat-mode-syntax-table)
|
|
|
|
(define-key self-chat-mode-map (kbd "RET") #'self-chat-insert-next)
|
|
(define-key self-chat-mode-map (kbd "DEL") #'delete-self-chat-line)
|
|
(define-key self-chat-mode-map (kbd "C-DEL") #'sc/delete-full-line)
|
|
(define-key self-chat-mode-map (kbd "M-DEL") #'delete-self-chat-text)
|
|
|
|
(defun self-chat-insert-next ()
|
|
(interactive)
|
|
(call-interactively #'user-chat/body))
|
|
|
|
(defun chat-pre ()
|
|
(when (or (not self-chat-last)
|
|
(not (= self-chat-num self-chat-last)))
|
|
(setq self-chat-last2 self-chat-last
|
|
self-chat-last self-chat-num))
|
|
(unless (and (eobp) (bobp))
|
|
;; Are we fixing up an old line, or creating a new one?
|
|
(if (save-excursion
|
|
(beginning-of-line)
|
|
(not (looking-at (rx (+ nonl) ":"))))
|
|
(progn
|
|
(beginning-of-line)
|
|
(kill-line))
|
|
(call-interactively #'newline)
|
|
(call-interactively #'newline)))
|
|
(insert "> "))
|
|
|
|
(defun chat-post ()
|
|
(if-let ((name (alist-get self-chat-num self-chat-alist)))
|
|
(insert name ": ")))
|
|
|
|
(defun sc/delete-full-line ()
|
|
(interactive)
|
|
(set-mark-command nil)
|
|
(previous-line)
|
|
(previous-line)
|
|
(end-of-line)
|
|
(call-interactively #'kill-region))
|
|
|
|
(defun delete-self-chat-text ()
|
|
(interactive)
|
|
(beginning-of-line)
|
|
(search-forward ":")
|
|
(call-interactively #'forward-char)
|
|
(call-interactively #'set-mark-command)
|
|
(end-of-line)
|
|
(call-interactively #'kill-region))
|
|
|
|
(defun delete-self-chat-line ()
|
|
(interactive)
|
|
(save-excursion
|
|
(call-interactively #'set-mark-command)
|
|
(beginning-of-line)
|
|
(call-interactively #'kill-ring-save))
|
|
(cond ((= 0 (length (current-kill 0)))
|
|
(call-interactively #'backward-char))
|
|
((string-match-p
|
|
(rx line-start ">" (optional " ") (optional (+ alpha) ":" (optional " ")) line-end)
|
|
(current-kill 0))
|
|
(sc/delete-full-line))
|
|
(t
|
|
(call-interactively #'delete-backward-char))))
|
|
|
|
(defun swap (LIST el1 el2)
|
|
"in LIST swap indices EL1 and EL2 in place"
|
|
(let ((tmp (elt LIST el1)))
|
|
(setf (elt LIST el1) (elt LIST el2))
|
|
(setf (elt LIST el2) tmp)))
|
|
|
|
|
|
(defun shuffle (LIST)
|
|
"Shuffle the elements in LIST.
|
|
shuffling is done in place."
|
|
(loop for i in (reverse (number-sequence 1 (1- (length LIST))))
|
|
do (let ((j (random (+ i 1))))
|
|
(swap LIST i j)))
|
|
LIST)
|
|
|
|
(defmacro define-users (list)
|
|
`(progn
|
|
(setq self-chat-num 0
|
|
self-chat-last nil
|
|
self-chat-last2 nil
|
|
self-chat-highlights nil
|
|
self-chat-alist nil
|
|
self-chat-characters
|
|
',(remove-if-not (lambda (char)
|
|
(cadddr char))
|
|
list))
|
|
(defhydra user-chat (:exit t
|
|
:body-pre (chat-pre)
|
|
:after-exit (chat-post))
|
|
""
|
|
("RET" nil "Same")
|
|
("TAB" (when self-chat-last2 (setq self-chat-num self-chat-last2)) "Switch")
|
|
,@(let ((num 0))
|
|
(mapcar #'(lambda (triple)
|
|
(let ((name (car triple))
|
|
(key (cadr triple)))
|
|
(prog1 `(,key (setq self-chat-num ,num) ,name)
|
|
(cl-incf num))))
|
|
list))
|
|
("r" (setq self-chat-num
|
|
(progn
|
|
(unless self-chat-random-list
|
|
(setq self-chat-random-list
|
|
(--> (length self-chat-characters)
|
|
(number-sequence 0 (1- it))
|
|
(shuffle it))))
|
|
(pop self-chat-random-list)))
|
|
"Random"))
|
|
,@(let ((num 0))
|
|
(mapcan #'(lambda (triple)
|
|
(let* ((name (car triple))
|
|
(color (caddr triple))
|
|
(face-sym (intern (format "sc-%s-face" (downcase name)))))
|
|
(prog1`((add-to-list 'self-chat-alist
|
|
'(,num . ,name))
|
|
(defface ,face-sym '((t (:foreground ,color))) ,(concat name
|
|
"'s face for self-chat-mode"))
|
|
(defvar ,face-sym ',face-sym)
|
|
(add-to-list 'self-chat-highlights
|
|
'(,(format "^> %s:.*$" name) . ,face-sym))
|
|
(add-to-list 'self-chat-highlights
|
|
'(,(rx symbol-start (literal name) symbol-end) 0 ,face-sym prepend)))
|
|
(cl-incf num))))
|
|
list))))
|
|
|
|
(define-users (("Tau" "t" "turquoise1" t)
|
|
("Arc" "a" "gold" t)
|
|
("Tom" "T" "rosy brown" t)
|
|
("Dan" "d" "spring green" t)
|
|
("Ver" "v" "white" t)
|
|
("Coop" "c" "cornsilk" t)
|
|
("Net" "n" "magenta" t)
|
|
|
|
("Someone" "s" "dim gray" nil)
|
|
("Everyone" "e" "pale green" nil)
|
|
("Note" "N" "dim gray" nil)))
|
|
|
|
(provide 'self-chat-mode)
|