@@ -536,6 +536,49 @@ in a more natural order."
536536 :group 'transient
537537 :type 'boolean )
538538
539+ (defcustom transient-always-read-value nil
540+ " Whether to always read the new value.
541+
542+ If this is nil, then certain arguments are unconditionally disabled when
543+ they are invoked while they have a non-nil value. They then have to be
544+ invoked a second time to set another non-nil value. For other arguments
545+ which have a fixed set of possible values, all values are displayed at
546+ all times and the current non-nil value (if any) is highlighted using a
547+ different face.
548+
549+ If this is t, then more arguments will always read the value using the
550+ minibuffer. This is only intended for blind users, for whom the default
551+ behavior is problematic."
552+ :package-version '(transient . " 0.13.0" )
553+ :group 'transient
554+ :type 'boolean )
555+
556+ (defcustom transient-use-accessible-format nil
557+ " Whether to present arguments and commands in a more accessible format.
558+
559+ If this is nil, then the default format, specified by the `format' slot
560+ is used. Blind users should set this to either `braille' or `audio' to
561+ use the alternative format specified by the respective slot.
562+
563+ Please note that these defaults are still subject to change and that I
564+ need your help to come up with appropriate values. If necessary I will
565+ also make this more customizable and add more documentation.
566+
567+ If you enabled this, then `transient-always-read-value' likely should be
568+ enabled as well."
569+ :package-version '(transient . " 0.13.0" )
570+ :group 'transient
571+ :type '(choice (const :tag " Use format specified by `format' slot" nil )
572+ (const :tag " Use format specified by `braille' slot" braille)
573+ (const :tag " Use format specified by `audio' slot" audio)))
574+
575+ (defcustom transient-overriding-format-alist nil
576+ " TODO"
577+ :package-version '(transient . " 0.13.0" )
578+ :group 'transient
579+ :type '(alist :key-type (symbol :tag " Class" )
580+ :value-type (string :tag " Format" )))
581+
539582(defcustom transient-describe-menu nil
540583 " Whether to begin the menu buffer with a very short description.
541584
@@ -986,6 +1029,8 @@ predicate slots or more than one `inapt-if*' slots are non-nil."
9861029 (command :initarg :command )
9871030 (transient :initarg :transient )
9881031 (format :initarg :format :initform " %k %d" )
1032+ (braille :initarg :braille :initform " %i%k %d" )
1033+ (audio :initarg :audio :initform " %i%k %d" )
9891034 (description :initarg :description :initform nil )
9901035 (face :initarg :face :initform nil )
9911036 (show-help :initarg :show-help :initform nil ))
@@ -1016,7 +1061,9 @@ Technically a suffix object with no associated command.")
10161061 (reader :initarg :reader :initform nil )
10171062 (prompt :initarg :prompt :initform nil )
10181063 (choices :initarg :choices :initform nil )
1019- (format :initform " %k %d (%v)" ))
1064+ (format :initform " %k %d (%v)" )
1065+ (braille :initform " %i%k %a is %V (%d)" )
1066+ (audio :initform " %i%k %a is %V (%d)" ))
10201067 " Transient infix command."
10211068 :abstract t )
10221069
@@ -1032,7 +1079,9 @@ Technically a suffix object with no associated command.")
10321079
10331080(defclass transient-variable (transient-infix)
10341081 ((variable :initarg :variable )
1035- (format :initform " %k %d %v" ))
1082+ (format :initform " %k %d %v" )
1083+ (braille :initform " %k %a is %V (%d)" )
1084+ (audio :initform " %k %a is %V (%d)" ))
10361085 " Abstract superclass for infix commands that set a variable."
10371086 :abstract t )
10381087
@@ -3878,6 +3927,7 @@ it\", in which case it is pointless to preserve history.)"
38783927 (with-slots (value multi-value always-read allow-empty choices) obj
38793928 (if (and value
38803929 (not multi-value)
3930+ (not transient-always-read-value)
38813931 (not always-read)
38823932 transient--prefix)
38833933 (oset obj value nil )
@@ -3922,16 +3972,25 @@ it\", in which case it is pointless to preserve history.)"
39223972
39233973(cl-defmethod transient-infix-read ((obj transient-switch))
39243974 " Toggle the switch on or off."
3925- (if (oref obj value) nil (oref obj argument)))
3975+ (prog1 (if (oref obj value) nil (oref obj argument))
3976+ (when transient-always-read-value
3977+ (message " %s is now %s "
3978+ (oref obj argument)
3979+ (if (oref obj value) " enabled" " disabled" )))))
39263980
39273981(cl-defmethod transient-infix-read ((obj transient-switches))
39283982 " Cycle through the mutually exclusive switches.
39293983The last value is \" don't use any of these switches\" ."
39303984 (let ((choices (mapcar (apply-partially #'format (oref obj argument-format))
39313985 (oref obj choices))))
3932- (if-let ((value (oref obj value)))
3933- (cadr (member value choices))
3934- (car choices))))
3986+ (cond-let
3987+ (transient-always-read-value
3988+ (completing-read (transient-prompt obj)
3989+ (cons " *disable*" choices)
3990+ nil t ))
3991+ ([value (oref obj value)]
3992+ (cadr (member value choices)))
3993+ ((car choices)))))
39353994
39363995(cl-defmethod transient-infix-read ((command symbol))
39373996 " Elsewhere use the reader of the infix command COMMAND.
@@ -4768,26 +4827,34 @@ as a button."
47684827%d is formatted using `transient-format-description' .
47694828%v is formatted using `transient-format-value' ."
47704829 (static-if (>= emacs-major-version 29 )
4771- (format-spec (oref obj format )
4830+ (format-spec (transient--get-format obj)
47724831 `((?k . ,(lambda () (transient-format-key obj)))
47734832 (?d . ,(lambda () (transient-format-description obj)))
4774- (?v . ,(lambda () (transient-format-value obj)))))
4775- (format-spec (oref obj format)
4833+ (?v . ,(lambda () (transient-format-value obj)))
4834+ (?V . ,(lambda () (transient-format-value-only obj)))
4835+ (?a . ,(lambda () (transient-format-infix obj)))
4836+ (?i . ,(lambda () (transient-format-inapt obj)))))
4837+ (format-spec (transient--get-format obj)
47764838 `((?k . ,(transient-format-key obj))
47774839 (?d . ,(transient-format-description obj))
4778- (?v . ,(transient-format-value obj))))))
4840+ (?v . ,(transient-format-value obj))
4841+ (?V . ,(transient-format-value-only obj))
4842+ (?a . ,(transient-format-infix obj))
4843+ (?i . ,(transient-format-inapt obj))))))
47794844
47804845(cl-defmethod transient-format ((obj transient-suffix))
47814846 " Return a string generated using OBJ's `format' .
47824847%k is formatted using `transient-format-key' .
47834848%d is formatted using `transient-format-description' ."
47844849 (static-if (>= emacs-major-version 29 )
4785- (format-spec (oref obj format )
4850+ (format-spec (transient--get-format obj)
47864851 `((?k . ,(lambda () (transient-format-key obj)))
4787- (?d . ,(lambda () (transient-format-description obj)))))
4788- (format-spec (oref obj format)
4852+ (?d . ,(lambda () (transient-format-description obj)))
4853+ (?i . ,(lambda () (transient-format-inapt obj)))))
4854+ (format-spec (transient--get-format obj)
47894855 `((?k . ,(transient-format-key obj))
4790- (?d . ,(transient-format-description obj))))))
4856+ (?d . ,(transient-format-description obj))
4857+ (?i . ,(transient-format-inapt obj))))))
47914858
47924859(cl-defgeneric transient-format-key (obj)
47934860 " Format OBJ's `key' for display and return the result." )
@@ -4980,6 +5047,34 @@ apply the face `transient-unreachable' to the complete string."
49805047 choices
49815048 (propertize " |" 'face 'transient-delimiter ))))))
49825049
5050+ (cl-defmethod transient-format-value-only ((obj transient-infix))
5051+ (if-let ((value (oref obj value)))
5052+ (prin1-to-string value t )
5053+ " disabled" ))
5054+
5055+ (cl-defmethod transient-format-value-only ((obj transient-switch))
5056+ (if (oref obj value) " enabled" " disabled" ))
5057+
5058+ (cl-defmethod transient-format-value-only ((_obj transient-switches))
5059+ " TODO" " TODO" )
5060+
5061+ (cl-defmethod transient-format-infix ((obj transient-infix))
5062+ (or (ignore-error (invalid-slot-name unbound-slot) (oref obj argument))
5063+ (ignore-error (invalid-slot-name unbound-slot) (oref obj variable))
5064+ " BUG: Neither argument nor variable is bound" ))
5065+
5066+ (cl-defmethod transient-format-inapt ((obj transient-suffix))
5067+ (if (oref obj inapt) " inapt " " " ))
5068+
5069+ (cl-defmethod transient--get-format ((obj transient-suffix))
5070+ (alist-get obj transient-overriding-format-alist
5071+ (pcase transient-use-accessible-format
5072+ ('braille (oref obj braille))
5073+ ('audio (oref obj audio))
5074+ (_ (oref obj format)))
5075+ nil
5076+ (lambda (type obj ) (ignore-errors (cl-typep obj type)))))
5077+
49835078(cl-defmethod transient--get-description ((obj transient-child))
49845079 (cond-let*
49855080 [[desc (oref obj description)]]
0 commit comments