2

I am using repeat for now. But I don't know how to have the same for vector.

EDIT: I want INS and DEL options like in repeat.

1 Answers1

3

Use :type restricted-sexp. It accepts a Lisp value that must fit the :match-alternatives restriction that you specify -- in this case that the value must satisfy vectorp and each of the vector's elements must satisfy stringp.

   (defcustom foo ["a" "bb" "ccc"]
     "Foo's doc."
     :type  '(restricted-sexp :tag "Vector"
              :match-alternatives
              (lambda (xs) (and (vectorp xs) (seq-every-p #'stringp xs))))
     :group 'convenience)

See the Elisp manual, node Composite Types.


If you want to specify a fixed vector length then you can use a :type of (vector string string string) etc. instead.


If restricted-sexp doesn't satisfy you (e.g., because you don't get INS and DEL buttons) then you can define your own custom type - see (elisp) Defining New Types.


Another possibility, if you really want INS and DEL buttons, is to define the option value as a list, using repeat, and then in your code that uses it convert to a vector. In that case, be sure to use :set with defcustom (with a setter that converts the new list value to a vector), so that whenever someone customizes the value you reconvert list to vector.

When I say "convert", I mean that you would have the option for a list value and a separate, internal variable for that list value converted to a vector. Users would see INS and DEL in Customize, and would thus configure a list value, but you would have a :set function on the defcustom which would both (1) set the option value according to the user's edit (as usual, using the default setter function) and (2) set the internal variable's value to the new value of the option, after converting that new list value to a vector.

For example:

(defcustom my-opt '("a" "bb" "ccc")
  "`my-opt's doc."
  :type  '(repeat string)
  :group 'convenience
  :set  (lambda (sym defs)
         (custom-set-default sym defs)
         (setq my-var  (vconcat my-opt))))

(defvar my-var [] "`my-var's doc.")

In sum, repeat is only for lists, and it is the only predefined defcustom :type construct that gives you INS and DEL buttons. The doc explicitly calls out these buttons in its description of repeat.

Drew
  • 75,699
  • 9
  • 109
  • 225
  • I am getting a `STANDARD. (mismatch)` in customize buffer. And it doesn't show INS and DEL options like in `repeat`. – Compro Prasad Jul 11 '18 at 13:54
  • I corrected the predicate; please try again. No, you won't get INS and DEL - you get a single sexp field to edit. (You added wanting to have INS and DEL after you posted the question.) – Drew Jul 11 '18 at 14:03
  • Where do I find `repeat` widget's definition? – Compro Prasad Jul 11 '18 at 14:29
  • 1
    You find it in standard library `wid-edit.el`: `(define-widget 'repeat 'editable-list "A variable length homogeneous list." :tag "Repeat" :format "%{%t%}:\n%v%i\n")` – Drew Jul 11 '18 at 15:11