Álvaro Ramírez
Swapping Emacs ivy collections/sources
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.