Skip to content

Instantly share code, notes, and snippets.

@zhaojiangbin
Created April 19, 2020 17:50
Show Gist options
  • Save zhaojiangbin/ae76ca86cde0e486affaf9299cadbe76 to your computer and use it in GitHub Desktop.
Save zhaojiangbin/ae76ca86cde0e486affaf9299cadbe76 to your computer and use it in GitHub Desktop.
Emacs: experiment with transient
(require 'transient)
;; True value for boolean variables has to be the slot value of
;; :argument.
(defvar tt--toggle "--toggle")
;; Empty string "" in string variables are considered changed and
;; highlighted in transient as if they were boolean.
(defvar tt--strarg nil)
(defclass tt--class-boolean (transient-infix)
((variable :initarg :variable)))
(defclass tt--class-string (transient-argument)
((variable :initarg :variable)))
(defun tt-reset ()
(interactive)
(setq-local tt--toggle "--toggle")
(setq-local tt--strarg nil)
(setq transient-history nil))
(defun tt-show ()
(interactive)
(message "toggle: %s, string: '%s', history:[\n%s\n]"
(buffer-local-value 'tt--toggle (current-buffer))
(buffer-local-value 'tt--strarg (current-buffer))
(mapconcat (lambda (e) (format "%s" e)) transient-history "\n")))
(cl-defmethod transient-init-value ((obj tt--class-boolean))
(let ((his (oref transient--prefix value)))
(if his
(let ((ent (member (oref obj argument) his)))
(message "toggle init, ref: %s, his: [%s], ent: %s" (oref obj value) his ent)
(oset obj value (car ent)))
(let ((var (buffer-local-value (oref obj variable)
(current-buffer))))
(message "toggle init, ref: %s, var: %s" (oref obj value) var)
(oset obj value var)))))
(cl-defmethod transient-init-value ((obj tt--class-string))
(let ((his (oref transient--prefix value)))
(if his
(let ((ent (member (oref obj history-key) his)))
(message "string init, ref: %s, his: [%s], ent: %s" (oref obj value) his ent)
(oset obj value (car ent)))
(let ((var (buffer-local-value (oref obj variable)
(current-buffer))))
(message "string init, ref: %s, var: %s" (oref obj value) var)
(oset obj value var)))))
(cl-defmethod transient-infix-read ((obj tt--class-boolean))
(message "toggle read, ref: %s" (oref obj value))
(if (oref obj value) nil (oref obj argument)))
(cl-defmethod transient-infix-set ((obj tt--class-boolean) val)
(let ((var-sym (oref obj variable)))
(message "toggle before set, val: %s, var: %s, ref: %s"
val (buffer-local-value var-sym (current-buffer))
(oref obj value))
(oset obj value val)
(set (make-local-variable var-sym) val)
(message "toggle after set, val: %s, var: %s, ref: %s"
val (buffer-local-value var-sym (current-buffer))
(oref obj value))))
(cl-defmethod transient-infix-set ((obj tt--class-string) val)
(let ((var-sym (oref obj variable)))
(message "string before set, val: '%s', var: %s, ref: %s"
val (buffer-local-value var-sym (current-buffer))
(oref obj value))
(oset obj value val)
(set (make-local-variable var-sym) val)
(message "string after set, val: '%s', var: %s, ref: %s"
val (buffer-local-value var-sym (current-buffer))
(oref obj value))))
(define-infix-command tt--arg-toggle ()
:class 'tt--class-boolean
:variable 'tt--toggle
:description (lambda ()
(if (buffer-local-value 'tt--toggle (current-buffer))
"on" "off"))
:key "-o" :argument "--toggle")
;; TODO: show the current value in transient
;;
;; TODO: change from a non-nil value to another non-nil value without
;; having to resetting it to nil first.
(define-infix-command tt--arg-string ()
:class 'tt--class-string
:variable 'tt--strarg
:history-key "tt-str"
:description "string arg"
:key "-v" :argument "--value")
(define-suffix-command tt--run (&optional args)
(interactive (list (transient-args 'tt-popup)))
(message "tt--toggle value: %s, tt--strarg value: '%s'\nargs: [%s], history: [%s]"
(buffer-local-value 'tt--toggle (current-buffer))
(buffer-local-value 'tt--strarg (current-buffer))
(mapconcat #'identity args ",") transient-history))
;; Run interactive command `tt-popup' to start the transient.
(define-transient-command tt-popup
"Test transient"
["arguments"
(tt--arg-toggle)
(tt--arg-string)
("s" "transient switch" "--switch")
("a" "transient argument" "--argument=")
]
["actions"
("r" "run" tt--run)
])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment