rii

Homepage: https://github.com/ROCKTAKEY/rii

Author: ROCKTAKEY

Updated:

Summary

Reversible input interface for multiple input

Commentary

Rii: Reversible Input Interface for Emacs
  You can read multiple input from users.  Users can go back backward input
  through the buttons in the buffer.

    (rii ((editor (completing-read "Favorite editor: " '("Emacs" "Vim" "VSCode")))
          (fruit  (intern (completing-read "Favorite fruit: " '(apple orange lemon)))))
      (switch-to-buffer "*Welcome-to-Rii*")
      (erase-buffer)
      (insert "Welcome to Rii!\n\n"
              "Your favorite editor is " editor "!\n"
              "Your favorite fruit is " (pp fruit) "!\n"))


How to Use?
  You can just use macro `rii' for the purpose.  Semantics is almost same as `let',
  but a little expanded.  Buffer is shown to provide backward input.

    (rii (
          ;; You can bind any object, such as string, and symbol.
          (editor (completing-read "Favorite editor: " '("Emacs" "Vim" "VSCode")))
          (fruit  (intern (completing-read "Favorite fruit: " '(apple orange lemon))))
          ;; If you would like to display string in buffer instead of value,
          ;; use `rii-change-display-value'.
          (str-list (let* ((list-list '(("star" . ("Sun" "Vega" "Antares" "Sirius"))
                                        ("planet" . ("Mercury" "Venus" "Earth" "Mars"))))
                           (key (completing-read "Which list do you use: " list-list))
                           (value (cdr (assoc key list-list))))
                      (rii-change-display-value
                       value                ;Actual value
                       key)))               ;Displayed string
          ;; If you want to change string of button, use list instead of symbol as car.
          ;; Cdr the car list is plist.
          ((sport                            ;Symbol bound by value
            :display "Your favorite sports") ;String displayed on the buffer
           (completing-read "Favorite sports: "
                            '("soccer" "baseball" "basketball" "skiing"))))
      (switch-to-buffer "*Welcome-to-Rii*")
      (erase-buffer)
      (insert "Welcome to Rii!\n\n"
              "Your favorite editor is " editor "!\n"
              "Your favorite fruit is " (pp fruit) "!\n"
              "Your favorite sport is " sport "!\n\n")
      (dolist (x str-list)
        (insert x ", "))
      (insert "are very beautiful!\n"))


Detail of `rii' macro

    (rii ((VAR VALUE) ...)
      BODY...)


Basic structure
  Basical smantics is same as `let', except that `VAR' cannot be used instead of
  =(VAR nil)= (because binding by `nil' is unecessary).  Also constant or noninteractive
  sexp can be also accepted as `VALUE', but button is still displayed, so `let' is
  recommended for that case.

    (rii (
          ;;Input string
          (str (read-string "Input some str: "))
          ;; Constant is accepted but not recommended
          (x 1))
      (message "%s / %d" str x))


Change button string
  If you want to change button string, use =((VAR :display "something") VALUE)=
  instead of =(VAR VALUE)=, in first argument of `rii'.  By default, string capitalized
  `VAR' and repleced "-" with " " is used.

    (rii (((str :display "My string")       ;Button is shown as "My string" instead of "Str"
           (read-string "Hit some str: "))
          ((num :display "My number")       ;Button is shown as "My number" inttead of "Num"
           (read-number "Hit number: ")))
      (message "%s%d" str num))


Change displayed string of each value
   If you want to change string displayed after button instead of value returned by `VALUE',
   use `rii-change-display-value' or `rii-change-display-value-func'.
   First argument is commonly value returned by `VALUE'.
   On `rii-change-display-value', second argument is string displayed instead of `VALUE'.
   On `rii-change-display-value-func', second argument is function which recieves
   first argument and which returns displayed string.

     (rii ((str1 (rii-change-display-value
                  (read-string "String1: ")
                  "xyz"))                    ;Always display "xyz"
           (str2 (let ((s (read-string "String1: ")))
                     (rii-change-display-value
                      s                      ;Actually bound value
                      (concat "xyz" s))))    ;Prefixed by "xyz"
           (num (rii-change-display-value-func
                 (read-number "Number: ")    ;Actually bound value
                 (lambda (x)                 ;x is bound by read number
                   (make-string x ?a)))))    ;display "a" X times.
       (message "%s\n%s\n%d" str1 str2 num))


Use custom variables prefixed by =rii-=
   When symbol prefixed by "rii-" is used as `VAR', the =(VAR VALUE)=
   is regarded as special.  While the other `VALUE' s are evaluated
   sequencially, `VALUE' s of "rii-"-prefixed `VAR' are evaluated
   earlier than any others.  These `VAR' is bound buffer-locally
   (not bound dynamically), so accessable only in the buffer.

     (rii ((rii-buffer-name "*Welcome*")     ;Like this
           (str (read-string "str: ")))
       (message str))


Keybinding in buffer
  | Key            | Function                | Description                   |
  |----------------+-------------------------+-------------------------------|
  | TAB            | forward-button          | Go to next button             |
  | backtab(S-TAB) | backward-button         | Go to previous button         |
  | SPC            | scroll-up-command       | Scroll up the buffer          |
  | S-SPC          | scroll-down-command     | Scroll down the buffer        |
  | M-p            | rii-previous-history    | Load previous history         |
  | M-n            | rii-next-history        | Load next history             |
  | q              | quit-window             | Quit this buffer (not killed) |
  | C-c C-k        | rii-kill-current-buffer | Kill buffer                   |
  | C-c C-c        | rii-apply               | Push apply button             |

Custom variables
  All custom variables below can use as `VAR' in first argument of `rii'.
  You can change default value by set variable globally.

`rii-button-type', `rii-button-apply-type'
   Button type which is used to create input button or application button.
   See document of `define-button-type'.

`rii-buffer-name'
   Buffer name used by `rii'.

`rii-multiple-buffer'
   Whether create multiple buffers when buffer named `rii-buffer-name'
   is already exist.  when the value is `non-nil' and when buffer named
   `rii-buffer-name' is already exist, `rii' creates buffer named
   `rii-buffer-name' + "" (N is serial number).  When the value is `nil',
   ask whether kill the buffer or not.

`rii-separator-after-button'
   Separator string between section.
   (section means pair of button and displayed value).

`rii-separator-between-section'
   Separator string between button and value.

`rii-confirm-when-apply'
   Whether confirm before apply or not.

`rii-header-document'
  Comment inserted on head of the buffer.

`rii-ring-history-variable'
   Variable which has history.
   Set this on `rii' if you want to use isolated history.

`rii-ring-history-size-default'
   Default size of history saved in `rii-ring-history-variable'.

License
  This package is licensed by GPLv3. See LICENSE.

Dependencies