Ivy is great. I've been meaning to figure out a way to swap sources while running ivy. This would enable me to cycle through different sources using the existing search parameters.
At first look, 'ivy-set-sources seemed like the right choice, but it's used during setup to agregate sources. Subsequent 'ivy-set-sources calls are ignored during an 'ivy-read session.
There's an ivy feature request over at github with a similar goal in mind. Although the feature is not yet supported, there's a handy suggestion to use 'ivy-quit-and-run to quit the current command and run a different one.
With 'ivy-quit-and-run in mind, we can write our 'ar/ivy-read function to take a list of sources and add a little logic to cycle through them using a keybiding, in my case <left> and <right>.
;;; -*- lexical-binding: t; -*-
(require 'cl)
(cl-defstruct
ar/ivy-source
prompt
collection
action)
(cl-defun ar/ivy-read (sources &key index initial-input)
(let ((kmap (make-sparse-keymap))
(source))
(cl-assert (> (length sources) 0))
(when (null index) (setq index 0))
(setq source (nth index sources))
(define-key kmap (kbd "<right>") (lambda ()
(interactive)
(ivy-quit-and-run (ar/ivy-read sources
:index (if (>= (1+ index)
(length sources))
0
(1+ index))
:initial-input ivy-text))))
(define-key kmap (kbd "<left>") (lambda ()
(interactive)
(ivy-quit-and-run (ar/ivy-read sources
:index (if (< (1- index)
0)
(1- (length sources))
(1- index))
:initial-input ivy-text))))
(ivy-read (ar/ivy-source-prompt source)
(ar/ivy-source-collection source)
:action (ar/ivy-source-action source)
:initial-input initial-input
:keymap kmap)))
(defun ar/ivy-food-menu ()
(interactive)
(ar/ivy-read (list
(make-ar/ivy-source :prompt "Pizza: "
:action (lambda (selection)
(message "Selected pizza: %s" selection))
:collection (lambda (str pred v)
(list "Bianca Neve - Mozzarella, Ricotta, Sausage, Extra Virgin Olive Oil, Basil"
"Boscaiola - Mozzarella, Tomato Sauce, Sausage, Mushrooms, Extra Virgin Olive Oil, Basil"
"Calzone - Ricotta, Ham, Mushrooms, Artichokes. Topped with Tomato Sauce and Extra Virgin Olive Oil."
"Capricciosa - Mozzarella,Tomato Sauce, Prosciutto Cotto Ham, Mushrooms, Artichokes, Extra Virgin Olive Oil."
"Carciofi - Mozzarella, Tomato Sauce, Artichokes, Extra Virgin Olive Oil, Basil."
"Diavola - Mozzarella, Tomato Sauce, Spicy Salami, Extra Virgin Olive Oil, Basil."
"Funghi - Mozzarella, Tomato Sauce, Mushrooms, Extra Virgin Olive Oil, Basil.")))
(make-ar/ivy-source :prompt "Tacos: "
:action (lambda (selection)
(message "Selected taco: %s" selection))
:collection (lambda (str pred v)
(list "Pork pibil - Slow cooked in citrus & spices, with pink pickled onions."
"Grilled chicken & avocado - Ancho rub, guacamole & green tomatillo salsa."
"Plantain - Sweet & spicy chipotle & crumbled feta."
"Poblano pepper - Caramelised onions, corn & cashew nut mole."
"Buttermilk chicken - Served crispy fried with habanero & white onion relish & spiced mayo."
"Sustainable battered cod - mSC certified cod with shredded slaw, chipotle mayo & pickled cucumber."
"Chargrilled steak - Avocado & chipotle salsas.")))
(make-ar/ivy-source :prompt "Burgers: "
:action (lambda (selection)
(message "Selected burger: %s" selection))
:collection (lambda (str pred v)
(list "The cheese - Aged beef patty with american cheese, gherkins, ketchup & mustard."
"The yeah! - Aged beef patty with american cheese, gherkins, yeah! sauce & salad."
"The yfc or hot yfc - Crispy chicken with lime or chipotle crema, lettuce, pickled onion & slaw."
"The rancher - Grilled chicken with ranch dressing, bacon & salad."
"The bubbah - Aged beef patty with smokey aubergine, pickled red cabbage, lettuce, roast toms, onions & cheddar."
"The bulgogi - Sesame-spiced beef patty with miso mayo, pickled radish, onion, cucumber & spring onion."
"The summer - Aged beef patty with sriracha mayo, lettuce, onion, toms, avo, cheddar & bacon."))))))
ps. Menu data from Star of Kings, Wahaca, and Pizzarino.