(defun my/read-list (&optional f stop-pred) "Return a list by repeatedly requesting input using function F. By default, F is `read-string', and should be a function that takes a prompt as its first argument. The collection of input continues until STOP-PRED returns t on the last input value, by default the empty string." (named-let read-element ((result nil) (counter 1) (f (or f #'read-string)) (stop-pred (or stop-pred #'string-empty-p))) (let ((e nil)) (setq e (funcall f (format "Read element %d: " counter))) (if (funcall stop-pred e) result (read-element (append result (list e)) (1+ counter) f stop-pred))))) (defun my/execute-command-repeat (command &rest arguments) "Execute COMMAND repeatedly on all the given ARGUMENTS. COMMAND is an interactive function that takes a single argument. Arguments are collected one by one with my/read-list and then COMMAND is executed (length arguments) times, once for each value." (interactive (append (list (read-command "Command: ")) (my/read-list))) (mapc (lambda (arg) (with-demoted-errors "Error: %S" (funcall command arg))) arguments))