Adam Oudad
Adam Oudad

Reputation: 347

Keyboard macro cycling over a list of entries and inserting

I was learning about keyboard macros and counters which are awesome. For example, you can increment a counter within your keyboard macro with C-x C-k C-i.

Is it possible to cycle over a list? For example, let's say I have this list: ("oranges" "apples" "bananas") How can I edit the following text

Monday, I eat
Tuesday, I eat
Wednesday, I eat

To look like this?

Monday, I eat oranges
Tuesday, I eat apples
Wednesday, I eat bananas

Arriving at the end of the list, the next execution of the keyboard macro would cycle back to the beginning. How can I do this with keyboard macros? Are keyboard macros the best way?

Upvotes: 0

Views: 66

Answers (1)

Steve Vinoski
Steve Vinoski

Reputation: 20024

Assume we have a buffer with the following contents:

Monday, I eat
Tuesday, I eat
Wednesday, I eat
Thursday, I eat
Friday, I eat
Saturday, I eat
Sunday, I eat

Also assume we have our choices in a list, let's call it my-snacks:

(setq my-snacks '("oranges" "apples" "bananas"))

To use a counter to iterate repeatedly over the my-snacks list, we can use an index value formed from the remainder of dividing the value of the keyboard macro counter by the length of the list:

(nth (% MACRO-COUNTER-VALUE (length my-snacks)) my-snacks)

Our keyboard macro can use eval-expression to insert the value of the list indexing operation.

We start with point at the beginning of the buffer. The keyboard macro performs the following steps:

  1. Go to end of line: C-e
  2. Insert a space: SPC
  3. Eval expression: M-:
  4. Insert the portion of the above elisp expression that precedes the insertion of the keyboard counter value: (insert (nth (%
  5. Insert the keyboard macro counter value: F3
  6. Insert the rest of the elisp expression: (length my-snacks)) my-snacks))
  7. Hit enter: RET
  8. Go to the beginning of the line: C-a
  9. Go to the next line: C-n

As indicated in the keyboard macro counter documentation, the keyboard macro uses the F3 key to insert the current value of the keyboard macro counter.

Here's the same macro in keyboard macro form:

C-e                 ;; move-end-of-line
SPC                 ;; self-insert-command
M-:                 ;; eval-expression
(insert             ;; self-insert-command * 7
SPC                 ;; self-insert-command
(nth                ;; self-insert-command * 4
SPC                 ;; self-insert-command
(%                  ;; self-insert-command * 2
SPC                 ;; self-insert-command
<f3>                ;; kmacro-start-macro-or-insert-counter
SPC                 ;; self-insert-command
(length             ;; self-insert-command * 7
SPC                 ;; self-insert-command
my-snacks))         ;; self-insert-command * 11
SPC                 ;; self-insert-command
my-snacks))         ;; self-insert-command * 11
RET                 ;; newline
C-a                 ;; move-beginning-of-line
C-n                 ;; next-line

Upvotes: 3

Related Questions