diff --git a/elpa/dash-2.17.0/dash-autoloads.el b/elpa/dash-2.17.0/dash-autoloads.el
deleted file mode 100755
index 9c3f8a9..0000000
--- a/elpa/dash-2.17.0/dash-autoloads.el
+++ /dev/null
@@ -1,26 +0,0 @@
-;;; dash-autoloads.el --- automatically extracted autoloads
-;;
-;;; Code:
-
-(add-to-list 'load-path (directory-file-name
- (or (file-name-directory #$) (car load-path))))
-
-
-;;;### (autoloads nil "dash" "dash.el" (0 0 0 0))
-;;; Generated autoloads from dash.el
-
-(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "dash" '("!cdr" "!cons" "--" "->" "-a" "-butlast" "-c" "-d" "-e" "-f" "-gr" "-i" "-keep" "-l" "-m" "-non" "-only-some" "-p" "-r" "-s" "-t" "-u" "-value-to-list" "-when-let" "-zip" "dash-")))
-
-;;;***
-
-;;;### (autoloads nil nil ("dash-pkg.el") (0 0 0 0))
-
-;;;***
-
-;; Local Variables:
-;; version-control: never
-;; no-byte-compile: t
-;; no-update-autoloads: t
-;; coding: utf-8
-;; End:
-;;; dash-autoloads.el ends here
diff --git a/elpa/dash-2.17.0/dash-pkg.el b/elpa/dash-2.17.0/dash-pkg.el
deleted file mode 100755
index 73ae4ae..0000000
--- a/elpa/dash-2.17.0/dash-pkg.el
+++ /dev/null
@@ -1,9 +0,0 @@
-(define-package "dash" "2.17.0" "A modern list library for Emacs" 'nil :commit "721436b04da4e2795387cb48a98ac6de37ece0fd" :keywords
- ("lists")
- :authors
- (("Magnar Sveen" . "magnars@gmail.com"))
- :maintainer
- ("Magnar Sveen" . "magnars@gmail.com"))
-;; Local Variables:
-;; no-byte-compile: t
-;; End:
diff --git a/elpa/dash-2.17.0/dash.info b/elpa/dash-2.17.0/dash.info
deleted file mode 100755
index ee791c4..0000000
--- a/elpa/dash-2.17.0/dash.info
+++ /dev/null
@@ -1,3410 +0,0 @@
-This is dash.info, produced by makeinfo version 6.5 from dash.texi.
-
-This manual is for ‘dash.el’ version 2.12.1.
-
- Copyright © 2012-2015 Magnar Sveen
-
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License as
- published by the Free Software Foundation, either version 3 of the
- License, or (at your option) any later version.
-
- This program is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- .
-INFO-DIR-SECTION Emacs
-START-INFO-DIR-ENTRY
-* Dash: (dash.info). A modern list library for GNU Emacs
-END-INFO-DIR-ENTRY
-
-
-File: dash.info, Node: Top, Next: Installation, Up: (dir)
-
-dash
-****
-
-This manual is for ‘dash.el’ version 2.12.1.
-
- Copyright © 2012-2015 Magnar Sveen
-
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License as
- published by the Free Software Foundation, either version 3 of the
- License, or (at your option) any later version.
-
- This program is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see
- .
-
-* Menu:
-
-* Installation::
-* Functions::
-* Development::
-* Index::
-
-— The Detailed Node Listing —
-
-Installation
-
-* Using in a package::
-* Syntax highlighting of dash functions::
-
-Functions
-
-* Maps::
-* Sublist selection::
-* List to list::
-* Reductions::
-* Unfolding::
-* Predicates::
-* Partitioning::
-* Indexing::
-* Set operations::
-* Other list operations::
-* Tree operations::
-* Threading macros::
-* Binding::
-* Side-effects::
-* Destructive operations::
-* Function combinators::
-
-Development
-
-* Contribute:: How to contribute
-* Changes:: List of significant changes by version
-* Contributors:: List of contributors
-
-
-File: dash.info, Node: Installation, Next: Functions, Prev: Top, Up: Top
-
-1 Installation
-**************
-
-It’s available on Melpa (https://melpa.org/); use ‘M-x package-install’:
-
-‘M-x package-install dash’
- Install the dash library.
-
-‘M-x package-install dash-functional’
- Optional, if you want the function combinators.
-
- Alternatively, you can just dump dash.el or dash-functional.el in
-your load path somewhere.
-
-* Menu:
-
-* Using in a package::
-* Syntax highlighting of dash functions::
-
-
-File: dash.info, Node: Using in a package, Next: Syntax highlighting of dash functions, Up: Installation
-
-1.1 Using in a package
-======================
-
-Add this to the big comment block at the top:
-
- ;; Package-Requires: ((dash "2.12.1"))
-
-To get function combinators:
-
- ;; Package-Requires: ((dash "2.12.1") (dash-functional "1.2.0") (emacs "24"))
-
-
-File: dash.info, Node: Syntax highlighting of dash functions, Prev: Using in a package, Up: Installation
-
-1.2 Syntax highlighting of dash functions
-=========================================
-
-Font lock of dash functions in emacs lisp buffers is now optional.
-Include this in your emacs settings to get syntax highlighting:
-
- (eval-after-load 'dash '(dash-enable-font-lock))
-
-
-File: dash.info, Node: Functions, Next: Development, Prev: Installation, Up: Top
-
-2 Functions
-***********
-
-This chapter contains reference documentation for the dash application
-programming interface (API). All functions and constructs in the library
-are prefixed with a dash (-).
-
- There are also anaphoric versions of functions where that makes
-sense, prefixed with two dashes instead of one.
-
- For instance, while ‘-map’ takes a function to map over the list, one
-can also use the anaphoric form with double dashes - which will then be
-executed with ‘it’ exposed as the list item. Here’s an example:
-
- (-map (lambda (n) (* n n)) '(1 2 3 4)) ;; normal version
-
- (--map (* it it) '(1 2 3 4)) ;; anaphoric version
-
-Of course, the original can also be written like
-
- (defun square (n) (* n n))
-
- (-map 'square '(1 2 3 4))
-
-which demonstrates the usefulness of both versions.
-
-* Menu:
-
-* Maps::
-* Sublist selection::
-* List to list::
-* Reductions::
-* Unfolding::
-* Predicates::
-* Partitioning::
-* Indexing::
-* Set operations::
-* Other list operations::
-* Tree operations::
-* Threading macros::
-* Binding::
-* Side-effects::
-* Destructive operations::
-* Function combinators::
-
-
-File: dash.info, Node: Maps, Next: Sublist selection, Up: Functions
-
-2.1 Maps
-========
-
-Functions in this category take a transforming function, which is then
-applied sequentially to each or selected elements of the input list.
-The results are collected in order and returned as new list.
-
- -- Function: -map (fn list)
- Return a new list consisting of the result of applying FN to the
- items in LIST.
-
- (-map (lambda (num) (* num num)) '(1 2 3 4))
- ⇒ '(1 4 9 16)
- (-map 'square '(1 2 3 4))
- ⇒ '(1 4 9 16)
- (--map (* it it) '(1 2 3 4))
- ⇒ '(1 4 9 16)
-
- -- Function: -map-when (pred rep list)
- Return a new list where the elements in LIST that do not match the
- PRED function are unchanged, and where the elements in LIST that do
- match the PRED function are mapped through the REP function.
-
- Alias: ‘-replace-where’
-
- See also: ‘-update-at’ (*note -update-at::)
-
- (-map-when 'even? 'square '(1 2 3 4))
- ⇒ '(1 4 3 16)
- (--map-when (> it 2) (* it it) '(1 2 3 4))
- ⇒ '(1 2 9 16)
- (--map-when (= it 2) 17 '(1 2 3 4))
- ⇒ '(1 17 3 4)
-
- -- Function: -map-first (pred rep list)
- Replace first item in LIST satisfying PRED with result of REP
- called on this item.
-
- See also: ‘-map-when’ (*note -map-when::), ‘-replace-first’ (*note
- -replace-first::)
-
- (-map-first 'even? 'square '(1 2 3 4))
- ⇒ '(1 4 3 4)
- (--map-first (> it 2) (* it it) '(1 2 3 4))
- ⇒ '(1 2 9 4)
- (--map-first (= it 2) 17 '(1 2 3 2))
- ⇒ '(1 17 3 2)
-
- -- Function: -map-last (pred rep list)
- Replace last item in LIST satisfying PRED with result of REP called
- on this item.
-
- See also: ‘-map-when’ (*note -map-when::), ‘-replace-last’ (*note
- -replace-last::)
-
- (-map-last 'even? 'square '(1 2 3 4))
- ⇒ '(1 2 3 16)
- (--map-last (> it 2) (* it it) '(1 2 3 4))
- ⇒ '(1 2 3 16)
- (--map-last (= it 2) 17 '(1 2 3 2))
- ⇒ '(1 2 3 17)
-
- -- Function: -map-indexed (fn list)
- Return a new list consisting of the result of (FN index item) for
- each item in LIST.
-
- In the anaphoric form ‘--map-indexed’, the index is exposed as
- symbol ‘it-index’.
-
- See also: ‘-each-indexed’ (*note -each-indexed::).
-
- (-map-indexed (lambda (index item) (- item index)) '(1 2 3 4))
- ⇒ '(1 1 1 1)
- (--map-indexed (- it it-index) '(1 2 3 4))
- ⇒ '(1 1 1 1)
-
- -- Function: -annotate (fn list)
- Return a list of cons cells where each cell is FN applied to each
- element of LIST paired with the unmodified element of LIST.
-
- (-annotate '1+ '(1 2 3))
- ⇒ '((2 . 1) (3 . 2) (4 . 3))
- (-annotate 'length '(("h" "e" "l" "l" "o") ("hello" "world")))
- ⇒ '((5 "h" "e" "l" "l" "o") (2 "hello" "world"))
- (--annotate (< 1 it) '(0 1 2 3))
- ⇒ '((nil . 0) (nil . 1) (t . 2) (t . 3))
-
- -- Function: -splice (pred fun list)
- Splice lists generated by FUN in place of elements matching PRED in
- LIST.
-
- FUN takes the element matching PRED as input.
-
- This function can be used as replacement for ‘,@’ in case you need
- to splice several lists at marked positions (for example with
- keywords).
-
- See also: ‘-splice-list’ (*note -splice-list::), ‘-insert-at’
- (*note -insert-at::)
-
- (-splice 'even? (lambda (x) (list x x)) '(1 2 3 4))
- ⇒ '(1 2 2 3 4 4)
- (--splice 't (list it it) '(1 2 3 4))
- ⇒ '(1 1 2 2 3 3 4 4)
- (--splice (equal it :magic) '((list of) (magical) (code)) '((foo) (bar) :magic (baz)))
- ⇒ '((foo) (bar) (list of) (magical) (code) (baz))
-
- -- Function: -splice-list (pred new-list list)
- Splice NEW-LIST in place of elements matching PRED in LIST.
-
- See also: ‘-splice’ (*note -splice::), ‘-insert-at’ (*note
- -insert-at::)
-
- (-splice-list 'keywordp '(a b c) '(1 :foo 2))
- ⇒ '(1 a b c 2)
- (-splice-list 'keywordp nil '(1 :foo 2))
- ⇒ '(1 2)
- (--splice-list (keywordp it) '(a b c) '(1 :foo 2))
- ⇒ '(1 a b c 2)
-
- -- Function: -mapcat (fn list)
- Return the concatenation of the result of mapping FN over LIST.
- Thus function FN should return a list.
-
- (-mapcat 'list '(1 2 3))
- ⇒ '(1 2 3)
- (-mapcat (lambda (item) (list 0 item)) '(1 2 3))
- ⇒ '(0 1 0 2 0 3)
- (--mapcat (list 0 it) '(1 2 3))
- ⇒ '(0 1 0 2 0 3)
-
- -- Function: -copy (arg)
- Create a shallow copy of LIST.
-
- (fn LIST)
-
- (-copy '(1 2 3))
- ⇒ '(1 2 3)
- (let ((a '(1 2 3))) (eq a (-copy a)))
- ⇒ nil
-
-
-File: dash.info, Node: Sublist selection, Next: List to list, Prev: Maps, Up: Functions
-
-2.2 Sublist selection
-=====================
-
-Functions returning a sublist of the original list.
-
- -- Function: -filter (pred list)
- Return a new list of the items in LIST for which PRED returns a
- non-nil value.
-
- Alias: ‘-select’
-
- See also: ‘-keep’ (*note -keep::), ‘-remove’ (*note -remove::).
-
- (-filter (lambda (num) (= 0 (% num 2))) '(1 2 3 4))
- ⇒ '(2 4)
- (-filter 'even? '(1 2 3 4))
- ⇒ '(2 4)
- (--filter (= 0 (% it 2)) '(1 2 3 4))
- ⇒ '(2 4)
-
- -- Function: -remove (pred list)
- Return a new list of the items in LIST for which PRED returns nil.
-
- Alias: ‘-reject’
-
- See also: ‘-filter’ (*note -filter::).
-
- (-remove (lambda (num) (= 0 (% num 2))) '(1 2 3 4))
- ⇒ '(1 3)
- (-remove 'even? '(1 2 3 4))
- ⇒ '(1 3)
- (--remove (= 0 (% it 2)) '(1 2 3 4))
- ⇒ '(1 3)
-
- -- Function: -remove-first (pred list)
- Return a new list with the first item matching PRED removed.
-
- Alias: ‘-reject-first’
-
- See also: ‘-remove’ (*note -remove::), ‘-map-first’ (*note
- -map-first::)
-
- (-remove-first 'even? '(1 3 5 4 7 8 10))
- ⇒ '(1 3 5 7 8 10)
- (-remove-first 'stringp '(1 2 "first" "second" "third"))
- ⇒ '(1 2 "second" "third")
- (--remove-first (> it 3) '(1 2 3 4 5 6 7 8 9 10))
- ⇒ '(1 2 3 5 6 7 8 9 10)
-
- -- Function: -remove-last (pred list)
- Return a new list with the last item matching PRED removed.
-
- Alias: ‘-reject-last’
-
- See also: ‘-remove’ (*note -remove::), ‘-map-last’ (*note
- -map-last::)
-
- (-remove-last 'even? '(1 3 5 4 7 8 10 11))
- ⇒ '(1 3 5 4 7 8 11)
- (-remove-last 'stringp '(1 2 "last" "second" "third"))
- ⇒ '(1 2 "last" "second")
- (--remove-last (> it 3) '(1 2 3 4 5 6 7 8 9 10))
- ⇒ '(1 2 3 4 5 6 7 8 9)
-
- -- Function: -remove-item (item list)
- Remove all occurrences of ITEM from LIST.
-
- Comparison is done with ‘equal’.
-
- (-remove-item 3 '(1 2 3 2 3 4 5 3))
- ⇒ '(1 2 2 4 5)
- (-remove-item 'foo '(foo bar baz foo))
- ⇒ '(bar baz)
- (-remove-item "bob" '("alice" "bob" "eve" "bob" "dave"))
- ⇒ '("alice" "eve" "dave")
-
- -- Function: -non-nil (list)
- Return all non-nil elements of LIST.
-
- (-non-nil '(1 nil 2 nil nil 3 4 nil 5 nil))
- ⇒ '(1 2 3 4 5)
-
- -- Function: -slice (list from &optional to step)
- Return copy of LIST, starting from index FROM to index TO.
-
- FROM or TO may be negative. These values are then interpreted
- modulo the length of the list.
-
- If STEP is a number, only each STEPth item in the resulting section
- is returned. Defaults to 1.
-
- (-slice '(1 2 3 4 5) 1)
- ⇒ '(2 3 4 5)
- (-slice '(1 2 3 4 5) 0 3)
- ⇒ '(1 2 3)
- (-slice '(1 2 3 4 5 6 7 8 9) 1 -1 2)
- ⇒ '(2 4 6 8)
-
- -- Function: -take (n list)
- Return a new list of the first N items in LIST, or all items if
- there are fewer than N.
-
- See also: ‘-take-last’ (*note -take-last::)
-
- (-take 3 '(1 2 3 4 5))
- ⇒ '(1 2 3)
- (-take 17 '(1 2 3 4 5))
- ⇒ '(1 2 3 4 5)
-
- -- Function: -take-last (n list)
- Return the last N items of LIST in order.
-
- See also: ‘-take’ (*note -take::)
-
- (-take-last 3 '(1 2 3 4 5))
- ⇒ '(3 4 5)
- (-take-last 17 '(1 2 3 4 5))
- ⇒ '(1 2 3 4 5)
- (-take-last 1 '(1 2 3 4 5))
- ⇒ '(5)
-
- -- Function: -drop (n list)
- Return the tail of LIST without the first N items.
-
- See also: ‘-drop-last’ (*note -drop-last::)
-
- (fn N LIST)
-
- (-drop 3 '(1 2 3 4 5))
- ⇒ '(4 5)
- (-drop 17 '(1 2 3 4 5))
- ⇒ '()
-
- -- Function: -drop-last (n list)
- Remove the last N items of LIST and return a copy.
-
- See also: ‘-drop’ (*note -drop::)
-
- (-drop-last 3 '(1 2 3 4 5))
- ⇒ '(1 2)
- (-drop-last 17 '(1 2 3 4 5))
- ⇒ '()
-
- -- Function: -take-while (pred list)
- Return a new list of successive items from LIST while (PRED item)
- returns a non-nil value.
-
- (-take-while 'even? '(1 2 3 4))
- ⇒ '()
- (-take-while 'even? '(2 4 5 6))
- ⇒ '(2 4)
- (--take-while (< it 4) '(1 2 3 4 3 2 1))
- ⇒ '(1 2 3)
-
- -- Function: -drop-while (pred list)
- Return the tail of LIST starting from the first item for which
- (PRED item) returns nil.
-
- (-drop-while 'even? '(1 2 3 4))
- ⇒ '(1 2 3 4)
- (-drop-while 'even? '(2 4 5 6))
- ⇒ '(5 6)
- (--drop-while (< it 4) '(1 2 3 4 3 2 1))
- ⇒ '(4 3 2 1)
-
- -- Function: -select-by-indices (indices list)
- Return a list whose elements are elements from LIST selected as
- ‘(nth i list)‘ for all i from INDICES.
-
- (-select-by-indices '(4 10 2 3 6) '("v" "e" "l" "o" "c" "i" "r" "a" "p" "t" "o" "r"))
- ⇒ '("c" "o" "l" "o" "r")
- (-select-by-indices '(2 1 0) '("a" "b" "c"))
- ⇒ '("c" "b" "a")
- (-select-by-indices '(0 1 2 0 1 3 3 1) '("f" "a" "r" "l"))
- ⇒ '("f" "a" "r" "f" "a" "l" "l" "a")
-
- -- Function: -select-columns (columns table)
- Select COLUMNS from TABLE.
-
- TABLE is a list of lists where each element represents one row. It
- is assumed each row has the same length.
-
- Each row is transformed such that only the specified COLUMNS are
- selected.
-
- See also: ‘-select-column’ (*note -select-column::),
- ‘-select-by-indices’ (*note -select-by-indices::)
-
- (-select-columns '(0 2) '((1 2 3) (a b c) (:a :b :c)))
- ⇒ '((1 3) (a c) (:a :c))
- (-select-columns '(1) '((1 2 3) (a b c) (:a :b :c)))
- ⇒ '((2) (b) (:b))
- (-select-columns nil '((1 2 3) (a b c) (:a :b :c)))
- ⇒ '(nil nil nil)
-
- -- Function: -select-column (column table)
- Select COLUMN from TABLE.
-
- TABLE is a list of lists where each element represents one row. It
- is assumed each row has the same length.
-
- The single selected column is returned as a list.
-
- See also: ‘-select-columns’ (*note -select-columns::),
- ‘-select-by-indices’ (*note -select-by-indices::)
-
- (-select-column 1 '((1 2 3) (a b c) (:a :b :c)))
- ⇒ '(2 b :b)
-
-
-File: dash.info, Node: List to list, Next: Reductions, Prev: Sublist selection, Up: Functions
-
-2.3 List to list
-================
-
-Functions returning a modified copy of the input list.
-
- -- Function: -keep (fn list)
- Return a new list of the non-nil results of applying FN to the
- items in LIST.
-
- If you want to select the original items satisfying a predicate use
- ‘-filter’ (*note -filter::).
-
- (-keep 'cdr '((1 2 3) (4 5) (6)))
- ⇒ '((2 3) (5))
- (-keep (lambda (num) (when (> num 3) (* 10 num))) '(1 2 3 4 5 6))
- ⇒ '(40 50 60)
- (--keep (when (> it 3) (* 10 it)) '(1 2 3 4 5 6))
- ⇒ '(40 50 60)
-
- -- Function: -concat (&rest lists)
- Return a new list with the concatenation of the elements in the
- supplied LISTS.
-
- (-concat '(1))
- ⇒ '(1)
- (-concat '(1) '(2))
- ⇒ '(1 2)
- (-concat '(1) '(2 3) '(4))
- ⇒ '(1 2 3 4)
-
- -- Function: -flatten (l)
- Take a nested list L and return its contents as a single, flat
- list.
-
- Note that because ‘nil’ represents a list of zero elements (an
- empty list), any mention of nil in L will disappear after
- flattening. If you need to preserve nils, consider ‘-flatten-n’
- (*note -flatten-n::) or map them to some unique symbol and then map
- them back.
-
- Conses of two atoms are considered "terminals", that is, they
- aren’t flattened further.
-
- See also: ‘-flatten-n’ (*note -flatten-n::)
-
- (-flatten '((1)))
- ⇒ '(1)
- (-flatten '((1 (2 3) (((4 (5)))))))
- ⇒ '(1 2 3 4 5)
- (-flatten '(1 2 (3 . 4)))
- ⇒ '(1 2 (3 . 4))
-
- -- Function: -flatten-n (num list)
- Flatten NUM levels of a nested LIST.
-
- See also: ‘-flatten’ (*note -flatten::)
-
- (-flatten-n 1 '((1 2) ((3 4) ((5 6)))))
- ⇒ '(1 2 (3 4) ((5 6)))
- (-flatten-n 2 '((1 2) ((3 4) ((5 6)))))
- ⇒ '(1 2 3 4 (5 6))
- (-flatten-n 3 '((1 2) ((3 4) ((5 6)))))
- ⇒ '(1 2 3 4 5 6)
-
- -- Function: -replace (old new list)
- Replace all OLD items in LIST with NEW.
-
- Elements are compared using ‘equal’.
-
- See also: ‘-replace-at’ (*note -replace-at::)
-
- (-replace 1 "1" '(1 2 3 4 3 2 1))
- ⇒ '("1" 2 3 4 3 2 "1")
- (-replace "foo" "bar" '("a" "nice" "foo" "sentence" "about" "foo"))
- ⇒ '("a" "nice" "bar" "sentence" "about" "bar")
- (-replace 1 2 nil)
- ⇒ nil
-
- -- Function: -replace-first (old new list)
- Replace the first occurrence of OLD with NEW in LIST.
-
- Elements are compared using ‘equal’.
-
- See also: ‘-map-first’ (*note -map-first::)
-
- (-replace-first 1 "1" '(1 2 3 4 3 2 1))
- ⇒ '("1" 2 3 4 3 2 1)
- (-replace-first "foo" "bar" '("a" "nice" "foo" "sentence" "about" "foo"))
- ⇒ '("a" "nice" "bar" "sentence" "about" "foo")
- (-replace-first 1 2 nil)
- ⇒ nil
-
- -- Function: -replace-last (old new list)
- Replace the last occurrence of OLD with NEW in LIST.
-
- Elements are compared using ‘equal’.
-
- See also: ‘-map-last’ (*note -map-last::)
-
- (-replace-last 1 "1" '(1 2 3 4 3 2 1))
- ⇒ '(1 2 3 4 3 2 "1")
- (-replace-last "foo" "bar" '("a" "nice" "foo" "sentence" "about" "foo"))
- ⇒ '("a" "nice" "foo" "sentence" "about" "bar")
- (-replace-last 1 2 nil)
- ⇒ nil
-
- -- Function: -insert-at (n x list)
- Return a list with X inserted into LIST at position N.
-
- See also: ‘-splice’ (*note -splice::), ‘-splice-list’ (*note
- -splice-list::)
-
- (-insert-at 1 'x '(a b c))
- ⇒ '(a x b c)
- (-insert-at 12 'x '(a b c))
- ⇒ '(a b c x)
-
- -- Function: -replace-at (n x list)
- Return a list with element at Nth position in LIST replaced with X.
-
- See also: ‘-replace’ (*note -replace::)
-
- (-replace-at 0 9 '(0 1 2 3 4 5))
- ⇒ '(9 1 2 3 4 5)
- (-replace-at 1 9 '(0 1 2 3 4 5))
- ⇒ '(0 9 2 3 4 5)
- (-replace-at 4 9 '(0 1 2 3 4 5))
- ⇒ '(0 1 2 3 9 5)
-
- -- Function: -update-at (n func list)
- Return a list with element at Nth position in LIST replaced with
- ‘(func (nth n list))‘.
-
- See also: ‘-map-when’ (*note -map-when::)
-
- (-update-at 0 (lambda (x) (+ x 9)) '(0 1 2 3 4 5))
- ⇒ '(9 1 2 3 4 5)
- (-update-at 1 (lambda (x) (+ x 8)) '(0 1 2 3 4 5))
- ⇒ '(0 9 2 3 4 5)
- (--update-at 2 (length it) '("foo" "bar" "baz" "quux"))
- ⇒ '("foo" "bar" 3 "quux")
-
- -- Function: -remove-at (n list)
- Return a list with element at Nth position in LIST removed.
-
- See also: ‘-remove-at-indices’ (*note -remove-at-indices::),
- ‘-remove’ (*note -remove::)
-
- (-remove-at 0 '("0" "1" "2" "3" "4" "5"))
- ⇒ '("1" "2" "3" "4" "5")
- (-remove-at 1 '("0" "1" "2" "3" "4" "5"))
- ⇒ '("0" "2" "3" "4" "5")
- (-remove-at 2 '("0" "1" "2" "3" "4" "5"))
- ⇒ '("0" "1" "3" "4" "5")
-
- -- Function: -remove-at-indices (indices list)
- Return a list whose elements are elements from LIST without
- elements selected as ‘(nth i list)‘ for all i from INDICES.
-
- See also: ‘-remove-at’ (*note -remove-at::), ‘-remove’ (*note
- -remove::)
-
- (-remove-at-indices '(0) '("0" "1" "2" "3" "4" "5"))
- ⇒ '("1" "2" "3" "4" "5")
- (-remove-at-indices '(0 2 4) '("0" "1" "2" "3" "4" "5"))
- ⇒ '("1" "3" "5")
- (-remove-at-indices '(0 5) '("0" "1" "2" "3" "4" "5"))
- ⇒ '("1" "2" "3" "4")
-
-
-File: dash.info, Node: Reductions, Next: Unfolding, Prev: List to list, Up: Functions
-
-2.4 Reductions
-==============
-
-Functions reducing lists into single value.
-
- -- Function: -reduce-from (fn initial-value list)
- Return the result of applying FN to INITIAL-VALUE and the first
- item in LIST, then applying FN to that result and the 2nd item,
- etc. If LIST contains no items, return INITIAL-VALUE and do not
- call FN.
-
- In the anaphoric form ‘--reduce-from’, the accumulated value is
- exposed as symbol ‘acc’.
-
- See also: ‘-reduce’ (*note -reduce::), ‘-reduce-r’ (*note
- -reduce-r::)
-
- (-reduce-from '- 10 '(1 2 3))
- ⇒ 4
- (-reduce-from (lambda (memo item) (format "(%s - %d)" memo item)) "10" '(1 2 3))
- ⇒ "(((10 - 1) - 2) - 3)"
- (--reduce-from (concat acc " " it) "START" '("a" "b" "c"))
- ⇒ "START a b c"
-
- -- Function: -reduce-r-from (fn initial-value list)
- Replace conses with FN, nil with INITIAL-VALUE and evaluate the
- resulting expression. If LIST is empty, INITIAL-VALUE is returned
- and FN is not called.
-
- Note: this function works the same as ‘-reduce-from’ (*note
- -reduce-from::) but the operation associates from right instead of
- from left.
-
- See also: ‘-reduce-r’ (*note -reduce-r::), ‘-reduce’ (*note
- -reduce::)
-
- (-reduce-r-from '- 10 '(1 2 3))
- ⇒ -8
- (-reduce-r-from (lambda (item memo) (format "(%d - %s)" item memo)) "10" '(1 2 3))
- ⇒ "(1 - (2 - (3 - 10)))"
- (--reduce-r-from (concat it " " acc) "END" '("a" "b" "c"))
- ⇒ "a b c END"
-
- -- Function: -reduce (fn list)
- Return the result of applying FN to the first 2 items in LIST, then
- applying FN to that result and the 3rd item, etc. If LIST contains
- no items, return the result of calling FN with no arguments. If
- LIST contains a single item, return that item and do not call FN.
-
- In the anaphoric form ‘--reduce’, the accumulated value is exposed
- as symbol ‘acc’.
-
- See also: ‘-reduce-from’ (*note -reduce-from::), ‘-reduce-r’ (*note
- -reduce-r::)
-
- (-reduce '- '(1 2 3 4))
- ⇒ -8
- (-reduce 'list '(1 2 3 4))
- ⇒ '(((1 2) 3) 4)
- (--reduce (format "%s-%d" acc it) '(1 2 3))
- ⇒ "1-2-3"
-
- -- Function: -reduce-r (fn list)
- Replace conses with FN and evaluate the resulting expression. The
- final nil is ignored. If LIST contains no items, return the result
- of calling FN with no arguments. If LIST contains a single item,
- return that item and do not call FN.
-
- The first argument of FN is the new item, the second is the
- accumulated value.
-
- Note: this function works the same as ‘-reduce’ (*note -reduce::)
- but the operation associates from right instead of from left.
-
- See also: ‘-reduce-r-from’ (*note -reduce-r-from::), ‘-reduce’
- (*note -reduce::)
-
- (-reduce-r '- '(1 2 3 4))
- ⇒ -2
- (-reduce-r (lambda (item memo) (format "%s-%d" memo item)) '(1 2 3))
- ⇒ "3-2-1"
- (--reduce-r (format "%s-%d" acc it) '(1 2 3))
- ⇒ "3-2-1"
-
- -- Function: -reductions-from (fn init list)
- Return a list of the intermediate values of the reduction.
-
- See ‘-reduce-from’ (*note -reduce-from::) for explanation of the
- arguments.
-
- See also: ‘-reductions’ (*note -reductions::), ‘-reductions-r’
- (*note -reductions-r::), ‘-reduce-r’ (*note -reduce-r::)
-
- (-reductions-from (lambda (a i) (format "(%s FN %d)" a i)) "INIT" '(1 2 3 4))
- ⇒ '("INIT" "(INIT FN 1)" "((INIT FN 1) FN 2)" "(((INIT FN 1) FN 2) FN 3)" "((((INIT FN 1) FN 2) FN 3) FN 4)")
- (-reductions-from 'max 0 '(2 1 4 3))
- ⇒ '(0 2 2 4 4)
- (-reductions-from '* 1 '(1 2 3 4))
- ⇒ '(1 1 2 6 24)
-
- -- Function: -reductions-r-from (fn init list)
- Return a list of the intermediate values of the reduction.
-
- See ‘-reduce-r-from’ (*note -reduce-r-from::) for explanation of
- the arguments.
-
- See also: ‘-reductions-r’ (*note -reductions-r::), ‘-reductions’
- (*note -reductions::), ‘-reduce’ (*note -reduce::)
-
- (-reductions-r-from (lambda (i a) (format "(%d FN %s)" i a)) "INIT" '(1 2 3 4))
- ⇒ '("(1 FN (2 FN (3 FN (4 FN INIT))))" "(2 FN (3 FN (4 FN INIT)))" "(3 FN (4 FN INIT))" "(4 FN INIT)" "INIT")
- (-reductions-r-from 'max 0 '(2 1 4 3))
- ⇒ '(4 4 4 3 0)
- (-reductions-r-from '* 1 '(1 2 3 4))
- ⇒ '(24 24 12 4 1)
-
- -- Function: -reductions (fn list)
- Return a list of the intermediate values of the reduction.
-
- See ‘-reduce’ (*note -reduce::) for explanation of the arguments.
-
- See also: ‘-reductions-from’ (*note -reductions-from::),
- ‘-reductions-r’ (*note -reductions-r::), ‘-reduce-r’ (*note
- -reduce-r::)
-
- (-reductions (lambda (a i) (format "(%s FN %d)" a i)) '(1 2 3 4))
- ⇒ '(1 "(1 FN 2)" "((1 FN 2) FN 3)" "(((1 FN 2) FN 3) FN 4)")
- (-reductions '+ '(1 2 3 4))
- ⇒ '(1 3 6 10)
- (-reductions '* '(1 2 3 4))
- ⇒ '(1 2 6 24)
-
- -- Function: -reductions-r (fn list)
- Return a list of the intermediate values of the reduction.
-
- See ‘-reduce-r’ (*note -reduce-r::) for explanation of the
- arguments.
-
- See also: ‘-reductions-r-from’ (*note -reductions-r-from::),
- ‘-reductions’ (*note -reductions::), ‘-reduce’ (*note -reduce::)
-
- (-reductions-r (lambda (i a) (format "(%d FN %s)" i a)) '(1 2 3 4))
- ⇒ '("(1 FN (2 FN (3 FN 4)))" "(2 FN (3 FN 4))" "(3 FN 4)" 4)
- (-reductions-r '+ '(1 2 3 4))
- ⇒ '(10 9 7 4)
- (-reductions-r '* '(1 2 3 4))
- ⇒ '(24 24 12 4)
-
- -- Function: -count (pred list)
- Counts the number of items in LIST where (PRED item) is non-nil.
-
- (-count 'even? '(1 2 3 4 5))
- ⇒ 2
- (--count (< it 4) '(1 2 3 4))
- ⇒ 3
-
- -- Function: -sum (list)
- Return the sum of LIST.
-
- (-sum '())
- ⇒ 0
- (-sum '(1))
- ⇒ 1
- (-sum '(1 2 3 4))
- ⇒ 10
-
- -- Function: -running-sum (list)
- Return a list with running sums of items in LIST.
-
- LIST must be non-empty.
-
- (-running-sum '(1 2 3 4))
- ⇒ '(1 3 6 10)
- (-running-sum '(1))
- ⇒ '(1)
- (-running-sum '())
- ⇒ error
-
- -- Function: -product (list)
- Return the product of LIST.
-
- (-product '())
- ⇒ 1
- (-product '(1))
- ⇒ 1
- (-product '(1 2 3 4))
- ⇒ 24
-
- -- Function: -running-product (list)
- Return a list with running products of items in LIST.
-
- LIST must be non-empty.
-
- (-running-product '(1 2 3 4))
- ⇒ '(1 2 6 24)
- (-running-product '(1))
- ⇒ '(1)
- (-running-product '())
- ⇒ error
-
- -- Function: -inits (list)
- Return all prefixes of LIST.
-
- (-inits '(1 2 3 4))
- ⇒ '(nil (1) (1 2) (1 2 3) (1 2 3 4))
- (-inits nil)
- ⇒ '(nil)
- (-inits '(1))
- ⇒ '(nil (1))
-
- -- Function: -tails (list)
- Return all suffixes of LIST
-
- (-tails '(1 2 3 4))
- ⇒ '((1 2 3 4) (2 3 4) (3 4) (4) nil)
- (-tails nil)
- ⇒ '(nil)
- (-tails '(1))
- ⇒ '((1) nil)
-
- -- Function: -common-prefix (&rest lists)
- Return the longest common prefix of LISTS.
-
- (-common-prefix '(1))
- ⇒ '(1)
- (-common-prefix '(1 2) '(3 4) '(1 2))
- ⇒ nil
- (-common-prefix '(1 2) '(1 2 3) '(1 2 3 4))
- ⇒ '(1 2)
-
- -- Function: -common-suffix (&rest lists)
- Return the longest common suffix of LISTS.
-
- (-common-suffix '(1))
- ⇒ '(1)
- (-common-suffix '(1 2) '(3 4) '(1 2))
- ⇒ nil
- (-common-suffix '(1 2 3 4) '(2 3 4) '(3 4))
- ⇒ '(3 4)
-
- -- Function: -min (list)
- Return the smallest value from LIST of numbers or markers.
-
- (-min '(0))
- ⇒ 0
- (-min '(3 2 1))
- ⇒ 1
- (-min '(1 2 3))
- ⇒ 1
-
- -- Function: -min-by (comparator list)
- Take a comparison function COMPARATOR and a LIST and return the
- least element of the list by the comparison function.
-
- See also combinator ‘-on’ (*note -on::) which can transform the
- values before comparing them.
-
- (-min-by '> '(4 3 6 1))
- ⇒ 1
- (--min-by (> (car it) (car other)) '((1 2 3) (2) (3 2)))
- ⇒ '(1 2 3)
- (--min-by (> (length it) (length other)) '((1 2 3) (2) (3 2)))
- ⇒ '(2)
-
- -- Function: -max (list)
- Return the largest value from LIST of numbers or markers.
-
- (-max '(0))
- ⇒ 0
- (-max '(3 2 1))
- ⇒ 3
- (-max '(1 2 3))
- ⇒ 3
-
- -- Function: -max-by (comparator list)
- Take a comparison function COMPARATOR and a LIST and return the
- greatest element of the list by the comparison function.
-
- See also combinator ‘-on’ (*note -on::) which can transform the
- values before comparing them.
-
- (-max-by '> '(4 3 6 1))
- ⇒ 6
- (--max-by (> (car it) (car other)) '((1 2 3) (2) (3 2)))
- ⇒ '(3 2)
- (--max-by (> (length it) (length other)) '((1 2 3) (2) (3 2)))
- ⇒ '(1 2 3)
-
-
-File: dash.info, Node: Unfolding, Next: Predicates, Prev: Reductions, Up: Functions
-
-2.5 Unfolding
-=============
-
-Operations dual to reductions, building lists from seed value rather
-than consuming a list to produce a single value.
-
- -- Function: -iterate (fun init n)
- Return a list of iterated applications of FUN to INIT.
-
- This means a list of form:
-
- (init (fun init) (fun (fun init)) ...)
-
- N is the length of the returned list.
-
- (-iterate '1+ 1 10)
- ⇒ '(1 2 3 4 5 6 7 8 9 10)
- (-iterate (lambda (x) (+ x x)) 2 5)
- ⇒ '(2 4 8 16 32)
- (--iterate (* it it) 2 5)
- ⇒ '(2 4 16 256 65536)
-
- -- Function: -unfold (fun seed)
- Build a list from SEED using FUN.
-
- This is "dual" operation to ‘-reduce-r’ (*note -reduce-r::): while
- -reduce-r consumes a list to produce a single value, ‘-unfold’
- (*note -unfold::) takes a seed value and builds a (potentially
- infinite!) list.
-
- FUN should return ‘nil’ to stop the generating process, or a cons
- (A . B), where A will be prepended to the result and B is the new
- seed.
-
- (-unfold (lambda (x) (unless (= x 0) (cons x (1- x)))) 10)
- ⇒ '(10 9 8 7 6 5 4 3 2 1)
- (--unfold (when it (cons it (cdr it))) '(1 2 3 4))
- ⇒ '((1 2 3 4) (2 3 4) (3 4) (4))
- (--unfold (when it (cons it (butlast it))) '(1 2 3 4))
- ⇒ '((1 2 3 4) (1 2 3) (1 2) (1))
-
-
-File: dash.info, Node: Predicates, Next: Partitioning, Prev: Unfolding, Up: Functions
-
-2.6 Predicates
-==============
-
- -- Function: -any? (pred list)
- Return t if (PRED x) is non-nil for any x in LIST, else nil.
-
- Alias: ‘-any-p’, ‘-some?’, ‘-some-p’
-
- (-any? 'even? '(1 2 3))
- ⇒ t
- (-any? 'even? '(1 3 5))
- ⇒ nil
- (-any? 'null '(1 3 5))
- ⇒ nil
-
- -- Function: -all? (pred list)
- Return t if (PRED x) is non-nil for all x in LIST, else nil.
-
- Alias: ‘-all-p’, ‘-every?’, ‘-every-p’
-
- (-all? 'even? '(1 2 3))
- ⇒ nil
- (-all? 'even? '(2 4 6))
- ⇒ t
- (--all? (= 0 (% it 2)) '(2 4 6))
- ⇒ t
-
- -- Function: -none? (pred list)
- Return t if (PRED x) is nil for all x in LIST, else nil.
-
- Alias: ‘-none-p’
-
- (-none? 'even? '(1 2 3))
- ⇒ nil
- (-none? 'even? '(1 3 5))
- ⇒ t
- (--none? (= 0 (% it 2)) '(1 2 3))
- ⇒ nil
-
- -- Function: -only-some? (pred list)
- Return ‘t‘ if at least one item of LIST matches PRED and at least
- one item of LIST does not match PRED. Return ‘nil‘ both if all
- items match the predicate or if none of the items match the
- predicate.
-
- Alias: ‘-only-some-p’
-
- (-only-some? 'even? '(1 2 3))
- ⇒ t
- (-only-some? 'even? '(1 3 5))
- ⇒ nil
- (-only-some? 'even? '(2 4 6))
- ⇒ nil
-
- -- Function: -contains? (list element)
- Return non-nil if LIST contains ELEMENT.
-
- The test for equality is done with ‘equal’, or with ‘-compare-fn’
- if that’s non-nil.
-
- Alias: ‘-contains-p’
-
- (-contains? '(1 2 3) 1)
- ⇒ t
- (-contains? '(1 2 3) 2)
- ⇒ t
- (-contains? '(1 2 3) 4)
- ⇒ nil
-
- -- Function: -same-items? (list list2)
- Return true if LIST and LIST2 has the same items.
-
- The order of the elements in the lists does not matter.
-
- Alias: ‘-same-items-p’
-
- (-same-items? '(1 2 3) '(1 2 3))
- ⇒ t
- (-same-items? '(1 2 3) '(3 2 1))
- ⇒ t
- (-same-items? '(1 2 3) '(1 2 3 4))
- ⇒ nil
-
- -- Function: -is-prefix? (prefix list)
- Return non-nil if PREFIX is prefix of LIST.
-
- Alias: ‘-is-prefix-p’
-
- (-is-prefix? '(1 2 3) '(1 2 3 4 5))
- ⇒ t
- (-is-prefix? '(1 2 3 4 5) '(1 2 3))
- ⇒ nil
- (-is-prefix? '(1 3) '(1 2 3 4 5))
- ⇒ nil
-
- -- Function: -is-suffix? (suffix list)
- Return non-nil if SUFFIX is suffix of LIST.
-
- Alias: ‘-is-suffix-p’
-
- (-is-suffix? '(3 4 5) '(1 2 3 4 5))
- ⇒ t
- (-is-suffix? '(1 2 3 4 5) '(3 4 5))
- ⇒ nil
- (-is-suffix? '(3 5) '(1 2 3 4 5))
- ⇒ nil
-
- -- Function: -is-infix? (infix list)
- Return non-nil if INFIX is infix of LIST.
-
- This operation runs in O(n^2) time
-
- Alias: ‘-is-infix-p’
-
- (-is-infix? '(1 2 3) '(1 2 3 4 5))
- ⇒ t
- (-is-infix? '(2 3 4) '(1 2 3 4 5))
- ⇒ t
- (-is-infix? '(3 4 5) '(1 2 3 4 5))
- ⇒ t
-
-
-File: dash.info, Node: Partitioning, Next: Indexing, Prev: Predicates, Up: Functions
-
-2.7 Partitioning
-================
-
-Functions partitioning the input list into a list of lists.
-
- -- Function: -split-at (n list)
- Return a list of ((-take N LIST) (-drop N LIST)), in no more than
- one pass through the list.
-
- (-split-at 3 '(1 2 3 4 5))
- ⇒ '((1 2 3) (4 5))
- (-split-at 17 '(1 2 3 4 5))
- ⇒ '((1 2 3 4 5) nil)
-
- -- Function: -split-with (pred list)
- Return a list of ((-take-while PRED LIST) (-drop-while PRED LIST)),
- in no more than one pass through the list.
-
- (-split-with 'even? '(1 2 3 4))
- ⇒ '(nil (1 2 3 4))
- (-split-with 'even? '(2 4 5 6))
- ⇒ '((2 4) (5 6))
- (--split-with (< it 4) '(1 2 3 4 3 2 1))
- ⇒ '((1 2 3) (4 3 2 1))
-
- -- Macro: -split-on (item list)
- Split the LIST each time ITEM is found.
-
- Unlike ‘-partition-by’ (*note -partition-by::), the ITEM is
- discarded from the results. Empty lists are also removed from the
- result.
-
- Comparison is done by ‘equal’.
-
- See also ‘-split-when’ (*note -split-when::)
-
- (-split-on '| '(Nil | Leaf a | Node [Tree a]))
- ⇒ '((Nil) (Leaf a) (Node [Tree a]))
- (-split-on ':endgroup '("a" "b" :endgroup "c" :endgroup "d" "e"))
- ⇒ '(("a" "b") ("c") ("d" "e"))
- (-split-on ':endgroup '("a" "b" :endgroup :endgroup "d" "e"))
- ⇒ '(("a" "b") ("d" "e"))
-
- -- Function: -split-when (fn list)
- Split the LIST on each element where FN returns non-nil.
-
- Unlike ‘-partition-by’ (*note -partition-by::), the "matched"
- element is discarded from the results. Empty lists are also
- removed from the result.
-
- This function can be thought of as a generalization of
- ‘split-string’.
-
- (-split-when 'even? '(1 2 3 4 5 6))
- ⇒ '((1) (3) (5))
- (-split-when 'even? '(1 2 3 4 6 8 9))
- ⇒ '((1) (3) (9))
- (--split-when (memq it '(&optional &rest)) '(a b &optional c d &rest args))
- ⇒ '((a b) (c d) (args))
-
- -- Function: -separate (pred list)
- Return a list of ((-filter PRED LIST) (-remove PRED LIST)), in one
- pass through the list.
-
- (-separate (lambda (num) (= 0 (% num 2))) '(1 2 3 4 5 6 7))
- ⇒ '((2 4 6) (1 3 5 7))
- (--separate (< it 5) '(3 7 5 9 3 2 1 4 6))
- ⇒ '((3 3 2 1 4) (7 5 9 6))
- (-separate 'cdr '((1 2) (1) (1 2 3) (4)))
- ⇒ '(((1 2) (1 2 3)) ((1) (4)))
-
- -- Function: -partition (n list)
- Return a new list with the items in LIST grouped into N-sized
- sublists. If there are not enough items to make the last group
- N-sized, those items are discarded.
-
- (-partition 2 '(1 2 3 4 5 6))
- ⇒ '((1 2) (3 4) (5 6))
- (-partition 2 '(1 2 3 4 5 6 7))
- ⇒ '((1 2) (3 4) (5 6))
- (-partition 3 '(1 2 3 4 5 6 7))
- ⇒ '((1 2 3) (4 5 6))
-
- -- Function: -partition-all (n list)
- Return a new list with the items in LIST grouped into N-sized
- sublists. The last group may contain less than N items.
-
- (-partition-all 2 '(1 2 3 4 5 6))
- ⇒ '((1 2) (3 4) (5 6))
- (-partition-all 2 '(1 2 3 4 5 6 7))
- ⇒ '((1 2) (3 4) (5 6) (7))
- (-partition-all 3 '(1 2 3 4 5 6 7))
- ⇒ '((1 2 3) (4 5 6) (7))
-
- -- Function: -partition-in-steps (n step list)
- Return a new list with the items in LIST grouped into N-sized
- sublists at offsets STEP apart. If there are not enough items to
- make the last group N-sized, those items are discarded.
-
- (-partition-in-steps 2 1 '(1 2 3 4))
- ⇒ '((1 2) (2 3) (3 4))
- (-partition-in-steps 3 2 '(1 2 3 4))
- ⇒ '((1 2 3))
- (-partition-in-steps 3 2 '(1 2 3 4 5))
- ⇒ '((1 2 3) (3 4 5))
-
- -- Function: -partition-all-in-steps (n step list)
- Return a new list with the items in LIST grouped into N-sized
- sublists at offsets STEP apart. The last groups may contain less
- than N items.
-
- (-partition-all-in-steps 2 1 '(1 2 3 4))
- ⇒ '((1 2) (2 3) (3 4) (4))
- (-partition-all-in-steps 3 2 '(1 2 3 4))
- ⇒ '((1 2 3) (3 4))
- (-partition-all-in-steps 3 2 '(1 2 3 4 5))
- ⇒ '((1 2 3) (3 4 5) (5))
-
- -- Function: -partition-by (fn list)
- Apply FN to each item in LIST, splitting it each time FN returns a
- new value.
-
- (-partition-by 'even? '())
- ⇒ '()
- (-partition-by 'even? '(1 1 2 2 2 3 4 6 8))
- ⇒ '((1 1) (2 2 2) (3) (4 6 8))
- (--partition-by (< it 3) '(1 2 3 4 3 2 1))
- ⇒ '((1 2) (3 4 3) (2 1))
-
- -- Function: -partition-by-header (fn list)
- Apply FN to the first item in LIST. That is the header value.
- Apply FN to each item in LIST, splitting it each time FN returns
- the header value, but only after seeing at least one other value
- (the body).
-
- (--partition-by-header (= it 1) '(1 2 3 1 2 1 2 3 4))
- ⇒ '((1 2 3) (1 2) (1 2 3 4))
- (--partition-by-header (> it 0) '(1 2 0 1 0 1 2 3 0))
- ⇒ '((1 2 0) (1 0) (1 2 3 0))
- (-partition-by-header 'even? '(2 1 1 1 4 1 3 5 6 6 1))
- ⇒ '((2 1 1 1) (4 1 3 5) (6 6 1))
-
- -- Function: -partition-after-pred (pred list)
- Partition directly after each time PRED is true on an element of
- LIST.
-
- (-partition-after-pred #'odd? '())
- ⇒ '()
- (-partition-after-pred #'odd? '(1))
- ⇒ '((1))
- (-partition-after-pred #'odd? '(0 1))
- ⇒ '((0 1))
-
- -- Function: -partition-before-pred (pred list)
- Partition directly before each time PRED is true on an element of
- LIST.
-
- (-partition-before-pred #'odd? '())
- ⇒ '()
- (-partition-before-pred #'odd? '(1))
- ⇒ '((1))
- (-partition-before-pred #'odd? '(0 1))
- ⇒ '((0) (1))
-
- -- Function: -partition-before-item (item list)
- Partition directly before each time ITEM appears in LIST.
-
- (-partition-before-item 3 '())
- ⇒ '()
- (-partition-before-item 3 '(1))
- ⇒ '((1))
- (-partition-before-item 3 '(3))
- ⇒ '((3))
-
- -- Function: -partition-after-item (item list)
- Partition directly after each time ITEM appears in LIST.
-
- (-partition-after-item 3 '())
- ⇒ '()
- (-partition-after-item 3 '(1))
- ⇒ '((1))
- (-partition-after-item 3 '(3))
- ⇒ '((3))
-
- -- Function: -group-by (fn list)
- Separate LIST into an alist whose keys are FN applied to the
- elements of LIST. Keys are compared by ‘equal’.
-
- (-group-by 'even? '())
- ⇒ '()
- (-group-by 'even? '(1 1 2 2 2 3 4 6 8))
- ⇒ '((nil 1 1 3) (t 2 2 2 4 6 8))
- (--group-by (car (split-string it "/")) '("a/b" "c/d" "a/e"))
- ⇒ '(("a" "a/b" "a/e") ("c" "c/d"))
-
-
-File: dash.info, Node: Indexing, Next: Set operations, Prev: Partitioning, Up: Functions
-
-2.8 Indexing
-============
-
-Return indices of elements based on predicates, sort elements by indices
-etc.
-
- -- Function: -elem-index (elem list)
- Return the index of the first element in the given LIST which is
- equal to the query element ELEM, or nil if there is no such
- element.
-
- (-elem-index 2 '(6 7 8 2 3 4))
- ⇒ 3
- (-elem-index "bar" '("foo" "bar" "baz"))
- ⇒ 1
- (-elem-index '(1 2) '((3) (5 6) (1 2) nil))
- ⇒ 2
-
- -- Function: -elem-indices (elem list)
- Return the indices of all elements in LIST equal to the query
- element ELEM, in ascending order.
-
- (-elem-indices 2 '(6 7 8 2 3 4 2 1))
- ⇒ '(3 6)
- (-elem-indices "bar" '("foo" "bar" "baz"))
- ⇒ '(1)
- (-elem-indices '(1 2) '((3) (1 2) (5 6) (1 2) nil))
- ⇒ '(1 3)
-
- -- Function: -find-index (pred list)
- Take a predicate PRED and a LIST and return the index of the first
- element in the list satisfying the predicate, or nil if there is no
- such element.
-
- See also ‘-first’ (*note -first::).
-
- (-find-index 'even? '(2 4 1 6 3 3 5 8))
- ⇒ 0
- (--find-index (< 5 it) '(2 4 1 6 3 3 5 8))
- ⇒ 3
- (-find-index (-partial 'string-lessp "baz") '("bar" "foo" "baz"))
- ⇒ 1
-
- -- Function: -find-last-index (pred list)
- Take a predicate PRED and a LIST and return the index of the last
- element in the list satisfying the predicate, or nil if there is no
- such element.
-
- See also ‘-last’ (*note -last::).
-
- (-find-last-index 'even? '(2 4 1 6 3 3 5 8))
- ⇒ 7
- (--find-last-index (< 5 it) '(2 7 1 6 3 8 5 2))
- ⇒ 5
- (-find-last-index (-partial 'string-lessp "baz") '("q" "foo" "baz"))
- ⇒ 1
-
- -- Function: -find-indices (pred list)
- Return the indices of all elements in LIST satisfying the predicate
- PRED, in ascending order.
-
- (-find-indices 'even? '(2 4 1 6 3 3 5 8))
- ⇒ '(0 1 3 7)
- (--find-indices (< 5 it) '(2 4 1 6 3 3 5 8))
- ⇒ '(3 7)
- (-find-indices (-partial 'string-lessp "baz") '("bar" "foo" "baz"))
- ⇒ '(1)
-
- -- Function: -grade-up (comparator list)
- Grade elements of LIST using COMPARATOR relation, yielding a
- permutation vector such that applying this permutation to LIST
- sorts it in ascending order.
-
- (-grade-up '< '(3 1 4 2 1 3 3))
- ⇒ '(1 4 3 0 5 6 2)
- (let ((l '(3 1 4 2 1 3 3))) (-select-by-indices (-grade-up '< l) l))
- ⇒ '(1 1 2 3 3 3 4)
-
- -- Function: -grade-down (comparator list)
- Grade elements of LIST using COMPARATOR relation, yielding a
- permutation vector such that applying this permutation to LIST
- sorts it in descending order.
-
- (-grade-down '< '(3 1 4 2 1 3 3))
- ⇒ '(2 0 5 6 3 1 4)
- (let ((l '(3 1 4 2 1 3 3))) (-select-by-indices (-grade-down '< l) l))
- ⇒ '(4 3 3 3 2 1 1)
-
-
-File: dash.info, Node: Set operations, Next: Other list operations, Prev: Indexing, Up: Functions
-
-2.9 Set operations
-==================
-
-Operations pretending lists are sets.
-
- -- Function: -union (list list2)
- Return a new list containing the elements of LIST and elements of
- LIST2 that are not in LIST. The test for equality is done with
- ‘equal’, or with ‘-compare-fn’ if that’s non-nil.
-
- (-union '(1 2 3) '(3 4 5))
- ⇒ '(1 2 3 4 5)
- (-union '(1 2 3 4) '())
- ⇒ '(1 2 3 4)
- (-union '(1 1 2 2) '(3 2 1))
- ⇒ '(1 1 2 2 3)
-
- -- Function: -difference (list list2)
- Return a new list with only the members of LIST that are not in
- LIST2. The test for equality is done with ‘equal’, or with
- ‘-compare-fn’ if that’s non-nil.
-
- (-difference '() '())
- ⇒ '()
- (-difference '(1 2 3) '(4 5 6))
- ⇒ '(1 2 3)
- (-difference '(1 2 3 4) '(3 4 5 6))
- ⇒ '(1 2)
-
- -- Function: -intersection (list list2)
- Return a new list containing only the elements that are members of
- both LIST and LIST2. The test for equality is done with ‘equal’,
- or with ‘-compare-fn’ if that’s non-nil.
-
- (-intersection '() '())
- ⇒ '()
- (-intersection '(1 2 3) '(4 5 6))
- ⇒ '()
- (-intersection '(1 2 3 4) '(3 4 5 6))
- ⇒ '(3 4)
-
- -- Function: -powerset (list)
- Return the power set of LIST.
-
- (-powerset '())
- ⇒ '(nil)
- (-powerset '(x y z))
- ⇒ '((x y z) (x y) (x z) (x) (y z) (y) (z) nil)
-
- -- Function: -permutations (list)
- Return the permutations of LIST.
-
- (-permutations '())
- ⇒ '(nil)
- (-permutations '(1 2))
- ⇒ '((1 2) (2 1))
- (-permutations '(a b c))
- ⇒ '((a b c) (a c b) (b a c) (b c a) (c a b) (c b a))
-
- -- Function: -distinct (list)
- Return a new list with all duplicates removed. The test for
- equality is done with ‘equal’, or with ‘-compare-fn’ if that’s
- non-nil.
-
- Alias: ‘-uniq’
-
- (-distinct '())
- ⇒ '()
- (-distinct '(1 2 2 4))
- ⇒ '(1 2 4)
- (-distinct '(t t t))
- ⇒ '(t)
-
-
-File: dash.info, Node: Other list operations, Next: Tree operations, Prev: Set operations, Up: Functions
-
-2.10 Other list operations
-==========================
-
-Other list functions not fit to be classified elsewhere.
-
- -- Function: -rotate (n list)
- Rotate LIST N places to the right. With N negative, rotate to the
- left. The time complexity is O(n).
-
- (-rotate 3 '(1 2 3 4 5 6 7))
- ⇒ '(5 6 7 1 2 3 4)
- (-rotate -3 '(1 2 3 4 5 6 7))
- ⇒ '(4 5 6 7 1 2 3)
- (-rotate 16 '(1 2 3 4 5 6 7))
- ⇒ '(6 7 1 2 3 4 5)
-
- -- Function: -repeat (n x)
- Return a list with X repeated N times. Return nil if N is less
- than 1.
-
- (-repeat 3 :a)
- ⇒ '(:a :a :a)
- (-repeat 1 :a)
- ⇒ '(:a)
- (-repeat 0 :a)
- ⇒ nil
-
- -- Function: -cons* (&rest args)
- Make a new list from the elements of ARGS.
-
- The last 2 members of ARGS are used as the final cons of the result
- so if the final member of ARGS is not a list the result is a dotted
- list.
-
- (-cons* 1 2)
- ⇒ '(1 . 2)
- (-cons* 1 2 3)
- ⇒ '(1 2 . 3)
- (-cons* 1)
- ⇒ 1
-
- -- Function: -snoc (list elem &rest elements)
- Append ELEM to the end of the list.
-
- This is like ‘cons’, but operates on the end of list.
-
- If ELEMENTS is non nil, append these to the list as well.
-
- (-snoc '(1 2 3) 4)
- ⇒ '(1 2 3 4)
- (-snoc '(1 2 3) 4 5 6)
- ⇒ '(1 2 3 4 5 6)
- (-snoc '(1 2 3) '(4 5 6))
- ⇒ '(1 2 3 (4 5 6))
-
- -- Function: -interpose (sep list)
- Return a new list of all elements in LIST separated by SEP.
-
- (-interpose "-" '())
- ⇒ '()
- (-interpose "-" '("a"))
- ⇒ '("a")
- (-interpose "-" '("a" "b" "c"))
- ⇒ '("a" "-" "b" "-" "c")
-
- -- Function: -interleave (&rest lists)
- Return a new list of the first item in each list, then the second
- etc.
-
- (-interleave '(1 2) '("a" "b"))
- ⇒ '(1 "a" 2 "b")
- (-interleave '(1 2) '("a" "b") '("A" "B"))
- ⇒ '(1 "a" "A" 2 "b" "B")
- (-interleave '(1 2 3) '("a" "b"))
- ⇒ '(1 "a" 2 "b")
-
- -- Function: -zip-with (fn list1 list2)
- Zip the two lists LIST1 and LIST2 using a function FN. This
- function is applied pairwise taking as first argument element of
- LIST1 and as second argument element of LIST2 at corresponding
- position.
-
- The anaphoric form ‘--zip-with’ binds the elements from LIST1 as
- symbol ‘it’, and the elements from LIST2 as symbol ‘other’.
-
- (-zip-with '+ '(1 2 3) '(4 5 6))
- ⇒ '(5 7 9)
- (-zip-with 'cons '(1 2 3) '(4 5 6))
- ⇒ '((1 . 4) (2 . 5) (3 . 6))
- (--zip-with (concat it " and " other) '("Batman" "Jekyll") '("Robin" "Hyde"))
- ⇒ '("Batman and Robin" "Jekyll and Hyde")
-
- -- Function: -zip (&rest lists)
- Zip LISTS together. Group the head of each list, followed by the
- second elements of each list, and so on. The lengths of the
- returned groupings are equal to the length of the shortest input
- list.
-
- If two lists are provided as arguments, return the groupings as a
- list of cons cells. Otherwise, return the groupings as a list of
- lists.
-
- Use ‘-zip-lists’ (*note -zip-lists::) if you need the return value
- to always be a list of lists.
-
- Alias: ‘-zip-pair’
-
- See also: ‘-zip-lists’ (*note -zip-lists::)
-
- (-zip '(1 2 3) '(4 5 6))
- ⇒ '((1 . 4) (2 . 5) (3 . 6))
- (-zip '(1 2 3) '(4 5 6 7))
- ⇒ '((1 . 4) (2 . 5) (3 . 6))
- (-zip '(1 2) '(3 4 5) '(6))
- ⇒ '((1 3 6))
-
- -- Function: -zip-lists (&rest lists)
- Zip LISTS together. Group the head of each list, followed by the
- second elements of each list, and so on. The lengths of the
- returned groupings are equal to the length of the shortest input
- list.
-
- The return value is always list of lists, which is a difference
- from ‘-zip-pair’ which returns a cons-cell in case two input lists
- are provided.
-
- See also: ‘-zip’ (*note -zip::)
-
- (-zip-lists '(1 2 3) '(4 5 6))
- ⇒ '((1 4) (2 5) (3 6))
- (-zip-lists '(1 2 3) '(4 5 6 7))
- ⇒ '((1 4) (2 5) (3 6))
- (-zip-lists '(1 2) '(3 4 5) '(6))
- ⇒ '((1 3 6))
-
- -- Function: -zip-fill (fill-value &rest lists)
- Zip LISTS, with FILL-VALUE padded onto the shorter lists. The
- lengths of the returned groupings are equal to the length of the
- longest input list.
-
- (-zip-fill 0 '(1 2 3 4 5) '(6 7 8 9))
- ⇒ '((1 . 6) (2 . 7) (3 . 8) (4 . 9) (5 . 0))
-
- -- Function: -unzip (lists)
- Unzip LISTS.
-
- This works just like ‘-zip’ (*note -zip::) but takes a list of
- lists instead of a variable number of arguments, such that
-
- (-unzip (-zip L1 L2 L3 ...))
-
- is identity (given that the lists are the same length).
-
- Note in particular that calling this on a list of two lists will
- return a list of cons-cells such that the aboce identity works.
-
- See also: ‘-zip’ (*note -zip::)
-
- (-unzip (-zip '(1 2 3) '(a b c) '("e" "f" "g")))
- ⇒ '((1 2 3) (a b c) ("e" "f" "g"))
- (-unzip '((1 2) (3 4) (5 6) (7 8) (9 10)))
- ⇒ '((1 3 5 7 9) (2 4 6 8 10))
- (-unzip '((1 2) (3 4)))
- ⇒ '((1 . 3) (2 . 4))
-
- -- Function: -cycle (list)
- Return an infinite copy of LIST that will cycle through the
- elements and repeat from the beginning.
-
- (-take 5 (-cycle '(1 2 3)))
- ⇒ '(1 2 3 1 2)
- (-take 7 (-cycle '(1 "and" 3)))
- ⇒ '(1 "and" 3 1 "and" 3 1)
- (-zip (-cycle '(1 2 3)) '(1 2))
- ⇒ '((1 . 1) (2 . 2))
-
- -- Function: -pad (fill-value &rest lists)
- Appends FILL-VALUE to the end of each list in LISTS such that they
- will all have the same length.
-
- (-pad 0 '())
- ⇒ '(nil)
- (-pad 0 '(1))
- ⇒ '((1))
- (-pad 0 '(1 2 3) '(4 5))
- ⇒ '((1 2 3) (4 5 0))
-
- -- Function: -table (fn &rest lists)
- Compute outer product of LISTS using function FN.
-
- The function FN should have the same arity as the number of
- supplied lists.
-
- The outer product is computed by applying fn to all possible
- combinations created by taking one element from each list in order.
- The dimension of the result is (length lists).
-
- See also: ‘-table-flat’ (*note -table-flat::)
-
- (-table '* '(1 2 3) '(1 2 3))
- ⇒ '((1 2 3) (2 4 6) (3 6 9))
- (-table (lambda (a b) (-sum (-zip-with '* a b))) '((1 2) (3 4)) '((1 3) (2 4)))
- ⇒ '((7 15) (10 22))
- (apply '-table 'list (-repeat 3 '(1 2)))
- ⇒ '((((1 1 1) (2 1 1)) ((1 2 1) (2 2 1))) (((1 1 2) (2 1 2)) ((1 2 2) (2 2 2))))
-
- -- Function: -table-flat (fn &rest lists)
- Compute flat outer product of LISTS using function FN.
-
- The function FN should have the same arity as the number of
- supplied lists.
-
- The outer product is computed by applying fn to all possible
- combinations created by taking one element from each list in order.
- The results are flattened, ignoring the tensor structure of the
- result. This is equivalent to calling:
-
- (-flatten-n (1- (length lists)) (apply ’-table fn lists))
-
- but the implementation here is much more efficient.
-
- See also: ‘-flatten-n’ (*note -flatten-n::), ‘-table’ (*note
- -table::)
-
- (-table-flat 'list '(1 2 3) '(a b c))
- ⇒ '((1 a) (2 a) (3 a) (1 b) (2 b) (3 b) (1 c) (2 c) (3 c))
- (-table-flat '* '(1 2 3) '(1 2 3))
- ⇒ '(1 2 3 2 4 6 3 6 9)
- (apply '-table-flat 'list (-repeat 3 '(1 2)))
- ⇒ '((1 1 1) (2 1 1) (1 2 1) (2 2 1) (1 1 2) (2 1 2) (1 2 2) (2 2 2))
-
- -- Function: -first (pred list)
- Return the first x in LIST where (PRED x) is non-nil, else nil.
-
- To get the first item in the list no questions asked, use ‘car’.
-
- Alias: ‘-find’
-
- (-first 'even? '(1 2 3))
- ⇒ 2
- (-first 'even? '(1 3 5))
- ⇒ nil
- (-first 'null '(1 3 5))
- ⇒ nil
-
- -- Function: -some (pred list)
- Return (PRED x) for the first LIST item where (PRED x) is non-nil,
- else nil.
-
- Alias: ‘-any’
-
- (-some 'even? '(1 2 3))
- ⇒ t
- (-some 'null '(1 2 3))
- ⇒ nil
- (-some 'null '(1 2 nil))
- ⇒ t
-
- -- Function: -last (pred list)
- Return the last x in LIST where (PRED x) is non-nil, else nil.
-
- (-last 'even? '(1 2 3 4 5 6 3 3 3))
- ⇒ 6
- (-last 'even? '(1 3 7 5 9))
- ⇒ nil
- (--last (> (length it) 3) '("a" "looong" "word" "and" "short" "one"))
- ⇒ "short"
-
- -- Function: -first-item (list)
- Return the first item of LIST, or nil on an empty list.
-
- See also: ‘-second-item’ (*note -second-item::), ‘-last-item’
- (*note -last-item::).
-
- (fn LIST)
-
- (-first-item '(1 2 3))
- ⇒ 1
- (-first-item nil)
- ⇒ nil
- (let ((list (list 1 2 3))) (setf (-first-item list) 5) list)
- ⇒ '(5 2 3)
-
- -- Function: -second-item (arg1)
- Return the second item of LIST, or nil if LIST is too short.
-
- See also: ‘-third-item’ (*note -third-item::).
-
- (fn LIST)
-
- (-second-item '(1 2 3))
- ⇒ 2
- (-second-item nil)
- ⇒ nil
-
- -- Function: -third-item (arg1)
- Return the third item of LIST, or nil if LIST is too short.
-
- See also: ‘-fourth-item’ (*note -fourth-item::).
-
- (fn LIST)
-
- (-third-item '(1 2 3))
- ⇒ 3
- (-third-item nil)
- ⇒ nil
-
- -- Function: -fourth-item (list)
- Return the fourth item of LIST, or nil if LIST is too short.
-
- See also: ‘-fifth-item’ (*note -fifth-item::).
-
- (-fourth-item '(1 2 3 4))
- ⇒ 4
- (-fourth-item nil)
- ⇒ nil
-
- -- Function: -fifth-item (list)
- Return the fifth item of LIST, or nil if LIST is too short.
-
- See also: ‘-last-item’ (*note -last-item::).
-
- (-fifth-item '(1 2 3 4 5))
- ⇒ 5
- (-fifth-item nil)
- ⇒ nil
-
- -- Function: -last-item (list)
- Return the last item of LIST, or nil on an empty list.
-
- (-last-item '(1 2 3))
- ⇒ 3
- (-last-item nil)
- ⇒ nil
- (let ((list (list 1 2 3))) (setf (-last-item list) 5) list)
- ⇒ '(1 2 5)
-
- -- Function: -butlast (list)
- Return a list of all items in list except for the last.
-
- (-butlast '(1 2 3))
- ⇒ '(1 2)
- (-butlast '(1 2))
- ⇒ '(1)
- (-butlast '(1))
- ⇒ nil
-
- -- Function: -sort (comparator list)
- Sort LIST, stably, comparing elements using COMPARATOR. Return the
- sorted list. LIST is NOT modified by side effects. COMPARATOR is
- called with two elements of LIST, and should return non-nil if the
- first element should sort before the second.
-
- (-sort '< '(3 1 2))
- ⇒ '(1 2 3)
- (-sort '> '(3 1 2))
- ⇒ '(3 2 1)
- (--sort (< it other) '(3 1 2))
- ⇒ '(1 2 3)
-
- -- Function: -list (&rest args)
- Return a list with ARGS.
-
- If first item of ARGS is already a list, simply return ARGS. If
- not, return a list with ARGS as elements.
-
- (-list 1)
- ⇒ '(1)
- (-list 1 2 3)
- ⇒ '(1 2 3)
- (-list '(1 2 3))
- ⇒ '(1 2 3)
-
- -- Function: -fix (fn list)
- Compute the (least) fixpoint of FN with initial input LIST.
-
- FN is called at least once, results are compared with ‘equal’.
-
- (-fix (lambda (l) (-non-nil (--mapcat (-split-at (/ (length it) 2) it) l))) '((1 2 3 4 5 6)))
- ⇒ '((1) (2) (3) (4) (5) (6))
- (let ((data '(("starwars" "scifi") ("jedi" "starwars" "warrior")))) (--fix (-uniq (--mapcat (cons it (cdr (assoc it data))) it)) '("jedi" "book")))
- ⇒ '("jedi" "starwars" "warrior" "scifi" "book")
-
-
-File: dash.info, Node: Tree operations, Next: Threading macros, Prev: Other list operations, Up: Functions
-
-2.11 Tree operations
-====================
-
-Functions pretending lists are trees.
-
- -- Function: -tree-seq (branch children tree)
- Return a sequence of the nodes in TREE, in depth-first search
- order.
-
- BRANCH is a predicate of one argument that returns non-nil if the
- passed argument is a branch, that is, a node that can have
- children.
-
- CHILDREN is a function of one argument that returns the children of
- the passed branch node.
-
- Non-branch nodes are simply copied.
-
- (-tree-seq 'listp 'identity '(1 (2 3) 4 (5 (6 7))))
- ⇒ '((1 (2 3) 4 (5 (6 7))) 1 (2 3) 2 3 4 (5 (6 7)) 5 (6 7) 6 7)
- (-tree-seq 'listp 'reverse '(1 (2 3) 4 (5 (6 7))))
- ⇒ '((1 (2 3) 4 (5 (6 7))) (5 (6 7)) (6 7) 7 6 5 4 (2 3) 3 2 1)
- (--tree-seq (vectorp it) (append it nil) [1 [2 3] 4 [5 [6 7]]])
- ⇒ '([1 [2 3] 4 [5 [6 7]]] 1 [2 3] 2 3 4 [5 [6 7]] 5 [6 7] 6 7)
-
- -- Function: -tree-map (fn tree)
- Apply FN to each element of TREE while preserving the tree
- structure.
-
- (-tree-map '1+ '(1 (2 3) (4 (5 6) 7)))
- ⇒ '(2 (3 4) (5 (6 7) 8))
- (-tree-map '(lambda (x) (cons x (expt 2 x))) '(1 (2 3) 4))
- ⇒ '((1 . 2) ((2 . 4) (3 . 8)) (4 . 16))
- (--tree-map (length it) '("" ("" "text" "
") ""))
- ⇒ '(6 (3 4 4) 7)
-
- -- Function: -tree-map-nodes (pred fun tree)
- Call FUN on each node of TREE that satisfies PRED.
-
- If PRED returns nil, continue descending down this node. If PRED
- returns non-nil, apply FUN to this node and do not descend further.
-
- (-tree-map-nodes 'vectorp (lambda (x) (-sum (append x nil))) '(1 [2 3] 4 (5 [6 7] 8)))
- ⇒ '(1 5 4 (5 13 8))
- (-tree-map-nodes 'keywordp (lambda (x) (symbol-name x)) '(1 :foo 4 ((5 6 :bar) :baz 8)))
- ⇒ '(1 ":foo" 4 ((5 6 ":bar") ":baz" 8))
- (--tree-map-nodes (eq (car-safe it) 'add-mode) (-concat it (list :mode 'emacs-lisp-mode)) '(with-mode emacs-lisp-mode (foo bar) (add-mode a b) (baz (add-mode c d))))
- ⇒ '(with-mode emacs-lisp-mode (foo bar) (add-mode a b :mode emacs-lisp-mode) (baz (add-mode c d :mode emacs-lisp-mode)))
-
- -- Function: -tree-reduce (fn tree)
- Use FN to reduce elements of list TREE. If elements of TREE are
- lists themselves, apply the reduction recursively.
-
- FN is first applied to first element of the list and second
- element, then on this result and third element from the list etc.
-
- See ‘-reduce-r’ (*note -reduce-r::) for how exactly are lists of
- zero or one element handled.
-
- (-tree-reduce '+ '(1 (2 3) (4 5)))
- ⇒ 15
- (-tree-reduce 'concat '("strings" (" on" " various") ((" levels"))))
- ⇒ "strings on various levels"
- (--tree-reduce (cond ((stringp it) (concat it " " acc)) (t (let ((sn (symbol-name it))) (concat "<" sn ">" acc "" sn ">")))) '(body (p "some words") (div "more" (b "bold") "words")))
- ⇒ "some words
more bold words
"
-
- -- Function: -tree-reduce-from (fn init-value tree)
- Use FN to reduce elements of list TREE. If elements of TREE are
- lists themselves, apply the reduction recursively.
-
- FN is first applied to INIT-VALUE and first element of the list,
- then on this result and second element from the list etc.
-
- The initial value is ignored on cons pairs as they always contain
- two elements.
-
- (-tree-reduce-from '+ 1 '(1 (1 1) ((1))))
- ⇒ 8
- (--tree-reduce-from (-concat acc (list it)) nil '(1 (2 3 (4 5)) (6 7)))
- ⇒ '((7 6) ((5 4) 3 2) 1)
-
- -- Function: -tree-mapreduce (fn folder tree)
- Apply FN to each element of TREE, and make a list of the results.
- If elements of TREE are lists themselves, apply FN recursively to
- elements of these nested lists.
-
- Then reduce the resulting lists using FOLDER and initial value
- INIT-VALUE. See ‘-reduce-r-from’ (*note -reduce-r-from::).
-
- This is the same as calling ‘-tree-reduce’ (*note -tree-reduce::)
- after ‘-tree-map’ (*note -tree-map::) but is twice as fast as it
- only traverse the structure once.
-
- (-tree-mapreduce 'list 'append '(1 (2 (3 4) (5 6)) (7 (8 9))))
- ⇒ '(1 2 3 4 5 6 7 8 9)
- (--tree-mapreduce 1 (+ it acc) '(1 (2 (4 9) (2 1)) (7 (4 3))))
- ⇒ 9
- (--tree-mapreduce 0 (max acc (1+ it)) '(1 (2 (4 9) (2 1)) (7 (4 3))))
- ⇒ 3
-
- -- Function: -tree-mapreduce-from (fn folder init-value tree)
- Apply FN to each element of TREE, and make a list of the results.
- If elements of TREE are lists themselves, apply FN recursively to
- elements of these nested lists.
-
- Then reduce the resulting lists using FOLDER and initial value
- INIT-VALUE. See ‘-reduce-r-from’ (*note -reduce-r-from::).
-
- This is the same as calling ‘-tree-reduce-from’ (*note
- -tree-reduce-from::) after ‘-tree-map’ (*note -tree-map::) but is
- twice as fast as it only traverse the structure once.
-
- (-tree-mapreduce-from 'identity '* 1 '(1 (2 (3 4) (5 6)) (7 (8 9))))
- ⇒ 362880
- (--tree-mapreduce-from (+ it it) (cons it acc) nil '(1 (2 (4 9) (2 1)) (7 (4 3))))
- ⇒ '(2 (4 (8 18) (4 2)) (14 (8 6)))
- (concat "{" (--tree-mapreduce-from (cond ((-cons-pair? it) (concat (symbol-name (car it)) " -> " (symbol-name (cdr it)))) (t (concat (symbol-name it) " : {"))) (concat it (unless (or (equal acc "}") (equal (substring it (1- (length it))) "{")) ", ") acc) "}" '((elips-mode (foo (bar . booze)) (baz . qux)) (c-mode (foo . bla) (bum . bam)))))
- ⇒ "{elips-mode : {foo : {bar -> booze{, baz -> qux{, c-mode : {foo -> bla, bum -> bam}}"
-
- -- Function: -clone (list)
- Create a deep copy of LIST. The new list has the same elements and
- structure but all cons are replaced with new ones. This is useful
- when you need to clone a structure such as plist or alist.
-
- (let* ((a '(1 2 3)) (b (-clone a))) (nreverse a) b)
- ⇒ '(1 2 3)
-
-
-File: dash.info, Node: Threading macros, Next: Binding, Prev: Tree operations, Up: Functions
-
-2.12 Threading macros
-=====================
-
- -- Macro: -> (x &optional form &rest more)
- Thread the expr through the forms. Insert X as the second item in
- the first form, making a list of it if it is not a list already.
- If there are more forms, insert the first form as the second item
- in second form, etc.
-
- (-> '(2 3 5))
- ⇒ '(2 3 5)
- (-> '(2 3 5) (append '(8 13)))
- ⇒ '(2 3 5 8 13)
- (-> '(2 3 5) (append '(8 13)) (-slice 1 -1))
- ⇒ '(3 5 8)
-
- -- Macro: ->> (x &optional form &rest more)
- Thread the expr through the forms. Insert X as the last item in
- the first form, making a list of it if it is not a list already.
- If there are more forms, insert the first form as the last item in
- second form, etc.
-
- (->> '(1 2 3) (-map 'square))
- ⇒ '(1 4 9)
- (->> '(1 2 3) (-map 'square) (-remove 'even?))
- ⇒ '(1 9)
- (->> '(1 2 3) (-map 'square) (-reduce '+))
- ⇒ 14
-
- -- Macro: --> (x &rest forms)
- Starting with the value of X, thread each expression through FORMS.
-
- Insert X at the position signified by the symbol ‘it’ in the first
- form. If there are more forms, insert the first form at the
- position signified by ‘it’ in in second form, etc.
-
- (--> "def" (concat "abc" it "ghi"))
- ⇒ "abcdefghi"
- (--> "def" (concat "abc" it "ghi") (upcase it))
- ⇒ "ABCDEFGHI"
- (--> "def" (concat "abc" it "ghi") upcase)
- ⇒ "ABCDEFGHI"
-
- -- Macro: -as-> (value variable &rest forms)
- Starting with VALUE, thread VARIABLE through FORMS.
-
- In the first form, bind VARIABLE to VALUE. In the second form,
- bind VARIABLE to the result of the first form, and so forth.
-
- (-as-> 3 my-var (1+ my-var) (list my-var) (mapcar (lambda (ele) (* 2 ele)) my-var))
- ⇒ '(8)
- (-as-> 3 my-var 1+)
- ⇒ 4
- (-as-> 3 my-var)
- ⇒ 3
-
- -- Macro: -some-> (x &optional form &rest more)
- When expr is non-nil, thread it through the first form (via ‘->’
- (*note ->::)), and when that result is non-nil, through the next
- form, etc.
-
- (-some-> '(2 3 5))
- ⇒ '(2 3 5)
- (-some-> 5 square)
- ⇒ 25
- (-some-> 5 even? square)
- ⇒ nil
-
- -- Macro: -some->> (x &optional form &rest more)
- When expr is non-nil, thread it through the first form (via ‘->>’
- (*note ->>::)), and when that result is non-nil, through the next
- form, etc.
-
- (-some->> '(1 2 3) (-map 'square))
- ⇒ '(1 4 9)
- (-some->> '(1 3 5) (-last 'even?) (+ 100))
- ⇒ nil
- (-some->> '(2 4 6) (-last 'even?) (+ 100))
- ⇒ 106
-
- -- Macro: -some--> (x &optional form &rest more)
- When expr in non-nil, thread it through the first form (via ‘-->’
- (*note -->::)), and when that result is non-nil, through the next
- form, etc.
-
- (-some--> "def" (concat "abc" it "ghi"))
- ⇒ "abcdefghi"
- (-some--> nil (concat "abc" it "ghi"))
- ⇒ nil
- (-some--> '(1 3 5) (-filter 'even? it) (append it it) (-map 'square it))
- ⇒ nil
-
-
-File: dash.info, Node: Binding, Next: Side-effects, Prev: Threading macros, Up: Functions
-
-2.13 Binding
-============
-
-Convenient versions of ‘let‘ and ‘let*‘ constructs combined with flow
-control.
-
- -- Macro: -when-let (var-val &rest body)
- If VAL evaluates to non-nil, bind it to VAR and execute body.
-
- Note: binding is done according to ‘-let’ (*note -let::).
-
- (fn (VAR VAL) &rest BODY)
-
- (-when-let (match-index (string-match "d" "abcd")) (+ match-index 2))
- ⇒ 5
- (-when-let ((&plist :foo foo) (list :foo "foo")) foo)
- ⇒ "foo"
- (-when-let ((&plist :foo foo) (list :bar "bar")) foo)
- ⇒ nil
-
- -- Macro: -when-let* (vars-vals &rest body)
- If all VALS evaluate to true, bind them to their corresponding VARS
- and execute body. VARS-VALS should be a list of (VAR VAL) pairs.
-
- Note: binding is done according to ‘-let*’ (*note -let*::). VALS
- are evaluated sequentially, and evaluation stops after the first
- nil VAL is encountered.
-
- (-when-let* ((x 5) (y 3) (z (+ y 4))) (+ x y z))
- ⇒ 15
- (-when-let* ((x 5) (y nil) (z 7)) (+ x y z))
- ⇒ nil
-
- -- Macro: -if-let (var-val then &rest else)
- If VAL evaluates to non-nil, bind it to VAR and do THEN, otherwise
- do ELSE.
-
- Note: binding is done according to ‘-let’ (*note -let::).
-
- (fn (VAR VAL) THEN &rest ELSE)
-
- (-if-let (match-index (string-match "d" "abc")) (+ match-index 3) 7)
- ⇒ 7
- (--if-let (even? 4) it nil)
- ⇒ t
-
- -- Macro: -if-let* (vars-vals then &rest else)
- If all VALS evaluate to true, bind them to their corresponding VARS
- and do THEN, otherwise do ELSE. VARS-VALS should be a list of (VAR
- VAL) pairs.
-
- Note: binding is done according to ‘-let*’ (*note -let*::). VALS
- are evaluated sequentially, and evaluation stops after the first
- nil VAL is encountered.
-
- (-if-let* ((x 5) (y 3) (z 7)) (+ x y z) "foo")
- ⇒ 15
- (-if-let* ((x 5) (y nil) (z 7)) (+ x y z) "foo")
- ⇒ "foo"
- (-if-let* (((_ _ x) '(nil nil 7))) x)
- ⇒ 7
-
- -- Macro: -let (varlist &rest body)
- Bind variables according to VARLIST then eval BODY.
-
- VARLIST is a list of lists of the form (PATTERN SOURCE). Each
- PATTERN is matched against the SOURCE "structurally". SOURCE is
- only evaluated once for each PATTERN. Each PATTERN is matched
- recursively, and can therefore contain sub-patterns which are
- matched against corresponding sub-expressions of SOURCE.
-
- All the SOURCEs are evalled before any symbols are bound (i.e. "in
- parallel").
-
- If VARLIST only contains one (PATTERN SOURCE) element, you can
- optionally specify it using a vector and discarding the outer-most
- parens. Thus
-
- (-let ((PATTERN SOURCE)) ..)
-
- becomes
-
- (-let [PATTERN SOURCE] ..).
-
- ‘-let’ (*note -let::) uses a convention of not binding places
- (symbols) starting with _ whenever it’s possible. You can use this
- to skip over entries you don’t care about. However, this is not
- *always* possible (as a result of implementation) and these symbols
- might get bound to undefined values.
-
- Following is the overview of supported patterns. Remember that
- patterns can be matched recursively, so every a, b, aK in the
- following can be a matching construct and not necessarily a
- symbol/variable.
-
- Symbol:
-
- a - bind the SOURCE to A. This is just like regular ‘let’.
-
- Conses and lists:
-
- (a) - bind ‘car’ of cons/list to A
-
- (a . b) - bind car of cons to A and ‘cdr’ to B
-
- (a b) - bind car of list to A and ‘cadr’ to B
-
- (a1 a2 a3 ...) - bind 0th car of list to A1, 1st to A2, 2nd to A3
- ...
-
- (a1 a2 a3 ... aN . rest) - as above, but bind the Nth cdr to
- REST.
-
- Vectors:
-
- [a] - bind 0th element of a non-list sequence to A (works with
- vectors, strings, bit arrays...)
-
- [a1 a2 a3 ...] - bind 0th element of non-list sequence to A0, 1st
- to A1, 2nd to A2, ... If the PATTERN is shorter than SOURCE, the
- values at places not in PATTERN are ignored. If the PATTERN is
- longer than SOURCE, an ‘error’ is thrown.
-
- [a1 a2 a3 ... &rest rest] - as above, but bind the rest of the
- sequence to REST. This is conceptually the same as improper list
- matching (a1 a2 ... aN . rest)
-
- Key/value stores:
-
- (&plist key0 a0 ... keyN aN) - bind value mapped by keyK in the
- SOURCE plist to aK. If the value is not found, aK is nil. Uses
- ‘plist-get’ to fetch values.
-
- (&alist key0 a0 ... keyN aN) - bind value mapped by keyK in the
- SOURCE alist to aK. If the value is not found, aK is nil. Uses
- ‘assoc’ to fetch values.
-
- (&hash key0 a0 ... keyN aN) - bind value mapped by keyK in the
- SOURCE hash table to aK. If the value is not found, aK is nil.
- Uses ‘gethash’ to fetch values.
-
- Further, special keyword &keys supports "inline" matching of
- plist-like key-value pairs, similarly to &keys keyword of
- ‘cl-defun’.
-
- (a1 a2 ... aN &keys key1 b1 ... keyN bK)
-
- This binds N values from the list to a1 ... aN, then interprets
- the cdr as a plist (see key/value matching above).
-
- A shorthand notation for kv-destructuring exists which allows the
- patterns be optionally left out and derived from the key name in
- the following fashion:
-
- - a key :foo is converted into ‘foo’ pattern, - a key ’bar is
- converted into ‘bar’ pattern, - a key "baz" is converted into ‘baz’
- pattern.
-
- That is, the entire value under the key is bound to the derived
- variable without any further destructuring.
-
- This is possible only when the form following the key is not a
- valid pattern (i.e. not a symbol, a cons cell or a vector).
- Otherwise the matching proceeds as usual and in case of an invalid
- spec fails with an error.
-
- Thus the patterns are normalized as follows:
-
- ;; derive all the missing patterns (&plist :foo ’bar "baz") =>
- (&plist :foo foo ’bar bar "baz" baz)
-
- ;; we can specify some but not others (&plist :foo ’bar
- explicit-bar) => (&plist :foo foo ’bar explicit-bar)
-
- ;; nothing happens, we store :foo in x (&plist :foo x) => (&plist
- :foo x)
-
- ;; nothing happens, we match recursively (&plist :foo (a b c)) =>
- (&plist :foo (a b c))
-
- You can name the source using the syntax SYMBOL &as PATTERN. This
- syntax works with lists (proper or improper), vectors and all types
- of maps.
-
- (list &as a b c) (list 1 2 3)
-
- binds A to 1, B to 2, C to 3 and LIST to (1 2 3).
-
- Similarly:
-
- (bounds &as beg . end) (cons 1 2)
-
- binds BEG to 1, END to 2 and BOUNDS to (1 . 2).
-
- (items &as first . rest) (list 1 2 3)
-
- binds FIRST to 1, REST to (2 3) and ITEMS to (1 2 3)
-
- [vect &as _ b c] [1 2 3]
-
- binds B to 2, C to 3 and VECT to [1 2 3] (_ avoids binding as
- usual).
-
- (plist &as &plist :b b) (list :a 1 :b 2 :c 3)
-
- binds B to 2 and PLIST to (:a 1 :b 2 :c 3). Same for &alist and
- &hash.
-
- This is especially useful when we want to capture the result of a
- computation and destructure at the same time. Consider the form
- (function-returning-complex-structure) returning a list of two
- vectors with two items each. We want to capture this entire result
- and pass it to another computation, but at the same time we want to
- get the second item from each vector. We can achieve it with
- pattern
-
- (result &as [_ a] [_ b]) (function-returning-complex-structure)
-
- Note: Clojure programmers may know this feature as the ":as
- binding". The difference is that we put the &as at the front
- because we need to support improper list binding.
-
- (-let (([a (b c) d] [1 (2 3) 4])) (list a b c d))
- ⇒ '(1 2 3 4)
- (-let [(a b c . d) (list 1 2 3 4 5 6)] (list a b c d))
- ⇒ '(1 2 3 (4 5 6))
- (-let [(&plist :foo foo :bar bar) (list :baz 3 :foo 1 :qux 4 :bar 2)] (list foo bar))
- ⇒ '(1 2)
-
- -- Macro: -let* (varlist &rest body)
- Bind variables according to VARLIST then eval BODY.
-
- VARLIST is a list of lists of the form (PATTERN SOURCE). Each
- PATTERN is matched against the SOURCE structurally. SOURCE is only
- evaluated once for each PATTERN.
-
- Each SOURCE can refer to the symbols already bound by this VARLIST.
- This is useful if you want to destructure SOURCE recursively but
- also want to name the intermediate structures.
-
- See ‘-let’ (*note -let::) for the list of all possible patterns.
-
- (-let* (((a . b) (cons 1 2)) ((c . d) (cons 3 4))) (list a b c d))
- ⇒ '(1 2 3 4)
- (-let* (((a . b) (cons 1 (cons 2 3))) ((c . d) b)) (list a b c d))
- ⇒ '(1 (2 . 3) 2 3)
- (-let* (((&alist "foo" foo "bar" bar) (list (cons "foo" 1) (cons "bar" (list 'a 'b 'c)))) ((a b c) bar)) (list foo a b c bar))
- ⇒ '(1 a b c (a b c))
-
- -- Macro: -lambda (match-form &rest body)
- Return a lambda which destructures its input as MATCH-FORM and
- executes BODY.
-
- Note that you have to enclose the MATCH-FORM in a pair of parens,
- such that:
-
- (-lambda (x) body) (-lambda (x y ...) body)
-
- has the usual semantics of ‘lambda’. Furthermore, these get
- translated into normal lambda, so there is no performance penalty.
-
- See ‘-let’ (*note -let::) for the description of destructuring
- mechanism.
-
- (-map (-lambda ((x y)) (+ x y)) '((1 2) (3 4) (5 6)))
- ⇒ '(3 7 11)
- (-map (-lambda ([x y]) (+ x y)) '([1 2] [3 4] [5 6]))
- ⇒ '(3 7 11)
- (funcall (-lambda ((_ . a) (_ . b)) (-concat a b)) '(1 2 3) '(4 5 6))
- ⇒ '(2 3 5 6)
-
- -- Macro: -setq (&rest forms)
- Bind each MATCH-FORM to the value of its VAL.
-
- MATCH-FORM destructuring is done according to the rules of ‘-let’
- (*note -let::).
-
- This macro allows you to bind multiple variables by destructuring
- the value, so for example:
-
- (-setq (a b) x (&plist :c c) plist)
-
- expands roughly speaking to the following code
-
- (setq a (car x) b (cadr x) c (plist-get plist :c))
-
- Care is taken to only evaluate each VAL once so that in case of
- multiple assignments it does not cause unexpected side effects.
-
- (fn [MATCH-FORM VAL]...)
-
- (progn (-setq a 1) a)
- ⇒ 1
- (progn (-setq (a b) (list 1 2)) (list a b))
- ⇒ '(1 2)
- (progn (-setq (&plist :c c) (list :c "c")) c)
- ⇒ "c"
-
-
-File: dash.info, Node: Side-effects, Next: Destructive operations, Prev: Binding, Up: Functions
-
-2.14 Side-effects
-=================
-
-Functions iterating over lists for side-effect only.
-
- -- Function: -each (list fn)
- Call FN with every item in LIST. Return nil, used for side-effects
- only.
-
- (let (s) (-each '(1 2 3) (lambda (item) (setq s (cons item s)))))
- ⇒ nil
- (let (s) (-each '(1 2 3) (lambda (item) (setq s (cons item s)))) s)
- ⇒ '(3 2 1)
- (let (s) (--each '(1 2 3) (setq s (cons it s))) s)
- ⇒ '(3 2 1)
-
- -- Function: -each-while (list pred fn)
- Call FN with every item in LIST while (PRED item) is non-nil.
- Return nil, used for side-effects only.
-
- (let (s) (-each-while '(2 4 5 6) 'even? (lambda (item) (!cons item s))) s)
- ⇒ '(4 2)
- (let (s) (--each-while '(1 2 3 4) (< it 3) (!cons it s)) s)
- ⇒ '(2 1)
-
- -- Function: -each-indexed (list fn)
- Call (FN index item) for each item in LIST.
-
- In the anaphoric form ‘--each-indexed’, the index is exposed as
- symbol ‘it-index’.
-
- See also: ‘-map-indexed’ (*note -map-indexed::).
-
- (let (s) (-each-indexed '(a b c) (lambda (index item) (setq s (cons (list item index) s)))) s)
- ⇒ '((c 2) (b 1) (a 0))
- (let (s) (--each-indexed '(a b c) (setq s (cons (list it it-index) s))) s)
- ⇒ '((c 2) (b 1) (a 0))
-
- -- Function: -each-r (list fn)
- Call FN with every item in LIST in reversed order. Return nil,
- used for side-effects only.
-
- (let (s) (-each-r '(1 2 3) (lambda (item) (setq s (cons item s)))))
- ⇒ nil
- (let (s) (-each-r '(1 2 3) (lambda (item) (setq s (cons item s)))) s)
- ⇒ '(1 2 3)
- (let (s) (--each-r '(1 2 3) (setq s (cons it s))) s)
- ⇒ '(1 2 3)
-
- -- Function: -each-r-while (list pred fn)
- Call FN with every item in reversed LIST while (PRED item) is
- non-nil. Return nil, used for side-effects only.
-
- (let (s) (-each-r-while '(2 4 5 6) 'even? (lambda (item) (!cons item s))) s)
- ⇒ '(6)
- (let (s) (--each-r-while '(1 2 3 4) (>= it 3) (!cons it s)) s)
- ⇒ '(3 4)
-
- -- Function: -dotimes (num fn)
- Repeatedly calls FN (presumably for side-effects) passing in
- integers from 0 through NUM-1.
-
- (let (s) (-dotimes 3 (lambda (n) (!cons n s))) s)
- ⇒ '(2 1 0)
- (let (s) (--dotimes 5 (!cons it s)) s)
- ⇒ '(4 3 2 1 0)
-
- -- Macro: -doto (eval-initial-value &rest forms)
- Eval a form, then insert that form as the 2nd argument to other
- forms. The EVAL-INITIAL-VALUE form is evaluated once. Its result
- is passed to FORMS, which are then evaluated sequentially. Returns
- the target form.
-
- (-doto '(1 2 3) (!cdr) (!cdr))
- ⇒ '(3)
- (-doto '(1 . 2) (setcar 3) (setcdr 4))
- ⇒ '(3 . 4)
-
- -- Macro: --doto (eval-initial-value &rest forms)
- Anaphoric form of ‘-doto’ (*note -doto::). Note: ‘it’ is not
- required in each form.
-
- (gethash "key" (--doto (make-hash-table :test 'equal) (puthash "key" "value" it)))
- ⇒ "value"
-
-
-File: dash.info, Node: Destructive operations, Next: Function combinators, Prev: Side-effects, Up: Functions
-
-2.15 Destructive operations
-===========================
-
- -- Macro: !cons (car cdr)
- Destructive: Set CDR to the cons of CAR and CDR.
-
- (let (l) (!cons 5 l) l)
- ⇒ '(5)
- (let ((l '(3))) (!cons 5 l) l)
- ⇒ '(5 3)
-
- -- Macro: !cdr (list)
- Destructive: Set LIST to the cdr of LIST.
-
- (let ((l '(3))) (!cdr l) l)
- ⇒ '()
- (let ((l '(3 5))) (!cdr l) l)
- ⇒ '(5)
-
-
-File: dash.info, Node: Function combinators, Prev: Destructive operations, Up: Functions
-
-2.16 Function combinators
-=========================
-
-These combinators require Emacs 24 for its lexical scope. So they are
-offered in a separate package: ‘dash-functional‘.
-
- -- Function: -partial (fn &rest args)
- Takes a function FN and fewer than the normal arguments to FN, and
- returns a fn that takes a variable number of additional ARGS. When
- called, the returned function calls FN with ARGS first and then
- additional args.
-
- (funcall (-partial '- 5) 3)
- ⇒ 2
- (funcall (-partial '+ 5 2) 3)
- ⇒ 10
-
- -- Function: -rpartial (fn &rest args)
- Takes a function FN and fewer than the normal arguments to FN, and
- returns a fn that takes a variable number of additional ARGS. When
- called, the returned function calls FN with the additional args
- first and then ARGS.
-
- (funcall (-rpartial '- 5) 8)
- ⇒ 3
- (funcall (-rpartial '- 5 2) 10)
- ⇒ 3
-
- -- Function: -juxt (&rest fns)
- Takes a list of functions and returns a fn that is the
- juxtaposition of those fns. The returned fn takes a variable
- number of args, and returns a list containing the result of
- applying each fn to the args (left-to-right).
-
- (funcall (-juxt '+ '-) 3 5)
- ⇒ '(8 -2)
- (-map (-juxt 'identity 'square) '(1 2 3))
- ⇒ '((1 1) (2 4) (3 9))
-
- -- Function: -compose (&rest fns)
- Takes a list of functions and returns a fn that is the composition
- of those fns. The returned fn takes a variable number of
- arguments, and returns the result of applying each fn to the result
- of applying the previous fn to the arguments (right-to-left).
-
- (funcall (-compose 'square '+) 2 3)
- ⇒ (square (+ 2 3))
- (funcall (-compose 'identity 'square) 3)
- ⇒ (square 3)
- (funcall (-compose 'square 'identity) 3)
- ⇒ (square 3)
-
- -- Function: -applify (fn)
- Changes an n-arity function FN to a 1-arity function that expects a
- list with n items as arguments
-
- (-map (-applify '+) '((1 1 1) (1 2 3) (5 5 5)))
- ⇒ '(3 6 15)
- (-map (-applify (lambda (a b c) `(,a (,b (,c))))) '((1 1 1) (1 2 3) (5 5 5)))
- ⇒ '((1 (1 (1))) (1 (2 (3))) (5 (5 (5))))
- (funcall (-applify '<) '(3 6))
- ⇒ t
-
- -- Function: -on (operator transformer)
- Return a function of two arguments that first applies TRANSFORMER
- to each of them and then applies OPERATOR on the results (in the
- same order).
-
- In types: (b -> b -> c) -> (a -> b) -> a -> a -> c
-
- (-sort (-on '< 'length) '((1 2 3) (1) (1 2)))
- ⇒ '((1) (1 2) (1 2 3))
- (-min-by (-on '> 'length) '((1 2 3) (4) (1 2)))
- ⇒ '(4)
- (-min-by (-on 'string-lessp 'number-to-string) '(2 100 22))
- ⇒ 22
-
- -- Function: -flip (func)
- Swap the order of arguments for binary function FUNC.
-
- In types: (a -> b -> c) -> b -> a -> c
-
- (funcall (-flip '<) 2 1)
- ⇒ t
- (funcall (-flip '-) 3 8)
- ⇒ 5
- (-sort (-flip '<) '(4 3 6 1))
- ⇒ '(6 4 3 1)
-
- -- Function: -const (c)
- Return a function that returns C ignoring any additional arguments.
-
- In types: a -> b -> a
-
- (funcall (-const 2) 1 3 "foo")
- ⇒ 2
- (-map (-const 1) '("a" "b" "c" "d"))
- ⇒ '(1 1 1 1)
- (-sum (-map (-const 1) '("a" "b" "c" "d")))
- ⇒ 4
-
- -- Macro: -cut (&rest params)
- Take n-ary function and n arguments and specialize some of them.
- Arguments denoted by <> will be left unspecialized.
-
- See SRFI-26 for detailed description.
-
- (funcall (-cut list 1 <> 3 <> 5) 2 4)
- ⇒ '(1 2 3 4 5)
- (-map (-cut funcall <> 5) '(1+ 1- (lambda (x) (/ 1.0 x))))
- ⇒ '(6 4 0.2)
- (-map (-cut <> 1 2 3) (list 'list 'vector 'string))
- ⇒ '((1 2 3) [1 2 3] "")
-
- -- Function: -not (pred)
- Take a unary predicate PRED and return a unary predicate that
- returns t if PRED returns nil and nil if PRED returns non-nil.
-
- (funcall (-not 'even?) 5)
- ⇒ t
- (-filter (-not (-partial '< 4)) '(1 2 3 4 5 6 7 8))
- ⇒ '(1 2 3 4)
-
- -- Function: -orfn (&rest preds)
- Take list of unary predicates PREDS and return a unary predicate
- with argument x that returns non-nil if at least one of the PREDS
- returns non-nil on x.
-
- In types: [a -> Bool] -> a -> Bool
-
- (-filter (-orfn 'even? (-partial (-flip '<) 5)) '(1 2 3 4 5 6 7 8 9 10))
- ⇒ '(1 2 3 4 6 8 10)
- (funcall (-orfn 'stringp 'even?) "foo")
- ⇒ t
-
- -- Function: -andfn (&rest preds)
- Take list of unary predicates PREDS and return a unary predicate
- with argument x that returns non-nil if all of the PREDS returns
- non-nil on x.
-
- In types: [a -> Bool] -> a -> Bool
-
- (funcall (-andfn (-cut < <> 10) 'even?) 6)
- ⇒ t
- (funcall (-andfn (-cut < <> 10) 'even?) 12)
- ⇒ nil
- (-filter (-andfn (-not 'even?) (-cut >= 5 <>)) '(1 2 3 4 5 6 7 8 9 10))
- ⇒ '(1 3 5)
-
- -- Function: -iteratefn (fn n)
- Return a function FN composed N times with itself.
-
- FN is a unary function. If you need to use a function of higher
- arity, use ‘-applify’ (*note -applify::) first to turn it into a
- unary function.
-
- With n = 0, this acts as identity function.
-
- In types: (a -> a) -> Int -> a -> a.
-
- This function satisfies the following law:
-
- (funcall (-iteratefn fn n) init) = (-last-item (-iterate fn init
- (1+ n))).
-
- (funcall (-iteratefn (lambda (x) (* x x)) 3) 2)
- ⇒ 256
- (funcall (-iteratefn '1+ 3) 1)
- ⇒ 4
- (funcall (-iteratefn 'cdr 3) '(1 2 3 4 5))
- ⇒ '(4 5)
-
- -- Function: -fixfn (fn &optional equal-test halt-test)
- Return a function that computes the (least) fixpoint of FN.
-
- FN must be a unary function. The returned lambda takes a single
- argument, X, the initial value for the fixpoint iteration. The
- iteration halts when either of the following conditions is
- satisfied:
-
- 1. Iteration converges to the fixpoint, with equality being tested
- using EQUAL-TEST. If EQUAL-TEST is not specified, ‘equal’ is used.
- For functions over the floating point numbers, it may be necessary
- to provide an appropriate appoximate comparison test.
-
- 2. HALT-TEST returns a non-nil value. HALT-TEST defaults to a
- simple counter that returns t after ‘-fixfn-max-iterations’, to
- guard against infinite iteration. Otherwise, HALT-TEST must be a
- function that accepts a single argument, the current value of X,
- and returns non-nil as long as iteration should continue. In this
- way, a more sophisticated convergence test may be supplied by the
- caller.
-
- The return value of the lambda is either the fixpoint or, if
- iteration halted before converging, a cons with car ‘halted’ and
- cdr the final output from HALT-TEST.
-
- In types: (a -> a) -> a -> a.
-
- (funcall (-fixfn 'cos 'approx-equal) 0.7)
- ⇒ 0.7390851332151607
- (funcall (-fixfn (lambda (x) (expt (+ x 10) 0.25))) 2.0)
- ⇒ 1.8555845286409378
- (funcall (-fixfn 'sin 'approx-equal) 0.1)
- ⇒ '(halted . t)
-
- -- Function: -prodfn (&rest fns)
- Take a list of n functions and return a function that takes a list
- of length n, applying i-th function to i-th element of the input
- list. Returns a list of length n.
-
- In types (for n=2): ((a -> b), (c -> d)) -> (a, c) -> (b, d)
-
- This function satisfies the following laws:
-
- (-compose (-prodfn f g ...) (-prodfn f’ g’ ...)) = (-prodfn
- (-compose f f’) (-compose g g’) ...) (-prodfn f g ...) = (-juxt
- (-compose f (-partial ’nth 0)) (-compose g (-partial ’nth 1)) ...)
- (-compose (-prodfn f g ...) (-juxt f’ g’ ...)) = (-juxt (-compose
- f f’) (-compose g g’) ...) (-compose (-partial ’nth n) (-prod f1
- f2 ...)) = (-compose fn (-partial ’nth n))
-
- (funcall (-prodfn '1+ '1- 'number-to-string) '(1 2 3))
- ⇒ '(2 1 "3")
- (-map (-prodfn '1+ '1-) '((1 2) (3 4) (5 6) (7 8)))
- ⇒ '((2 1) (4 3) (6 5) (8 7))
- (apply '+ (funcall (-prodfn 'length 'string-to-number) '((1 2 3) "15")))
- ⇒ 18
-
-
-File: dash.info, Node: Development, Next: Index, Prev: Functions, Up: Top
-
-3 Development
-*************
-
-The dash repository is hosted on GitHub:
-
-
-* Menu:
-
-* Contribute:: How to contribute
-* Changes:: List of significant changes by version
-* Contributors:: List of contributors
-
-
-File: dash.info, Node: Contribute, Next: Changes, Up: Development
-
-3.1 Contribute
-==============
-
-Yes, please do. Pure functions in the list manipulation realm only,
-please. There’s a suite of tests in dev/examples.el, so remember to add
-tests for your function, or it might get broken later.
-
- Run the tests with ‘./run-tests.sh’. Create the docs with
-‘./create-docs.sh’. I highly recommend that you install these as a
-pre-commit hook, so that the tests are always running and the docs are
-always in sync:
-
-cp pre-commit.sh .git/hooks/pre-commit
-
- Oh, and don’t edit ‘README.md’ directly, it is auto-generated.
-Change ‘readme-template.md’ or ‘examples-to-docs.el’ instead. The same
-goes for the info manual.
-
-
-File: dash.info, Node: Changes, Next: Contributors, Prev: Contribute, Up: Development
-
-3.2 Changes
-===========
-
-Changes in 2.10:
-
- • Add ‘-let’ destructuring to ‘-if-let’ and ‘-when-let’ (Fredrik
- Bergroth)
-
-Changes in 2.9:
-
- • Add ‘-let’, ‘-let*’ and ‘-lambda’ with destructuring
- • Add ‘-tree-seq’ and ‘-tree-map-nodes’
- • Add ‘-non-nil’
- • Add ‘-fix’
- • Add ‘-fixfn’ (dash-functional 1.2)
- • Add ‘-copy’ (Wilfred Hughes)
-
-Changes in 2.8:
-
- • Add ‘-butlast’
-
-Changes in 2.7:
-
- • ‘-zip’ now supports more than two lists (Steve Lamb)
- • Add ‘-cycle’, ‘-pad’, ‘-annotate’, ‘-zip-fill’ (Steve Lamb)
- • Add ‘-table’, ‘-table-flat’ (finite cartesian product)
- • Add ‘-flatten-n’
- • ‘-slice’ now supports "step" argument
- • Add functional combinators ‘-iteratefn’, ‘-prodfn’
- • Add ‘-replace’, ‘-splice’, ‘-splice-list’ which generalize
- ‘-replace-at’ and ‘-insert-at’
- • Add ‘-compose’, ‘-iteratefn’ and ‘-prodfn’ (dash-functional 1.1)
-
-Changes in 2.6:
-
- • Add ‘-is-prefix-p’, ‘-is-suffix-p’, ‘-is-infix-p’ (Matus Goljer)
- • Add ‘-iterate’, ‘-unfold’ (Matus Goljer)
- • Add ‘-split-on’, ‘-split-when’ (Matus Goljer)
- • Add ‘-find-last-index’ (Matus Goljer)
- • Add ‘-list’ (Johan Andersson)
-
-Changes in 2.5:
-
- • Add ‘-same-items?’ (Johan Andersson)
- • A few bugfixes
-
-Changes in 2.4:
-
- • Add ‘-snoc’ (Matus Goljer)
- • Add ‘-replace-at’, ‘-update-at’, ‘-remove-at’, and
- ‘-remove-at-indices’ (Matus Goljer)
-
-Changes in 2.3:
-
- • Add tree operations (Matus Goljer)
- • Make font-lock optional
-
-Changes in 2.2:
-
- • Add ‘-compose’ (Christina Whyte)
-
-Changes in 2.1:
-
- • Add indexing operations (Matus Goljer)
-
-Changes in 2.0:
-
- • Split out ‘dash-functional.el’ (Matus Goljer)
- • Add ‘-andfn’, ‘-orfn’, ‘-not’, ‘-cut’, ‘-const’, ‘-flip’ and ‘-on’.
- (Matus Goljer)
- • Fix ‘-min’, ‘-max’, ‘-min-by’ and ‘-max-by’ (Matus Goljer)
-
-Changes in 1.8:
-
- • Add ‘-first-item’ and ‘-last-item’ (Wilfred Hughes)
-
-Changes in 1.7:
-
- • Add ‘-rotate’ (Matus Goljer)
-
-Changes in 1.6:
-
- • Add ‘-min’, ‘-max’, ‘-min-by’ and ‘-max-by’ (Johan Andersson)
-
-Changes in 1.5:
-
- • Add ‘-sum’ and ‘-product’ (Johan Andersson)
-
-Changes in 1.4:
-
- • Add ‘-sort’
- • Add ‘-reduce-r’ (Matus Goljer)
- • Add ‘-reduce-r-from’ (Matus Goljer)
-
-Changes in 1.3:
-
- • Add ‘-partition-in-steps’
- • Add ‘-partition-all-in-steps’
-
-Changes in 1.2:
-
- • Add ‘-last’ (Matus Goljer)
- • Add ‘-insert-at’ (Emanuel Evans)
- • Add ‘-when-let’ and ‘-if-let’ (Emanuel Evans)
- • Add ‘-when-let*’ and ‘-if-let*’ (Emanuel Evans)
- • Some bugfixes
-
-
-File: dash.info, Node: Contributors, Prev: Changes, Up: Development
-
-3.3 Contributors
-================
-
- • Matus Goljer (https://github.com/Fuco1) contributed lots of
- features and functions.
- • Takafumi Arakaki (https://github.com/tkf) contributed ‘-group-by’.
- • tali713 (https://github.com/tali713) is the author of ‘-applify’.
- • Víctor M. Valenzuela (https://github.com/vemv) contributed
- ‘-repeat’.
- • Nic Ferrier (https://github.com/nicferrier) contributed ‘-cons*’.
- • Wilfred Hughes (https://github.com/Wilfred) contributed ‘-slice’,
- ‘-first-item’ and ‘-last-item’.
- • Emanuel Evans (https://github.com/shosti) contributed ‘-if-let’,
- ‘-when-let’ and ‘-insert-at’.
- • Johan Andersson (https://github.com/rejeep) contributed ‘-sum’,
- ‘-product’ and ‘-same-items?’
- • Christina Whyte (https://github.com/kurisuwhyte) contributed
- ‘-compose’
- • Steve Lamb (https://github.com/steventlamb) contributed ‘-cycle’,
- ‘-pad’, ‘-annotate’, ‘-zip-fill’ and an n-ary version of ‘-zip’.
- • Fredrik Bergroth (https://github.com/fbergroth) made the ‘-if-let’
- family use ‘-let’ destructuring and improved script for generating
- documentation.
- • Mark Oteiza (https://github.com/holomorph) contributed the script
- to create an info manual.
- • Vasilij Schneidermann (https://github.com/wasamasa) contributed
- ‘-some’.
- • William West (https://github.com/occidens) made ‘-fixfn’ more
- robust at handling floats.
-
- Thanks!
-
-
-File: dash.info, Node: Index, Prev: Development, Up: Top
-
-Index
-*****
-
- [index ]
-* Menu:
-
-* !cdr: Destructive operations.
- (line 14)
-* !cons: Destructive operations.
- (line 6)
-* -->: Threading macros. (line 32)
-* --doto: Side-effects. (line 81)
-* ->: Threading macros. (line 6)
-* ->>: Threading macros. (line 19)
-* -all?: Predicates. (line 18)
-* -andfn: Function combinators.
- (line 138)
-* -annotate: Maps. (line 79)
-* -any?: Predicates. (line 6)
-* -applify: Function combinators.
- (line 55)
-* -as->: Threading macros. (line 46)
-* -butlast: Other list operations.
- (line 340)
-* -clone: Tree operations. (line 122)
-* -common-prefix: Reductions. (line 223)
-* -common-suffix: Reductions. (line 233)
-* -compose: Function combinators.
- (line 42)
-* -concat: List to list. (line 22)
-* -cons*: Other list operations.
- (line 30)
-* -const: Function combinators.
- (line 92)
-* -contains?: Predicates. (line 57)
-* -copy: Maps. (line 134)
-* -count: Reductions. (line 151)
-* -cut: Function combinators.
- (line 104)
-* -cycle: Other list operations.
- (line 168)
-* -difference: Set operations. (line 20)
-* -distinct: Set operations. (line 62)
-* -dotimes: Side-effects. (line 61)
-* -doto: Side-effects. (line 70)
-* -drop: Sublist selection. (line 124)
-* -drop-last: Sublist selection. (line 136)
-* -drop-while: Sublist selection. (line 157)
-* -each: Side-effects. (line 8)
-* -each-indexed: Side-effects. (line 28)
-* -each-r: Side-effects. (line 41)
-* -each-r-while: Side-effects. (line 52)
-* -each-while: Side-effects. (line 19)
-* -elem-index: Indexing. (line 9)
-* -elem-indices: Indexing. (line 21)
-* -fifth-item: Other list operations.
- (line 320)
-* -filter: Sublist selection. (line 8)
-* -find-index: Indexing. (line 32)
-* -find-indices: Indexing. (line 60)
-* -find-last-index: Indexing. (line 46)
-* -first: Other list operations.
- (line 234)
-* -first-item: Other list operations.
- (line 271)
-* -fix: Other list operations.
- (line 376)
-* -fixfn: Function combinators.
- (line 175)
-* -flatten: List to list. (line 33)
-* -flatten-n: List to list. (line 55)
-* -flip: Function combinators.
- (line 80)
-* -fourth-item: Other list operations.
- (line 310)
-* -grade-down: Indexing. (line 81)
-* -grade-up: Indexing. (line 71)
-* -group-by: Partitioning. (line 187)
-* -if-let: Binding. (line 36)
-* -if-let*: Binding. (line 49)
-* -inits: Reductions. (line 203)
-* -insert-at: List to list. (line 109)
-* -interleave: Other list operations.
- (line 68)
-* -interpose: Other list operations.
- (line 58)
-* -intersection: Set operations. (line 32)
-* -is-infix?: Predicates. (line 110)
-* -is-prefix?: Predicates. (line 86)
-* -is-suffix?: Predicates. (line 98)
-* -iterate: Unfolding. (line 9)
-* -iteratefn: Function combinators.
- (line 152)
-* -juxt: Function combinators.
- (line 31)
-* -keep: List to list. (line 8)
-* -lambda: Binding. (line 252)
-* -last: Other list operations.
- (line 261)
-* -last-item: Other list operations.
- (line 330)
-* -let: Binding. (line 65)
-* -let*: Binding. (line 232)
-* -list: Other list operations.
- (line 363)
-* -map: Maps. (line 10)
-* -map-first: Maps. (line 37)
-* -map-indexed: Maps. (line 65)
-* -map-last: Maps. (line 51)
-* -map-when: Maps. (line 21)
-* -mapcat: Maps. (line 123)
-* -max: Reductions. (line 267)
-* -max-by: Reductions. (line 277)
-* -min: Reductions. (line 243)
-* -min-by: Reductions. (line 253)
-* -non-nil: Sublist selection. (line 79)
-* -none?: Predicates. (line 30)
-* -not: Function combinators.
- (line 117)
-* -on: Function combinators.
- (line 66)
-* -only-some?: Predicates. (line 42)
-* -orfn: Function combinators.
- (line 126)
-* -pad: Other list operations.
- (line 179)
-* -partial: Function combinators.
- (line 9)
-* -partition: Partitioning. (line 74)
-* -partition-after-item: Partitioning. (line 177)
-* -partition-after-pred: Partitioning. (line 145)
-* -partition-all: Partitioning. (line 86)
-* -partition-all-in-steps: Partitioning. (line 109)
-* -partition-before-item: Partitioning. (line 167)
-* -partition-before-pred: Partitioning. (line 156)
-* -partition-by: Partitioning. (line 121)
-* -partition-by-header: Partitioning. (line 132)
-* -partition-in-steps: Partitioning. (line 97)
-* -permutations: Set operations. (line 52)
-* -powerset: Set operations. (line 44)
-* -prodfn: Function combinators.
- (line 209)
-* -product: Reductions. (line 181)
-* -reduce: Reductions. (line 46)
-* -reduce-from: Reductions. (line 8)
-* -reduce-r: Reductions. (line 65)
-* -reduce-r-from: Reductions. (line 27)
-* -reductions: Reductions. (line 119)
-* -reductions-from: Reductions. (line 87)
-* -reductions-r: Reductions. (line 135)
-* -reductions-r-from: Reductions. (line 103)
-* -remove: Sublist selection. (line 23)
-* -remove-at: List to list. (line 145)
-* -remove-at-indices: List to list. (line 158)
-* -remove-first: Sublist selection. (line 37)
-* -remove-item: Sublist selection. (line 67)
-* -remove-last: Sublist selection. (line 52)
-* -repeat: Other list operations.
- (line 19)
-* -replace: List to list. (line 67)
-* -replace-at: List to list. (line 120)
-* -replace-first: List to list. (line 81)
-* -replace-last: List to list. (line 95)
-* -rotate: Other list operations.
- (line 8)
-* -rpartial: Function combinators.
- (line 20)
-* -running-product: Reductions. (line 191)
-* -running-sum: Reductions. (line 169)
-* -same-items?: Predicates. (line 72)
-* -second-item: Other list operations.
- (line 286)
-* -select-by-indices: Sublist selection. (line 168)
-* -select-column: Sublist selection. (line 198)
-* -select-columns: Sublist selection. (line 179)
-* -separate: Partitioning. (line 63)
-* -setq: Binding. (line 274)
-* -slice: Sublist selection. (line 85)
-* -snoc: Other list operations.
- (line 44)
-* -some: Other list operations.
- (line 248)
-* -some-->: Threading macros. (line 83)
-* -some->: Threading macros. (line 59)
-* -some->>: Threading macros. (line 71)
-* -sort: Other list operations.
- (line 350)
-* -splice: Maps. (line 90)
-* -splice-list: Maps. (line 110)
-* -split-at: Partitioning. (line 8)
-* -split-on: Partitioning. (line 28)
-* -split-when: Partitioning. (line 46)
-* -split-with: Partitioning. (line 17)
-* -sum: Reductions. (line 159)
-* -table: Other list operations.
- (line 190)
-* -table-flat: Other list operations.
- (line 209)
-* -tails: Reductions. (line 213)
-* -take: Sublist selection. (line 101)
-* -take-last: Sublist selection. (line 112)
-* -take-while: Sublist selection. (line 146)
-* -third-item: Other list operations.
- (line 298)
-* -tree-map: Tree operations. (line 28)
-* -tree-map-nodes: Tree operations. (line 39)
-* -tree-mapreduce: Tree operations. (line 84)
-* -tree-mapreduce-from: Tree operations. (line 103)
-* -tree-reduce: Tree operations. (line 52)
-* -tree-reduce-from: Tree operations. (line 69)
-* -tree-seq: Tree operations. (line 8)
-* -unfold: Unfolding. (line 25)
-* -union: Set operations. (line 8)
-* -unzip: Other list operations.
- (line 146)
-* -update-at: List to list. (line 132)
-* -when-let: Binding. (line 9)
-* -when-let*: Binding. (line 23)
-* -zip: Other list operations.
- (line 95)
-* -zip-fill: Other list operations.
- (line 138)
-* -zip-lists: Other list operations.
- (line 119)
-* -zip-with: Other list operations.
- (line 79)
-
-
-
-Tag Table:
-Node: Top946
-Node: Installation2425
-Node: Using in a package2958
-Node: Syntax highlighting of dash functions3322
-Node: Functions3705
-Node: Maps4916
-Ref: -map5211
-Ref: -map-when5552
-Ref: -map-first6130
-Ref: -map-last6608
-Ref: -map-indexed7081
-Ref: -annotate7561
-Ref: -splice8051
-Ref: -splice-list8832
-Ref: -mapcat9294
-Ref: -copy9670
-Node: Sublist selection9874
-Ref: -filter10067
-Ref: -remove10519
-Ref: -remove-first10925
-Ref: -remove-last11452
-Ref: -remove-item11973
-Ref: -non-nil12368
-Ref: -slice12527
-Ref: -take13059
-Ref: -take-last13367
-Ref: -drop13690
-Ref: -drop-last13963
-Ref: -take-while14223
-Ref: -drop-while14573
-Ref: -select-by-indices14929
-Ref: -select-columns15443
-Ref: -select-column16149
-Node: List to list16613
-Ref: -keep16805
-Ref: -concat17308
-Ref: -flatten17605
-Ref: -flatten-n18364
-Ref: -replace18751
-Ref: -replace-first19214
-Ref: -replace-last19711
-Ref: -insert-at20201
-Ref: -replace-at20528
-Ref: -update-at20918
-Ref: -remove-at21409
-Ref: -remove-at-indices21897
-Node: Reductions22479
-Ref: -reduce-from22648
-Ref: -reduce-r-from23414
-Ref: -reduce24181
-Ref: -reduce-r24910
-Ref: -reductions-from25781
-Ref: -reductions-r-from26496
-Ref: -reductions27221
-Ref: -reductions-r27846
-Ref: -count28481
-Ref: -sum28705
-Ref: -running-sum28894
-Ref: -product29187
-Ref: -running-product29396
-Ref: -inits29709
-Ref: -tails29957
-Ref: -common-prefix30204
-Ref: -common-suffix30501
-Ref: -min30798
-Ref: -min-by31024
-Ref: -max31547
-Ref: -max-by31772
-Node: Unfolding32300
-Ref: -iterate32539
-Ref: -unfold32984
-Node: Predicates33792
-Ref: -any?33916
-Ref: -all?34236
-Ref: -none?34566
-Ref: -only-some?34868
-Ref: -contains?35353
-Ref: -same-items?35742
-Ref: -is-prefix?36127
-Ref: -is-suffix?36450
-Ref: -is-infix?36773
-Node: Partitioning37127
-Ref: -split-at37315
-Ref: -split-with37600
-Ref: -split-on38003
-Ref: -split-when38679
-Ref: -separate39319
-Ref: -partition39761
-Ref: -partition-all40213
-Ref: -partition-in-steps40641
-Ref: -partition-all-in-steps41138
-Ref: -partition-by41623
-Ref: -partition-by-header42005
-Ref: -partition-after-pred42609
-Ref: -partition-before-pred42953
-Ref: -partition-before-item43304
-Ref: -partition-after-item43615
-Ref: -group-by43921
-Node: Indexing44358
-Ref: -elem-index44560
-Ref: -elem-indices44955
-Ref: -find-index45338
-Ref: -find-last-index45827
-Ref: -find-indices46331
-Ref: -grade-up46739
-Ref: -grade-down47142
-Node: Set operations47552
-Ref: -union47735
-Ref: -difference48177
-Ref: -intersection48594
-Ref: -powerset49031
-Ref: -permutations49244
-Ref: -distinct49544
-Node: Other list operations49922
-Ref: -rotate50147
-Ref: -repeat50517
-Ref: -cons*50780
-Ref: -snoc51167
-Ref: -interpose51580
-Ref: -interleave51878
-Ref: -zip-with52247
-Ref: -zip52964
-Ref: -zip-lists53796
-Ref: -zip-fill54497
-Ref: -unzip54820
-Ref: -cycle55565
-Ref: -pad55938
-Ref: -table56261
-Ref: -table-flat57050
-Ref: -first58058
-Ref: -some58430
-Ref: -last58739
-Ref: -first-item59073
-Ref: -second-item59489
-Ref: -third-item59769
-Ref: -fourth-item60047
-Ref: -fifth-item60313
-Ref: -last-item60575
-Ref: -butlast60867
-Ref: -sort61114
-Ref: -list61603
-Ref: -fix61934
-Node: Tree operations62474
-Ref: -tree-seq62670
-Ref: -tree-map63528
-Ref: -tree-map-nodes63971
-Ref: -tree-reduce64821
-Ref: -tree-reduce-from65703
-Ref: -tree-mapreduce66304
-Ref: -tree-mapreduce-from67164
-Ref: -clone68450
-Node: Threading macros68778
-Ref: ->68923
-Ref: ->>69414
-Ref: -->69919
-Ref: -as->70475
-Ref: -some->70930
-Ref: -some->>71304
-Ref: -some-->71740
-Node: Binding72211
-Ref: -when-let72423
-Ref: -when-let*72908
-Ref: -if-let73431
-Ref: -if-let*73826
-Ref: -let74443
-Ref: -let*80533
-Ref: -lambda81473
-Ref: -setq82270
-Node: Side-effects83086
-Ref: -each83280
-Ref: -each-while83687
-Ref: -each-indexed84047
-Ref: -each-r84565
-Ref: -each-r-while84998
-Ref: -dotimes85373
-Ref: -doto85676
-Ref: --doto86104
-Node: Destructive operations86379
-Ref: !cons86552
-Ref: !cdr86758
-Node: Function combinators86953
-Ref: -partial87227
-Ref: -rpartial87623
-Ref: -juxt88026
-Ref: -compose88458
-Ref: -applify89011
-Ref: -on89442
-Ref: -flip89968
-Ref: -const90280
-Ref: -cut90619
-Ref: -not91105
-Ref: -orfn91415
-Ref: -andfn91849
-Ref: -iteratefn92344
-Ref: -fixfn93047
-Ref: -prodfn94609
-Node: Development95677
-Node: Contribute96026
-Node: Changes96774
-Node: Contributors99772
-Node: Index101391
-
-End Tag Table
-
-
-Local Variables:
-coding: utf-8
-End:
diff --git a/elpa/dash-2.18.0/dash-autoloads.el b/elpa/dash-2.18.0/dash-autoloads.el
new file mode 100644
index 0000000..3a96693
--- /dev/null
+++ b/elpa/dash-2.18.0/dash-autoloads.el
@@ -0,0 +1,74 @@
+;;; dash-autoloads.el --- automatically extracted autoloads
+;;
+;;; Code:
+
+(add-to-list 'load-path (directory-file-name
+ (or (file-name-directory #$) (car load-path))))
+
+
+;;;### (autoloads nil "dash" "dash.el" (0 0 0 0))
+;;; Generated autoloads from dash.el
+
+(autoload 'dash-fontify-mode "dash" "\
+Toggle fontification of Dash special variables.
+
+If called interactively, enable Dash-Fontify mode if ARG is
+positive, and disable it if ARG is zero or negative. If called
+from Lisp, also enable the mode if ARG is omitted or nil, and
+toggle it if ARG is `toggle'; disable the mode otherwise.
+
+Dash-Fontify mode is a buffer-local minor mode intended for Emacs
+Lisp buffers. Enabling it causes the special variables bound in
+anaphoric Dash macros to be fontified. These anaphoras include
+`it', `it-index', `acc', and `other'. In older Emacs versions
+which do not dynamically detect macros, Dash-Fontify mode
+additionally fontifies Dash macro calls.
+
+See also `dash-fontify-mode-lighter' and
+`global-dash-fontify-mode'.
+
+\(fn &optional ARG)" t nil)
+
+(put 'global-dash-fontify-mode 'globalized-minor-mode t)
+
+(defvar global-dash-fontify-mode nil "\
+Non-nil if Global Dash-Fontify mode is enabled.
+See the `global-dash-fontify-mode' command
+for a description of this minor mode.
+Setting this variable directly does not take effect;
+either customize it (see the info node `Easy Customization')
+or call the function `global-dash-fontify-mode'.")
+
+(custom-autoload 'global-dash-fontify-mode "dash" nil)
+
+(autoload 'global-dash-fontify-mode "dash" "\
+Toggle Dash-Fontify mode in all buffers.
+With prefix ARG, enable Global Dash-Fontify mode if ARG is positive;
+otherwise, disable it. If called from Lisp, enable the mode if
+ARG is omitted or nil.
+
+Dash-Fontify mode is enabled in all buffers where
+`dash--turn-on-fontify-mode' would do it.
+See `dash-fontify-mode' for more information on Dash-Fontify mode.
+
+\(fn &optional ARG)" t nil)
+
+(autoload 'dash-register-info-lookup "dash" "\
+Register the Dash Info manual with `info-lookup-symbol'.
+This allows Dash symbols to be looked up with \\[info-lookup-symbol]." t nil)
+
+(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "dash" '("!cdr" "!cons" "--" "->" "-a" "-butlast" "-c" "-d" "-e" "-f" "-gr" "-i" "-juxt" "-keep" "-l" "-m" "-no" "-o" "-p" "-r" "-s" "-t" "-u" "-value-to-list" "-when-let" "-zip" "dash-")))
+
+;;;***
+
+;;;### (autoloads nil nil ("dash-pkg.el") (0 0 0 0))
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; coding: utf-8
+;; End:
+;;; dash-autoloads.el ends here
diff --git a/elpa/dash-2.18.0/dash-pkg.el b/elpa/dash-2.18.0/dash-pkg.el
new file mode 100644
index 0000000..b7be1dc
--- /dev/null
+++ b/elpa/dash-2.18.0/dash-pkg.el
@@ -0,0 +1,12 @@
+(define-package "dash" "2.18.0" "A modern list library for Emacs"
+ '((emacs "24"))
+ :commit "0e975782086020aa12863fdb658d6a3cc748a10c" :authors
+ '(("Magnar Sveen" . "magnars@gmail.com"))
+ :maintainer
+ '("Magnar Sveen" . "magnars@gmail.com")
+ :keywords
+ '("extensions" "lisp")
+ :url "https://github.com/magnars/dash.el")
+;; Local Variables:
+;; no-byte-compile: t
+;; End:
diff --git a/elpa/dash-2.17.0/dash.el b/elpa/dash-2.18.0/dash.el
old mode 100755
new mode 100644
similarity index 65%
rename from elpa/dash-2.17.0/dash.el
rename to elpa/dash-2.18.0/dash.el
index bc713ce..80d4ef9
--- a/elpa/dash-2.17.0/dash.el
+++ b/elpa/dash-2.18.0/dash.el
@@ -1,12 +1,14 @@
;;; dash.el --- A modern list library for Emacs -*- lexical-binding: t -*-
-;; Copyright (C) 2012-2016 Free Software Foundation, Inc.
+;; Copyright (C) 2012-2021 Free Software Foundation, Inc.
;; Author: Magnar Sveen
-;; Version: 2.17.0
-;; Keywords: lists
+;; Version: 2.18.0
+;; Package-Requires: ((emacs "24"))
+;; Keywords: extensions, lisp
+;; Homepage: https://github.com/magnars/dash.el
-;; This program is free software; you can redistribute it and/or modify
+;; This program is free software: you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.
@@ -17,19 +19,13 @@
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
-;; along with this program. If not, see .
+;; along with this program. If not, see .
;;; Commentary:
-;; A modern list api for Emacs.
-;;
-;; See documentation on https://github.com/magnars/dash.el#functions
-;;
-;; **Please note** The lexical binding in this file is not utilised at the
-;; moment. We will take full advantage of lexical binding in an upcoming 3.0
-;; release of Dash. In the meantime, we've added the pragma to avoid a bug that
-;; you can read more about in https://github.com/magnars/dash.el/issues/130.
+;; A modern list API for Emacs.
;;
+;; See its overview at https://github.com/magnars/dash.el#functions.
;;; Code:
@@ -40,22 +36,11 @@
(require 'cl)))
(defgroup dash ()
- "Customize group for dash.el"
+ "Customize group for Dash, a modern list library."
+ :group 'extensions
:group 'lisp
:prefix "dash-")
-(defun dash--enable-fontlock (symbol value)
- (when value
- (dash-enable-font-lock))
- (set-default symbol value))
-
-(defcustom dash-enable-fontlock nil
- "If non-nil, enable fontification of dash functions, macros and
-special values."
- :type 'boolean
- :set 'dash--enable-fontlock
- :group 'dash)
-
(defmacro !cons (car cdr)
"Destructive: Set CDR to the cons of CAR and CDR."
`(setq ,cdr (cons ,car ,cdr)))
@@ -65,385 +50,552 @@ special values."
`(setq ,list (cdr ,list)))
(defmacro --each (list &rest body)
- "Anaphoric form of `-each'."
- (declare (debug (form body))
- (indent 1))
- (let ((l (make-symbol "list")))
+ "Evaluate BODY for each element of LIST and return nil.
+Each element of LIST in turn is bound to `it' and its index
+within LIST to `it-index' before evaluating BODY.
+This is the anaphoric counterpart to `-each'."
+ (declare (debug (form body)) (indent 1))
+ (let ((l (make-symbol "list"))
+ (i (make-symbol "i")))
`(let ((,l ,list)
- (it-index 0))
+ (,i 0)
+ it it-index)
+ (ignore it it-index)
(while ,l
- (let ((it (car ,l)))
- ,@body)
- (setq it-index (1+ it-index))
- (!cdr ,l)))))
-
-(defmacro -doto (eval-initial-value &rest forms)
- "Eval a form, then insert that form as the 2nd argument to other forms.
-The EVAL-INITIAL-VALUE form is evaluated once. Its result is
-passed to FORMS, which are then evaluated sequentially. Returns
-the target form."
- (declare (indent 1))
- (let ((retval (make-symbol "value")))
- `(let ((,retval ,eval-initial-value))
- ,@(mapcar (lambda (form)
- (if (sequencep form)
- `(,(-first-item form) ,retval ,@(cdr form))
- `(funcall form ,retval)))
- forms)
- ,retval)))
-
-(defmacro --doto (eval-initial-value &rest forms)
- "Anaphoric form of `-doto'.
-Note: `it' is not required in each form."
- (declare (indent 1))
- `(let ((it ,eval-initial-value))
- ,@forms
- it))
+ (setq it (pop ,l) it-index ,i ,i (1+ ,i))
+ ,@body))))
(defun -each (list fn)
- "Call FN with every item in LIST. Return nil, used for side-effects only."
- (--each list (funcall fn it)))
+ "Call FN on each element of LIST.
+Return nil; this function is intended for side effects.
+
+Its anaphoric counterpart is `--each'.
-(put '-each 'lisp-indent-function 1)
+For access to the current element's index in LIST, see
+`-each-indexed'."
+ (declare (indent 1))
+ (ignore (mapc fn list)))
(defalias '--each-indexed '--each)
(defun -each-indexed (list fn)
- "Call (FN index item) for each item in LIST.
-
-In the anaphoric form `--each-indexed', the index is exposed as symbol `it-index'.
+ "Call FN on each index and element of LIST.
+For each ITEM at INDEX in LIST, call (funcall FN INDEX ITEM).
+Return nil; this function is intended for side effects.
See also: `-map-indexed'."
+ (declare (indent 1))
(--each list (funcall fn it-index it)))
-(put '-each-indexed 'lisp-indent-function 1)
(defmacro --each-while (list pred &rest body)
- "Anaphoric form of `-each-while'."
- (declare (debug (form form body))
- (indent 2))
+ "Evaluate BODY for each item in LIST, while PRED evaluates to non-nil.
+Each element of LIST in turn is bound to `it' and its index
+within LIST to `it-index' before evaluating PRED or BODY. Once
+an element is reached for which PRED evaluates to nil, no further
+BODY is evaluated. The return value is always nil.
+This is the anaphoric counterpart to `-each-while'."
+ (declare (debug (form form body)) (indent 2))
(let ((l (make-symbol "list"))
- (c (make-symbol "continue")))
+ (i (make-symbol "i"))
+ (elt (make-symbol "elt")))
`(let ((,l ,list)
- (,c t)
- (it-index 0))
- (while (and ,l ,c)
- (let ((it (car ,l)))
- (if (not ,pred) (setq ,c nil) ,@body))
- (setq it-index (1+ it-index))
- (!cdr ,l)))))
+ (,i 0)
+ ,elt it it-index)
+ (ignore it it-index)
+ (while (and ,l (setq ,elt (pop ,l) it ,elt it-index ,i) ,pred)
+ (setq it ,elt it-index ,i ,i (1+ ,i))
+ ,@body))))
(defun -each-while (list pred fn)
- "Call FN with every item in LIST while (PRED item) is non-nil.
-Return nil, used for side-effects only."
- (--each-while list (funcall pred it) (funcall fn it)))
+ "Call FN on each ITEM in LIST, while (PRED ITEM) is non-nil.
+Once an ITEM is reached for which PRED returns nil, FN is no
+longer called. Return nil; this function is intended for side
+effects.
-(put '-each-while 'lisp-indent-function 2)
+Its anaphoric counterpart is `--each-while'."
+ (declare (indent 2))
+ (--each-while list (funcall pred it) (funcall fn it)))
(defmacro --each-r (list &rest body)
- "Anaphoric form of `-each-r'."
- (declare (debug (form body))
- (indent 1))
- (let ((v (make-symbol "vector")))
- ;; Implementation note: building vector is considerably faster
+ "Evaluate BODY for each element of LIST in reversed order.
+Each element of LIST in turn, starting at its end, is bound to
+`it' and its index within LIST to `it-index' before evaluating
+BODY. The return value is always nil.
+This is the anaphoric counterpart to `-each-r'."
+ (declare (debug (form body)) (indent 1))
+ (let ((v (make-symbol "vector"))
+ (i (make-symbol "i")))
+ ;; Implementation note: building a vector is considerably faster
;; than building a reversed list (vector takes less memory, so
- ;; there is less GC), plus length comes naturally. In-place
- ;; 'nreverse' would be faster still, but BODY would be able to see
- ;; that, even if modification was reversed before we return.
+ ;; there is less GC), plus `length' comes naturally. In-place
+ ;; `nreverse' would be faster still, but BODY would be able to see
+ ;; that, even if the modification was undone before we return.
`(let* ((,v (vconcat ,list))
- (it-index (length ,v))
- it)
- (while (> it-index 0)
- (setq it-index (1- it-index))
- (setq it (aref ,v it-index))
+ (,i (length ,v))
+ it it-index)
+ (ignore it it-index)
+ (while (> ,i 0)
+ (setq ,i (1- ,i) it-index ,i it (aref ,v ,i))
,@body))))
(defun -each-r (list fn)
- "Call FN with every item in LIST in reversed order.
- Return nil, used for side-effects only."
+ "Call FN on each element of LIST in reversed order.
+Return nil; this function is intended for side effects.
+
+Its anaphoric counterpart is `--each-r'."
(--each-r list (funcall fn it)))
(defmacro --each-r-while (list pred &rest body)
- "Anaphoric form of `-each-r-while'."
- (declare (debug (form form body))
- (indent 2))
- (let ((v (make-symbol "vector")))
+ "Eval BODY for each item in reversed LIST, while PRED evals to non-nil.
+Each element of LIST in turn, starting at its end, is bound to
+`it' and its index within LIST to `it-index' before evaluating
+PRED or BODY. Once an element is reached for which PRED
+evaluates to nil, no further BODY is evaluated. The return value
+is always nil.
+This is the anaphoric counterpart to `-each-r-while'."
+ (declare (debug (form form body)) (indent 2))
+ (let ((v (make-symbol "vector"))
+ (i (make-symbol "i"))
+ (elt (make-symbol "elt")))
`(let* ((,v (vconcat ,list))
- (it-index (length ,v))
- it)
- (while (> it-index 0)
- (setq it-index (1- it-index))
- (setq it (aref ,v it-index))
- (if (not ,pred)
- (setq it-index -1)
- ,@body)))))
+ (,i (length ,v))
+ ,elt it it-index)
+ (ignore it it-index)
+ (while (when (> ,i 0)
+ (setq ,i (1- ,i) it-index ,i)
+ (setq ,elt (aref ,v ,i) it ,elt)
+ ,pred)
+ (setq it-index ,i it ,elt)
+ ,@body))))
(defun -each-r-while (list pred fn)
- "Call FN with every item in reversed LIST while (PRED item) is non-nil.
-Return nil, used for side-effects only."
+ "Call FN on each ITEM in reversed LIST, while (PRED ITEM) is non-nil.
+Once an ITEM is reached for which PRED returns nil, FN is no
+longer called. Return nil; this function is intended for side
+effects.
+
+Its anaphoric counterpart is `--each-r-while'."
(--each-r-while list (funcall pred it) (funcall fn it)))
(defmacro --dotimes (num &rest body)
- "Repeatedly executes BODY (presumably for side-effects) with symbol `it' bound to integers from 0 through NUM-1."
- (declare (debug (form body))
- (indent 1))
- (let ((n (make-symbol "num")))
+ "Evaluate BODY NUM times, presumably for side effects.
+BODY is evaluated with the local variable `it' temporarily bound
+to successive integers running from 0, inclusive, to NUM,
+exclusive. BODY is not evaluated if NUM is less than 1.
+This is the anaphoric counterpart to `-dotimes'."
+ (declare (debug (form body)) (indent 1))
+ (let ((n (make-symbol "num"))
+ (i (make-symbol "i")))
`(let ((,n ,num)
- (it 0))
- (while (< it ,n)
- ,@body
- (setq it (1+ it))))))
+ (,i 0)
+ it)
+ (ignore it)
+ (while (< ,i ,n)
+ (setq it ,i ,i (1+ ,i))
+ ,@body))))
(defun -dotimes (num fn)
- "Repeatedly calls FN (presumably for side-effects) passing in integers from 0 through NUM-1."
- (--dotimes num (funcall fn it)))
+ "Call FN NUM times, presumably for side effects.
+FN is called with a single argument on successive integers
+running from 0, inclusive, to NUM, exclusive. FN is not called
+if NUM is less than 1.
-(put '-dotimes 'lisp-indent-function 1)
+This function's anaphoric counterpart is `--dotimes'."
+ (declare (indent 1))
+ (--dotimes num (funcall fn it)))
(defun -map (fn list)
- "Return a new list consisting of the result of applying FN to the items in LIST."
+ "Apply FN to each item in LIST and return the list of results.
+
+This function's anaphoric counterpart is `--map'."
(mapcar fn list))
(defmacro --map (form list)
- "Anaphoric form of `-map'."
- (declare (debug (form form)))
- `(mapcar (lambda (it) ,form) ,list))
-
-(defmacro --reduce-from (form initial-value list)
- "Anaphoric form of `-reduce-from'."
+ "Eval FORM for each item in LIST and return the list of results.
+Each element of LIST in turn is bound to `it' before evaluating
+FORM.
+This is the anaphoric counterpart to `-map'."
+ (declare (debug (def-form form)))
+ `(mapcar (lambda (it) (ignore it) ,form) ,list))
+
+(defmacro --reduce-from (form init list)
+ "Accumulate a value by evaluating FORM across LIST.
+This macro is like `--each' (which see), but it additionally
+provides an accumulator variable `acc' which it successively
+binds to the result of evaluating FORM for the current LIST
+element before processing the next element. For the first
+element, `acc' is initialized with the result of evaluating INIT.
+The return value is the resulting value of `acc'. If LIST is
+empty, FORM is not evaluated, and the return value is the result
+of INIT.
+This is the anaphoric counterpart to `-reduce-from'."
(declare (debug (form form form)))
- `(let ((acc ,initial-value))
+ `(let ((acc ,init))
(--each ,list (setq acc ,form))
acc))
-(defun -reduce-from (fn initial-value list)
- "Return the result of applying FN to INITIAL-VALUE and the
-first item in LIST, then applying FN to that result and the 2nd
-item, etc. If LIST contains no items, return INITIAL-VALUE and
-do not call FN.
+(defun -reduce-from (fn init list)
+ "Reduce the function FN across LIST, starting with INIT.
+Return the result of applying FN to INIT and the first element of
+LIST, then applying FN to that result and the second element,
+etc. If LIST is empty, return INIT without calling FN.
-In the anaphoric form `--reduce-from', the accumulated value is
-exposed as symbol `acc'.
+This function's anaphoric counterpart is `--reduce-from'.
-See also: `-reduce', `-reduce-r'"
- (--reduce-from (funcall fn acc it) initial-value list))
+For other folds, see also `-reduce' and `-reduce-r'."
+ (--reduce-from (funcall fn acc it) init list))
(defmacro --reduce (form list)
- "Anaphoric form of `-reduce'."
+ "Accumulate a value by evaluating FORM across LIST.
+This macro is like `--reduce-from' (which see), except the first
+element of LIST is taken as INIT. Thus if LIST contains a single
+item, it is returned without evaluating FORM. If LIST is empty,
+FORM is evaluated with `it' and `acc' bound to nil.
+This is the anaphoric counterpart to `-reduce'."
(declare (debug (form form)))
(let ((lv (make-symbol "list-value")))
`(let ((,lv ,list))
(if ,lv
(--reduce-from ,form (car ,lv) (cdr ,lv))
- (let (acc it) ,form)))))
+ (let (acc it)
+ (ignore acc it)
+ ,form)))))
(defun -reduce (fn list)
- "Return the result of applying FN to the first 2 items in LIST,
-then applying FN to that result and the 3rd item, etc. If LIST
-contains no items, return the result of calling FN with no
-arguments. If LIST contains a single item, return that item
-and do not call FN.
+ "Reduce the function FN across LIST.
+Return the result of applying FN to the first two elements of
+LIST, then applying FN to that result and the third element, etc.
+If LIST contains a single element, return it without calling FN.
+If LIST is empty, return the result of calling FN with no
+arguments.
-In the anaphoric form `--reduce', the accumulated value is
-exposed as symbol `acc'.
+This function's anaphoric counterpart is `--reduce'.
-See also: `-reduce-from', `-reduce-r'"
+For other folds, see also `-reduce-from' and `-reduce-r'."
(if list
(-reduce-from fn (car list) (cdr list))
(funcall fn)))
-(defmacro --reduce-r-from (form initial-value list)
- "Anaphoric version of `-reduce-r-from'."
+(defmacro --reduce-r-from (form init list)
+ "Accumulate a value by evaluating FORM across LIST in reverse.
+This macro is like `--reduce-from', except it starts from the end
+of LIST.
+This is the anaphoric counterpart to `-reduce-r-from'."
(declare (debug (form form form)))
- `(--reduce-from ,form ,initial-value (reverse ,list)))
+ `(let ((acc ,init))
+ (--each-r ,list (setq acc ,form))
+ acc))
+
+(defun -reduce-r-from (fn init list)
+ "Reduce the function FN across LIST in reverse, starting with INIT.
+Return the result of applying FN to the last element of LIST and
+INIT, then applying FN to the second-to-last element and the
+previous result of FN, etc. That is, the first argument of FN is
+the current element, and its second argument the accumulated
+value. If LIST is empty, return INIT without calling FN.
-(defun -reduce-r-from (fn initial-value list)
- "Replace conses with FN, nil with INITIAL-VALUE and evaluate
-the resulting expression. If LIST is empty, INITIAL-VALUE is
-returned and FN is not called.
+This function is like `-reduce-from' but the operation associates
+from the right rather than left. In other words, it starts from
+the end of LIST and flips the arguments to FN. Conceptually, it
+is like replacing the conses in LIST with applications of FN, and
+its last link with INIT, and evaluating the resulting expression.
-Note: this function works the same as `-reduce-from' but the
-operation associates from right instead of from left.
+This function's anaphoric counterpart is `--reduce-r-from'.
-See also: `-reduce-r', `-reduce'"
- (--reduce-r-from (funcall fn it acc) initial-value list))
+For other folds, see also `-reduce-r' and `-reduce'."
+ (--reduce-r-from (funcall fn it acc) init list))
(defmacro --reduce-r (form list)
- "Anaphoric version of `-reduce-r'."
+ "Accumulate a value by evaluating FORM across LIST in reverse order.
+This macro is like `--reduce', except it starts from the end of
+LIST.
+This is the anaphoric counterpart to `-reduce-r'."
(declare (debug (form form)))
`(--reduce ,form (reverse ,list)))
(defun -reduce-r (fn list)
- "Replace conses with FN and evaluate the resulting expression.
-The final nil is ignored. If LIST contains no items, return the
-result of calling FN with no arguments. If LIST contains a single
-item, return that item and do not call FN.
-
-The first argument of FN is the new item, the second is the
-accumulated value.
-
-Note: this function works the same as `-reduce' but the operation
-associates from right instead of from left.
-
-See also: `-reduce-r-from', `-reduce'"
+ "Reduce the function FN across LIST in reverse.
+Return the result of applying FN to the last two elements of
+LIST, then applying FN to the third-to-last element and the
+previous result of FN, etc. That is, the first argument of FN is
+the current element, and its second argument the accumulated
+value. If LIST contains a single element, return it without
+calling FN. If LIST is empty, return the result of calling FN
+with no arguments.
+
+This function is like `-reduce' but the operation associates from
+the right rather than left. In other words, it starts from the
+end of LIST and flips the arguments to FN. Conceptually, it is
+like replacing the conses in LIST with applications of FN,
+ignoring its last link, and evaluating the resulting expression.
+
+This function's anaphoric counterpart is `--reduce-r'.
+
+For other folds, see also `-reduce-r-from' and `-reduce'."
(if list
(--reduce-r (funcall fn it acc) list)
(funcall fn)))
+(defmacro --reductions-from (form init list)
+ "Return a list of FORM's intermediate reductions across LIST.
+That is, a list of the intermediate values of the accumulator
+when `--reduce-from' (which see) is called with the same
+arguments.
+This is the anaphoric counterpart to `-reductions-from'."
+ (declare (debug (form form form)))
+ `(nreverse
+ (--reduce-from (cons (let ((acc (car acc))) (ignore acc) ,form) acc)
+ (list ,init)
+ ,list)))
+
(defun -reductions-from (fn init list)
- "Return a list of the intermediate values of the reduction.
+ "Return a list of FN's intermediate reductions across LIST.
+That is, a list of the intermediate values of the accumulator
+when `-reduce-from' (which see) is called with the same
+arguments.
+
+This function's anaphoric counterpart is `--reductions-from'.
-See `-reduce-from' for explanation of the arguments.
+For other folds, see also `-reductions' and `-reductions-r'."
+ (--reductions-from (funcall fn acc it) init list))
-See also: `-reductions', `-reductions-r', `-reduce-r'"
- (nreverse (--reduce-from (cons (funcall fn (car acc) it) acc) (list init) list)))
+(defmacro --reductions (form list)
+ "Return a list of FORM's intermediate reductions across LIST.
+That is, a list of the intermediate values of the accumulator
+when `--reduce' (which see) is called with the same arguments.
+This is the anaphoric counterpart to `-reductions'."
+ (declare (debug (form form)))
+ (let ((lv (make-symbol "list-value")))
+ `(let ((,lv ,list))
+ (if ,lv
+ (--reductions-from ,form (car ,lv) (cdr ,lv))
+ (let (acc it)
+ (ignore acc it)
+ (list ,form))))))
(defun -reductions (fn list)
- "Return a list of the intermediate values of the reduction.
+ "Return a list of FN's intermediate reductions across LIST.
+That is, a list of the intermediate values of the accumulator
+when `-reduce' (which see) is called with the same arguments.
-See `-reduce' for explanation of the arguments.
+This function's anaphoric counterpart is `--reductions'.
-See also: `-reductions-from', `-reductions-r', `-reduce-r'"
- (and list (-reductions-from fn (car list) (cdr list))))
+For other folds, see also `-reductions' and `-reductions-r'."
+ (if list
+ (--reductions-from (funcall fn acc it) (car list) (cdr list))
+ (list (funcall fn))))
+
+(defmacro --reductions-r-from (form init list)
+ "Return a list of FORM's intermediate reductions across reversed LIST.
+That is, a list of the intermediate values of the accumulator
+when `--reduce-r-from' (which see) is called with the same
+arguments.
+This is the anaphoric counterpart to `-reductions-r-from'."
+ (declare (debug (form form form)))
+ `(--reduce-r-from (cons (let ((acc (car acc))) (ignore acc) ,form) acc)
+ (list ,init)
+ ,list))
(defun -reductions-r-from (fn init list)
- "Return a list of the intermediate values of the reduction.
-
-See `-reduce-r-from' for explanation of the arguments.
-
-See also: `-reductions-r', `-reductions', `-reduce'"
- (--reduce-r-from (cons (funcall fn it (car acc)) acc) (list init) list))
+ "Return a list of FN's intermediate reductions across reversed LIST.
+That is, a list of the intermediate values of the accumulator
+when `-reduce-r-from' (which see) is called with the same
+arguments.
+
+This function's anaphoric counterpart is `--reductions-r-from'.
+
+For other folds, see also `-reductions' and `-reductions-r'."
+ (--reductions-r-from (funcall fn it acc) init list))
+
+(defmacro --reductions-r (form list)
+ "Return a list of FORM's intermediate reductions across reversed LIST.
+That is, a list of the intermediate values of the accumulator
+when `--reduce-re' (which see) is called with the same arguments.
+This is the anaphoric counterpart to `-reductions-r'."
+ (declare (debug (form list)))
+ (let ((lv (make-symbol "list-value")))
+ `(let ((,lv (reverse ,list)))
+ (if ,lv
+ (--reduce-from (cons (let ((acc (car acc))) (ignore acc) ,form) acc)
+ (list (car ,lv))
+ (cdr ,lv))
+ (let (acc it)
+ (ignore acc it)
+ (list ,form))))))
(defun -reductions-r (fn list)
- "Return a list of the intermediate values of the reduction.
+ "Return a list of FN's intermediate reductions across reversed LIST.
+That is, a list of the intermediate values of the accumulator
+when `-reduce-r' (which see) is called with the same arguments.
-See `-reduce-r' for explanation of the arguments.
+This function's anaphoric counterpart is `--reductions-r'.
-See also: `-reductions-r-from', `-reductions', `-reduce'"
- (when list
- (let ((rev (reverse list)))
- (--reduce-from (cons (funcall fn it (car acc)) acc)
- (list (car rev))
- (cdr rev)))))
+For other folds, see also `-reductions-r-from' and
+`-reductions'."
+ (if list
+ (--reductions-r (funcall fn it acc) list)
+ (list (funcall fn))))
(defmacro --filter (form list)
- "Anaphoric form of `-filter'.
-
-See also: `--remove'."
+ "Return a new list of the items in LIST for which FORM evals to non-nil.
+Each element of LIST in turn is bound to `it' and its index
+within LIST to `it-index' before evaluating FORM.
+This is the anaphoric counterpart to `-filter'.
+For the opposite operation, see also `--remove'."
(declare (debug (form form)))
(let ((r (make-symbol "result")))
`(let (,r)
- (--each ,list (when ,form (!cons it ,r)))
+ (--each ,list (when ,form (push it ,r)))
(nreverse ,r))))
(defun -filter (pred list)
- "Return a new list of the items in LIST for which PRED returns a non-nil value.
+ "Return a new list of the items in LIST for which PRED returns non-nil.
-Alias: `-select'
+Alias: `-select'.
-See also: `-keep', `-remove'."
+This function's anaphoric counterpart is `--filter'.
+
+For similar operations, see also `-keep' and `-remove'."
(--filter (funcall pred it) list))
(defalias '-select '-filter)
(defalias '--select '--filter)
(defmacro --remove (form list)
- "Anaphoric form of `-remove'.
-
-See also `--filter'."
+ "Return a new list of the items in LIST for which FORM evals to nil.
+Each element of LIST in turn is bound to `it' and its index
+within LIST to `it-index' before evaluating FORM.
+This is the anaphoric counterpart to `-remove'.
+For the opposite operation, see also `--filter'."
(declare (debug (form form)))
`(--filter (not ,form) ,list))
(defun -remove (pred list)
"Return a new list of the items in LIST for which PRED returns nil.
-Alias: `-reject'
+Alias: `-reject'.
+
+This function's anaphoric counterpart is `--remove'.
-See also: `-filter'."
+For similar operations, see also `-keep' and `-filter'."
(--remove (funcall pred it) list))
(defalias '-reject '-remove)
(defalias '--reject '--remove)
+(defmacro --remove-first (form list)
+ "Remove the first item from LIST for which FORM evals to non-nil.
+Each element of LIST in turn is bound to `it' and its index
+within LIST to `it-index' before evaluating FORM. This is a
+non-destructive operation, but only the front of LIST leading up
+to the removed item is a copy; the rest is LIST's original tail.
+If no item is removed, then the result is a complete copy.
+This is the anaphoric counterpart to `-remove-first'."
+ (declare (debug (form form)))
+ (let ((front (make-symbol "front"))
+ (tail (make-symbol "tail")))
+ `(let ((,tail ,list) ,front)
+ (--each-while ,tail (not ,form)
+ (push (pop ,tail) ,front))
+ (if ,tail
+ (nconc (nreverse ,front) (cdr ,tail))
+ (nreverse ,front)))))
+
(defun -remove-first (pred list)
- "Return a new list with the first item matching PRED removed.
+ "Remove the first item from LIST for which PRED returns non-nil.
+This is a non-destructive operation, but only the front of LIST
+leading up to the removed item is a copy; the rest is LIST's
+original tail. If no item is removed, then the result is a
+complete copy.
-Alias: `-reject-first'
+Alias: `-reject-first'.
-See also: `-remove', `-map-first'"
- (let (front)
- (while (and list (not (funcall pred (car list))))
- (push (car list) front)
- (!cdr list))
- (if list
- (-concat (nreverse front) (cdr list))
- (nreverse front))))
+This function's anaphoric counterpart is `--remove-first'.
-(defmacro --remove-first (form list)
- "Anaphoric form of `-remove-first'."
- (declare (debug (form form)))
- `(-remove-first (lambda (it) ,form) ,list))
+See also `-map-first', `-remove-item', and `-remove-last'."
+ (--remove-first (funcall pred it) list))
(defalias '-reject-first '-remove-first)
(defalias '--reject-first '--remove-first)
+(defmacro --remove-last (form list)
+ "Remove the last item from LIST for which FORM evals to non-nil.
+Each element of LIST in turn is bound to `it' before evaluating
+FORM. The result is a copy of LIST regardless of whether an
+element is removed.
+This is the anaphoric counterpart to `-remove-last'."
+ (declare (debug (form form)))
+ `(nreverse (--remove-first ,form (reverse ,list))))
+
(defun -remove-last (pred list)
- "Return a new list with the last item matching PRED removed.
+ "Remove the last item from LIST for which PRED returns non-nil.
+The result is a copy of LIST regardless of whether an element is
+removed.
-Alias: `-reject-last'
+Alias: `-reject-last'.
-See also: `-remove', `-map-last'"
- (nreverse (-remove-first pred (reverse list))))
+This function's anaphoric counterpart is `--remove-last'.
-(defmacro --remove-last (form list)
- "Anaphoric form of `-remove-last'."
- (declare (debug (form form)))
- `(-remove-last (lambda (it) ,form) ,list))
+See also `-map-last', `-remove-item', and `-remove-first'."
+ (--remove-last (funcall pred it) list))
(defalias '-reject-last '-remove-last)
(defalias '--reject-last '--remove-last)
-(defun -remove-item (item list)
- "Remove all occurrences of ITEM from LIST.
-
-Comparison is done with `equal'."
- (declare (pure t) (side-effect-free t))
- (--remove (equal it item) list))
+(defalias '-remove-item #'remove
+ "Return a copy of LIST with all occurrences of ITEM removed.
+The comparison is done with `equal'.
+\n(fn ITEM LIST)")
(defmacro --keep (form list)
- "Anaphoric form of `-keep'."
+ "Eval FORM for each item in LIST and return the non-nil results.
+Like `--filter', but returns the non-nil results of FORM instead
+of the corresponding elements of LIST. Each element of LIST in
+turn is bound to `it' and its index within LIST to `it-index'
+before evaluating FORM.
+This is the anaphoric counterpart to `-keep'."
(declare (debug (form form)))
(let ((r (make-symbol "result"))
(m (make-symbol "mapped")))
`(let (,r)
- (--each ,list (let ((,m ,form)) (when ,m (!cons ,m ,r))))
+ (--each ,list (let ((,m ,form)) (when ,m (push ,m ,r))))
(nreverse ,r))))
(defun -keep (fn list)
- "Return a new list of the non-nil results of applying FN to the items in LIST.
+ "Return a new list of the non-nil results of applying FN to each item in LIST.
+Like `-filter', but returns the non-nil results of FN instead of
+the corresponding elements of LIST.
-If you want to select the original items satisfying a predicate use `-filter'."
+Its anaphoric counterpart is `--keep'."
(--keep (funcall fn it) list))
(defun -non-nil (list)
- "Return all non-nil elements of LIST."
+ "Return a copy of LIST with all nil items removed."
(declare (pure t) (side-effect-free t))
- (-remove 'null list))
+ (--filter it list))
(defmacro --map-indexed (form list)
- "Anaphoric form of `-map-indexed'."
+ "Eval FORM for each item in LIST and return the list of results.
+Each element of LIST in turn is bound to `it' and its index
+within LIST to `it-index' before evaluating FORM. This is like
+`--map', but additionally makes `it-index' available to FORM.
+
+This is the anaphoric counterpart to `-map-indexed'."
(declare (debug (form form)))
(let ((r (make-symbol "result")))
`(let (,r)
(--each ,list
- (!cons ,form ,r))
+ (push ,form ,r))
(nreverse ,r))))
(defun -map-indexed (fn list)
- "Return a new list consisting of the result of (FN index item) for each item in LIST.
+ "Apply FN to each index and item in LIST and return the list of results.
+This is like `-map', but FN takes two arguments: the index of the
+current element within LIST, and the element itself.
-In the anaphoric form `--map-indexed', the index is exposed as symbol `it-index'.
+This function's anaphoric counterpart is `--map-indexed'.
-See also: `-each-indexed'."
+For a side-effecting variant, see also `-each-indexed'."
(--map-indexed (funcall fn it-index it) list))
(defmacro --map-when (pred rep list)
@@ -530,6 +682,26 @@ See also: `-map-last'"
Thus function FN should return a list."
(--mapcat (funcall fn it) list))
+(defmacro --iterate (form init n)
+ "Anaphoric version of `-iterate'."
+ (declare (debug (form form form)))
+ (let ((res (make-symbol "result")))
+ `(let ((it ,init) ,res)
+ (dotimes (_ ,n)
+ (push it ,res)
+ (setq it ,form))
+ (nreverse ,res))))
+
+(defun -iterate (fun init n)
+ "Return a list of iterated applications of FUN to INIT.
+
+This means a list of the form:
+
+ (INIT (FUN INIT) (FUN (FUN INIT)) ...)
+
+N is the length of the returned list."
+ (--iterate (funcall fun it) init n))
+
(defun -flatten (l)
"Take a nested list L and return its contents as a single, flat list.
@@ -547,11 +719,6 @@ See also: `-flatten-n'"
(-mapcat '-flatten l)
(list l)))
-(defmacro --iterate (form init n)
- "Anaphoric version of `-iterate'."
- (declare (debug (form form form)))
- `(-iterate (lambda (it) ,form) ,init ,n))
-
(defun -flatten-n (num list)
"Flatten NUM levels of a nested LIST.
@@ -603,12 +770,17 @@ See also: `-splice', `-insert-at'"
(defun -cons* (&rest args)
"Make a new list from the elements of ARGS.
-
-The last 2 members of ARGS are used as the final cons of the
-result so if the final member of ARGS is not a list the result is
-a dotted list."
+The last 2 elements of ARGS are used as the final cons of the
+result, so if the final element of ARGS is not a list, the result
+is a dotted list. With no ARGS, return nil."
(declare (pure t) (side-effect-free t))
- (-reduce-r 'cons args))
+ (let* ((len (length args))
+ (tail (nthcdr (- len 2) args))
+ (last (cdr tail)))
+ (if (null last)
+ (car args)
+ (setcdr tail (car last))
+ args)))
(defun -snoc (list elem &rest elements)
"Append ELEM to the end of the list.
@@ -619,38 +791,49 @@ If ELEMENTS is non nil, append these to the list as well."
(-concat list (list elem) elements))
(defmacro --first (form list)
- "Anaphoric form of `-first'."
+ "Return the first item in LIST for which FORM evals to non-nil.
+Return nil if no such element is found.
+Each element of LIST in turn is bound to `it' and its index
+within LIST to `it-index' before evaluating FORM.
+This is the anaphoric counterpart to `-first'."
(declare (debug (form form)))
(let ((n (make-symbol "needle")))
`(let (,n)
- (--each-while ,list (not ,n)
- (when ,form (setq ,n it)))
+ (--each-while ,list (or (not ,form)
+ (ignore (setq ,n it))))
,n)))
(defun -first (pred list)
- "Return the first x in LIST where (PRED x) is non-nil, else nil.
-
+ "Return the first item in LIST for which PRED returns non-nil.
+Return nil if no such element is found.
To get the first item in the list no questions asked, use `car'.
-Alias: `-find'"
+Alias: `-find'.
+
+This function's anaphoric counterpart is `--first'."
(--first (funcall pred it) list))
(defalias '-find '-first)
(defalias '--find '--first)
(defmacro --some (form list)
- "Anaphoric form of `-some'."
+ "Return non-nil if FORM evals to non-nil for at least one item in LIST.
+If so, return the first such result of FORM.
+Each element of LIST in turn is bound to `it' and its index
+within LIST to `it-index' before evaluating FORM.
+This is the anaphoric counterpart to `-some'."
(declare (debug (form form)))
(let ((n (make-symbol "needle")))
`(let (,n)
- (--each-while ,list (not ,n)
- (setq ,n ,form))
+ (--each-while ,list (not (setq ,n ,form)))
,n)))
(defun -some (pred list)
"Return (PRED x) for the first LIST item where (PRED x) is non-nil, else nil.
-Alias: `-any'"
+Alias: `-any'.
+
+This function's anaphoric counterpart is `--some'."
(--some (funcall pred it) list))
(defalias '-any '-some)
@@ -743,9 +926,10 @@ See also: `-last-item'."
"Counts the number of items in LIST where (PRED item) is non-nil."
(--count (funcall pred it) list))
-(defun ---truthy? (val)
+(defun ---truthy? (obj)
+ "Return OBJ as a boolean value (t or nil)."
(declare (pure t) (side-effect-free t))
- (not (null val)))
+ (and obj t))
(defmacro --any? (form list)
"Anaphoric form of `-any?'."
@@ -847,73 +1031,100 @@ section is returned. Defaults to 1."
(push it new-list)))
(nreverse new-list)))
-(defun -take (n list)
- "Return a new list of the first N items in LIST, or all items if there are fewer than N.
-
-See also: `-take-last'"
- (declare (pure t) (side-effect-free t))
- (let (result)
- (--dotimes n
- (when list
- (!cons (car list) result)
- (!cdr list)))
- (nreverse result)))
-
-(defun -take-last (n list)
- "Return the last N items of LIST in order.
-
-See also: `-take'"
- (declare (pure t) (side-effect-free t))
- (copy-sequence (last list n)))
-
-(defalias '-drop 'nthcdr
- "Return the tail of LIST without the first N items.
-
-See also: `-drop-last'
-
-\(fn N LIST)")
-
-(defun -drop-last (n list)
- "Remove the last N items of LIST and return a copy.
-
-See also: `-drop'"
- ;; No alias because we don't want magic optional argument
- (declare (pure t) (side-effect-free t))
- (butlast list n))
-
(defmacro --take-while (form list)
- "Anaphoric form of `-take-while'."
+ "Take successive items from LIST for which FORM evals to non-nil.
+Each element of LIST in turn is bound to `it' and its index
+within LIST to `it-index' before evaluating FORM. Return a new
+list of the successive elements from the start of LIST for which
+FORM evaluates to non-nil.
+This is the anaphoric counterpart to `-take-while'."
(declare (debug (form form)))
(let ((r (make-symbol "result")))
`(let (,r)
- (--each-while ,list ,form (!cons it ,r))
+ (--each-while ,list ,form (push it ,r))
(nreverse ,r))))
(defun -take-while (pred list)
- "Return a new list of successive items from LIST while (PRED item) returns a non-nil value."
+ "Take successive items from LIST for which PRED returns non-nil.
+PRED is a function of one argument. Return a new list of the
+successive elements from the start of LIST for which PRED returns
+non-nil.
+
+This function's anaphoric counterpart is `--take-while'.
+
+For another variant, see also `-drop-while'."
(--take-while (funcall pred it) list))
(defmacro --drop-while (form list)
- "Anaphoric form of `-drop-while'."
+ "Drop successive items from LIST for which FORM evals to non-nil.
+Each element of LIST in turn is bound to `it' and its index
+within LIST to `it-index' before evaluating FORM. Return the
+tail (not a copy) of LIST starting from its first element for
+which FORM evaluates to nil.
+This is the anaphoric counterpart to `-drop-while'."
(declare (debug (form form)))
(let ((l (make-symbol "list")))
`(let ((,l ,list))
- (while (and ,l (let ((it (car ,l))) ,form))
- (!cdr ,l))
+ (--each-while ,l ,form (pop ,l))
,l)))
(defun -drop-while (pred list)
- "Return the tail of LIST starting from the first item for which (PRED item) returns nil."
+ "Drop successive items from LIST for which PRED returns non-nil.
+PRED is a function of one argument. Return the tail (not a copy)
+of LIST starting from its first element for which PRED returns
+nil.
+
+This function's anaphoric counterpart is `--drop-while'.
+
+For another variant, see also `-take-while'."
(--drop-while (funcall pred it) list))
+(defun -take (n list)
+ "Return a copy of the first N items in LIST.
+Return a copy of LIST if it contains N items or fewer.
+Return nil if N is zero or less.
+
+See also: `-take-last'."
+ (declare (pure t) (side-effect-free t))
+ (--take-while (< it-index n) list))
+
+(defun -take-last (n list)
+ "Return a copy of the last N items of LIST in order.
+Return a copy of LIST if it contains N items or fewer.
+Return nil if N is zero or less.
+
+See also: `-take'."
+ (declare (pure t) (side-effect-free t))
+ (copy-sequence (last list n)))
+
+(defalias '-drop #'nthcdr
+ "Return the tail (not a copy) of LIST without the first N items.
+Return nil if LIST contains N items or fewer.
+Return LIST if N is zero or less.
+
+For another variant, see also `-drop-last'.
+\n(fn N LIST)")
+
+(defun -drop-last (n list)
+ "Return a copy of LIST without its last N items.
+Return a copy of LIST if N is zero or less.
+Return nil if LIST contains N items or fewer.
+
+See also: `-drop'."
+ (declare (pure t) (side-effect-free t))
+ (nbutlast (copy-sequence list) n))
+
(defun -split-at (n list)
- "Return a list of ((-take N LIST) (-drop N LIST)), in no more than one pass through the list."
+ "Split LIST into two sublists after the Nth element.
+The result is a list of two elements (TAKE DROP) where TAKE is a
+new list of the first N elements of LIST, and DROP is the
+remaining elements of LIST (not a copy). TAKE and DROP are like
+the results of `-take' and `-drop', respectively, but the split
+is done in a single list traversal."
(declare (pure t) (side-effect-free t))
(let (result)
- (--dotimes n
- (when list
- (!cons (car list) result)
- (!cdr list)))
+ (--each-while list (< it-index n)
+ (push (pop list) result))
(list (nreverse result) list)))
(defun -rotate (n list)
@@ -924,7 +1135,7 @@ The time complexity is O(n)."
(let* ((len (length list))
(n-mod-len (mod n len))
(new-tail-len (- len n-mod-len)))
- (append (-drop new-tail-len list) (-take new-tail-len list)))))
+ (append (nthcdr new-tail-len list) (-take new-tail-len list)))))
(defun -insert-at (n x list)
"Return a list with X inserted into LIST at position N.
@@ -1047,28 +1258,29 @@ This function can be thought of as a generalization of
"Return a list of ((-filter PRED LIST) (-remove PRED LIST)), in one pass through the list."
(--separate (funcall pred it) list))
-(defun ---partition-all-in-steps-reversed (n step list)
- "Private: Used by -partition-all-in-steps and -partition-in-steps."
+(defun dash--partition-all-in-steps-reversed (n step list)
+ "Used by `-partition-all-in-steps' and `-partition-in-steps'."
(when (< step 1)
- (error "Step must be a positive number, or you're looking at some juicy infinite loops."))
- (let ((result nil))
+ (signal 'wrong-type-argument
+ `("Step size < 1 results in juicy infinite loops" ,step)))
+ (let (result)
(while list
- (!cons (-take n list) result)
- (setq list (-drop step list)))
+ (push (-take n list) result)
+ (setq list (nthcdr step list)))
result))
(defun -partition-all-in-steps (n step list)
"Return a new list with the items in LIST grouped into N-sized sublists at offsets STEP apart.
The last groups may contain less than N items."
(declare (pure t) (side-effect-free t))
- (nreverse (---partition-all-in-steps-reversed n step list)))
+ (nreverse (dash--partition-all-in-steps-reversed n step list)))
(defun -partition-in-steps (n step list)
"Return a new list with the items in LIST grouped into N-sized sublists at offsets STEP apart.
If there are not enough items to make the last group N-sized,
those items are discarded."
(declare (pure t) (side-effect-free t))
- (let ((result (---partition-all-in-steps-reversed n step list)))
+ (let ((result (dash--partition-all-in-steps-reversed n step list)))
(while (and result (< (length (car result)) n))
(!cdr result))
(nreverse result)))
@@ -1328,16 +1540,18 @@ a variable number of arguments, such that
is identity (given that the lists are the same length).
Note in particular that calling this on a list of two lists will
-return a list of cons-cells such that the aboce identity works.
+return a list of cons-cells such that the above identity works.
See also: `-zip'"
(apply '-zip lists))
(defun -cycle (list)
- "Return an infinite copy of LIST that will cycle through the
-elements and repeat from the beginning."
+ "Return an infinite circular copy of LIST.
+The returned list cycles through the elements of LIST and repeats
+from the beginning."
(declare (pure t) (side-effect-free t))
- (let ((newlist (-map 'identity list)))
+ ;; Also works with sequences that aren't lists.
+ (let ((newlist (append list ())))
(nconc newlist newlist)))
(defun -pad (fill-value &rest lists)
@@ -1419,13 +1633,6 @@ See also: `-flatten-n', `-table'"
(dash--table-carry lists restore-lists)))
(nreverse re)))
-(defun -partial (fn &rest args)
- "Take a function FN and fewer than the normal arguments to FN,
-and return a fn that takes a variable number of additional ARGS.
-When called, the returned function calls FN with ARGS first and
-then additional args."
- (apply 'apply-partially fn args))
-
(defun -elem-index (elem list)
"Return the index of the first element in the given LIST which
is equal to the query element ELEM, or nil if there is no
@@ -1540,7 +1747,7 @@ last item in second form, etc."
Insert X at the position signified by the symbol `it' in the first
form. If there are more forms, insert the first form at the position
signified by `it' in in second form, etc."
- (declare (debug (form body)))
+ (declare (debug (form body)) (indent 1))
`(-as-> ,x it ,@forms))
(defmacro -as-> (value variable &rest forms)
@@ -1580,36 +1787,54 @@ and when that result is non-nil, through the next form, etc."
(->> ,result ,form))
,@more))))
-(defmacro -some--> (x &optional form &rest more)
- "When expr in non-nil, thread it through the first form (via `-->'),
-and when that result is non-nil, through the next form, etc."
- (declare (debug ->)
- (indent 1))
- (if (null form) x
+(defmacro -some--> (expr &rest forms)
+ "Thread EXPR through FORMS via `-->', while the result is non-nil.
+When EXPR evaluates to non-nil, thread the result through the
+first of FORMS, and when that result is non-nil, thread it
+through the next form, etc."
+ (declare (debug (form &rest &or symbolp consp)) (indent 1))
+ (if (null forms) expr
(let ((result (make-symbol "result")))
- `(-some--> (-when-let (,result ,x)
- (--> ,result ,form))
- ,@more))))
+ `(-some--> (-when-let (,result ,expr)
+ (--> ,result ,(car forms)))
+ ,@(cdr forms)))))
+
+(defmacro -doto (init &rest forms)
+ "Evaluate INIT and pass it as argument to FORMS with `->'.
+The RESULT of evaluating INIT is threaded through each of FORMS
+individually using `->', which see. The return value is RESULT,
+which FORMS may have modified by side effect."
+ (declare (debug (form &rest &or symbolp consp)) (indent 1))
+ (let ((retval (make-symbol "result")))
+ `(let ((,retval ,init))
+ ,@(mapcar (lambda (form) `(-> ,retval ,form)) forms)
+ ,retval)))
+
+(defmacro --doto (init &rest forms)
+ "Anaphoric form of `-doto'.
+This just evaluates INIT, binds the result to `it', evaluates
+FORMS, and returns the final value of `it'.
+Note: `it' need not be used in each form."
+ (declare (debug (form body)) (indent 1))
+ `(let ((it ,init))
+ ,@forms
+ it))
(defun -grade-up (comparator list)
- "Grade elements of LIST using COMPARATOR relation, yielding a
-permutation vector such that applying this permutation to LIST
-sorts it in ascending order."
- ;; ugly hack to "fix" lack of lexical scope
- (let ((comp `(lambda (it other) (funcall ',comparator (car it) (car other)))))
- (->> (--map-indexed (cons it it-index) list)
- (-sort comp)
- (-map 'cdr))))
+ "Grade elements of LIST using COMPARATOR relation.
+This yields a permutation vector such that applying this
+permutation to LIST sorts it in ascending order."
+ (->> (--map-indexed (cons it it-index) list)
+ (-sort (lambda (it other) (funcall comparator (car it) (car other))))
+ (mapcar #'cdr)))
(defun -grade-down (comparator list)
- "Grade elements of LIST using COMPARATOR relation, yielding a
-permutation vector such that applying this permutation to LIST
-sorts it in descending order."
- ;; ugly hack to "fix" lack of lexical scope
- (let ((comp `(lambda (it other) (funcall ',comparator (car other) (car it)))))
- (->> (--map-indexed (cons it it-index) list)
- (-sort comp)
- (-map 'cdr))))
+ "Grade elements of LIST using COMPARATOR relation.
+This yields a permutation vector such that applying this
+permutation to LIST sorts it in descending order."
+ (->> (--map-indexed (cons it it-index) list)
+ (-sort (lambda (it other) (funcall comparator (car other) (car it))))
+ (mapcar #'cdr)))
(defvar dash--source-counter 0
"Monotonic counter for generated symbols.")
@@ -1717,17 +1942,6 @@ SOURCE is a proper or improper list."
(t ;; Handle improper lists. Last matching place, no need for shift
(dash--match match-form (dash--match-cons-get-cdr skip-cdr source))))))
-(defun dash--vector-tail (seq start)
- "Return the tail of SEQ starting at START."
- (cond
- ((vectorp seq)
- (let* ((re-length (- (length seq) start))
- (re (make-vector re-length 0)))
- (--dotimes re-length (aset re it (aref seq (+ it start))))
- re))
- ((stringp seq)
- (substring seq start))))
-
(defun dash--match-vector (match-form source)
"Setup a vector matching environment and call the real matcher."
(let ((s (dash--match-make-source-symbol)))
@@ -1775,7 +1989,7 @@ is discarded."
(eq m '&rest))
(prog1 (dash--match
(aref match-form (1+ i))
- `(dash--vector-tail ,source ,i))
+ `(substring ,source ,i))
(setq i l)))
((and (symbolp m)
;; do not match symbols starting with _
@@ -1926,7 +2140,7 @@ Key-value stores are disambiguated by placing a token &plist,
(eq '&as (aref match-form 1)))
(let ((s (aref match-form 0)))
(cons (list s source)
- (dash--match (dash--vector-tail match-form 2) s))))
+ (dash--match (substring match-form 2) s))))
(t (dash--match-vector match-form source))))))
(defun dash--normalize-let-varlist (varlist)
@@ -1978,11 +2192,11 @@ If VARLIST only contains one (PATTERN SOURCE) element, you can
optionally specify it using a vector and discarding the
outer-most parens. Thus
- (-let ((PATTERN SOURCE)) ..)
+ (-let ((PATTERN SOURCE)) ...)
becomes
- (-let [PATTERN SOURCE] ..).
+ (-let [PATTERN SOURCE] ...).
`-let' uses a convention of not binding places (symbols) starting
with _ whenever it's possible. You can use this to skip over
@@ -2007,7 +2221,7 @@ Conses and lists:
(a b) - bind car of list to A and `cadr' to B
- (a1 a2 a3 ...) - bind 0th car of list to A1, 1st to A2, 2nd to A3 ...
+ (a1 a2 a3 ...) - bind 0th car of list to A1, 1st to A2, 2nd to A3...
(a1 a2 a3 ... aN . rest) - as above, but bind the Nth cdr to REST.
@@ -2146,27 +2360,28 @@ such that:
(-lambda (x y ...) body)
has the usual semantics of `lambda'. Furthermore, these get
-translated into normal lambda, so there is no performance
+translated into normal `lambda', so there is no performance
penalty.
-See `-let' for the description of destructuring mechanism."
+See `-let' for a description of the destructuring mechanism."
(declare (doc-string 2) (indent defun)
(debug (&define sexp
[&optional stringp]
[&optional ("interactive" interactive)]
def-body)))
(cond
- ((not (consp match-form))
- (signal 'wrong-type-argument "match-form must be a list"))
- ;; no destructuring, so just return regular lambda to make things faster
- ((-all? 'symbolp match-form)
+ ((nlistp match-form)
+ (signal 'wrong-type-argument (list #'listp match-form)))
+ ;; No destructuring, so just return regular `lambda' for speed.
+ ((-all? #'symbolp match-form)
`(lambda ,match-form ,@body))
- (t
- (let* ((inputs (--map-indexed (list it (make-symbol (format "input%d" it-index))) match-form)))
- ;; TODO: because inputs to the lambda are evaluated only once,
- ;; -let* need not to create the extra bindings to ensure that.
+ ((let ((inputs (--map-indexed
+ (list it (make-symbol (format "input%d" it-index)))
+ match-form)))
+ ;; TODO: because inputs to the `lambda' are evaluated only once,
+ ;; `-let*' need not create the extra bindings to ensure that.
;; We should find a way to optimize that. Not critical however.
- `(lambda ,(--map (cadr it) inputs)
+ `(lambda ,(mapcar #'cadr inputs)
(-let* ,inputs ,@body))))))
(defmacro -setq (&rest forms)
@@ -2193,7 +2408,7 @@ multiple assignments it does not cause unexpected side effects.
(declare (debug (&rest sexp form))
(indent 1))
(when (= (mod (length forms) 2) 1)
- (error "Odd number of arguments"))
+ (signal 'wrong-number-of-arguments (list '-setq (1+ (length forms)))))
(let* ((forms-and-sources
;; First get all the necessary mappings with all the
;; intermediate bindings.
@@ -2426,20 +2641,22 @@ Alias: `-same-items-p'"
(defalias '-same-items-p '-same-items?)
(defun -is-prefix? (prefix list)
- "Return non-nil if PREFIX is prefix of LIST.
+ "Return non-nil if PREFIX is a prefix of LIST.
-Alias: `-is-prefix-p'"
+Alias: `-is-prefix-p'."
(declare (pure t) (side-effect-free t))
- (--each-while list (equal (car prefix) it)
- (!cdr prefix))
- (not prefix))
+ (--each-while list (and (equal (car prefix) it)
+ (!cdr prefix)))
+ (null prefix))
(defun -is-suffix? (suffix list)
- "Return non-nil if SUFFIX is suffix of LIST.
+ "Return non-nil if SUFFIX is a suffix of LIST.
-Alias: `-is-suffix-p'"
+Alias: `-is-suffix-p'."
(declare (pure t) (side-effect-free t))
- (-is-prefix? (reverse suffix) (reverse list)))
+ (cond ((null suffix))
+ ((setq list (member (car suffix) list))
+ (equal (cdr suffix) (cdr list)))))
(defun -is-infix? (infix list)
"Return non-nil if INFIX is infix of LIST.
@@ -2470,22 +2687,24 @@ if the first element should sort before the second."
(declare (debug (form form)))
`(-sort (lambda (it other) ,form) ,list))
-(defun -list (&rest args)
- "Return a list with ARGS.
+(defun -list (&optional arg &rest args)
+ "Ensure ARG is a list.
+If ARG is already a list, return it as is (not a copy).
+Otherwise, return a new list with ARG as its only element.
-If first item of ARGS is already a list, simply return ARGS. If
-not, return a list with ARGS as elements."
- (declare (pure t) (side-effect-free t))
- (let ((arg (car args)))
- (if (listp arg) arg args)))
+Another supported calling convention is (-list &rest ARGS).
+In this case, if ARG is not a list, a new list with all of
+ARGS as elements is returned. This use is supported for
+backward compatibility and is otherwise deprecated."
+ (declare (advertised-calling-convention (arg) "2.18.0")
+ (pure t) (side-effect-free t))
+ (if (listp arg) arg (cons arg args)))
(defun -repeat (n x)
- "Return a list with X repeated N times.
+ "Return a new list of length N with each element being X.
Return nil if N is less than 1."
(declare (pure t) (side-effect-free t))
- (let (ret)
- (--dotimes n (!cons x ret))
- ret))
+ (and (natnump n) (make-list n x)))
(defun -sum (list)
"Return the sum of LIST."
@@ -2494,12 +2713,10 @@ Return nil if N is less than 1."
(defun -running-sum (list)
"Return a list with running sums of items in LIST.
-
LIST must be non-empty."
(declare (pure t) (side-effect-free t))
- (unless (consp list)
- (error "LIST must be non-empty"))
- (-reductions '+ list))
+ (or list (signal 'wrong-type-argument (list #'consp list)))
+ (-reductions #'+ list))
(defun -product (list)
"Return the product of LIST."
@@ -2508,12 +2725,10 @@ LIST must be non-empty."
(defun -running-product (list)
"Return a list with running products of items in LIST.
-
LIST must be non-empty."
(declare (pure t) (side-effect-free t))
- (unless (consp list)
- (error "LIST must be non-empty"))
- (-reductions '* list))
+ (or list (signal 'wrong-type-argument (list #'consp list)))
+ (-reductions #'* list))
(defun -max (list)
"Return the largest value from LIST of numbers or markers."
@@ -2555,19 +2770,20 @@ The items for the comparator form are exposed as \"it\" and \"other\"."
(declare (debug (form form)))
`(-min-by (lambda (it other) ,form) ,list))
-(defun -iterate (fun init n)
- "Return a list of iterated applications of FUN to INIT.
-
-This means a list of form:
-
- (init (fun init) (fun (fun init)) ...)
-
-N is the length of the returned list."
- (if (= n 0) nil
- (let ((r (list init)))
- (--dotimes (1- n)
- (push (funcall fun (car r)) r))
- (nreverse r))))
+(defun -iota (count &optional start step)
+ "Return a list containing COUNT numbers.
+Starts from START and adds STEP each time. The default START is
+zero, the default STEP is 1.
+This function takes its name from the corresponding primitive in
+the APL language."
+ (declare (pure t) (side-effect-free t))
+ (unless (natnump count)
+ (signal 'wrong-type-argument (list #'natnump count)))
+ (or start (setq start 0))
+ (or step (setq step 1))
+ (if (zerop step)
+ (make-list count start)
+ (--iterate (+ it step) start count)))
(defun -fix (fn list)
"Compute the (least) fixpoint of FN with initial input LIST.
@@ -2604,14 +2820,13 @@ the new seed."
(declare (debug (form form)))
`(-unfold (lambda (it) ,form) ,seed))
-(defun -cons-pair? (con)
- "Return non-nil if CON is true cons pair.
-That is (A . B) where B is not a list.
+(defun -cons-pair? (obj)
+ "Return non-nil if OBJ is a true cons pair.
+That is, a cons (A . B) where B is not a list.
-Alias: `-cons-pair-p'"
+Alias: `-cons-pair-p'."
(declare (pure t) (side-effect-free t))
- (and (listp con)
- (not (listp (cdr con)))))
+ (nlistp (cdr-safe obj)))
(defalias '-cons-pair-p '-cons-pair?)
@@ -2774,299 +2989,389 @@ replaced with new ones. This is useful when you need to clone a
structure such as plist or alist."
(declare (pure t) (side-effect-free t))
(-tree-map 'identity list))
+
+;;; Combinators
-(defun dash-enable-font-lock ()
- "Add syntax highlighting to dash functions, macros and magic values."
- (eval-after-load 'lisp-mode
- '(progn
- (let ((new-keywords '(
- "!cons"
- "!cdr"
- "-each"
- "--each"
- "-each-indexed"
- "--each-indexed"
- "-each-while"
- "--each-while"
- "-doto"
- "-dotimes"
- "--dotimes"
- "-map"
- "--map"
- "-reduce-from"
- "--reduce-from"
- "-reduce"
- "--reduce"
- "-reduce-r-from"
- "--reduce-r-from"
- "-reduce-r"
- "--reduce-r"
- "-reductions-from"
- "-reductions-r-from"
- "-reductions"
- "-reductions-r"
- "-filter"
- "--filter"
- "-select"
- "--select"
- "-remove"
- "--remove"
- "-reject"
- "--reject"
- "-remove-first"
- "--remove-first"
- "-reject-first"
- "--reject-first"
- "-remove-last"
- "--remove-last"
- "-reject-last"
- "--reject-last"
- "-remove-item"
- "-non-nil"
- "-keep"
- "--keep"
- "-map-indexed"
- "--map-indexed"
- "-splice"
- "--splice"
- "-splice-list"
- "--splice-list"
- "-map-when"
- "--map-when"
- "-replace-where"
- "--replace-where"
- "-map-first"
- "--map-first"
- "-map-last"
- "--map-last"
- "-replace"
- "-replace-first"
- "-replace-last"
- "-flatten"
- "-flatten-n"
- "-concat"
- "-mapcat"
- "--mapcat"
- "-copy"
- "-cons*"
- "-snoc"
- "-first"
- "--first"
- "-find"
- "--find"
- "-some"
- "--some"
- "-any"
- "--any"
- "-last"
- "--last"
- "-first-item"
- "-second-item"
- "-third-item"
- "-fourth-item"
- "-fifth-item"
- "-last-item"
- "-butlast"
- "-count"
- "--count"
- "-any?"
- "--any?"
- "-some?"
- "--some?"
- "-any-p"
- "--any-p"
- "-some-p"
- "--some-p"
- "-some->"
- "-some->>"
- "-some-->"
- "-all?"
- "-all-p"
- "--all?"
- "--all-p"
- "-every?"
- "--every?"
- "-all-p"
- "--all-p"
- "-every-p"
- "--every-p"
- "-none?"
- "--none?"
- "-none-p"
- "--none-p"
- "-only-some?"
- "--only-some?"
- "-only-some-p"
- "--only-some-p"
- "-slice"
- "-take"
- "-drop"
- "-drop-last"
- "-take-last"
- "-take-while"
- "--take-while"
- "-drop-while"
- "--drop-while"
- "-split-at"
- "-rotate"
- "-insert-at"
- "-replace-at"
- "-update-at"
- "--update-at"
- "-remove-at"
- "-remove-at-indices"
- "-split-with"
- "--split-with"
- "-split-on"
- "-split-when"
- "--split-when"
- "-separate"
- "--separate"
- "-partition-all-in-steps"
- "-partition-in-steps"
- "-partition-all"
- "-partition"
- "-partition-after-item"
- "-partition-after-pred"
- "-partition-before-item"
- "-partition-before-pred"
- "-partition-by"
- "--partition-by"
- "-partition-by-header"
- "--partition-by-header"
- "-group-by"
- "--group-by"
- "-interpose"
- "-interleave"
- "-unzip"
- "-zip-with"
- "--zip-with"
- "-zip"
- "-zip-fill"
- "-zip-lists"
- "-zip-pair"
- "-cycle"
- "-pad"
- "-annotate"
- "--annotate"
- "-table"
- "-table-flat"
- "-partial"
- "-elem-index"
- "-elem-indices"
- "-find-indices"
- "--find-indices"
- "-find-index"
- "--find-index"
- "-find-last-index"
- "--find-last-index"
- "-select-by-indices"
- "-select-columns"
- "-select-column"
- "-grade-up"
- "-grade-down"
- "->"
- "->>"
- "-->"
- "-as->"
- "-when-let"
- "-when-let*"
- "--when-let"
- "-if-let"
- "-if-let*"
- "--if-let"
- "-let*"
- "-let"
- "-lambda"
- "-distinct"
- "-uniq"
- "-union"
- "-intersection"
- "-difference"
- "-powerset"
- "-permutations"
- "-inits"
- "-tails"
- "-common-prefix"
- "-common-suffix"
- "-contains?"
- "-contains-p"
- "-same-items?"
- "-same-items-p"
- "-is-prefix-p"
- "-is-prefix?"
- "-is-suffix-p"
- "-is-suffix?"
- "-is-infix-p"
- "-is-infix?"
- "-sort"
- "--sort"
- "-list"
- "-repeat"
- "-sum"
- "-running-sum"
- "-product"
- "-running-product"
- "-max"
- "-min"
- "-max-by"
- "--max-by"
- "-min-by"
- "--min-by"
- "-iterate"
- "--iterate"
- "-fix"
- "--fix"
- "-unfold"
- "--unfold"
- "-cons-pair?"
- "-cons-pair-p"
- "-cons-to-list"
- "-value-to-list"
- "-tree-mapreduce-from"
- "--tree-mapreduce-from"
- "-tree-mapreduce"
- "--tree-mapreduce"
- "-tree-map"
- "--tree-map"
- "-tree-reduce-from"
- "--tree-reduce-from"
- "-tree-reduce"
- "--tree-reduce"
- "-tree-seq"
- "--tree-seq"
- "-tree-map-nodes"
- "--tree-map-nodes"
- "-clone"
- "-rpartial"
- "-juxt"
- "-applify"
- "-on"
- "-flip"
- "-const"
- "-cut"
- "-orfn"
- "-andfn"
- "-iteratefn"
- "-fixfn"
- "-prodfn"
- ))
- (special-variables '(
- "it"
- "it-index"
- "acc"
- "other"
- )))
- (font-lock-add-keywords 'emacs-lisp-mode `((,(concat "\\_<" (regexp-opt special-variables 'paren) "\\_>")
- 1 font-lock-variable-name-face)) 'append)
- (font-lock-add-keywords 'emacs-lisp-mode `((,(concat "(\\s-*" (regexp-opt new-keywords 'paren) "\\_>")
- 1 font-lock-keyword-face)) 'append))
- (--each (buffer-list)
- (with-current-buffer it
- (when (and (eq major-mode 'emacs-lisp-mode)
- (boundp 'font-lock-mode)
- font-lock-mode)
- (font-lock-refresh-defaults)))))))
+(defun -partial (fn &rest args)
+ "Take a function FN and fewer than the normal arguments to FN,
+and return a fn that takes a variable number of additional ARGS.
+When called, the returned function calls FN with ARGS first and
+then additional args."
+ (apply 'apply-partially fn args))
+
+(defun -rpartial (fn &rest args)
+ "Takes a function FN and fewer than the normal arguments to FN,
+and returns a fn that takes a variable number of additional ARGS.
+When called, the returned function calls FN with the additional
+args first and then ARGS."
+ (lambda (&rest args-before) (apply fn (append args-before args))))
+
+(defun -juxt (&rest fns)
+ "Takes a list of functions and returns a fn that is the
+juxtaposition of those fns. The returned fn takes a variable
+number of args, and returns a list containing the result of
+applying each fn to the args (left-to-right)."
+ (lambda (&rest args) (mapcar (lambda (x) (apply x args)) fns)))
+
+(defun -compose (&rest fns)
+ "Takes a list of functions and returns a fn that is the
+composition of those fns. The returned fn takes a variable
+number of arguments, and returns the result of applying
+each fn to the result of applying the previous fn to
+the arguments (right-to-left)."
+ (lambda (&rest args)
+ (car (-reduce-r-from (lambda (fn xs) (list (apply fn xs)))
+ args fns))))
+
+(defun -applify (fn)
+ "Changes an n-arity function FN to a 1-arity function that
+expects a list with n items as arguments"
+ (apply-partially 'apply fn))
+
+(defun -on (operator transformer)
+ "Return a function of two arguments that first applies
+TRANSFORMER to each of them and then applies OPERATOR on the
+results (in the same order).
+
+In types: (b -> b -> c) -> (a -> b) -> a -> a -> c"
+ (lambda (x y) (funcall operator (funcall transformer x) (funcall transformer y))))
+
+(defun -flip (func)
+ "Swap the order of arguments for binary function FUNC.
+
+In types: (a -> b -> c) -> b -> a -> c"
+ (lambda (x y) (funcall func y x)))
+
+(defun -const (c)
+ "Return a function that returns C ignoring any additional arguments.
+
+In types: a -> b -> a"
+ (lambda (&rest _) c))
+
+(defmacro -cut (&rest params)
+ "Take n-ary function and n arguments and specialize some of them.
+Arguments denoted by <> will be left unspecialized.
+
+See SRFI-26 for detailed description."
+ (let* ((i 0)
+ (args (--keep (when (eq it '<>)
+ (setq i (1+ i))
+ (make-symbol (format "D%d" i)))
+ params)))
+ `(lambda ,args
+ ,(let ((body (--map (if (eq it '<>) (pop args) it) params)))
+ (if (eq (car params) '<>)
+ (cons 'funcall body)
+ body)))))
+
+(defun -not (pred)
+ "Take a unary predicate PRED and return a unary predicate
+that returns t if PRED returns nil and nil if PRED returns
+non-nil."
+ (lambda (x) (not (funcall pred x))))
+
+(defun -orfn (&rest preds)
+ "Take list of unary predicates PREDS and return a unary
+predicate with argument x that returns non-nil if at least one of
+the PREDS returns non-nil on x.
+
+In types: [a -> Bool] -> a -> Bool"
+ (lambda (x) (-any? (-cut funcall <> x) preds)))
+
+(defun -andfn (&rest preds)
+ "Take list of unary predicates PREDS and return a unary
+predicate with argument x that returns non-nil if all of the
+PREDS returns non-nil on x.
+
+In types: [a -> Bool] -> a -> Bool"
+ (lambda (x) (-all? (-cut funcall <> x) preds)))
+
+(defun -iteratefn (fn n)
+ "Return a function FN composed N times with itself.
+
+FN is a unary function. If you need to use a function of higher
+arity, use `-applify' first to turn it into a unary function.
+
+With n = 0, this acts as identity function.
+
+In types: (a -> a) -> Int -> a -> a.
+
+This function satisfies the following law:
+
+ (funcall (-iteratefn fn n) init) = (-last-item (-iterate fn init (1+ n)))."
+ (lambda (x) (--dotimes n (setq x (funcall fn x))) x))
+
+(defun -counter (&optional beg end inc)
+ "Return a closure that counts from BEG to END, with increment INC.
+
+The closure will return the next value in the counting sequence
+each time it is called, and nil after END is reached. BEG
+defaults to 0, INC defaults to 1, and if END is nil, the counter
+will increment indefinitely.
+
+The closure accepts any number of arguments, which are discarded."
+ (let ((inc (or inc 1))
+ (n (or beg 0)))
+ (lambda (&rest _)
+ (when (or (not end) (< n end))
+ (prog1 n
+ (setq n (+ n inc)))))))
+
+(defvar -fixfn-max-iterations 1000
+ "The default maximum number of iterations performed by `-fixfn'
+ unless otherwise specified.")
+
+(defun -fixfn (fn &optional equal-test halt-test)
+ "Return a function that computes the (least) fixpoint of FN.
+
+FN must be a unary function. The returned lambda takes a single
+argument, X, the initial value for the fixpoint iteration. The
+iteration halts when either of the following conditions is satisfied:
+
+ 1. Iteration converges to the fixpoint, with equality being
+ tested using EQUAL-TEST. If EQUAL-TEST is not specified,
+ `equal' is used. For functions over the floating point
+ numbers, it may be necessary to provide an appropriate
+ approximate comparison test.
+
+ 2. HALT-TEST returns a non-nil value. HALT-TEST defaults to a
+ simple counter that returns t after `-fixfn-max-iterations',
+ to guard against infinite iteration. Otherwise, HALT-TEST
+ must be a function that accepts a single argument, the
+ current value of X, and returns non-nil as long as iteration
+ should continue. In this way, a more sophisticated
+ convergence test may be supplied by the caller.
+
+The return value of the lambda is either the fixpoint or, if
+iteration halted before converging, a cons with car `halted' and
+cdr the final output from HALT-TEST.
+
+In types: (a -> a) -> a -> a."
+ (let ((eqfn (or equal-test 'equal))
+ (haltfn (or halt-test
+ (-not
+ (-counter 0 -fixfn-max-iterations)))))
+ (lambda (x)
+ (let ((re (funcall fn x))
+ (halt? (funcall haltfn x)))
+ (while (and (not halt?) (not (funcall eqfn x re)))
+ (setq x re
+ re (funcall fn re)
+ halt? (funcall haltfn re)))
+ (if halt? (cons 'halted halt?)
+ re)))))
+
+(defun -prodfn (&rest fns)
+ "Take a list of n functions and return a function that takes a
+list of length n, applying i-th function to i-th element of the
+input list. Returns a list of length n.
+
+In types (for n=2): ((a -> b), (c -> d)) -> (a, c) -> (b, d)
+
+This function satisfies the following laws:
+
+ (-compose (-prodfn f g ...) (-prodfn f\\=' g\\=' ...)) = (-prodfn (-compose f f\\=') (-compose g g\\=') ...)
+ (-prodfn f g ...) = (-juxt (-compose f (-partial \\='nth 0)) (-compose g (-partial \\='nth 1)) ...)
+ (-compose (-prodfn f g ...) (-juxt f\\=' g\\=' ...)) = (-juxt (-compose f f\\=') (-compose g g\\=') ...)
+ (-compose (-partial \\='nth n) (-prod f1 f2 ...)) = (-compose fn (-partial \\='nth n))"
+ (lambda (x) (-zip-with 'funcall fns x)))
+
+;;; Font lock
+
+(defvar dash--keywords
+ `(;; TODO: Do not fontify the following automatic variables
+ ;; globally; detect and limit to their local anaphoric scope.
+ (,(rx symbol-start (| "acc" "it" "it-index" "other") symbol-end)
+ 0 font-lock-variable-name-face)
+ ;; Macros in dev/examples.el. Based on `lisp-mode-symbol-regexp'.
+ (,(rx ?\( (group (| "defexamples" "def-example-group")) symbol-end
+ (+ (in "\t "))
+ (group (* (| (syntax word) (syntax symbol) (: ?\\ nonl)))))
+ (1 font-lock-keyword-face)
+ (2 font-lock-function-name-face))
+ ;; Symbols in dev/examples.el.
+ ,(rx symbol-start (| "=>" "~>" "!!>") symbol-end)
+ ;; Elisp macro fontification was static prior to Emacs 25.
+ ,@(when (< emacs-major-version 25)
+ (let ((macs '("!cdr"
+ "!cons"
+ "-->"
+ "--all?"
+ "--annotate"
+ "--any?"
+ "--count"
+ "--dotimes"
+ "--doto"
+ "--drop-while"
+ "--each"
+ "--each-r"
+ "--each-r-while"
+ "--each-while"
+ "--filter"
+ "--find-index"
+ "--find-indices"
+ "--find-last-index"
+ "--first"
+ "--fix"
+ "--group-by"
+ "--if-let"
+ "--iterate"
+ "--keep"
+ "--last"
+ "--map"
+ "--map-first"
+ "--map-indexed"
+ "--map-last"
+ "--map-when"
+ "--mapcat"
+ "--max-by"
+ "--min-by"
+ "--none?"
+ "--only-some?"
+ "--partition-by"
+ "--partition-by-header"
+ "--reduce"
+ "--reduce-from"
+ "--reduce-r"
+ "--reduce-r-from"
+ "--reductions"
+ "--reductions-from"
+ "--reductions-r"
+ "--reductions-r-from"
+ "--remove"
+ "--remove-first"
+ "--remove-last"
+ "--separate"
+ "--some"
+ "--sort"
+ "--splice"
+ "--splice-list"
+ "--split-when"
+ "--split-with"
+ "--take-while"
+ "--tree-map"
+ "--tree-map-nodes"
+ "--tree-mapreduce"
+ "--tree-mapreduce-from"
+ "--tree-reduce"
+ "--tree-reduce-from"
+ "--tree-seq"
+ "--unfold"
+ "--update-at"
+ "--when-let"
+ "--zip-with"
+ "->"
+ "->>"
+ "-as->"
+ "-doto"
+ "-if-let"
+ "-if-let*"
+ "-lambda"
+ "-let"
+ "-let*"
+ "-setq"
+ "-some-->"
+ "-some->"
+ "-some->>"
+ "-split-on"
+ "-when-let"
+ "-when-let*")))
+ `((,(concat "(" (regexp-opt macs 'symbols)) . 1)))))
+ "Font lock keywords for `dash-fontify-mode'.")
+
+(defcustom dash-fontify-mode-lighter nil
+ "Mode line lighter for `dash-fontify-mode'.
+Either a string to display in the mode line when
+`dash-fontify-mode' is on, or nil to display
+nothing (the default)."
+ :package-version '(dash . "2.18.0")
+ :group 'dash
+ :type '(choice (string :tag "Lighter" :value " Dash")
+ (const :tag "Nothing" nil)))
+
+;;;###autoload
+(define-minor-mode dash-fontify-mode
+ "Toggle fontification of Dash special variables.
+
+Dash-Fontify mode is a buffer-local minor mode intended for Emacs
+Lisp buffers. Enabling it causes the special variables bound in
+anaphoric Dash macros to be fontified. These anaphoras include
+`it', `it-index', `acc', and `other'. In older Emacs versions
+which do not dynamically detect macros, Dash-Fontify mode
+additionally fontifies Dash macro calls.
+
+See also `dash-fontify-mode-lighter' and
+`global-dash-fontify-mode'."
+ :group 'dash :lighter dash-fontify-mode-lighter
+ (if dash-fontify-mode
+ (font-lock-add-keywords nil dash--keywords t)
+ (font-lock-remove-keywords nil dash--keywords))
+ (cond ((fboundp 'font-lock-flush) ;; Added in Emacs 25.
+ (font-lock-flush))
+ ;; `font-lock-fontify-buffer' unconditionally enables
+ ;; `font-lock-mode' and is marked `interactive-only' in later
+ ;; Emacs versions which have `font-lock-flush', so we guard
+ ;; and pacify as needed, respectively.
+ (font-lock-mode
+ (with-no-warnings
+ (font-lock-fontify-buffer)))))
+
+(defun dash--turn-on-fontify-mode ()
+ "Enable `dash-fontify-mode' if in an Emacs Lisp buffer."
+ (when (derived-mode-p #'emacs-lisp-mode)
+ (dash-fontify-mode)))
+
+;;;###autoload
+(define-globalized-minor-mode global-dash-fontify-mode
+ dash-fontify-mode dash--turn-on-fontify-mode
+ :group 'dash)
+
+(defcustom dash-enable-fontlock nil
+ "If non-nil, fontify Dash macro calls and special variables."
+ :group 'dash
+ :set (lambda (sym val)
+ (set-default sym val)
+ (global-dash-fontify-mode (if val 1 0)))
+ :type 'boolean)
+
+(make-obsolete-variable
+ 'dash-enable-fontlock #'global-dash-fontify-mode "2.18.0")
+
+(define-obsolete-function-alias
+ 'dash-enable-font-lock #'global-dash-fontify-mode "2.18.0")
+
+;;; Info
+
+(defvar dash--info-doc-spec '("(dash) Index" nil "^ -+ .*: " "\\( \\|$\\)")
+ "The Dash :doc-spec entry for `info-lookup-alist'.
+It is based on that for `emacs-lisp-mode'.")
+
+(defun dash--info-elisp-docs ()
+ "Return the `emacs-lisp-mode' symbol docs from `info-lookup-alist'.
+Specifically, return the cons containing their
+`info-lookup->doc-spec' so that we can modify it."
+ (defvar info-lookup-alist)
+ (nthcdr 3 (assq #'emacs-lisp-mode (cdr (assq 'symbol info-lookup-alist)))))
+
+;;;###autoload
+(defun dash-register-info-lookup ()
+ "Register the Dash Info manual with `info-lookup-symbol'.
+This allows Dash symbols to be looked up with \\[info-lookup-symbol]."
+ (interactive)
+ (require 'info-look)
+ (let ((docs (dash--info-elisp-docs)))
+ (setcar docs (append (car docs) (list dash--info-doc-spec)))
+ (info-lookup-reset)))
+
+(defun dash-unload-function ()
+ "Remove Dash from `info-lookup-alist'.
+Used by `unload-feature', which see."
+ (let ((docs (and (featurep 'info-look)
+ (dash--info-elisp-docs))))
+ (when (member dash--info-doc-spec (car docs))
+ (setcar docs (remove dash--info-doc-spec (car docs)))
+ (info-lookup-reset)))
+ nil)
(provide 'dash)
;;; dash.el ends here
diff --git a/elpa/dash-2.18.0/dash.info b/elpa/dash-2.18.0/dash.info
new file mode 100644
index 0000000..d4550b0
--- /dev/null
+++ b/elpa/dash-2.18.0/dash.info
@@ -0,0 +1,4656 @@
+This is dash.info, produced by makeinfo version 6.5 from dash.texi.
+
+This manual is for Dash version 2.18.0.
+
+ Copyright © 2012–2021 Free Software Foundation, Inc.
+
+ Permission is granted to copy, distribute and/or modify this
+ document under the terms of the GNU Free Documentation License,
+ Version 1.3 or any later version published by the Free Software
+ Foundation; with the Invariant Sections being “GNU General Public
+ License,” and no Front-Cover Texts or Back-Cover Texts. A copy of
+ the license is included in the section entitled “GNU Free
+ Documentation License”.
+INFO-DIR-SECTION Emacs
+START-INFO-DIR-ENTRY
+* Dash: (dash.info). A modern list library for GNU Emacs.
+END-INFO-DIR-ENTRY
+
+
+File: dash.info, Node: Top, Next: Installation, Up: (dir)
+
+Dash
+****
+
+This manual is for Dash version 2.18.0.
+
+ Copyright © 2012–2021 Free Software Foundation, Inc.
+
+ Permission is granted to copy, distribute and/or modify this
+ document under the terms of the GNU Free Documentation License,
+ Version 1.3 or any later version published by the Free Software
+ Foundation; with the Invariant Sections being “GNU General Public
+ License,” and no Front-Cover Texts or Back-Cover Texts. A copy of
+ the license is included in the section entitled “GNU Free
+ Documentation License”.
+
+* Menu:
+
+* Installation:: Installing and configuring Dash.
+* Functions:: Dash API reference.
+* Development:: Contributing to Dash development.
+
+Appendices
+
+* FDL:: The license for this documentation.
+* GPL:: Conditions for copying and changing Dash.
+* Index:: Index including functions and macros.
+
+ — The Detailed Node Listing —
+
+Installation
+
+* Using in a package:: Listing Dash as a package dependency.
+* Fontification of special variables:: Font Lock of anaphoric macro variables.
+* Info symbol lookup:: Looking up Dash symbols in this manual.
+
+Functions
+
+* Maps::
+* Sublist selection::
+* List to list::
+* Reductions::
+* Unfolding::
+* Predicates::
+* Partitioning::
+* Indexing::
+* Set operations::
+* Other list operations::
+* Tree operations::
+* Threading macros::
+* Binding::
+* Side effects::
+* Destructive operations::
+* Function combinators::
+
+Development
+
+* Contribute:: How to contribute.
+* Contributors:: List of contributors.
+
+
+File: dash.info, Node: Installation, Next: Functions, Prev: Top, Up: Top
+
+1 Installation
+**************
+
+Dash is available on GNU ELPA (https://elpa.gnu.org/) and MELPA
+(https://melpa.org/), and can be installed with the standard command
+‘package-install’ (*note (emacs)Package Installation::).
+
+‘M-x package-install dash ’
+ Install the Dash library.
+
+ Alternatively, you can just dump ‘dash.el’ in your ‘load-path’
+somewhere (*note (emacs)Lisp Libraries::).
+
+* Menu:
+
+* Using in a package:: Listing Dash as a package dependency.
+* Fontification of special variables:: Font Lock of anaphoric macro variables.
+* Info symbol lookup:: Looking up Dash symbols in this manual.
+
+
+File: dash.info, Node: Using in a package, Next: Fontification of special variables, Up: Installation
+
+1.1 Using in a package
+======================
+
+If you use Dash in your own package, be sure to list it as a dependency
+in the library’s headers as follows (*note (elisp)Library Headers::).
+
+ ;; Package-Requires: ((dash "2.18.0"))
+
+
+File: dash.info, Node: Fontification of special variables, Next: Info symbol lookup, Prev: Using in a package, Up: Installation
+
+1.2 Fontification of special variables
+======================================
+
+The autoloaded minor mode ‘dash-fontify-mode’ is provided for optional
+fontification of anaphoric Dash variables (‘it’, ‘acc’, etc.) in Emacs
+Lisp buffers using search-based Font Lock (*note (emacs)Font Lock::).
+In older Emacs versions which do not dynamically detect macros, the
+minor mode also fontifies calls to Dash macros.
+
+ To automatically enable the minor mode in all Emacs Lisp buffers,
+just call its autoloaded global counterpart ‘global-dash-fontify-mode’,
+either interactively or from your ‘user-init-file’:
+
+ (global-dash-fontify-mode)
+
+
+File: dash.info, Node: Info symbol lookup, Prev: Fontification of special variables, Up: Installation
+
+1.3 Info symbol lookup
+======================
+
+While editing Elisp files, you can use ‘C-h S’ (‘info-lookup-symbol’) to
+look up Elisp symbols in the relevant Info manuals (*note (emacs)Info
+Lookup::). To enable the same for Dash symbols, use the command
+‘dash-register-info-lookup’. It can be called directly when needed, or
+automatically from your ‘user-init-file’. For example:
+
+ (with-eval-after-load 'info-look
+ (dash-register-info-lookup))
+
+
+File: dash.info, Node: Functions, Next: Development, Prev: Installation, Up: Top
+
+2 Functions
+***********
+
+This chapter contains reference documentation for the Dash API
+(Application Programming Interface). The names of all public functions
+defined in the library are prefixed with a dash character (‘-’).
+
+ The library also provides anaphoric macro versions of functions where
+that makes sense. The names of these macros are prefixed with two
+dashes (‘--’) instead of one.
+
+ For instance, while the function ‘-map’ applies a function to each
+element of a list, its anaphoric counterpart ‘--map’ evaluates a form
+with the local variable ‘it’ temporarily bound to the current list
+element instead.
+
+ ;; Normal version.
+ (-map (lambda (n) (* n n)) '(1 2 3 4))
+ ⇒ (1 4 9 16)
+
+ ;; Anaphoric version.
+ (--map (* it it) '(1 2 3 4))
+ ⇒ (1 4 9 16)
+
+ The normal version can, of course, also be written as in the
+following example, which demonstrates the utility of both versions.
+
+ (defun my-square (n)
+ "Return N multiplied by itself."
+ (* n n))
+
+ (-map #'my-square '(1 2 3 4))
+ ⇒ (1 4 9 16)
+
+* Menu:
+
+* Maps::
+* Sublist selection::
+* List to list::
+* Reductions::
+* Unfolding::
+* Predicates::
+* Partitioning::
+* Indexing::
+* Set operations::
+* Other list operations::
+* Tree operations::
+* Threading macros::
+* Binding::
+* Side effects::
+* Destructive operations::
+* Function combinators::
+
+
+File: dash.info, Node: Maps, Next: Sublist selection, Up: Functions
+
+2.1 Maps
+========
+
+Functions in this category take a transforming function, which is then
+applied sequentially to each or selected elements of the input list.
+The results are collected in order and returned as a new list.
+
+ -- Function: -map (fn list)
+ Apply FN to each item in LIST and return the list of results.
+
+ This function’s anaphoric counterpart is ‘--map’.
+
+ (-map (lambda (num) (* num num)) '(1 2 3 4))
+ ⇒ (1 4 9 16)
+ (-map #'1+ '(1 2 3 4))
+ ⇒ (2 3 4 5)
+ (--map (* it it) '(1 2 3 4))
+ ⇒ (1 4 9 16)
+
+ -- Function: -map-when (pred rep list)
+ Return a new list where the elements in LIST that do not match the
+ PRED function are unchanged, and where the elements in LIST that do
+ match the PRED function are mapped through the REP function.
+
+ Alias: ‘-replace-where’
+
+ See also: ‘-update-at’ (*note -update-at::)
+
+ (-map-when 'even? 'square '(1 2 3 4))
+ ⇒ (1 4 3 16)
+ (--map-when (> it 2) (* it it) '(1 2 3 4))
+ ⇒ (1 2 9 16)
+ (--map-when (= it 2) 17 '(1 2 3 4))
+ ⇒ (1 17 3 4)
+
+ -- Function: -map-first (pred rep list)
+ Replace first item in LIST satisfying PRED with result of REP
+ called on this item.
+
+ See also: ‘-map-when’ (*note -map-when::), ‘-replace-first’ (*note
+ -replace-first::)
+
+ (-map-first 'even? 'square '(1 2 3 4))
+ ⇒ (1 4 3 4)
+ (--map-first (> it 2) (* it it) '(1 2 3 4))
+ ⇒ (1 2 9 4)
+ (--map-first (= it 2) 17 '(1 2 3 2))
+ ⇒ (1 17 3 2)
+
+ -- Function: -map-last (pred rep list)
+ Replace last item in LIST satisfying PRED with result of REP called
+ on this item.
+
+ See also: ‘-map-when’ (*note -map-when::), ‘-replace-last’ (*note
+ -replace-last::)
+
+ (-map-last 'even? 'square '(1 2 3 4))
+ ⇒ (1 2 3 16)
+ (--map-last (> it 2) (* it it) '(1 2 3 4))
+ ⇒ (1 2 3 16)
+ (--map-last (= it 2) 17 '(1 2 3 2))
+ ⇒ (1 2 3 17)
+
+ -- Function: -map-indexed (fn list)
+ Apply FN to each index and item in LIST and return the list of
+ results. This is like ‘-map’ (*note -map::), but FN takes two
+ arguments: the index of the current element within LIST, and the
+ element itself.
+
+ This function’s anaphoric counterpart is ‘--map-indexed’.
+
+ For a side-effecting variant, see also ‘-each-indexed’ (*note
+ -each-indexed::).
+
+ (-map-indexed (lambda (index item) (- item index)) '(1 2 3 4))
+ ⇒ (1 1 1 1)
+ (--map-indexed (- it it-index) '(1 2 3 4))
+ ⇒ (1 1 1 1)
+ (-map-indexed #'* '(1 2 3 4))
+ ⇒ (0 2 6 12)
+
+ -- Function: -annotate (fn list)
+ Return a list of cons cells where each cell is FN applied to each
+ element of LIST paired with the unmodified element of LIST.
+
+ (-annotate '1+ '(1 2 3))
+ ⇒ ((2 . 1) (3 . 2) (4 . 3))
+ (-annotate 'length '(("h" "e" "l" "l" "o") ("hello" "world")))
+ ⇒ ((5 "h" "e" "l" "l" "o") (2 "hello" "world"))
+ (--annotate (< 1 it) '(0 1 2 3))
+ ⇒ ((nil . 0) (nil . 1) (t . 2) (t . 3))
+
+ -- Function: -splice (pred fun list)
+ Splice lists generated by FUN in place of elements matching PRED in
+ LIST.
+
+ FUN takes the element matching PRED as input.
+
+ This function can be used as replacement for ‘,@’ in case you need
+ to splice several lists at marked positions (for example with
+ keywords).
+
+ See also: ‘-splice-list’ (*note -splice-list::), ‘-insert-at’
+ (*note -insert-at::)
+
+ (-splice 'even? (lambda (x) (list x x)) '(1 2 3 4))
+ ⇒ (1 2 2 3 4 4)
+ (--splice 't (list it it) '(1 2 3 4))
+ ⇒ (1 1 2 2 3 3 4 4)
+ (--splice (equal it :magic) '((list of) (magical) (code)) '((foo) (bar) :magic (baz)))
+ ⇒ ((foo) (bar) (list of) (magical) (code) (baz))
+
+ -- Function: -splice-list (pred new-list list)
+ Splice NEW-LIST in place of elements matching PRED in LIST.
+
+ See also: ‘-splice’ (*note -splice::), ‘-insert-at’ (*note
+ -insert-at::)
+
+ (-splice-list 'keywordp '(a b c) '(1 :foo 2))
+ ⇒ (1 a b c 2)
+ (-splice-list 'keywordp nil '(1 :foo 2))
+ ⇒ (1 2)
+ (--splice-list (keywordp it) '(a b c) '(1 :foo 2))
+ ⇒ (1 a b c 2)
+
+ -- Function: -mapcat (fn list)
+ Return the concatenation of the result of mapping FN over LIST.
+ Thus function FN should return a list.
+
+ (-mapcat 'list '(1 2 3))
+ ⇒ (1 2 3)
+ (-mapcat (lambda (item) (list 0 item)) '(1 2 3))
+ ⇒ (0 1 0 2 0 3)
+ (--mapcat (list 0 it) '(1 2 3))
+ ⇒ (0 1 0 2 0 3)
+
+ -- Function: -copy (list)
+ Create a shallow copy of LIST.
+
+ (-copy '(1 2 3))
+ ⇒ (1 2 3)
+ (let ((a '(1 2 3))) (eq a (-copy a)))
+ ⇒ nil
+
+
+File: dash.info, Node: Sublist selection, Next: List to list, Prev: Maps, Up: Functions
+
+2.2 Sublist selection
+=====================
+
+Functions returning a sublist of the original list.
+
+ -- Function: -filter (pred list)
+ Return a new list of the items in LIST for which PRED returns
+ non-nil.
+
+ Alias: ‘-select’.
+
+ This function’s anaphoric counterpart is ‘--filter’.
+
+ For similar operations, see also ‘-keep’ (*note -keep::) and
+ ‘-remove’ (*note -remove::).
+
+ (-filter (lambda (num) (= 0 (% num 2))) '(1 2 3 4))
+ ⇒ (2 4)
+ (-filter #'natnump '(-2 -1 0 1 2))
+ ⇒ (0 1 2)
+ (--filter (= 0 (% it 2)) '(1 2 3 4))
+ ⇒ (2 4)
+
+ -- Function: -remove (pred list)
+ Return a new list of the items in LIST for which PRED returns nil.
+
+ Alias: ‘-reject’.
+
+ This function’s anaphoric counterpart is ‘--remove’.
+
+ For similar operations, see also ‘-keep’ (*note -keep::) and
+ ‘-filter’ (*note -filter::).
+
+ (-remove (lambda (num) (= 0 (% num 2))) '(1 2 3 4))
+ ⇒ (1 3)
+ (-remove #'natnump '(-2 -1 0 1 2))
+ ⇒ (-2 -1)
+ (--remove (= 0 (% it 2)) '(1 2 3 4))
+ ⇒ (1 3)
+
+ -- Function: -remove-first (pred list)
+ Remove the first item from LIST for which PRED returns non-nil.
+ This is a non-destructive operation, but only the front of LIST
+ leading up to the removed item is a copy; the rest is LIST’s
+ original tail. If no item is removed, then the result is a
+ complete copy.
+
+ Alias: ‘-reject-first’.
+
+ This function’s anaphoric counterpart is ‘--remove-first’.
+
+ See also ‘-map-first’ (*note -map-first::), ‘-remove-item’ (*note
+ -remove-item::), and ‘-remove-last’ (*note -remove-last::).
+
+ (-remove-first #'natnump '(-2 -1 0 1 2))
+ ⇒ (-2 -1 1 2)
+ (-remove-first #'stringp '(1 2 "first" "second"))
+ ⇒ (1 2 "second")
+ (--remove-first (> it 3) '(1 2 3 4 5 6))
+ ⇒ (1 2 3 5 6)
+
+ -- Function: -remove-last (pred list)
+ Remove the last item from LIST for which PRED returns non-nil. The
+ result is a copy of LIST regardless of whether an element is
+ removed.
+
+ Alias: ‘-reject-last’.
+
+ This function’s anaphoric counterpart is ‘--remove-last’.
+
+ See also ‘-map-last’ (*note -map-last::), ‘-remove-item’ (*note
+ -remove-item::), and ‘-remove-first’ (*note -remove-first::).
+
+ (-remove-last #'natnump '(1 3 5 4 7 8 10 -11))
+ ⇒ (1 3 5 4 7 8 -11)
+ (-remove-last #'stringp '(1 2 "last" "second"))
+ ⇒ (1 2 "last")
+ (--remove-last (> it 3) '(1 2 3 4 5 6 7 8 9 10))
+ ⇒ (1 2 3 4 5 6 7 8 9)
+
+ -- Function: -remove-item (item list)
+ Return a copy of LIST with all occurrences of ITEM removed. The
+ comparison is done with ‘equal’.
+
+ (-remove-item 3 '(1 2 3 2 3 4 5 3))
+ ⇒ (1 2 2 4 5)
+ (-remove-item 'foo '(foo bar baz foo))
+ ⇒ (bar baz)
+ (-remove-item "bob" '("alice" "bob" "eve" "bob"))
+ ⇒ ("alice" "eve")
+
+ -- Function: -non-nil (list)
+ Return a copy of LIST with all nil items removed.
+
+ (-non-nil '(nil 1 nil 2 nil nil 3 4 nil 5 nil))
+ ⇒ (1 2 3 4 5)
+ (-non-nil '((nil)))
+ ⇒ ((nil))
+ (-non-nil ())
+ ⇒ ()
+
+ -- Function: -slice (list from &optional to step)
+ Return copy of LIST, starting from index FROM to index TO.
+
+ FROM or TO may be negative. These values are then interpreted
+ modulo the length of the list.
+
+ If STEP is a number, only each STEPth item in the resulting section
+ is returned. Defaults to 1.
+
+ (-slice '(1 2 3 4 5) 1)
+ ⇒ (2 3 4 5)
+ (-slice '(1 2 3 4 5) 0 3)
+ ⇒ (1 2 3)
+ (-slice '(1 2 3 4 5 6 7 8 9) 1 -1 2)
+ ⇒ (2 4 6 8)
+
+ -- Function: -take (n list)
+ Return a copy of the first N items in LIST. Return a copy of LIST
+ if it contains N items or fewer. Return nil if N is zero or less.
+
+ See also: ‘-take-last’ (*note -take-last::).
+
+ (-take 3 '(1 2 3 4 5))
+ ⇒ (1 2 3)
+ (-take 17 '(1 2 3 4 5))
+ ⇒ (1 2 3 4 5)
+ (-take 0 '(1 2 3 4 5))
+ ⇒ ()
+
+ -- Function: -take-last (n list)
+ Return a copy of the last N items of LIST in order. Return a copy
+ of LIST if it contains N items or fewer. Return nil if N is zero
+ or less.
+
+ See also: ‘-take’ (*note -take::).
+
+ (-take-last 3 '(1 2 3 4 5))
+ ⇒ (3 4 5)
+ (-take-last 17 '(1 2 3 4 5))
+ ⇒ (1 2 3 4 5)
+ (-take-last 1 '(1 2 3 4 5))
+ ⇒ (5)
+
+ -- Function: -drop (n list)
+ Return the tail (not a copy) of LIST without the first N items.
+ Return nil if LIST contains N items or fewer. Return LIST if N is
+ zero or less.
+
+ For another variant, see also ‘-drop-last’ (*note -drop-last::).
+
+ (-drop 3 '(1 2 3 4 5))
+ ⇒ (4 5)
+ (-drop 17 '(1 2 3 4 5))
+ ⇒ ()
+ (-drop 0 '(1 2 3 4 5))
+ ⇒ (1 2 3 4 5)
+
+ -- Function: -drop-last (n list)
+ Return a copy of LIST without its last N items. Return a copy of
+ LIST if N is zero or less. Return nil if LIST contains N items or
+ fewer.
+
+ See also: ‘-drop’ (*note -drop::).
+
+ (-drop-last 3 '(1 2 3 4 5))
+ ⇒ (1 2)
+ (-drop-last 17 '(1 2 3 4 5))
+ ⇒ ()
+ (-drop-last 0 '(1 2 3 4 5))
+ ⇒ (1 2 3 4 5)
+
+ -- Function: -take-while (pred list)
+ Take successive items from LIST for which PRED returns non-nil.
+ PRED is a function of one argument. Return a new list of the
+ successive elements from the start of LIST for which PRED returns
+ non-nil.
+
+ This function’s anaphoric counterpart is ‘--take-while’.
+
+ For another variant, see also ‘-drop-while’ (*note -drop-while::).
+
+ (-take-while #'even? '(1 2 3 4))
+ ⇒ ()
+ (-take-while #'even? '(2 4 5 6))
+ ⇒ (2 4)
+ (--take-while (< it 4) '(1 2 3 4 3 2 1))
+ ⇒ (1 2 3)
+
+ -- Function: -drop-while (pred list)
+ Drop successive items from LIST for which PRED returns non-nil.
+ PRED is a function of one argument. Return the tail (not a copy)
+ of LIST starting from its first element for which PRED returns nil.
+
+ This function’s anaphoric counterpart is ‘--drop-while’.
+
+ For another variant, see also ‘-take-while’ (*note -take-while::).
+
+ (-drop-while #'even? '(1 2 3 4))
+ ⇒ (1 2 3 4)
+ (-drop-while #'even? '(2 4 5 6))
+ ⇒ (5 6)
+ (--drop-while (< it 4) '(1 2 3 4 3 2 1))
+ ⇒ (4 3 2 1)
+
+ -- Function: -select-by-indices (indices list)
+ Return a list whose elements are elements from LIST selected as
+ ‘(nth i list)‘ for all i from INDICES.
+
+ (-select-by-indices '(4 10 2 3 6) '("v" "e" "l" "o" "c" "i" "r" "a" "p" "t" "o" "r"))
+ ⇒ ("c" "o" "l" "o" "r")
+ (-select-by-indices '(2 1 0) '("a" "b" "c"))
+ ⇒ ("c" "b" "a")
+ (-select-by-indices '(0 1 2 0 1 3 3 1) '("f" "a" "r" "l"))
+ ⇒ ("f" "a" "r" "f" "a" "l" "l" "a")
+
+ -- Function: -select-columns (columns table)
+ Select COLUMNS from TABLE.
+
+ TABLE is a list of lists where each element represents one row. It
+ is assumed each row has the same length.
+
+ Each row is transformed such that only the specified COLUMNS are
+ selected.
+
+ See also: ‘-select-column’ (*note -select-column::),
+ ‘-select-by-indices’ (*note -select-by-indices::)
+
+ (-select-columns '(0 2) '((1 2 3) (a b c) (:a :b :c)))
+ ⇒ ((1 3) (a c) (:a :c))
+ (-select-columns '(1) '((1 2 3) (a b c) (:a :b :c)))
+ ⇒ ((2) (b) (:b))
+ (-select-columns nil '((1 2 3) (a b c) (:a :b :c)))
+ ⇒ (nil nil nil)
+
+ -- Function: -select-column (column table)
+ Select COLUMN from TABLE.
+
+ TABLE is a list of lists where each element represents one row. It
+ is assumed each row has the same length.
+
+ The single selected column is returned as a list.
+
+ See also: ‘-select-columns’ (*note -select-columns::),
+ ‘-select-by-indices’ (*note -select-by-indices::)
+
+ (-select-column 1 '((1 2 3) (a b c) (:a :b :c)))
+ ⇒ (2 b :b)
+
+
+File: dash.info, Node: List to list, Next: Reductions, Prev: Sublist selection, Up: Functions
+
+2.3 List to list
+================
+
+Functions returning a modified copy of the input list.
+
+ -- Function: -keep (fn list)
+ Return a new list of the non-nil results of applying FN to each
+ item in LIST. Like ‘-filter’ (*note -filter::), but returns the
+ non-nil results of FN instead of the corresponding elements of
+ LIST.
+
+ Its anaphoric counterpart is ‘--keep’.
+
+ (-keep #'cdr '((1 2 3) (4 5) (6)))
+ ⇒ ((2 3) (5))
+ (-keep (lambda (n) (and (> n 3) (* 10 n))) '(1 2 3 4 5 6))
+ ⇒ (40 50 60)
+ (--keep (and (> it 3) (* 10 it)) '(1 2 3 4 5 6))
+ ⇒ (40 50 60)
+
+ -- Function: -concat (&rest lists)
+ Return a new list with the concatenation of the elements in the
+ supplied LISTS.
+
+ (-concat '(1))
+ ⇒ (1)
+ (-concat '(1) '(2))
+ ⇒ (1 2)
+ (-concat '(1) '(2 3) '(4))
+ ⇒ (1 2 3 4)
+
+ -- Function: -flatten (l)
+ Take a nested list L and return its contents as a single, flat
+ list.
+
+ Note that because ‘nil’ represents a list of zero elements (an
+ empty list), any mention of nil in L will disappear after
+ flattening. If you need to preserve nils, consider ‘-flatten-n’
+ (*note -flatten-n::) or map them to some unique symbol and then map
+ them back.
+
+ Conses of two atoms are considered "terminals", that is, they
+ aren’t flattened further.
+
+ See also: ‘-flatten-n’ (*note -flatten-n::)
+
+ (-flatten '((1)))
+ ⇒ (1)
+ (-flatten '((1 (2 3) (((4 (5)))))))
+ ⇒ (1 2 3 4 5)
+ (-flatten '(1 2 (3 . 4)))
+ ⇒ (1 2 (3 . 4))
+
+ -- Function: -flatten-n (num list)
+ Flatten NUM levels of a nested LIST.
+
+ See also: ‘-flatten’ (*note -flatten::)
+
+ (-flatten-n 1 '((1 2) ((3 4) ((5 6)))))
+ ⇒ (1 2 (3 4) ((5 6)))
+ (-flatten-n 2 '((1 2) ((3 4) ((5 6)))))
+ ⇒ (1 2 3 4 (5 6))
+ (-flatten-n 3 '((1 2) ((3 4) ((5 6)))))
+ ⇒ (1 2 3 4 5 6)
+
+ -- Function: -replace (old new list)
+ Replace all OLD items in LIST with NEW.
+
+ Elements are compared using ‘equal’.
+
+ See also: ‘-replace-at’ (*note -replace-at::)
+
+ (-replace 1 "1" '(1 2 3 4 3 2 1))
+ ⇒ ("1" 2 3 4 3 2 "1")
+ (-replace "foo" "bar" '("a" "nice" "foo" "sentence" "about" "foo"))
+ ⇒ ("a" "nice" "bar" "sentence" "about" "bar")
+ (-replace 1 2 nil)
+ ⇒ nil
+
+ -- Function: -replace-first (old new list)
+ Replace the first occurrence of OLD with NEW in LIST.
+
+ Elements are compared using ‘equal’.
+
+ See also: ‘-map-first’ (*note -map-first::)
+
+ (-replace-first 1 "1" '(1 2 3 4 3 2 1))
+ ⇒ ("1" 2 3 4 3 2 1)
+ (-replace-first "foo" "bar" '("a" "nice" "foo" "sentence" "about" "foo"))
+ ⇒ ("a" "nice" "bar" "sentence" "about" "foo")
+ (-replace-first 1 2 nil)
+ ⇒ nil
+
+ -- Function: -replace-last (old new list)
+ Replace the last occurrence of OLD with NEW in LIST.
+
+ Elements are compared using ‘equal’.
+
+ See also: ‘-map-last’ (*note -map-last::)
+
+ (-replace-last 1 "1" '(1 2 3 4 3 2 1))
+ ⇒ (1 2 3 4 3 2 "1")
+ (-replace-last "foo" "bar" '("a" "nice" "foo" "sentence" "about" "foo"))
+ ⇒ ("a" "nice" "foo" "sentence" "about" "bar")
+ (-replace-last 1 2 nil)
+ ⇒ nil
+
+ -- Function: -insert-at (n x list)
+ Return a list with X inserted into LIST at position N.
+
+ See also: ‘-splice’ (*note -splice::), ‘-splice-list’ (*note
+ -splice-list::)
+
+ (-insert-at 1 'x '(a b c))
+ ⇒ (a x b c)
+ (-insert-at 12 'x '(a b c))
+ ⇒ (a b c x)
+
+ -- Function: -replace-at (n x list)
+ Return a list with element at Nth position in LIST replaced with X.
+
+ See also: ‘-replace’ (*note -replace::)
+
+ (-replace-at 0 9 '(0 1 2 3 4 5))
+ ⇒ (9 1 2 3 4 5)
+ (-replace-at 1 9 '(0 1 2 3 4 5))
+ ⇒ (0 9 2 3 4 5)
+ (-replace-at 4 9 '(0 1 2 3 4 5))
+ ⇒ (0 1 2 3 9 5)
+
+ -- Function: -update-at (n func list)
+ Return a list with element at Nth position in LIST replaced with
+ ‘(func (nth n list))‘.
+
+ See also: ‘-map-when’ (*note -map-when::)
+
+ (-update-at 0 (lambda (x) (+ x 9)) '(0 1 2 3 4 5))
+ ⇒ (9 1 2 3 4 5)
+ (-update-at 1 (lambda (x) (+ x 8)) '(0 1 2 3 4 5))
+ ⇒ (0 9 2 3 4 5)
+ (--update-at 2 (length it) '("foo" "bar" "baz" "quux"))
+ ⇒ ("foo" "bar" 3 "quux")
+
+ -- Function: -remove-at (n list)
+ Return a list with element at Nth position in LIST removed.
+
+ See also: ‘-remove-at-indices’ (*note -remove-at-indices::),
+ ‘-remove’ (*note -remove::)
+
+ (-remove-at 0 '("0" "1" "2" "3" "4" "5"))
+ ⇒ ("1" "2" "3" "4" "5")
+ (-remove-at 1 '("0" "1" "2" "3" "4" "5"))
+ ⇒ ("0" "2" "3" "4" "5")
+ (-remove-at 2 '("0" "1" "2" "3" "4" "5"))
+ ⇒ ("0" "1" "3" "4" "5")
+
+ -- Function: -remove-at-indices (indices list)
+ Return a list whose elements are elements from LIST without
+ elements selected as ‘(nth i list)‘ for all i from INDICES.
+
+ See also: ‘-remove-at’ (*note -remove-at::), ‘-remove’ (*note
+ -remove::)
+
+ (-remove-at-indices '(0) '("0" "1" "2" "3" "4" "5"))
+ ⇒ ("1" "2" "3" "4" "5")
+ (-remove-at-indices '(0 2 4) '("0" "1" "2" "3" "4" "5"))
+ ⇒ ("1" "3" "5")
+ (-remove-at-indices '(0 5) '("0" "1" "2" "3" "4" "5"))
+ ⇒ ("1" "2" "3" "4")
+
+
+File: dash.info, Node: Reductions, Next: Unfolding, Prev: List to list, Up: Functions
+
+2.4 Reductions
+==============
+
+Functions reducing lists to a single value (which may also be a list).
+
+ -- Function: -reduce-from (fn init list)
+ Reduce the function FN across LIST, starting with INIT. Return the
+ result of applying FN to INIT and the first element of LIST, then
+ applying FN to that result and the second element, etc. If LIST is
+ empty, return INIT without calling FN.
+
+ This function’s anaphoric counterpart is ‘--reduce-from’.
+
+ For other folds, see also ‘-reduce’ (*note -reduce::) and
+ ‘-reduce-r’ (*note -reduce-r::).
+
+ (-reduce-from #'- 10 '(1 2 3))
+ ⇒ 4
+ (-reduce-from #'list 10 '(1 2 3))
+ ⇒ (((10 1) 2) 3)
+ (--reduce-from (concat acc " " it) "START" '("a" "b" "c"))
+ ⇒ "START a b c"
+
+ -- Function: -reduce-r-from (fn init list)
+ Reduce the function FN across LIST in reverse, starting with INIT.
+ Return the result of applying FN to the last element of LIST and
+ INIT, then applying FN to the second-to-last element and the
+ previous result of FN, etc. That is, the first argument of FN is
+ the current element, and its second argument the accumulated value.
+ If LIST is empty, return INIT without calling FN.
+
+ This function is like ‘-reduce-from’ (*note -reduce-from::) but the
+ operation associates from the right rather than left. In other
+ words, it starts from the end of LIST and flips the arguments to
+ FN. Conceptually, it is like replacing the conses in LIST with
+ applications of FN, and its last link with INIT, and evaluating the
+ resulting expression.
+
+ This function’s anaphoric counterpart is ‘--reduce-r-from’.
+
+ For other folds, see also ‘-reduce-r’ (*note -reduce-r::) and
+ ‘-reduce’ (*note -reduce::).
+
+ (-reduce-r-from #'- 10 '(1 2 3))
+ ⇒ -8
+ (-reduce-r-from #'list 10 '(1 2 3))
+ ⇒ (1 (2 (3 10)))
+ (--reduce-r-from (concat it " " acc) "END" '("a" "b" "c"))
+ ⇒ "a b c END"
+
+ -- Function: -reduce (fn list)
+ Reduce the function FN across LIST. Return the result of applying
+ FN to the first two elements of LIST, then applying FN to that
+ result and the third element, etc. If LIST contains a single
+ element, return it without calling FN. If LIST is empty, return
+ the result of calling FN with no arguments.
+
+ This function’s anaphoric counterpart is ‘--reduce’.
+
+ For other folds, see also ‘-reduce-from’ (*note -reduce-from::) and
+ ‘-reduce-r’ (*note -reduce-r::).
+
+ (-reduce #'- '(1 2 3 4))
+ ⇒ -8
+ (-reduce #'list '(1 2 3 4))
+ ⇒ (((1 2) 3) 4)
+ (--reduce (format "%s-%d" acc it) '(1 2 3))
+ ⇒ "1-2-3"
+
+ -- Function: -reduce-r (fn list)
+ Reduce the function FN across LIST in reverse. Return the result
+ of applying FN to the last two elements of LIST, then applying FN
+ to the third-to-last element and the previous result of FN, etc.
+ That is, the first argument of FN is the current element, and its
+ second argument the accumulated value. If LIST contains a single
+ element, return it without calling FN. If LIST is empty, return
+ the result of calling FN with no arguments.
+
+ This function is like ‘-reduce’ (*note -reduce::) but the operation
+ associates from the right rather than left. In other words, it
+ starts from the end of LIST and flips the arguments to FN.
+ Conceptually, it is like replacing the conses in LIST with
+ applications of FN, ignoring its last link, and evaluating the
+ resulting expression.
+
+ This function’s anaphoric counterpart is ‘--reduce-r’.
+
+ For other folds, see also ‘-reduce-r-from’ (*note -reduce-r-from::)
+ and ‘-reduce’ (*note -reduce::).
+
+ (-reduce-r #'- '(1 2 3 4))
+ ⇒ -2
+ (-reduce-r #'list '(1 2 3 4))
+ ⇒ (1 (2 (3 4)))
+ (--reduce-r (format "%s-%d" acc it) '(1 2 3))
+ ⇒ "3-2-1"
+
+ -- Function: -reductions-from (fn init list)
+ Return a list of FN’s intermediate reductions across LIST. That
+ is, a list of the intermediate values of the accumulator when
+ ‘-reduce-from’ (*note -reduce-from::) (which see) is called with
+ the same arguments.
+
+ This function’s anaphoric counterpart is ‘--reductions-from’.
+
+ For other folds, see also ‘-reductions’ (*note -reductions::) and
+ ‘-reductions-r’ (*note -reductions-r::).
+
+ (-reductions-from #'max 0 '(2 1 4 3))
+ ⇒ (0 2 2 4 4)
+ (-reductions-from #'* 1 '(1 2 3 4))
+ ⇒ (1 1 2 6 24)
+ (--reductions-from (format "(FN %s %d)" acc it) "INIT" '(1 2 3))
+ ⇒ ("INIT" "(FN INIT 1)" "(FN (FN INIT 1) 2)" "(FN (FN (FN INIT 1) 2) 3)")
+
+ -- Function: -reductions-r-from (fn init list)
+ Return a list of FN’s intermediate reductions across reversed LIST.
+ That is, a list of the intermediate values of the accumulator when
+ ‘-reduce-r-from’ (*note -reduce-r-from::) (which see) is called
+ with the same arguments.
+
+ This function’s anaphoric counterpart is ‘--reductions-r-from’.
+
+ For other folds, see also ‘-reductions’ (*note -reductions::) and
+ ‘-reductions-r’ (*note -reductions-r::).
+
+ (-reductions-r-from #'max 0 '(2 1 4 3))
+ ⇒ (4 4 4 3 0)
+ (-reductions-r-from #'* 1 '(1 2 3 4))
+ ⇒ (24 24 12 4 1)
+ (--reductions-r-from (format "(FN %d %s)" it acc) "INIT" '(1 2 3))
+ ⇒ ("(FN 1 (FN 2 (FN 3 INIT)))" "(FN 2 (FN 3 INIT))" "(FN 3 INIT)" "INIT")
+
+ -- Function: -reductions (fn list)
+ Return a list of FN’s intermediate reductions across LIST. That
+ is, a list of the intermediate values of the accumulator when
+ ‘-reduce’ (*note -reduce::) (which see) is called with the same
+ arguments.
+
+ This function’s anaphoric counterpart is ‘--reductions’.
+
+ For other folds, see also ‘-reductions’ (*note -reductions::) and
+ ‘-reductions-r’ (*note -reductions-r::).
+
+ (-reductions #'+ '(1 2 3 4))
+ ⇒ (1 3 6 10)
+ (-reductions #'* '(1 2 3 4))
+ ⇒ (1 2 6 24)
+ (--reductions (format "(FN %s %d)" acc it) '(1 2 3))
+ ⇒ (1 "(FN 1 2)" "(FN (FN 1 2) 3)")
+
+ -- Function: -reductions-r (fn list)
+ Return a list of FN’s intermediate reductions across reversed LIST.
+ That is, a list of the intermediate values of the accumulator when
+ ‘-reduce-r’ (*note -reduce-r::) (which see) is called with the same
+ arguments.
+
+ This function’s anaphoric counterpart is ‘--reductions-r’.
+
+ For other folds, see also ‘-reductions-r-from’ (*note
+ -reductions-r-from::) and ‘-reductions’ (*note -reductions::).
+
+ (-reductions-r #'+ '(1 2 3 4))
+ ⇒ (10 9 7 4)
+ (-reductions-r #'* '(1 2 3 4))
+ ⇒ (24 24 12 4)
+ (--reductions-r (format "(FN %d %s)" it acc) '(1 2 3))
+ ⇒ ("(FN 1 (FN 2 3))" "(FN 2 3)" 3)
+
+ -- Function: -count (pred list)
+ Counts the number of items in LIST where (PRED item) is non-nil.
+
+ (-count 'even? '(1 2 3 4 5))
+ ⇒ 2
+ (--count (< it 4) '(1 2 3 4))
+ ⇒ 3
+
+ -- Function: -sum (list)
+ Return the sum of LIST.
+
+ (-sum ())
+ ⇒ 0
+ (-sum '(1))
+ ⇒ 1
+ (-sum '(1 2 3 4))
+ ⇒ 10
+
+ -- Function: -running-sum (list)
+ Return a list with running sums of items in LIST. LIST must be
+ non-empty.
+
+ (-running-sum '(1 2 3 4))
+ ⇒ (1 3 6 10)
+ (-running-sum '(1))
+ ⇒ (1)
+ (-running-sum ())
+ error→ Wrong type argument: consp, nil
+
+ -- Function: -product (list)
+ Return the product of LIST.
+
+ (-product ())
+ ⇒ 1
+ (-product '(1))
+ ⇒ 1
+ (-product '(1 2 3 4))
+ ⇒ 24
+
+ -- Function: -running-product (list)
+ Return a list with running products of items in LIST. LIST must be
+ non-empty.
+
+ (-running-product '(1 2 3 4))
+ ⇒ (1 2 6 24)
+ (-running-product '(1))
+ ⇒ (1)
+ (-running-product ())
+ error→ Wrong type argument: consp, nil
+
+ -- Function: -inits (list)
+ Return all prefixes of LIST.
+
+ (-inits '(1 2 3 4))
+ ⇒ (nil (1) (1 2) (1 2 3) (1 2 3 4))
+ (-inits nil)
+ ⇒ (nil)
+ (-inits '(1))
+ ⇒ (nil (1))
+
+ -- Function: -tails (list)
+ Return all suffixes of LIST
+
+ (-tails '(1 2 3 4))
+ ⇒ ((1 2 3 4) (2 3 4) (3 4) (4) nil)
+ (-tails nil)
+ ⇒ (nil)
+ (-tails '(1))
+ ⇒ ((1) nil)
+
+ -- Function: -common-prefix (&rest lists)
+ Return the longest common prefix of LISTS.
+
+ (-common-prefix '(1))
+ ⇒ (1)
+ (-common-prefix '(1 2) '(3 4) '(1 2))
+ ⇒ ()
+ (-common-prefix '(1 2) '(1 2 3) '(1 2 3 4))
+ ⇒ (1 2)
+
+ -- Function: -common-suffix (&rest lists)
+ Return the longest common suffix of LISTS.
+
+ (-common-suffix '(1))
+ ⇒ (1)
+ (-common-suffix '(1 2) '(3 4) '(1 2))
+ ⇒ ()
+ (-common-suffix '(1 2 3 4) '(2 3 4) '(3 4))
+ ⇒ (3 4)
+
+ -- Function: -min (list)
+ Return the smallest value from LIST of numbers or markers.
+
+ (-min '(0))
+ ⇒ 0
+ (-min '(3 2 1))
+ ⇒ 1
+ (-min '(1 2 3))
+ ⇒ 1
+
+ -- Function: -min-by (comparator list)
+ Take a comparison function COMPARATOR and a LIST and return the
+ least element of the list by the comparison function.
+
+ See also combinator ‘-on’ (*note -on::) which can transform the
+ values before comparing them.
+
+ (-min-by '> '(4 3 6 1))
+ ⇒ 1
+ (--min-by (> (car it) (car other)) '((1 2 3) (2) (3 2)))
+ ⇒ (1 2 3)
+ (--min-by (> (length it) (length other)) '((1 2 3) (2) (3 2)))
+ ⇒ (2)
+
+ -- Function: -max (list)
+ Return the largest value from LIST of numbers or markers.
+
+ (-max '(0))
+ ⇒ 0
+ (-max '(3 2 1))
+ ⇒ 3
+ (-max '(1 2 3))
+ ⇒ 3
+
+ -- Function: -max-by (comparator list)
+ Take a comparison function COMPARATOR and a LIST and return the
+ greatest element of the list by the comparison function.
+
+ See also combinator ‘-on’ (*note -on::) which can transform the
+ values before comparing them.
+
+ (-max-by '> '(4 3 6 1))
+ ⇒ 6
+ (--max-by (> (car it) (car other)) '((1 2 3) (2) (3 2)))
+ ⇒ (3 2)
+ (--max-by (> (length it) (length other)) '((1 2 3) (2) (3 2)))
+ ⇒ (1 2 3)
+
+
+File: dash.info, Node: Unfolding, Next: Predicates, Prev: Reductions, Up: Functions
+
+2.5 Unfolding
+=============
+
+Operations dual to reductions, building lists from a seed value rather
+than consuming a list to produce a single value.
+
+ -- Function: -iterate (fun init n)
+ Return a list of iterated applications of FUN to INIT.
+
+ This means a list of the form:
+
+ (INIT (FUN INIT) (FUN (FUN INIT)) ...)
+
+ N is the length of the returned list.
+
+ (-iterate #'1+ 1 10)
+ ⇒ (1 2 3 4 5 6 7 8 9 10)
+ (-iterate (lambda (x) (+ x x)) 2 5)
+ ⇒ (2 4 8 16 32)
+ (--iterate (* it it) 2 5)
+ ⇒ (2 4 16 256 65536)
+
+ -- Function: -unfold (fun seed)
+ Build a list from SEED using FUN.
+
+ This is "dual" operation to ‘-reduce-r’ (*note -reduce-r::): while
+ -reduce-r consumes a list to produce a single value, ‘-unfold’
+ (*note -unfold::) takes a seed value and builds a (potentially
+ infinite!) list.
+
+ FUN should return ‘nil’ to stop the generating process, or a cons
+ (A . B), where A will be prepended to the result and B is the new
+ seed.
+
+ (-unfold (lambda (x) (unless (= x 0) (cons x (1- x)))) 10)
+ ⇒ (10 9 8 7 6 5 4 3 2 1)
+ (--unfold (when it (cons it (cdr it))) '(1 2 3 4))
+ ⇒ ((1 2 3 4) (2 3 4) (3 4) (4))
+ (--unfold (when it (cons it (butlast it))) '(1 2 3 4))
+ ⇒ ((1 2 3 4) (1 2 3) (1 2) (1))
+
+
+File: dash.info, Node: Predicates, Next: Partitioning, Prev: Unfolding, Up: Functions
+
+2.6 Predicates
+==============
+
+Reductions of one or more lists to a boolean value.
+
+ -- Function: -any? (pred list)
+ Return t if (PRED x) is non-nil for any x in LIST, else nil.
+
+ Alias: ‘-any-p’, ‘-some?’, ‘-some-p’
+
+ (-any? 'even? '(1 2 3))
+ ⇒ t
+ (-any? 'even? '(1 3 5))
+ ⇒ nil
+ (-any? 'null '(1 3 5))
+ ⇒ nil
+
+ -- Function: -all? (pred list)
+ Return t if (PRED x) is non-nil for all x in LIST, else nil.
+
+ Alias: ‘-all-p’, ‘-every?’, ‘-every-p’
+
+ (-all? 'even? '(1 2 3))
+ ⇒ nil
+ (-all? 'even? '(2 4 6))
+ ⇒ t
+ (--all? (= 0 (% it 2)) '(2 4 6))
+ ⇒ t
+
+ -- Function: -none? (pred list)
+ Return t if (PRED x) is nil for all x in LIST, else nil.
+
+ Alias: ‘-none-p’
+
+ (-none? 'even? '(1 2 3))
+ ⇒ nil
+ (-none? 'even? '(1 3 5))
+ ⇒ t
+ (--none? (= 0 (% it 2)) '(1 2 3))
+ ⇒ nil
+
+ -- Function: -only-some? (pred list)
+ Return ‘t‘ if at least one item of LIST matches PRED and at least
+ one item of LIST does not match PRED. Return ‘nil‘ both if all
+ items match the predicate or if none of the items match the
+ predicate.
+
+ Alias: ‘-only-some-p’
+
+ (-only-some? 'even? '(1 2 3))
+ ⇒ t
+ (-only-some? 'even? '(1 3 5))
+ ⇒ nil
+ (-only-some? 'even? '(2 4 6))
+ ⇒ nil
+
+ -- Function: -contains? (list element)
+ Return non-nil if LIST contains ELEMENT.
+
+ The test for equality is done with ‘equal’, or with ‘-compare-fn’
+ if that’s non-nil.
+
+ Alias: ‘-contains-p’
+
+ (-contains? '(1 2 3) 1)
+ ⇒ t
+ (-contains? '(1 2 3) 2)
+ ⇒ t
+ (-contains? '(1 2 3) 4)
+ ⇒ nil
+
+ -- Function: -same-items? (list list2)
+ Return true if LIST and LIST2 has the same items.
+
+ The order of the elements in the lists does not matter.
+
+ Alias: ‘-same-items-p’
+
+ (-same-items? '(1 2 3) '(1 2 3))
+ ⇒ t
+ (-same-items? '(1 2 3) '(3 2 1))
+ ⇒ t
+ (-same-items? '(1 2 3) '(1 2 3 4))
+ ⇒ nil
+
+ -- Function: -is-prefix? (prefix list)
+ Return non-nil if PREFIX is a prefix of LIST.
+
+ Alias: ‘-is-prefix-p’.
+
+ (-is-prefix? '(1 2 3) '(1 2 3 4 5))
+ ⇒ t
+ (-is-prefix? '(1 2 3 4 5) '(1 2 3))
+ ⇒ nil
+ (-is-prefix? '(1 3) '(1 2 3 4 5))
+ ⇒ nil
+
+ -- Function: -is-suffix? (suffix list)
+ Return non-nil if SUFFIX is a suffix of LIST.
+
+ Alias: ‘-is-suffix-p’.
+
+ (-is-suffix? '(3 4 5) '(1 2 3 4 5))
+ ⇒ t
+ (-is-suffix? '(1 2 3 4 5) '(3 4 5))
+ ⇒ nil
+ (-is-suffix? '(3 5) '(1 2 3 4 5))
+ ⇒ nil
+
+ -- Function: -is-infix? (infix list)
+ Return non-nil if INFIX is infix of LIST.
+
+ This operation runs in O(n^2) time
+
+ Alias: ‘-is-infix-p’
+
+ (-is-infix? '(1 2 3) '(1 2 3 4 5))
+ ⇒ t
+ (-is-infix? '(2 3 4) '(1 2 3 4 5))
+ ⇒ t
+ (-is-infix? '(3 4 5) '(1 2 3 4 5))
+ ⇒ t
+
+ -- Function: -cons-pair? (obj)
+ Return non-nil if OBJ is a true cons pair. That is, a cons (A .
+ B) where B is not a list.
+
+ Alias: ‘-cons-pair-p’.
+
+ (-cons-pair? '(1 . 2))
+ ⇒ t
+ (-cons-pair? '(1 2))
+ ⇒ nil
+ (-cons-pair? '(1))
+ ⇒ nil
+
+
+File: dash.info, Node: Partitioning, Next: Indexing, Prev: Predicates, Up: Functions
+
+2.7 Partitioning
+================
+
+Functions partitioning the input list into a list of lists.
+
+ -- Function: -split-at (n list)
+ Split LIST into two sublists after the Nth element. The result is
+ a list of two elements (TAKE DROP) where TAKE is a new list of the
+ first N elements of LIST, and DROP is the remaining elements of
+ LIST (not a copy). TAKE and DROP are like the results of ‘-take’
+ (*note -take::) and ‘-drop’ (*note -drop::), respectively, but the
+ split is done in a single list traversal.
+
+ (-split-at 3 '(1 2 3 4 5))
+ ⇒ ((1 2 3) (4 5))
+ (-split-at 17 '(1 2 3 4 5))
+ ⇒ ((1 2 3 4 5) nil)
+ (-split-at 0 '(1 2 3 4 5))
+ ⇒ (nil (1 2 3 4 5))
+
+ -- Function: -split-with (pred list)
+ Return a list of ((-take-while PRED LIST) (-drop-while PRED LIST)),
+ in no more than one pass through the list.
+
+ (-split-with 'even? '(1 2 3 4))
+ ⇒ (nil (1 2 3 4))
+ (-split-with 'even? '(2 4 5 6))
+ ⇒ ((2 4) (5 6))
+ (--split-with (< it 4) '(1 2 3 4 3 2 1))
+ ⇒ ((1 2 3) (4 3 2 1))
+
+ -- Macro: -split-on (item list)
+ Split the LIST each time ITEM is found.
+
+ Unlike ‘-partition-by’ (*note -partition-by::), the ITEM is
+ discarded from the results. Empty lists are also removed from the
+ result.
+
+ Comparison is done by ‘equal’.
+
+ See also ‘-split-when’ (*note -split-when::)
+
+ (-split-on '| '(Nil | Leaf a | Node [Tree a]))
+ ⇒ ((Nil) (Leaf a) (Node [Tree a]))
+ (-split-on ':endgroup '("a" "b" :endgroup "c" :endgroup "d" "e"))
+ ⇒ (("a" "b") ("c") ("d" "e"))
+ (-split-on ':endgroup '("a" "b" :endgroup :endgroup "d" "e"))
+ ⇒ (("a" "b") ("d" "e"))
+
+ -- Function: -split-when (fn list)
+ Split the LIST on each element where FN returns non-nil.
+
+ Unlike ‘-partition-by’ (*note -partition-by::), the "matched"
+ element is discarded from the results. Empty lists are also
+ removed from the result.
+
+ This function can be thought of as a generalization of
+ ‘split-string’.
+
+ (-split-when 'even? '(1 2 3 4 5 6))
+ ⇒ ((1) (3) (5))
+ (-split-when 'even? '(1 2 3 4 6 8 9))
+ ⇒ ((1) (3) (9))
+ (--split-when (memq it '(&optional &rest)) '(a b &optional c d &rest args))
+ ⇒ ((a b) (c d) (args))
+
+ -- Function: -separate (pred list)
+ Return a list of ((-filter PRED LIST) (-remove PRED LIST)), in one
+ pass through the list.
+
+ (-separate (lambda (num) (= 0 (% num 2))) '(1 2 3 4 5 6 7))
+ ⇒ ((2 4 6) (1 3 5 7))
+ (--separate (< it 5) '(3 7 5 9 3 2 1 4 6))
+ ⇒ ((3 3 2 1 4) (7 5 9 6))
+ (-separate 'cdr '((1 2) (1) (1 2 3) (4)))
+ ⇒ (((1 2) (1 2 3)) ((1) (4)))
+
+ -- Function: -partition (n list)
+ Return a new list with the items in LIST grouped into N-sized
+ sublists. If there are not enough items to make the last group
+ N-sized, those items are discarded.
+
+ (-partition 2 '(1 2 3 4 5 6))
+ ⇒ ((1 2) (3 4) (5 6))
+ (-partition 2 '(1 2 3 4 5 6 7))
+ ⇒ ((1 2) (3 4) (5 6))
+ (-partition 3 '(1 2 3 4 5 6 7))
+ ⇒ ((1 2 3) (4 5 6))
+
+ -- Function: -partition-all (n list)
+ Return a new list with the items in LIST grouped into N-sized
+ sublists. The last group may contain less than N items.
+
+ (-partition-all 2 '(1 2 3 4 5 6))
+ ⇒ ((1 2) (3 4) (5 6))
+ (-partition-all 2 '(1 2 3 4 5 6 7))
+ ⇒ ((1 2) (3 4) (5 6) (7))
+ (-partition-all 3 '(1 2 3 4 5 6 7))
+ ⇒ ((1 2 3) (4 5 6) (7))
+
+ -- Function: -partition-in-steps (n step list)
+ Return a new list with the items in LIST grouped into N-sized
+ sublists at offsets STEP apart. If there are not enough items to
+ make the last group N-sized, those items are discarded.
+
+ (-partition-in-steps 2 1 '(1 2 3 4))
+ ⇒ ((1 2) (2 3) (3 4))
+ (-partition-in-steps 3 2 '(1 2 3 4))
+ ⇒ ((1 2 3))
+ (-partition-in-steps 3 2 '(1 2 3 4 5))
+ ⇒ ((1 2 3) (3 4 5))
+
+ -- Function: -partition-all-in-steps (n step list)
+ Return a new list with the items in LIST grouped into N-sized
+ sublists at offsets STEP apart. The last groups may contain less
+ than N items.
+
+ (-partition-all-in-steps 2 1 '(1 2 3 4))
+ ⇒ ((1 2) (2 3) (3 4) (4))
+ (-partition-all-in-steps 3 2 '(1 2 3 4))
+ ⇒ ((1 2 3) (3 4))
+ (-partition-all-in-steps 3 2 '(1 2 3 4 5))
+ ⇒ ((1 2 3) (3 4 5) (5))
+
+ -- Function: -partition-by (fn list)
+ Apply FN to each item in LIST, splitting it each time FN returns a
+ new value.
+
+ (-partition-by 'even? ())
+ ⇒ ()
+ (-partition-by 'even? '(1 1 2 2 2 3 4 6 8))
+ ⇒ ((1 1) (2 2 2) (3) (4 6 8))
+ (--partition-by (< it 3) '(1 2 3 4 3 2 1))
+ ⇒ ((1 2) (3 4 3) (2 1))
+
+ -- Function: -partition-by-header (fn list)
+ Apply FN to the first item in LIST. That is the header value.
+ Apply FN to each item in LIST, splitting it each time FN returns
+ the header value, but only after seeing at least one other value
+ (the body).
+
+ (--partition-by-header (= it 1) '(1 2 3 1 2 1 2 3 4))
+ ⇒ ((1 2 3) (1 2) (1 2 3 4))
+ (--partition-by-header (> it 0) '(1 2 0 1 0 1 2 3 0))
+ ⇒ ((1 2 0) (1 0) (1 2 3 0))
+ (-partition-by-header 'even? '(2 1 1 1 4 1 3 5 6 6 1))
+ ⇒ ((2 1 1 1) (4 1 3 5) (6 6 1))
+
+ -- Function: -partition-after-pred (pred list)
+ Partition directly after each time PRED is true on an element of
+ LIST.
+
+ (-partition-after-pred #'booleanp ())
+ ⇒ ()
+ (-partition-after-pred #'booleanp '(t t))
+ ⇒ ((t) (t))
+ (-partition-after-pred #'booleanp '(0 0 t t 0 t))
+ ⇒ ((0 0 t) (t) (0 t))
+
+ -- Function: -partition-before-pred (pred list)
+ Partition directly before each time PRED is true on an element of
+ LIST.
+
+ (-partition-before-pred #'booleanp ())
+ ⇒ ()
+ (-partition-before-pred #'booleanp '(0 t))
+ ⇒ ((0) (t))
+ (-partition-before-pred #'booleanp '(0 0 t 0 t t))
+ ⇒ ((0 0) (t 0) (t) (t))
+
+ -- Function: -partition-before-item (item list)
+ Partition directly before each time ITEM appears in LIST.
+
+ (-partition-before-item 3 ())
+ ⇒ ()
+ (-partition-before-item 3 '(1))
+ ⇒ ((1))
+ (-partition-before-item 3 '(3))
+ ⇒ ((3))
+
+ -- Function: -partition-after-item (item list)
+ Partition directly after each time ITEM appears in LIST.
+
+ (-partition-after-item 3 ())
+ ⇒ ()
+ (-partition-after-item 3 '(1))
+ ⇒ ((1))
+ (-partition-after-item 3 '(3))
+ ⇒ ((3))
+
+ -- Function: -group-by (fn list)
+ Separate LIST into an alist whose keys are FN applied to the
+ elements of LIST. Keys are compared by ‘equal’.
+
+ (-group-by 'even? ())
+ ⇒ ()
+ (-group-by 'even? '(1 1 2 2 2 3 4 6 8))
+ ⇒ ((nil 1 1 3) (t 2 2 2 4 6 8))
+ (--group-by (car (split-string it "/")) '("a/b" "c/d" "a/e"))
+ ⇒ (("a" "a/b" "a/e") ("c" "c/d"))
+
+
+File: dash.info, Node: Indexing, Next: Set operations, Prev: Partitioning, Up: Functions
+
+2.8 Indexing
+============
+
+Functions retrieving or sorting based on list indices and related
+predicates.
+
+ -- Function: -elem-index (elem list)
+ Return the index of the first element in the given LIST which is
+ equal to the query element ELEM, or nil if there is no such
+ element.
+
+ (-elem-index 2 '(6 7 8 2 3 4))
+ ⇒ 3
+ (-elem-index "bar" '("foo" "bar" "baz"))
+ ⇒ 1
+ (-elem-index '(1 2) '((3) (5 6) (1 2) nil))
+ ⇒ 2
+
+ -- Function: -elem-indices (elem list)
+ Return the indices of all elements in LIST equal to the query
+ element ELEM, in ascending order.
+
+ (-elem-indices 2 '(6 7 8 2 3 4 2 1))
+ ⇒ (3 6)
+ (-elem-indices "bar" '("foo" "bar" "baz"))
+ ⇒ (1)
+ (-elem-indices '(1 2) '((3) (1 2) (5 6) (1 2) nil))
+ ⇒ (1 3)
+
+ -- Function: -find-index (pred list)
+ Take a predicate PRED and a LIST and return the index of the first
+ element in the list satisfying the predicate, or nil if there is no
+ such element.
+
+ See also ‘-first’ (*note -first::).
+
+ (-find-index 'even? '(2 4 1 6 3 3 5 8))
+ ⇒ 0
+ (--find-index (< 5 it) '(2 4 1 6 3 3 5 8))
+ ⇒ 3
+ (-find-index (-partial 'string-lessp "baz") '("bar" "foo" "baz"))
+ ⇒ 1
+
+ -- Function: -find-last-index (pred list)
+ Take a predicate PRED and a LIST and return the index of the last
+ element in the list satisfying the predicate, or nil if there is no
+ such element.
+
+ See also ‘-last’ (*note -last::).
+
+ (-find-last-index 'even? '(2 4 1 6 3 3 5 8))
+ ⇒ 7
+ (--find-last-index (< 5 it) '(2 7 1 6 3 8 5 2))
+ ⇒ 5
+ (-find-last-index (-partial 'string-lessp "baz") '("q" "foo" "baz"))
+ ⇒ 1
+
+ -- Function: -find-indices (pred list)
+ Return the indices of all elements in LIST satisfying the predicate
+ PRED, in ascending order.
+
+ (-find-indices 'even? '(2 4 1 6 3 3 5 8))
+ ⇒ (0 1 3 7)
+ (--find-indices (< 5 it) '(2 4 1 6 3 3 5 8))
+ ⇒ (3 7)
+ (-find-indices (-partial 'string-lessp "baz") '("bar" "foo" "baz"))
+ ⇒ (1)
+
+ -- Function: -grade-up (comparator list)
+ Grade elements of LIST using COMPARATOR relation. This yields a
+ permutation vector such that applying this permutation to LIST
+ sorts it in ascending order.
+
+ (-grade-up #'< '(3 1 4 2 1 3 3))
+ ⇒ (1 4 3 0 5 6 2)
+ (let ((l '(3 1 4 2 1 3 3))) (-select-by-indices (-grade-up #'< l) l))
+ ⇒ (1 1 2 3 3 3 4)
+
+ -- Function: -grade-down (comparator list)
+ Grade elements of LIST using COMPARATOR relation. This yields a
+ permutation vector such that applying this permutation to LIST
+ sorts it in descending order.
+
+ (-grade-down #'< '(3 1 4 2 1 3 3))
+ ⇒ (2 0 5 6 3 1 4)
+ (let ((l '(3 1 4 2 1 3 3))) (-select-by-indices (-grade-down #'< l) l))
+ ⇒ (4 3 3 3 2 1 1)
+
+
+File: dash.info, Node: Set operations, Next: Other list operations, Prev: Indexing, Up: Functions
+
+2.9 Set operations
+==================
+
+Operations pretending lists are sets.
+
+ -- Function: -union (list list2)
+ Return a new list containing the elements of LIST and elements of
+ LIST2 that are not in LIST. The test for equality is done with
+ ‘equal’, or with ‘-compare-fn’ if that’s non-nil.
+
+ (-union '(1 2 3) '(3 4 5))
+ ⇒ (1 2 3 4 5)
+ (-union '(1 2 3 4) ())
+ ⇒ (1 2 3 4)
+ (-union '(1 1 2 2) '(3 2 1))
+ ⇒ (1 1 2 2 3)
+
+ -- Function: -difference (list list2)
+ Return a new list with only the members of LIST that are not in
+ LIST2. The test for equality is done with ‘equal’, or with
+ ‘-compare-fn’ if that’s non-nil.
+
+ (-difference () ())
+ ⇒ ()
+ (-difference '(1 2 3) '(4 5 6))
+ ⇒ (1 2 3)
+ (-difference '(1 2 3 4) '(3 4 5 6))
+ ⇒ (1 2)
+
+ -- Function: -intersection (list list2)
+ Return a new list containing only the elements that are members of
+ both LIST and LIST2. The test for equality is done with ‘equal’,
+ or with ‘-compare-fn’ if that’s non-nil.
+
+ (-intersection () ())
+ ⇒ ()
+ (-intersection '(1 2 3) '(4 5 6))
+ ⇒ ()
+ (-intersection '(1 2 3 4) '(3 4 5 6))
+ ⇒ (3 4)
+
+ -- Function: -powerset (list)
+ Return the power set of LIST.
+
+ (-powerset ())
+ ⇒ (nil)
+ (-powerset '(x y z))
+ ⇒ ((x y z) (x y) (x z) (x) (y z) (y) (z) nil)
+
+ -- Function: -permutations (list)
+ Return the permutations of LIST.
+
+ (-permutations ())
+ ⇒ (nil)
+ (-permutations '(1 2))
+ ⇒ ((1 2) (2 1))
+ (-permutations '(a b c))
+ ⇒ ((a b c) (a c b) (b a c) (b c a) (c a b) (c b a))
+
+ -- Function: -distinct (list)
+ Return a new list with all duplicates removed. The test for
+ equality is done with ‘equal’, or with ‘-compare-fn’ if that’s
+ non-nil.
+
+ Alias: ‘-uniq’
+
+ (-distinct ())
+ ⇒ ()
+ (-distinct '(1 2 2 4))
+ ⇒ (1 2 4)
+ (-distinct '(t t t))
+ ⇒ (t)
+
+
+File: dash.info, Node: Other list operations, Next: Tree operations, Prev: Set operations, Up: Functions
+
+2.10 Other list operations
+==========================
+
+Other list functions not fit to be classified elsewhere.
+
+ -- Function: -rotate (n list)
+ Rotate LIST N places to the right. With N negative, rotate to the
+ left. The time complexity is O(n).
+
+ (-rotate 3 '(1 2 3 4 5 6 7))
+ ⇒ (5 6 7 1 2 3 4)
+ (-rotate -3 '(1 2 3 4 5 6 7))
+ ⇒ (4 5 6 7 1 2 3)
+ (-rotate 16 '(1 2 3 4 5 6 7))
+ ⇒ (6 7 1 2 3 4 5)
+
+ -- Function: -repeat (n x)
+ Return a new list of length N with each element being X. Return
+ nil if N is less than 1.
+
+ (-repeat 3 :a)
+ ⇒ (:a :a :a)
+ (-repeat 1 :a)
+ ⇒ (:a)
+ (-repeat 0 :a)
+ ⇒ nil
+
+ -- Function: -cons* (&rest args)
+ Make a new list from the elements of ARGS. The last 2 elements of
+ ARGS are used as the final cons of the result, so if the final
+ element of ARGS is not a list, the result is a dotted list. With
+ no ARGS, return nil.
+
+ (-cons* 1 2)
+ ⇒ (1 . 2)
+ (-cons* 1 2 3)
+ ⇒ (1 2 . 3)
+ (-cons* 1)
+ ⇒ 1
+
+ -- Function: -snoc (list elem &rest elements)
+ Append ELEM to the end of the list.
+
+ This is like ‘cons’, but operates on the end of list.
+
+ If ELEMENTS is non nil, append these to the list as well.
+
+ (-snoc '(1 2 3) 4)
+ ⇒ (1 2 3 4)
+ (-snoc '(1 2 3) 4 5 6)
+ ⇒ (1 2 3 4 5 6)
+ (-snoc '(1 2 3) '(4 5 6))
+ ⇒ (1 2 3 (4 5 6))
+
+ -- Function: -interpose (sep list)
+ Return a new list of all elements in LIST separated by SEP.
+
+ (-interpose "-" ())
+ ⇒ ()
+ (-interpose "-" '("a"))
+ ⇒ ("a")
+ (-interpose "-" '("a" "b" "c"))
+ ⇒ ("a" "-" "b" "-" "c")
+
+ -- Function: -interleave (&rest lists)
+ Return a new list of the first item in each list, then the second
+ etc.
+
+ (-interleave '(1 2) '("a" "b"))
+ ⇒ (1 "a" 2 "b")
+ (-interleave '(1 2) '("a" "b") '("A" "B"))
+ ⇒ (1 "a" "A" 2 "b" "B")
+ (-interleave '(1 2 3) '("a" "b"))
+ ⇒ (1 "a" 2 "b")
+
+ -- Function: -iota (count &optional start step)
+ Return a list containing COUNT numbers. Starts from START and adds
+ STEP each time. The default START is zero, the default STEP is 1.
+ This function takes its name from the corresponding primitive in
+ the APL language.
+
+ (-iota 6)
+ ⇒ (0 1 2 3 4 5)
+ (-iota 4 2.5 -2)
+ ⇒ (2.5 0.5 -1.5 -3.5)
+ (-iota -1)
+ error→ Wrong type argument: natnump, -1
+
+ -- Function: -zip-with (fn list1 list2)
+ Zip the two lists LIST1 and LIST2 using a function FN. This
+ function is applied pairwise taking as first argument element of
+ LIST1 and as second argument element of LIST2 at corresponding
+ position.
+
+ The anaphoric form ‘--zip-with’ binds the elements from LIST1 as
+ symbol ‘it’, and the elements from LIST2 as symbol ‘other’.
+
+ (-zip-with '+ '(1 2 3) '(4 5 6))
+ ⇒ (5 7 9)
+ (-zip-with 'cons '(1 2 3) '(4 5 6))
+ ⇒ ((1 . 4) (2 . 5) (3 . 6))
+ (--zip-with (concat it " and " other) '("Batman" "Jekyll") '("Robin" "Hyde"))
+ ⇒ ("Batman and Robin" "Jekyll and Hyde")
+
+ -- Function: -zip (&rest lists)
+ Zip LISTS together. Group the head of each list, followed by the
+ second elements of each list, and so on. The lengths of the
+ returned groupings are equal to the length of the shortest input
+ list.
+
+ If two lists are provided as arguments, return the groupings as a
+ list of cons cells. Otherwise, return the groupings as a list of
+ lists.
+
+ Use ‘-zip-lists’ (*note -zip-lists::) if you need the return value
+ to always be a list of lists.
+
+ Alias: ‘-zip-pair’
+
+ See also: ‘-zip-lists’ (*note -zip-lists::)
+
+ (-zip '(1 2 3) '(4 5 6))
+ ⇒ ((1 . 4) (2 . 5) (3 . 6))
+ (-zip '(1 2 3) '(4 5 6 7))
+ ⇒ ((1 . 4) (2 . 5) (3 . 6))
+ (-zip '(1 2) '(3 4 5) '(6))
+ ⇒ ((1 3 6))
+
+ -- Function: -zip-lists (&rest lists)
+ Zip LISTS together. Group the head of each list, followed by the
+ second elements of each list, and so on. The lengths of the
+ returned groupings are equal to the length of the shortest input
+ list.
+
+ The return value is always list of lists, which is a difference
+ from ‘-zip-pair’ which returns a cons-cell in case two input lists
+ are provided.
+
+ See also: ‘-zip’ (*note -zip::)
+
+ (-zip-lists '(1 2 3) '(4 5 6))
+ ⇒ ((1 4) (2 5) (3 6))
+ (-zip-lists '(1 2 3) '(4 5 6 7))
+ ⇒ ((1 4) (2 5) (3 6))
+ (-zip-lists '(1 2) '(3 4 5) '(6))
+ ⇒ ((1 3 6))
+
+ -- Function: -zip-fill (fill-value &rest lists)
+ Zip LISTS, with FILL-VALUE padded onto the shorter lists. The
+ lengths of the returned groupings are equal to the length of the
+ longest input list.
+
+ (-zip-fill 0 '(1 2 3 4 5) '(6 7 8 9))
+ ⇒ ((1 . 6) (2 . 7) (3 . 8) (4 . 9) (5 . 0))
+
+ -- Function: -unzip (lists)
+ Unzip LISTS.
+
+ This works just like ‘-zip’ (*note -zip::) but takes a list of
+ lists instead of a variable number of arguments, such that
+
+ (-unzip (-zip L1 L2 L3 ...))
+
+ is identity (given that the lists are the same length).
+
+ Note in particular that calling this on a list of two lists will
+ return a list of cons-cells such that the above identity works.
+
+ See also: ‘-zip’ (*note -zip::)
+
+ (-unzip (-zip '(1 2 3) '(a b c) '("e" "f" "g")))
+ ⇒ ((1 2 3) (a b c) ("e" "f" "g"))
+ (-unzip '((1 2) (3 4) (5 6) (7 8) (9 10)))
+ ⇒ ((1 3 5 7 9) (2 4 6 8 10))
+ (-unzip '((1 2) (3 4)))
+ ⇒ ((1 . 3) (2 . 4))
+
+ -- Function: -cycle (list)
+ Return an infinite circular copy of LIST. The returned list cycles
+ through the elements of LIST and repeats from the beginning.
+
+ (-take 5 (-cycle '(1 2 3)))
+ ⇒ (1 2 3 1 2)
+ (-take 7 (-cycle '(1 "and" 3)))
+ ⇒ (1 "and" 3 1 "and" 3 1)
+ (-zip (-cycle '(1 2 3)) '(1 2))
+ ⇒ ((1 . 1) (2 . 2))
+
+ -- Function: -pad (fill-value &rest lists)
+ Appends FILL-VALUE to the end of each list in LISTS such that they
+ will all have the same length.
+
+ (-pad 0 ())
+ ⇒ (nil)
+ (-pad 0 '(1))
+ ⇒ ((1))
+ (-pad 0 '(1 2 3) '(4 5))
+ ⇒ ((1 2 3) (4 5 0))
+
+ -- Function: -table (fn &rest lists)
+ Compute outer product of LISTS using function FN.
+
+ The function FN should have the same arity as the number of
+ supplied lists.
+
+ The outer product is computed by applying fn to all possible
+ combinations created by taking one element from each list in order.
+ The dimension of the result is (length lists).
+
+ See also: ‘-table-flat’ (*note -table-flat::)
+
+ (-table '* '(1 2 3) '(1 2 3))
+ ⇒ ((1 2 3) (2 4 6) (3 6 9))
+ (-table (lambda (a b) (-sum (-zip-with '* a b))) '((1 2) (3 4)) '((1 3) (2 4)))
+ ⇒ ((7 15) (10 22))
+ (apply '-table 'list (-repeat 3 '(1 2)))
+ ⇒ ((((1 1 1) (2 1 1)) ((1 2 1) (2 2 1))) (((1 1 2) (2 1 2)) ((1 2 2) (2 2 2))))
+
+ -- Function: -table-flat (fn &rest lists)
+ Compute flat outer product of LISTS using function FN.
+
+ The function FN should have the same arity as the number of
+ supplied lists.
+
+ The outer product is computed by applying fn to all possible
+ combinations created by taking one element from each list in order.
+ The results are flattened, ignoring the tensor structure of the
+ result. This is equivalent to calling:
+
+ (-flatten-n (1- (length lists)) (apply ’-table fn lists))
+
+ but the implementation here is much more efficient.
+
+ See also: ‘-flatten-n’ (*note -flatten-n::), ‘-table’ (*note
+ -table::)
+
+ (-table-flat 'list '(1 2 3) '(a b c))
+ ⇒ ((1 a) (2 a) (3 a) (1 b) (2 b) (3 b) (1 c) (2 c) (3 c))
+ (-table-flat '* '(1 2 3) '(1 2 3))
+ ⇒ (1 2 3 2 4 6 3 6 9)
+ (apply '-table-flat 'list (-repeat 3 '(1 2)))
+ ⇒ ((1 1 1) (2 1 1) (1 2 1) (2 2 1) (1 1 2) (2 1 2) (1 2 2) (2 2 2))
+
+ -- Function: -first (pred list)
+ Return the first item in LIST for which PRED returns non-nil.
+ Return nil if no such element is found. To get the first item in
+ the list no questions asked, use ‘car’.
+
+ Alias: ‘-find’.
+
+ This function’s anaphoric counterpart is ‘--first’.
+
+ (-first #'natnump '(-1 0 1))
+ ⇒ 0
+ (-first #'null '(1 2 3))
+ ⇒ nil
+ (--first (> it 2) '(1 2 3))
+ ⇒ 3
+
+ -- Function: -some (pred list)
+ Return (PRED x) for the first LIST item where (PRED x) is non-nil,
+ else nil.
+
+ Alias: ‘-any’.
+
+ This function’s anaphoric counterpart is ‘--some’.
+
+ (-some (lambda (s) (string-match-p "x" s)) '("foo" "axe" "xor"))
+ ⇒ 1
+ (-some (lambda (s) (string-match-p "x" s)) '("foo" "bar" "baz"))
+ ⇒ nil
+ (--some (member 'foo it) '((foo bar) (baz)))
+ ⇒ (foo bar)
+
+ -- Function: -last (pred list)
+ Return the last x in LIST where (PRED x) is non-nil, else nil.
+
+ (-last 'even? '(1 2 3 4 5 6 3 3 3))
+ ⇒ 6
+ (-last 'even? '(1 3 7 5 9))
+ ⇒ nil
+ (--last (> (length it) 3) '("a" "looong" "word" "and" "short" "one"))
+ ⇒ "short"
+
+ -- Function: -first-item (list)
+ Return the first item of LIST, or nil on an empty list.
+
+ See also: ‘-second-item’ (*note -second-item::), ‘-last-item’
+ (*note -last-item::).
+
+ (-first-item '(1 2 3))
+ ⇒ 1
+ (-first-item nil)
+ ⇒ nil
+ (let ((list (list 1 2 3))) (setf (-first-item list) 5) list)
+ ⇒ (5 2 3)
+
+ -- Function: -second-item (list)
+ Return the second item of LIST, or nil if LIST is too short.
+
+ See also: ‘-third-item’ (*note -third-item::).
+
+ (-second-item '(1 2 3))
+ ⇒ 2
+ (-second-item nil)
+ ⇒ nil
+
+ -- Function: -third-item (list)
+ Return the third item of LIST, or nil if LIST is too short.
+
+ See also: ‘-fourth-item’ (*note -fourth-item::).
+
+ (-third-item '(1 2 3))
+ ⇒ 3
+ (-third-item nil)
+ ⇒ nil
+
+ -- Function: -fourth-item (list)
+ Return the fourth item of LIST, or nil if LIST is too short.
+
+ See also: ‘-fifth-item’ (*note -fifth-item::).
+
+ (-fourth-item '(1 2 3 4))
+ ⇒ 4
+ (-fourth-item nil)
+ ⇒ nil
+
+ -- Function: -fifth-item (list)
+ Return the fifth item of LIST, or nil if LIST is too short.
+
+ See also: ‘-last-item’ (*note -last-item::).
+
+ (-fifth-item '(1 2 3 4 5))
+ ⇒ 5
+ (-fifth-item nil)
+ ⇒ nil
+
+ -- Function: -last-item (list)
+ Return the last item of LIST, or nil on an empty list.
+
+ (-last-item '(1 2 3))
+ ⇒ 3
+ (-last-item nil)
+ ⇒ nil
+ (let ((list (list 1 2 3))) (setf (-last-item list) 5) list)
+ ⇒ (1 2 5)
+
+ -- Function: -butlast (list)
+ Return a list of all items in list except for the last.
+
+ (-butlast '(1 2 3))
+ ⇒ (1 2)
+ (-butlast '(1 2))
+ ⇒ (1)
+ (-butlast '(1))
+ ⇒ nil
+
+ -- Function: -sort (comparator list)
+ Sort LIST, stably, comparing elements using COMPARATOR. Return the
+ sorted list. LIST is NOT modified by side effects. COMPARATOR is
+ called with two elements of LIST, and should return non-nil if the
+ first element should sort before the second.
+
+ (-sort '< '(3 1 2))
+ ⇒ (1 2 3)
+ (-sort '> '(3 1 2))
+ ⇒ (3 2 1)
+ (--sort (< it other) '(3 1 2))
+ ⇒ (1 2 3)
+
+ -- Function: -list (arg)
+ Ensure ARG is a list. If ARG is already a list, return it as is
+ (not a copy). Otherwise, return a new list with ARG as its only
+ element.
+
+ Another supported calling convention is (-list &rest ARGS). In
+ this case, if ARG is not a list, a new list with all of ARGS as
+ elements is returned. This use is supported for backward
+ compatibility and is otherwise deprecated.
+
+ (-list 1)
+ ⇒ (1)
+ (-list ())
+ ⇒ ()
+ (-list '(1 2 3))
+ ⇒ (1 2 3)
+
+ -- Function: -fix (fn list)
+ Compute the (least) fixpoint of FN with initial input LIST.
+
+ FN is called at least once, results are compared with ‘equal’.
+
+ (-fix (lambda (l) (-non-nil (--mapcat (-split-at (/ (length it) 2) it) l))) '((1 2 3)))
+ ⇒ ((1) (2) (3))
+ (let ((l '((starwars scifi) (jedi starwars warrior)))) (--fix (-uniq (--mapcat (cons it (cdr (assq it l))) it)) '(jedi book)))
+ ⇒ (jedi starwars warrior scifi book)
+
+
+File: dash.info, Node: Tree operations, Next: Threading macros, Prev: Other list operations, Up: Functions
+
+2.11 Tree operations
+====================
+
+Functions pretending lists are trees.
+
+ -- Function: -tree-seq (branch children tree)
+ Return a sequence of the nodes in TREE, in depth-first search
+ order.
+
+ BRANCH is a predicate of one argument that returns non-nil if the
+ passed argument is a branch, that is, a node that can have
+ children.
+
+ CHILDREN is a function of one argument that returns the children of
+ the passed branch node.
+
+ Non-branch nodes are simply copied.
+
+ (-tree-seq 'listp 'identity '(1 (2 3) 4 (5 (6 7))))
+ ⇒ ((1 (2 3) 4 (5 (6 7))) 1 (2 3) 2 3 4 (5 (6 7)) 5 (6 7) 6 7)
+ (-tree-seq 'listp 'reverse '(1 (2 3) 4 (5 (6 7))))
+ ⇒ ((1 (2 3) 4 (5 (6 7))) (5 (6 7)) (6 7) 7 6 5 4 (2 3) 3 2 1)
+ (--tree-seq (vectorp it) (append it nil) [1 [2 3] 4 [5 [6 7]]])
+ ⇒ ([1 [2 3] 4 [5 [6 7]]] 1 [2 3] 2 3 4 [5 [6 7]] 5 [6 7] 6 7)
+
+ -- Function: -tree-map (fn tree)
+ Apply FN to each element of TREE while preserving the tree
+ structure.
+
+ (-tree-map '1+ '(1 (2 3) (4 (5 6) 7)))
+ ⇒ (2 (3 4) (5 (6 7) 8))
+ (-tree-map '(lambda (x) (cons x (expt 2 x))) '(1 (2 3) 4))
+ ⇒ ((1 . 2) ((2 . 4) (3 . 8)) (4 . 16))
+ (--tree-map (length it) '("" ("" "text" "
") ""))
+ ⇒ (6 (3 4 4) 7)
+
+ -- Function: -tree-map-nodes (pred fun tree)
+ Call FUN on each node of TREE that satisfies PRED.
+
+ If PRED returns nil, continue descending down this node. If PRED
+ returns non-nil, apply FUN to this node and do not descend further.
+
+ (-tree-map-nodes 'vectorp (lambda (x) (-sum (append x nil))) '(1 [2 3] 4 (5 [6 7] 8)))
+ ⇒ (1 5 4 (5 13 8))
+ (-tree-map-nodes 'keywordp (lambda (x) (symbol-name x)) '(1 :foo 4 ((5 6 :bar) :baz 8)))
+ ⇒ (1 ":foo" 4 ((5 6 ":bar") ":baz" 8))
+ (--tree-map-nodes (eq (car-safe it) 'add-mode) (-concat it (list :mode 'emacs-lisp-mode)) '(with-mode emacs-lisp-mode (foo bar) (add-mode a b) (baz (add-mode c d))))
+ ⇒ (with-mode emacs-lisp-mode (foo bar) (add-mode a b :mode emacs-lisp-mode) (baz (add-mode c d :mode emacs-lisp-mode)))
+
+ -- Function: -tree-reduce (fn tree)
+ Use FN to reduce elements of list TREE. If elements of TREE are
+ lists themselves, apply the reduction recursively.
+
+ FN is first applied to first element of the list and second
+ element, then on this result and third element from the list etc.
+
+ See ‘-reduce-r’ (*note -reduce-r::) for how exactly are lists of
+ zero or one element handled.
+
+ (-tree-reduce '+ '(1 (2 3) (4 5)))
+ ⇒ 15
+ (-tree-reduce 'concat '("strings" (" on" " various") ((" levels"))))
+ ⇒ "strings on various levels"
+ (--tree-reduce (cond ((stringp it) (concat it " " acc)) (t (let ((sn (symbol-name it))) (concat "<" sn ">" acc "" sn ">")))) '(body (p "some words") (div "more" (b "bold") "words")))
+ ⇒ "some words
more bold words
"
+
+ -- Function: -tree-reduce-from (fn init-value tree)
+ Use FN to reduce elements of list TREE. If elements of TREE are
+ lists themselves, apply the reduction recursively.
+
+ FN is first applied to INIT-VALUE and first element of the list,
+ then on this result and second element from the list etc.
+
+ The initial value is ignored on cons pairs as they always contain
+ two elements.
+
+ (-tree-reduce-from '+ 1 '(1 (1 1) ((1))))
+ ⇒ 8
+ (--tree-reduce-from (-concat acc (list it)) nil '(1 (2 3 (4 5)) (6 7)))
+ ⇒ ((7 6) ((5 4) 3 2) 1)
+
+ -- Function: -tree-mapreduce (fn folder tree)
+ Apply FN to each element of TREE, and make a list of the results.
+ If elements of TREE are lists themselves, apply FN recursively to
+ elements of these nested lists.
+
+ Then reduce the resulting lists using FOLDER and initial value
+ INIT-VALUE. See ‘-reduce-r-from’ (*note -reduce-r-from::).
+
+ This is the same as calling ‘-tree-reduce’ (*note -tree-reduce::)
+ after ‘-tree-map’ (*note -tree-map::) but is twice as fast as it
+ only traverse the structure once.
+
+ (-tree-mapreduce 'list 'append '(1 (2 (3 4) (5 6)) (7 (8 9))))
+ ⇒ (1 2 3 4 5 6 7 8 9)
+ (--tree-mapreduce 1 (+ it acc) '(1 (2 (4 9) (2 1)) (7 (4 3))))
+ ⇒ 9
+ (--tree-mapreduce 0 (max acc (1+ it)) '(1 (2 (4 9) (2 1)) (7 (4 3))))
+ ⇒ 3
+
+ -- Function: -tree-mapreduce-from (fn folder init-value tree)
+ Apply FN to each element of TREE, and make a list of the results.
+ If elements of TREE are lists themselves, apply FN recursively to
+ elements of these nested lists.
+
+ Then reduce the resulting lists using FOLDER and initial value
+ INIT-VALUE. See ‘-reduce-r-from’ (*note -reduce-r-from::).
+
+ This is the same as calling ‘-tree-reduce-from’ (*note
+ -tree-reduce-from::) after ‘-tree-map’ (*note -tree-map::) but is
+ twice as fast as it only traverse the structure once.
+
+ (-tree-mapreduce-from 'identity '* 1 '(1 (2 (3 4) (5 6)) (7 (8 9))))
+ ⇒ 362880
+ (--tree-mapreduce-from (+ it it) (cons it acc) nil '(1 (2 (4 9) (2 1)) (7 (4 3))))
+ ⇒ (2 (4 (8 18) (4 2)) (14 (8 6)))
+ (concat "{" (--tree-mapreduce-from (cond ((-cons-pair? it) (concat (symbol-name (car it)) " -> " (symbol-name (cdr it)))) (t (concat (symbol-name it) " : {"))) (concat it (unless (or (equal acc "}") (equal (substring it (1- (length it))) "{")) ", ") acc) "}" '((elisp-mode (foo (bar . booze)) (baz . qux)) (c-mode (foo . bla) (bum . bam)))))
+ ⇒ "{elisp-mode : {foo : {bar -> booze}, baz -> qux}, c-mode : {foo -> bla, bum -> bam}}"
+
+ -- Function: -clone (list)
+ Create a deep copy of LIST. The new list has the same elements and
+ structure but all cons are replaced with new ones. This is useful
+ when you need to clone a structure such as plist or alist.
+
+ (let* ((a '(1 2 3)) (b (-clone a))) (nreverse a) b)
+ ⇒ (1 2 3)
+
+
+File: dash.info, Node: Threading macros, Next: Binding, Prev: Tree operations, Up: Functions
+
+2.12 Threading macros
+=====================
+
+Macros that conditionally combine sequential forms for brevity or
+readability.
+
+ -- Macro: -> (x &optional form &rest more)
+ Thread the expr through the forms. Insert X as the second item in
+ the first form, making a list of it if it is not a list already.
+ If there are more forms, insert the first form as the second item
+ in second form, etc.
+
+ (-> '(2 3 5))
+ ⇒ (2 3 5)
+ (-> '(2 3 5) (append '(8 13)))
+ ⇒ (2 3 5 8 13)
+ (-> '(2 3 5) (append '(8 13)) (-slice 1 -1))
+ ⇒ (3 5 8)
+
+ -- Macro: ->> (x &optional form &rest more)
+ Thread the expr through the forms. Insert X as the last item in
+ the first form, making a list of it if it is not a list already.
+ If there are more forms, insert the first form as the last item in
+ second form, etc.
+
+ (->> '(1 2 3) (-map 'square))
+ ⇒ (1 4 9)
+ (->> '(1 2 3) (-map 'square) (-remove 'even?))
+ ⇒ (1 9)
+ (->> '(1 2 3) (-map 'square) (-reduce '+))
+ ⇒ 14
+
+ -- Macro: --> (x &rest forms)
+ Starting with the value of X, thread each expression through FORMS.
+
+ Insert X at the position signified by the symbol ‘it’ in the first
+ form. If there are more forms, insert the first form at the
+ position signified by ‘it’ in in second form, etc.
+
+ (--> "def" (concat "abc" it "ghi"))
+ ⇒ "abcdefghi"
+ (--> "def" (concat "abc" it "ghi") (upcase it))
+ ⇒ "ABCDEFGHI"
+ (--> "def" (concat "abc" it "ghi") upcase)
+ ⇒ "ABCDEFGHI"
+
+ -- Macro: -as-> (value variable &rest forms)
+ Starting with VALUE, thread VARIABLE through FORMS.
+
+ In the first form, bind VARIABLE to VALUE. In the second form,
+ bind VARIABLE to the result of the first form, and so forth.
+
+ (-as-> 3 my-var (1+ my-var) (list my-var) (mapcar (lambda (ele) (* 2 ele)) my-var))
+ ⇒ (8)
+ (-as-> 3 my-var 1+)
+ ⇒ 4
+ (-as-> 3 my-var)
+ ⇒ 3
+
+ -- Macro: -some-> (x &optional form &rest more)
+ When expr is non-nil, thread it through the first form (via ‘->’
+ (*note ->::)), and when that result is non-nil, through the next
+ form, etc.
+
+ (-some-> '(2 3 5))
+ ⇒ (2 3 5)
+ (-some-> 5 square)
+ ⇒ 25
+ (-some-> 5 even? square)
+ ⇒ nil
+
+ -- Macro: -some->> (x &optional form &rest more)
+ When expr is non-nil, thread it through the first form (via ‘->>’
+ (*note ->>::)), and when that result is non-nil, through the next
+ form, etc.
+
+ (-some->> '(1 2 3) (-map 'square))
+ ⇒ (1 4 9)
+ (-some->> '(1 3 5) (-last 'even?) (+ 100))
+ ⇒ nil
+ (-some->> '(2 4 6) (-last 'even?) (+ 100))
+ ⇒ 106
+
+ -- Macro: -some--> (expr &rest forms)
+ Thread EXPR through FORMS via ‘-->’ (*note -->::), while the result
+ is non-nil. When EXPR evaluates to non-nil, thread the result
+ through the first of FORMS, and when that result is non-nil, thread
+ it through the next form, etc.
+
+ (-some--> "def" (concat "abc" it "ghi"))
+ ⇒ "abcdefghi"
+ (-some--> nil (concat "abc" it "ghi"))
+ ⇒ nil
+ (-some--> '(0 1) (-remove #'natnump it) (append it it) (-map #'1+ it))
+ ⇒ ()
+
+ -- Macro: -doto (init &rest forms)
+ Evaluate INIT and pass it as argument to FORMS with ‘->’ (*note
+ ->::). The RESULT of evaluating INIT is threaded through each of
+ FORMS individually using ‘->’ (*note ->::), which see. The return
+ value is RESULT, which FORMS may have modified by side effect.
+
+ (-doto (list 1 2 3) pop pop)
+ ⇒ (3)
+ (-doto (cons 1 2) (setcar 3) (setcdr 4))
+ ⇒ (3 . 4)
+ (gethash 'k (--doto (make-hash-table) (puthash 'k 'v it)))
+ ⇒ v
+
+
+File: dash.info, Node: Binding, Next: Side effects, Prev: Threading macros, Up: Functions
+
+2.13 Binding
+============
+
+Macros that combine ‘let’ and ‘let*’ with destructuring and flow
+control.
+
+ -- Macro: -when-let ((var val) &rest body)
+ If VAL evaluates to non-nil, bind it to VAR and execute body.
+
+ Note: binding is done according to ‘-let’ (*note -let::).
+
+ (-when-let (match-index (string-match "d" "abcd")) (+ match-index 2))
+ ⇒ 5
+ (-when-let ((&plist :foo foo) (list :foo "foo")) foo)
+ ⇒ "foo"
+ (-when-let ((&plist :foo foo) (list :bar "bar")) foo)
+ ⇒ nil
+
+ -- Macro: -when-let* (vars-vals &rest body)
+ If all VALS evaluate to true, bind them to their corresponding VARS
+ and execute body. VARS-VALS should be a list of (VAR VAL) pairs.
+
+ Note: binding is done according to ‘-let*’ (*note -let*::). VALS
+ are evaluated sequentially, and evaluation stops after the first
+ nil VAL is encountered.
+
+ (-when-let* ((x 5) (y 3) (z (+ y 4))) (+ x y z))
+ ⇒ 15
+ (-when-let* ((x 5) (y nil) (z 7)) (+ x y z))
+ ⇒ nil
+
+ -- Macro: -if-let ((var val) then &rest else)
+ If VAL evaluates to non-nil, bind it to VAR and do THEN, otherwise
+ do ELSE.
+
+ Note: binding is done according to ‘-let’ (*note -let::).
+
+ (-if-let (match-index (string-match "d" "abc")) (+ match-index 3) 7)
+ ⇒ 7
+ (--if-let (even? 4) it nil)
+ ⇒ t
+
+ -- Macro: -if-let* (vars-vals then &rest else)
+ If all VALS evaluate to true, bind them to their corresponding VARS
+ and do THEN, otherwise do ELSE. VARS-VALS should be a list of (VAR
+ VAL) pairs.
+
+ Note: binding is done according to ‘-let*’ (*note -let*::). VALS
+ are evaluated sequentially, and evaluation stops after the first
+ nil VAL is encountered.
+
+ (-if-let* ((x 5) (y 3) (z 7)) (+ x y z) "foo")
+ ⇒ 15
+ (-if-let* ((x 5) (y nil) (z 7)) (+ x y z) "foo")
+ ⇒ "foo"
+ (-if-let* (((_ _ x) '(nil nil 7))) x)
+ ⇒ 7
+
+ -- Macro: -let (varlist &rest body)
+ Bind variables according to VARLIST then eval BODY.
+
+ VARLIST is a list of lists of the form (PATTERN SOURCE). Each
+ PATTERN is matched against the SOURCE "structurally". SOURCE is
+ only evaluated once for each PATTERN. Each PATTERN is matched
+ recursively, and can therefore contain sub-patterns which are
+ matched against corresponding sub-expressions of SOURCE.
+
+ All the SOURCEs are evalled before any symbols are bound (i.e. "in
+ parallel").
+
+ If VARLIST only contains one (PATTERN SOURCE) element, you can
+ optionally specify it using a vector and discarding the outer-most
+ parens. Thus
+
+ (-let ((PATTERN SOURCE)) ...)
+
+ becomes
+
+ (-let [PATTERN SOURCE] ...).
+
+ ‘-let’ (*note -let::) uses a convention of not binding places
+ (symbols) starting with _ whenever it’s possible. You can use this
+ to skip over entries you don’t care about. However, this is not
+ *always* possible (as a result of implementation) and these symbols
+ might get bound to undefined values.
+
+ Following is the overview of supported patterns. Remember that
+ patterns can be matched recursively, so every a, b, aK in the
+ following can be a matching construct and not necessarily a
+ symbol/variable.
+
+ Symbol:
+
+ a - bind the SOURCE to A. This is just like regular ‘let’.
+
+ Conses and lists:
+
+ (a) - bind ‘car’ of cons/list to A
+
+ (a . b) - bind car of cons to A and ‘cdr’ to B
+
+ (a b) - bind car of list to A and ‘cadr’ to B
+
+ (a1 a2 a3 ...) - bind 0th car of list to A1, 1st to A2, 2nd to
+ A3...
+
+ (a1 a2 a3 ... aN . rest) - as above, but bind the Nth cdr to REST.
+
+ Vectors:
+
+ [a] - bind 0th element of a non-list sequence to A (works with
+ vectors, strings, bit arrays...)
+
+ [a1 a2 a3 ...] - bind 0th element of non-list sequence to A0, 1st
+ to A1, 2nd to A2, ... If the PATTERN is shorter than SOURCE, the
+ values at places not in PATTERN are ignored. If the PATTERN is
+ longer than SOURCE, an ‘error’ is thrown.
+
+ [a1 a2 a3 ... &rest rest] - as above, but bind the rest of the
+ sequence to REST. This is conceptually the same as improper list
+ matching (a1 a2 ... aN . rest)
+
+ Key/value stores:
+
+ (&plist key0 a0 ... keyN aN) - bind value mapped by keyK in the
+ SOURCE plist to aK. If the value is not found, aK is nil. Uses
+ ‘plist-get’ to fetch values.
+
+ (&alist key0 a0 ... keyN aN) - bind value mapped by keyK in the
+ SOURCE alist to aK. If the value is not found, aK is nil. Uses
+ ‘assoc’ to fetch values.
+
+ (&hash key0 a0 ... keyN aN) - bind value mapped by keyK in the
+ SOURCE hash table to aK. If the value is not found, aK is nil.
+ Uses ‘gethash’ to fetch values.
+
+ Further, special keyword &keys supports "inline" matching of
+ plist-like key-value pairs, similarly to &keys keyword of
+ ‘cl-defun’.
+
+ (a1 a2 ... aN &keys key1 b1 ... keyN bK)
+
+ This binds N values from the list to a1 ... aN, then interprets the
+ cdr as a plist (see key/value matching above).
+
+ A shorthand notation for kv-destructuring exists which allows the
+ patterns be optionally left out and derived from the key name in
+ the following fashion:
+
+ - a key :foo is converted into ‘foo’ pattern, - a key ’bar is
+ converted into ‘bar’ pattern, - a key "baz" is converted into ‘baz’
+ pattern.
+
+ That is, the entire value under the key is bound to the derived
+ variable without any further destructuring.
+
+ This is possible only when the form following the key is not a
+ valid pattern (i.e. not a symbol, a cons cell or a vector).
+ Otherwise the matching proceeds as usual and in case of an invalid
+ spec fails with an error.
+
+ Thus the patterns are normalized as follows:
+
+ ;; derive all the missing patterns (&plist :foo ’bar "baz") =>
+ (&plist :foo foo ’bar bar "baz" baz)
+
+ ;; we can specify some but not others (&plist :foo ’bar
+ explicit-bar) => (&plist :foo foo ’bar explicit-bar)
+
+ ;; nothing happens, we store :foo in x (&plist :foo x) => (&plist
+ :foo x)
+
+ ;; nothing happens, we match recursively (&plist :foo (a b c)) =>
+ (&plist :foo (a b c))
+
+ You can name the source using the syntax SYMBOL &as PATTERN. This
+ syntax works with lists (proper or improper), vectors and all types
+ of maps.
+
+ (list &as a b c) (list 1 2 3)
+
+ binds A to 1, B to 2, C to 3 and LIST to (1 2 3).
+
+ Similarly:
+
+ (bounds &as beg . end) (cons 1 2)
+
+ binds BEG to 1, END to 2 and BOUNDS to (1 . 2).
+
+ (items &as first . rest) (list 1 2 3)
+
+ binds FIRST to 1, REST to (2 3) and ITEMS to (1 2 3)
+
+ [vect &as _ b c] [1 2 3]
+
+ binds B to 2, C to 3 and VECT to [1 2 3] (_ avoids binding as
+ usual).
+
+ (plist &as &plist :b b) (list :a 1 :b 2 :c 3)
+
+ binds B to 2 and PLIST to (:a 1 :b 2 :c 3). Same for &alist and
+ &hash.
+
+ This is especially useful when we want to capture the result of a
+ computation and destructure at the same time. Consider the form
+ (function-returning-complex-structure) returning a list of two
+ vectors with two items each. We want to capture this entire result
+ and pass it to another computation, but at the same time we want to
+ get the second item from each vector. We can achieve it with
+ pattern
+
+ (result &as [_ a] [_ b]) (function-returning-complex-structure)
+
+ Note: Clojure programmers may know this feature as the ":as
+ binding". The difference is that we put the &as at the front
+ because we need to support improper list binding.
+
+ (-let (([a (b c) d] [1 (2 3) 4])) (list a b c d))
+ ⇒ (1 2 3 4)
+ (-let [(a b c . d) (list 1 2 3 4 5 6)] (list a b c d))
+ ⇒ (1 2 3 (4 5 6))
+ (-let [(&plist :foo foo :bar bar) (list :baz 3 :foo 1 :qux 4 :bar 2)] (list foo bar))
+ ⇒ (1 2)
+
+ -- Macro: -let* (varlist &rest body)
+ Bind variables according to VARLIST then eval BODY.
+
+ VARLIST is a list of lists of the form (PATTERN SOURCE). Each
+ PATTERN is matched against the SOURCE structurally. SOURCE is only
+ evaluated once for each PATTERN.
+
+ Each SOURCE can refer to the symbols already bound by this VARLIST.
+ This is useful if you want to destructure SOURCE recursively but
+ also want to name the intermediate structures.
+
+ See ‘-let’ (*note -let::) for the list of all possible patterns.
+
+ (-let* (((a . b) (cons 1 2)) ((c . d) (cons 3 4))) (list a b c d))
+ ⇒ (1 2 3 4)
+ (-let* (((a . b) (cons 1 (cons 2 3))) ((c . d) b)) (list a b c d))
+ ⇒ (1 (2 . 3) 2 3)
+ (-let* (((&alist "foo" foo "bar" bar) (list (cons "foo" 1) (cons "bar" (list 'a 'b 'c)))) ((a b c) bar)) (list foo a b c bar))
+ ⇒ (1 a b c (a b c))
+
+ -- Macro: -lambda (match-form &rest body)
+ Return a lambda which destructures its input as MATCH-FORM and
+ executes BODY.
+
+ Note that you have to enclose the MATCH-FORM in a pair of parens,
+ such that:
+
+ (-lambda (x) body) (-lambda (x y ...) body)
+
+ has the usual semantics of ‘lambda’. Furthermore, these get
+ translated into normal ‘lambda’, so there is no performance
+ penalty.
+
+ See ‘-let’ (*note -let::) for a description of the destructuring
+ mechanism.
+
+ (-map (-lambda ((x y)) (+ x y)) '((1 2) (3 4) (5 6)))
+ ⇒ (3 7 11)
+ (-map (-lambda ([x y]) (+ x y)) '([1 2] [3 4] [5 6]))
+ ⇒ (3 7 11)
+ (funcall (-lambda ((_ . a) (_ . b)) (-concat a b)) '(1 2 3) '(4 5 6))
+ ⇒ (2 3 5 6)
+
+ -- Macro: -setq ([match-form val] ...)
+ Bind each MATCH-FORM to the value of its VAL.
+
+ MATCH-FORM destructuring is done according to the rules of ‘-let’
+ (*note -let::).
+
+ This macro allows you to bind multiple variables by destructuring
+ the value, so for example:
+
+ (-setq (a b) x (&plist :c c) plist)
+
+ expands roughly speaking to the following code
+
+ (setq a (car x) b (cadr x) c (plist-get plist :c))
+
+ Care is taken to only evaluate each VAL once so that in case of
+ multiple assignments it does not cause unexpected side effects.
+
+ (let (a) (-setq a 1) a)
+ ⇒ 1
+ (let (a b) (-setq (a b) (list 1 2)) (list a b))
+ ⇒ (1 2)
+ (let (c) (-setq (&plist :c c) (list :c "c")) c)
+ ⇒ "c"
+
+
+File: dash.info, Node: Side effects, Next: Destructive operations, Prev: Binding, Up: Functions
+
+2.14 Side effects
+=================
+
+Functions iterating over lists for side effect only.
+
+ -- Function: -each (list fn)
+ Call FN on each element of LIST. Return nil; this function is
+ intended for side effects.
+
+ Its anaphoric counterpart is ‘--each’.
+
+ For access to the current element’s index in LIST, see
+ ‘-each-indexed’ (*note -each-indexed::).
+
+ (let (l) (-each '(1 2 3) (lambda (x) (push x l))) l)
+ ⇒ (3 2 1)
+ (let (l) (--each '(1 2 3) (push it l)) l)
+ ⇒ (3 2 1)
+ (-each '(1 2 3) #'identity)
+ ⇒ nil
+
+ -- Function: -each-while (list pred fn)
+ Call FN on each ITEM in LIST, while (PRED ITEM) is non-nil. Once
+ an ITEM is reached for which PRED returns nil, FN is no longer
+ called. Return nil; this function is intended for side effects.
+
+ Its anaphoric counterpart is ‘--each-while’.
+
+ (let (l) (-each-while '(2 4 5 6) #'even? (lambda (x) (push x l))) l)
+ ⇒ (4 2)
+ (let (l) (--each-while '(1 2 3 4) (< it 3) (push it l)) l)
+ ⇒ (2 1)
+ (let ((s 0)) (--each-while '(1 3 4 5) (< it 5) (setq s (+ s it))) s)
+ ⇒ 8
+
+ -- Function: -each-indexed (list fn)
+ Call FN on each index and element of LIST. For each ITEM at INDEX
+ in LIST, call (funcall FN INDEX ITEM). Return nil; this function
+ is intended for side effects.
+
+ See also: ‘-map-indexed’ (*note -map-indexed::).
+
+ (let (l) (-each-indexed '(a b c) (lambda (i x) (push (list x i) l))) l)
+ ⇒ ((c 2) (b 1) (a 0))
+ (let (l) (--each-indexed '(a b c) (push (list it it-index) l)) l)
+ ⇒ ((c 2) (b 1) (a 0))
+ (let (l) (--each-indexed () (push it l)) l)
+ ⇒ ()
+
+ -- Function: -each-r (list fn)
+ Call FN on each element of LIST in reversed order. Return nil;
+ this function is intended for side effects.
+
+ Its anaphoric counterpart is ‘--each-r’.
+
+ (let (l) (-each-r '(1 2 3) (lambda (x) (push x l))) l)
+ ⇒ (1 2 3)
+ (let (l) (--each-r '(1 2 3) (push it l)) l)
+ ⇒ (1 2 3)
+ (-each-r '(1 2 3) #'identity)
+ ⇒ nil
+
+ -- Function: -each-r-while (list pred fn)
+ Call FN on each ITEM in reversed LIST, while (PRED ITEM) is
+ non-nil. Once an ITEM is reached for which PRED returns nil, FN is
+ no longer called. Return nil; this function is intended for side
+ effects.
+
+ Its anaphoric counterpart is ‘--each-r-while’.
+
+ (let (l) (-each-r-while '(2 4 5 6) #'even? (lambda (x) (push x l))) l)
+ ⇒ (6)
+ (let (l) (--each-r-while '(1 2 3 4) (>= it 3) (push it l)) l)
+ ⇒ (3 4)
+ (let ((s 0)) (--each-r-while '(1 2 3 5) (> it 1) (setq s (+ s it))) s)
+ ⇒ 10
+
+ -- Function: -dotimes (num fn)
+ Call FN NUM times, presumably for side effects. FN is called with
+ a single argument on successive integers running from 0, inclusive,
+ to NUM, exclusive. FN is not called if NUM is less than 1.
+
+ This function’s anaphoric counterpart is ‘--dotimes’.
+
+ (let (s) (-dotimes 3 (lambda (n) (push n s))) s)
+ ⇒ (2 1 0)
+ (let (s) (-dotimes 0 (lambda (n) (push n s))) s)
+ ⇒ ()
+ (let (s) (--dotimes 5 (push it s)) s)
+ ⇒ (4 3 2 1 0)
+
+
+File: dash.info, Node: Destructive operations, Next: Function combinators, Prev: Side effects, Up: Functions
+
+2.15 Destructive operations
+===========================
+
+Macros that modify variables holding lists.
+
+ -- Macro: !cons (car cdr)
+ Destructive: Set CDR to the cons of CAR and CDR.
+
+ (let (l) (!cons 5 l) l)
+ ⇒ (5)
+ (let ((l '(3))) (!cons 5 l) l)
+ ⇒ (5 3)
+
+ -- Macro: !cdr (list)
+ Destructive: Set LIST to the cdr of LIST.
+
+ (let ((l '(3))) (!cdr l) l)
+ ⇒ ()
+ (let ((l '(3 5))) (!cdr l) l)
+ ⇒ (5)
+
+
+File: dash.info, Node: Function combinators, Prev: Destructive operations, Up: Functions
+
+2.16 Function combinators
+=========================
+
+Functions that manipulate and compose other functions.
+
+ -- Function: -partial (fn &rest args)
+ Take a function FN and fewer than the normal arguments to FN, and
+ return a fn that takes a variable number of additional ARGS. When
+ called, the returned function calls FN with ARGS first and then
+ additional args.
+
+ (funcall (-partial '- 5) 3)
+ ⇒ 2
+ (funcall (-partial '+ 5 2) 3)
+ ⇒ 10
+
+ -- Function: -rpartial (fn &rest args)
+ Takes a function FN and fewer than the normal arguments to FN, and
+ returns a fn that takes a variable number of additional ARGS. When
+ called, the returned function calls FN with the additional args
+ first and then ARGS.
+
+ (funcall (-rpartial '- 5) 8)
+ ⇒ 3
+ (funcall (-rpartial '- 5 2) 10)
+ ⇒ 3
+
+ -- Function: -juxt (&rest fns)
+ Takes a list of functions and returns a fn that is the
+ juxtaposition of those fns. The returned fn takes a variable
+ number of args, and returns a list containing the result of
+ applying each fn to the args (left-to-right).
+
+ (funcall (-juxt '+ '-) 3 5)
+ ⇒ (8 -2)
+ (-map (-juxt 'identity 'square) '(1 2 3))
+ ⇒ ((1 1) (2 4) (3 9))
+
+ -- Function: -compose (&rest fns)
+ Takes a list of functions and returns a fn that is the composition
+ of those fns. The returned fn takes a variable number of
+ arguments, and returns the result of applying each fn to the result
+ of applying the previous fn to the arguments (right-to-left).
+
+ (funcall (-compose 'square '+) 2 3)
+ ⇒ (square (+ 2 3))
+ (funcall (-compose 'identity 'square) 3)
+ ⇒ (square 3)
+ (funcall (-compose 'square 'identity) 3)
+ ⇒ (square 3)
+
+ -- Function: -applify (fn)
+ Changes an n-arity function FN to a 1-arity function that expects a
+ list with n items as arguments
+
+ (-map (-applify '+) '((1 1 1) (1 2 3) (5 5 5)))
+ ⇒ (3 6 15)
+ (-map (-applify (lambda (a b c) `(,a (,b (,c))))) '((1 1 1) (1 2 3) (5 5 5)))
+ ⇒ ((1 (1 (1))) (1 (2 (3))) (5 (5 (5))))
+ (funcall (-applify '<) '(3 6))
+ ⇒ t
+
+ -- Function: -on (operator transformer)
+ Return a function of two arguments that first applies TRANSFORMER
+ to each of them and then applies OPERATOR on the results (in the
+ same order).
+
+ In types: (b -> b -> c) -> (a -> b) -> a -> a -> c
+
+ (-sort (-on '< 'length) '((1 2 3) (1) (1 2)))
+ ⇒ ((1) (1 2) (1 2 3))
+ (-min-by (-on '> 'length) '((1 2 3) (4) (1 2)))
+ ⇒ (4)
+ (-min-by (-on 'string-lessp 'number-to-string) '(2 100 22))
+ ⇒ 22
+
+ -- Function: -flip (func)
+ Swap the order of arguments for binary function FUNC.
+
+ In types: (a -> b -> c) -> b -> a -> c
+
+ (funcall (-flip '<) 2 1)
+ ⇒ t
+ (funcall (-flip '-) 3 8)
+ ⇒ 5
+ (-sort (-flip '<) '(4 3 6 1))
+ ⇒ (6 4 3 1)
+
+ -- Function: -const (c)
+ Return a function that returns C ignoring any additional arguments.
+
+ In types: a -> b -> a
+
+ (funcall (-const 2) 1 3 "foo")
+ ⇒ 2
+ (-map (-const 1) '("a" "b" "c" "d"))
+ ⇒ (1 1 1 1)
+ (-sum (-map (-const 1) '("a" "b" "c" "d")))
+ ⇒ 4
+
+ -- Macro: -cut (&rest params)
+ Take n-ary function and n arguments and specialize some of them.
+ Arguments denoted by <> will be left unspecialized.
+
+ See SRFI-26 for detailed description.
+
+ (funcall (-cut list 1 <> 3 <> 5) 2 4)
+ ⇒ (1 2 3 4 5)
+ (-map (-cut funcall <> 5) `(1+ 1- ,(lambda (x) (/ 1.0 x))))
+ ⇒ (6 4 0.2)
+ (-map (-cut <> 1 2 3) '(list vector string))
+ ⇒ ((1 2 3) [1 2 3] "\1\2\3")
+
+ -- Function: -not (pred)
+ Take a unary predicate PRED and return a unary predicate that
+ returns t if PRED returns nil and nil if PRED returns non-nil.
+
+ (funcall (-not 'even?) 5)
+ ⇒ t
+ (-filter (-not (-partial '< 4)) '(1 2 3 4 5 6 7 8))
+ ⇒ (1 2 3 4)
+
+ -- Function: -orfn (&rest preds)
+ Take list of unary predicates PREDS and return a unary predicate
+ with argument x that returns non-nil if at least one of the PREDS
+ returns non-nil on x.
+
+ In types: [a -> Bool] -> a -> Bool
+
+ (-filter (-orfn 'even? (-partial (-flip '<) 5)) '(1 2 3 4 5 6 7 8 9 10))
+ ⇒ (1 2 3 4 6 8 10)
+ (funcall (-orfn 'stringp 'even?) "foo")
+ ⇒ t
+
+ -- Function: -andfn (&rest preds)
+ Take list of unary predicates PREDS and return a unary predicate
+ with argument x that returns non-nil if all of the PREDS returns
+ non-nil on x.
+
+ In types: [a -> Bool] -> a -> Bool
+
+ (funcall (-andfn (-cut < <> 10) 'even?) 6)
+ ⇒ t
+ (funcall (-andfn (-cut < <> 10) 'even?) 12)
+ ⇒ nil
+ (-filter (-andfn (-not 'even?) (-cut >= 5 <>)) '(1 2 3 4 5 6 7 8 9 10))
+ ⇒ (1 3 5)
+
+ -- Function: -iteratefn (fn n)
+ Return a function FN composed N times with itself.
+
+ FN is a unary function. If you need to use a function of higher
+ arity, use ‘-applify’ (*note -applify::) first to turn it into a
+ unary function.
+
+ With n = 0, this acts as identity function.
+
+ In types: (a -> a) -> Int -> a -> a.
+
+ This function satisfies the following law:
+
+ (funcall (-iteratefn fn n) init) = (-last-item (-iterate fn init
+ (1+ n))).
+
+ (funcall (-iteratefn (lambda (x) (* x x)) 3) 2)
+ ⇒ 256
+ (funcall (-iteratefn '1+ 3) 1)
+ ⇒ 4
+ (funcall (-iteratefn 'cdr 3) '(1 2 3 4 5))
+ ⇒ (4 5)
+
+ -- Function: -fixfn (fn &optional equal-test halt-test)
+ Return a function that computes the (least) fixpoint of FN.
+
+ FN must be a unary function. The returned lambda takes a single
+ argument, X, the initial value for the fixpoint iteration. The
+ iteration halts when either of the following conditions is
+ satisfied:
+
+ 1. Iteration converges to the fixpoint, with equality being tested
+ using EQUAL-TEST. If EQUAL-TEST is not specified, ‘equal’ is used.
+ For functions over the floating point numbers, it may be necessary
+ to provide an appropriate approximate comparison test.
+
+ 2. HALT-TEST returns a non-nil value. HALT-TEST defaults to a
+ simple counter that returns t after ‘-fixfn-max-iterations’, to
+ guard against infinite iteration. Otherwise, HALT-TEST must be a
+ function that accepts a single argument, the current value of X,
+ and returns non-nil as long as iteration should continue. In this
+ way, a more sophisticated convergence test may be supplied by the
+ caller.
+
+ The return value of the lambda is either the fixpoint or, if
+ iteration halted before converging, a cons with car ‘halted’ and
+ cdr the final output from HALT-TEST.
+
+ In types: (a -> a) -> a -> a.
+
+ (funcall (-fixfn #'cos #'approx=) 0.7)
+ ⇒ 0.7390851332151607
+ (funcall (-fixfn (lambda (x) (expt (+ x 10) 0.25))) 2.0)
+ ⇒ 1.8555845286409378
+ (funcall (-fixfn #'sin #'approx=) 0.1)
+ ⇒ (halted . t)
+
+ -- Function: -prodfn (&rest fns)
+ Take a list of n functions and return a function that takes a list
+ of length n, applying i-th function to i-th element of the input
+ list. Returns a list of length n.
+
+ In types (for n=2): ((a -> b), (c -> d)) -> (a, c) -> (b, d)
+
+ This function satisfies the following laws:
+
+ (-compose (-prodfn f g ...) (-prodfn f’ g’ ...)) = (-prodfn
+ (-compose f f’) (-compose g g’) ...) (-prodfn f g ...) = (-juxt
+ (-compose f (-partial ’nth 0)) (-compose g (-partial ’nth 1)) ...)
+ (-compose (-prodfn f g ...) (-juxt f’ g’ ...)) = (-juxt (-compose f
+ f’) (-compose g g’) ...) (-compose (-partial ’nth n) (-prod f1 f2
+ ...)) = (-compose fn (-partial ’nth n))
+
+ (funcall (-prodfn '1+ '1- 'number-to-string) '(1 2 3))
+ ⇒ (2 1 "3")
+ (-map (-prodfn '1+ '1-) '((1 2) (3 4) (5 6) (7 8)))
+ ⇒ ((2 1) (4 3) (6 5) (8 7))
+ (apply '+ (funcall (-prodfn 'length 'string-to-number) '((1 2 3) "15")))
+ ⇒ 18
+
+
+File: dash.info, Node: Development, Next: FDL, Prev: Functions, Up: Top
+
+3 Development
+*************
+
+The Dash repository is hosted on GitHub at
+.
+
+* Menu:
+
+* Contribute:: How to contribute.
+* Contributors:: List of contributors.
+
+
+File: dash.info, Node: Contribute, Next: Contributors, Up: Development
+
+3.1 Contribute
+==============
+
+Yes, please do. Pure functions in the list manipulation realm only,
+please. There’s a suite of examples/tests in ‘dev/examples.el’, so
+remember to add tests for your additions, or they may get broken later.
+
+ Run the tests with ‘make check’. Regenerate the docs with ‘make
+docs’. Contributors are encouraged to install these commands as a Git
+pre-commit hook, so that the tests are always running and the docs are
+always in sync:
+
+ $ cp dev/pre-commit.sh .git/hooks/pre-commit
+
+ Oh, and don’t edit ‘README.md’ or ‘dash.texi’ directly, as they are
+auto-generated. Instead, change their respective templates
+‘readme-template.md’ or ‘dash-template.texi’.
+
+ To ensure that Dash can be distributed with GNU ELPA or Emacs, we
+require that all contributors assign copyright to the Free Software
+Foundation. For more on this, *note (emacs)Copyright Assignment::.
+
+
+File: dash.info, Node: Contributors, Prev: Contribute, Up: Development
+
+3.2 Contributors
+================
+
+ • Matus Goljer (https://github.com/Fuco1) contributed lots of
+ features and functions.
+ • Takafumi Arakaki (https://github.com/tkf) contributed ‘-group-by’.
+ • tali713 (https://github.com/tali713) is the author of ‘-applify’.
+ • Víctor M. Valenzuela (https://github.com/vemv) contributed
+ ‘-repeat’.
+ • Nic Ferrier (https://github.com/nicferrier) contributed ‘-cons*’.
+ • Wilfred Hughes (https://github.com/Wilfred) contributed ‘-slice’,
+ ‘-first-item’, and ‘-last-item’.
+ • Emanuel Evans (https://github.com/shosti) contributed ‘-if-let’,
+ ‘-when-let’, and ‘-insert-at’.
+ • Johan Andersson (https://github.com/rejeep) contributed ‘-sum’,
+ ‘-product’, and ‘-same-items?’.
+ • Christina Whyte (https://github.com/kurisuwhyte) contributed
+ ‘-compose’.
+ • Steve Lamb (https://github.com/steventlamb) contributed ‘-cycle’,
+ ‘-pad’, ‘-annotate’, ‘-zip-fill’, and a variadic version of ‘-zip’.
+ • Fredrik Bergroth (https://github.com/fbergroth) made the ‘-if-let’
+ family use ‘-let’ destructuring and improved the script for
+ generating documentation.
+ • Mark Oteiza (https://github.com/holomorph) contributed ‘-iota’ and
+ the script to create an Info manual.
+ • Vasilij Schneidermann (https://github.com/wasamasa) contributed
+ ‘-some’.
+ • William West (https://github.com/occidens) made ‘-fixfn’ more
+ robust at handling floats.
+ • Cam Saul (https://github.com/camsaul) contributed ‘-some->’,
+ ‘-some->>’, and ‘-some-->’.
+ • Basil L. Contovounesios (https://github.com/basil-conto)
+ contributed ‘-common-prefix’, ‘-common-suffix’, and various other
+ improvements.
+ • Paul Pogonyshev (https://github.com/doublep) contributed ‘-each-r’
+ and ‘-each-r-while’.
+
+ Thanks!
+
+ New contributors are very welcome. *Note Contribute::.
+
+
+File: dash.info, Node: FDL, Next: GPL, Prev: Development, Up: Top
+
+Appendix A GNU Free Documentation License
+*****************************************
+
+ Version 1.3, 3 November 2008
+
+ Copyright © 2000, 2001, 2002, 2007, 2008 Free Software Foundation, Inc.
+
+
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ 0. PREAMBLE
+
+ The purpose of this License is to make a manual, textbook, or other
+ functional and useful document “free” in the sense of freedom: to
+ assure everyone the effective freedom to copy and redistribute it,
+ with or without modifying it, either commercially or
+ noncommercially. Secondarily, this License preserves for the
+ author and publisher a way to get credit for their work, while not
+ being considered responsible for modifications made by others.
+
+ This License is a kind of “copyleft”, which means that derivative
+ works of the document must themselves be free in the same sense.
+ It complements the GNU General Public License, which is a copyleft
+ license designed for free software.
+
+ We have designed this License in order to use it for manuals for
+ free software, because free software needs free documentation: a
+ free program should come with manuals providing the same freedoms
+ that the software does. But this License is not limited to
+ software manuals; it can be used for any textual work, regardless
+ of subject matter or whether it is published as a printed book. We
+ recommend this License principally for works whose purpose is
+ instruction or reference.
+
+ 1. APPLICABILITY AND DEFINITIONS
+
+ This License applies to any manual or other work, in any medium,
+ that contains a notice placed by the copyright holder saying it can
+ be distributed under the terms of this License. Such a notice
+ grants a world-wide, royalty-free license, unlimited in duration,
+ to use that work under the conditions stated herein. The
+ “Document”, below, refers to any such manual or work. Any member
+ of the public is a licensee, and is addressed as “you”. You accept
+ the license if you copy, modify or distribute the work in a way
+ requiring permission under copyright law.
+
+ A “Modified Version” of the Document means any work containing the
+ Document or a portion of it, either copied verbatim, or with
+ modifications and/or translated into another language.
+
+ A “Secondary Section” is a named appendix or a front-matter section
+ of the Document that deals exclusively with the relationship of the
+ publishers or authors of the Document to the Document’s overall
+ subject (or to related matters) and contains nothing that could
+ fall directly within that overall subject. (Thus, if the Document
+ is in part a textbook of mathematics, a Secondary Section may not
+ explain any mathematics.) The relationship could be a matter of
+ historical connection with the subject or with related matters, or
+ of legal, commercial, philosophical, ethical or political position
+ regarding them.
+
+ The “Invariant Sections” are certain Secondary Sections whose
+ titles are designated, as being those of Invariant Sections, in the
+ notice that says that the Document is released under this License.
+ If a section does not fit the above definition of Secondary then it
+ is not allowed to be designated as Invariant. The Document may
+ contain zero Invariant Sections. If the Document does not identify
+ any Invariant Sections then there are none.
+
+ The “Cover Texts” are certain short passages of text that are
+ listed, as Front-Cover Texts or Back-Cover Texts, in the notice
+ that says that the Document is released under this License. A
+ Front-Cover Text may be at most 5 words, and a Back-Cover Text may
+ be at most 25 words.
+
+ A “Transparent” copy of the Document means a machine-readable copy,
+ represented in a format whose specification is available to the
+ general public, that is suitable for revising the document
+ straightforwardly with generic text editors or (for images composed
+ of pixels) generic paint programs or (for drawings) some widely
+ available drawing editor, and that is suitable for input to text
+ formatters or for automatic translation to a variety of formats
+ suitable for input to text formatters. A copy made in an otherwise
+ Transparent file format whose markup, or absence of markup, has
+ been arranged to thwart or discourage subsequent modification by
+ readers is not Transparent. An image format is not Transparent if
+ used for any substantial amount of text. A copy that is not
+ “Transparent” is called “Opaque”.
+
+ Examples of suitable formats for Transparent copies include plain
+ ASCII without markup, Texinfo input format, LaTeX input format,
+ SGML or XML using a publicly available DTD, and standard-conforming
+ simple HTML, PostScript or PDF designed for human modification.
+ Examples of transparent image formats include PNG, XCF and JPG.
+ Opaque formats include proprietary formats that can be read and
+ edited only by proprietary word processors, SGML or XML for which
+ the DTD and/or processing tools are not generally available, and
+ the machine-generated HTML, PostScript or PDF produced by some word
+ processors for output purposes only.
+
+ The “Title Page” means, for a printed book, the title page itself,
+ plus such following pages as are needed to hold, legibly, the
+ material this License requires to appear in the title page. For
+ works in formats which do not have any title page as such, “Title
+ Page” means the text near the most prominent appearance of the
+ work’s title, preceding the beginning of the body of the text.
+
+ The “publisher” means any person or entity that distributes copies
+ of the Document to the public.
+
+ A section “Entitled XYZ” means a named subunit of the Document
+ whose title either is precisely XYZ or contains XYZ in parentheses
+ following text that translates XYZ in another language. (Here XYZ
+ stands for a specific section name mentioned below, such as
+ “Acknowledgements”, “Dedications”, “Endorsements”, or “History”.)
+ To “Preserve the Title” of such a section when you modify the
+ Document means that it remains a section “Entitled XYZ” according
+ to this definition.
+
+ The Document may include Warranty Disclaimers next to the notice
+ which states that this License applies to the Document. These
+ Warranty Disclaimers are considered to be included by reference in
+ this License, but only as regards disclaiming warranties: any other
+ implication that these Warranty Disclaimers may have is void and
+ has no effect on the meaning of this License.
+
+ 2. VERBATIM COPYING
+
+ You may copy and distribute the Document in any medium, either
+ commercially or noncommercially, provided that this License, the
+ copyright notices, and the license notice saying this License
+ applies to the Document are reproduced in all copies, and that you
+ add no other conditions whatsoever to those of this License. You
+ may not use technical measures to obstruct or control the reading
+ or further copying of the copies you make or distribute. However,
+ you may accept compensation in exchange for copies. If you
+ distribute a large enough number of copies you must also follow the
+ conditions in section 3.
+
+ You may also lend copies, under the same conditions stated above,
+ and you may publicly display copies.
+
+ 3. COPYING IN QUANTITY
+
+ If you publish printed copies (or copies in media that commonly
+ have printed covers) of the Document, numbering more than 100, and
+ the Document’s license notice requires Cover Texts, you must
+ enclose the copies in covers that carry, clearly and legibly, all
+ these Cover Texts: Front-Cover Texts on the front cover, and
+ Back-Cover Texts on the back cover. Both covers must also clearly
+ and legibly identify you as the publisher of these copies. The
+ front cover must present the full title with all words of the title
+ equally prominent and visible. You may add other material on the
+ covers in addition. Copying with changes limited to the covers, as
+ long as they preserve the title of the Document and satisfy these
+ conditions, can be treated as verbatim copying in other respects.
+
+ If the required texts for either cover are too voluminous to fit
+ legibly, you should put the first ones listed (as many as fit
+ reasonably) on the actual cover, and continue the rest onto
+ adjacent pages.
+
+ If you publish or distribute Opaque copies of the Document
+ numbering more than 100, you must either include a machine-readable
+ Transparent copy along with each Opaque copy, or state in or with
+ each Opaque copy a computer-network location from which the general
+ network-using public has access to download using public-standard
+ network protocols a complete Transparent copy of the Document, free
+ of added material. If you use the latter option, you must take
+ reasonably prudent steps, when you begin distribution of Opaque
+ copies in quantity, to ensure that this Transparent copy will
+ remain thus accessible at the stated location until at least one
+ year after the last time you distribute an Opaque copy (directly or
+ through your agents or retailers) of that edition to the public.
+
+ It is requested, but not required, that you contact the authors of
+ the Document well before redistributing any large number of copies,
+ to give them a chance to provide you with an updated version of the
+ Document.
+
+ 4. MODIFICATIONS
+
+ You may copy and distribute a Modified Version of the Document
+ under the conditions of sections 2 and 3 above, provided that you
+ release the Modified Version under precisely this License, with the
+ Modified Version filling the role of the Document, thus licensing
+ distribution and modification of the Modified Version to whoever
+ possesses a copy of it. In addition, you must do these things in
+ the Modified Version:
+
+ A. Use in the Title Page (and on the covers, if any) a title
+ distinct from that of the Document, and from those of previous
+ versions (which should, if there were any, be listed in the
+ History section of the Document). You may use the same title
+ as a previous version if the original publisher of that
+ version gives permission.
+
+ B. List on the Title Page, as authors, one or more persons or
+ entities responsible for authorship of the modifications in
+ the Modified Version, together with at least five of the
+ principal authors of the Document (all of its principal
+ authors, if it has fewer than five), unless they release you
+ from this requirement.
+
+ C. State on the Title page the name of the publisher of the
+ Modified Version, as the publisher.
+
+ D. Preserve all the copyright notices of the Document.
+
+ E. Add an appropriate copyright notice for your modifications
+ adjacent to the other copyright notices.
+
+ F. Include, immediately after the copyright notices, a license
+ notice giving the public permission to use the Modified
+ Version under the terms of this License, in the form shown in
+ the Addendum below.
+
+ G. Preserve in that license notice the full lists of Invariant
+ Sections and required Cover Texts given in the Document’s
+ license notice.
+
+ H. Include an unaltered copy of this License.
+
+ I. Preserve the section Entitled “History”, Preserve its Title,
+ and add to it an item stating at least the title, year, new
+ authors, and publisher of the Modified Version as given on the
+ Title Page. If there is no section Entitled “History” in the
+ Document, create one stating the title, year, authors, and
+ publisher of the Document as given on its Title Page, then add
+ an item describing the Modified Version as stated in the
+ previous sentence.
+
+ J. Preserve the network location, if any, given in the Document
+ for public access to a Transparent copy of the Document, and
+ likewise the network locations given in the Document for
+ previous versions it was based on. These may be placed in the
+ “History” section. You may omit a network location for a work
+ that was published at least four years before the Document
+ itself, or if the original publisher of the version it refers
+ to gives permission.
+
+ K. For any section Entitled “Acknowledgements” or “Dedications”,
+ Preserve the Title of the section, and preserve in the section
+ all the substance and tone of each of the contributor
+ acknowledgements and/or dedications given therein.
+
+ L. Preserve all the Invariant Sections of the Document, unaltered
+ in their text and in their titles. Section numbers or the
+ equivalent are not considered part of the section titles.
+
+ M. Delete any section Entitled “Endorsements”. Such a section
+ may not be included in the Modified Version.
+
+ N. Do not retitle any existing section to be Entitled
+ “Endorsements” or to conflict in title with any Invariant
+ Section.
+
+ O. Preserve any Warranty Disclaimers.
+
+ If the Modified Version includes new front-matter sections or
+ appendices that qualify as Secondary Sections and contain no
+ material copied from the Document, you may at your option designate
+ some or all of these sections as invariant. To do this, add their
+ titles to the list of Invariant Sections in the Modified Version’s
+ license notice. These titles must be distinct from any other
+ section titles.
+
+ You may add a section Entitled “Endorsements”, provided it contains
+ nothing but endorsements of your Modified Version by various
+ parties—for example, statements of peer review or that the text has
+ been approved by an organization as the authoritative definition of
+ a standard.
+
+ You may add a passage of up to five words as a Front-Cover Text,
+ and a passage of up to 25 words as a Back-Cover Text, to the end of
+ the list of Cover Texts in the Modified Version. Only one passage
+ of Front-Cover Text and one of Back-Cover Text may be added by (or
+ through arrangements made by) any one entity. If the Document
+ already includes a cover text for the same cover, previously added
+ by you or by arrangement made by the same entity you are acting on
+ behalf of, you may not add another; but you may replace the old
+ one, on explicit permission from the previous publisher that added
+ the old one.
+
+ The author(s) and publisher(s) of the Document do not by this
+ License give permission to use their names for publicity for or to
+ assert or imply endorsement of any Modified Version.
+
+ 5. COMBINING DOCUMENTS
+
+ You may combine the Document with other documents released under
+ this License, under the terms defined in section 4 above for
+ modified versions, provided that you include in the combination all
+ of the Invariant Sections of all of the original documents,
+ unmodified, and list them all as Invariant Sections of your
+ combined work in its license notice, and that you preserve all
+ their Warranty Disclaimers.
+
+ The combined work need only contain one copy of this License, and
+ multiple identical Invariant Sections may be replaced with a single
+ copy. If there are multiple Invariant Sections with the same name
+ but different contents, make the title of each such section unique
+ by adding at the end of it, in parentheses, the name of the
+ original author or publisher of that section if known, or else a
+ unique number. Make the same adjustment to the section titles in
+ the list of Invariant Sections in the license notice of the
+ combined work.
+
+ In the combination, you must combine any sections Entitled
+ “History” in the various original documents, forming one section
+ Entitled “History”; likewise combine any sections Entitled
+ “Acknowledgements”, and any sections Entitled “Dedications”. You
+ must delete all sections Entitled “Endorsements.”
+
+ 6. COLLECTIONS OF DOCUMENTS
+
+ You may make a collection consisting of the Document and other
+ documents released under this License, and replace the individual
+ copies of this License in the various documents with a single copy
+ that is included in the collection, provided that you follow the
+ rules of this License for verbatim copying of each of the documents
+ in all other respects.
+
+ You may extract a single document from such a collection, and
+ distribute it individually under this License, provided you insert
+ a copy of this License into the extracted document, and follow this
+ License in all other respects regarding verbatim copying of that
+ document.
+
+ 7. AGGREGATION WITH INDEPENDENT WORKS
+
+ A compilation of the Document or its derivatives with other
+ separate and independent documents or works, in or on a volume of a
+ storage or distribution medium, is called an “aggregate” if the
+ copyright resulting from the compilation is not used to limit the
+ legal rights of the compilation’s users beyond what the individual
+ works permit. When the Document is included in an aggregate, this
+ License does not apply to the other works in the aggregate which
+ are not themselves derivative works of the Document.
+
+ If the Cover Text requirement of section 3 is applicable to these
+ copies of the Document, then if the Document is less than one half
+ of the entire aggregate, the Document’s Cover Texts may be placed
+ on covers that bracket the Document within the aggregate, or the
+ electronic equivalent of covers if the Document is in electronic
+ form. Otherwise they must appear on printed covers that bracket
+ the whole aggregate.
+
+ 8. TRANSLATION
+
+ Translation is considered a kind of modification, so you may
+ distribute translations of the Document under the terms of section
+ 4. Replacing Invariant Sections with translations requires special
+ permission from their copyright holders, but you may include
+ translations of some or all Invariant Sections in addition to the
+ original versions of these Invariant Sections. You may include a
+ translation of this License, and all the license notices in the
+ Document, and any Warranty Disclaimers, provided that you also
+ include the original English version of this License and the
+ original versions of those notices and disclaimers. In case of a
+ disagreement between the translation and the original version of
+ this License or a notice or disclaimer, the original version will
+ prevail.
+
+ If a section in the Document is Entitled “Acknowledgements”,
+ “Dedications”, or “History”, the requirement (section 4) to
+ Preserve its Title (section 1) will typically require changing the
+ actual title.
+
+ 9. TERMINATION
+
+ You may not copy, modify, sublicense, or distribute the Document
+ except as expressly provided under this License. Any attempt
+ otherwise to copy, modify, sublicense, or distribute it is void,
+ and will automatically terminate your rights under this License.
+
+ However, if you cease all violation of this License, then your
+ license from a particular copyright holder is reinstated (a)
+ provisionally, unless and until the copyright holder explicitly and
+ finally terminates your license, and (b) permanently, if the
+ copyright holder fails to notify you of the violation by some
+ reasonable means prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+ reinstated permanently if the copyright holder notifies you of the
+ violation by some reasonable means, this is the first time you have
+ received notice of violation of this License (for any work) from
+ that copyright holder, and you cure the violation prior to 30 days
+ after your receipt of the notice.
+
+ Termination of your rights under this section does not terminate
+ the licenses of parties who have received copies or rights from you
+ under this License. If your rights have been terminated and not
+ permanently reinstated, receipt of a copy of some or all of the
+ same material does not give you any rights to use it.
+
+ 10. FUTURE REVISIONS OF THIS LICENSE
+
+ The Free Software Foundation may publish new, revised versions of
+ the GNU Free Documentation License from time to time. Such new
+ versions will be similar in spirit to the present version, but may
+ differ in detail to address new problems or concerns. See
+ .
+
+ Each version of the License is given a distinguishing version
+ number. If the Document specifies that a particular numbered
+ version of this License “or any later version” applies to it, you
+ have the option of following the terms and conditions either of
+ that specified version or of any later version that has been
+ published (not as a draft) by the Free Software Foundation. If the
+ Document does not specify a version number of this License, you may
+ choose any version ever published (not as a draft) by the Free
+ Software Foundation. If the Document specifies that a proxy can
+ decide which future versions of this License can be used, that
+ proxy’s public statement of acceptance of a version permanently
+ authorizes you to choose that version for the Document.
+
+ 11. RELICENSING
+
+ “Massive Multiauthor Collaboration Site” (or “MMC Site”) means any
+ World Wide Web server that publishes copyrightable works and also
+ provides prominent facilities for anybody to edit those works. A
+ public wiki that anybody can edit is an example of such a server.
+ A “Massive Multiauthor Collaboration” (or “MMC”) contained in the
+ site means any set of copyrightable works thus published on the MMC
+ site.
+
+ “CC-BY-SA” means the Creative Commons Attribution-Share Alike 3.0
+ license published by Creative Commons Corporation, a not-for-profit
+ corporation with a principal place of business in San Francisco,
+ California, as well as future copyleft versions of that license
+ published by that same organization.
+
+ “Incorporate” means to publish or republish a Document, in whole or
+ in part, as part of another Document.
+
+ An MMC is “eligible for relicensing” if it is licensed under this
+ License, and if all works that were first published under this
+ License somewhere other than this MMC, and subsequently
+ incorporated in whole or in part into the MMC, (1) had no cover
+ texts or invariant sections, and (2) were thus incorporated prior
+ to November 1, 2008.
+
+ The operator of an MMC Site may republish an MMC contained in the
+ site under CC-BY-SA on the same site at any time before August 1,
+ 2009, provided the MMC is eligible for relicensing.
+
+ADDENDUM: How to use this License for your documents
+====================================================
+
+To use this License in a document you have written, include a copy of
+the License in the document and put the following copyright and license
+notices just after the title page:
+
+ Copyright (C) YEAR YOUR NAME.
+ Permission is granted to copy, distribute and/or modify this document
+ under the terms of the GNU Free Documentation License, Version 1.3
+ or any later version published by the Free Software Foundation;
+ with no Invariant Sections, no Front-Cover Texts, and no Back-Cover
+ Texts. A copy of the license is included in the section entitled ``GNU
+ Free Documentation License''.
+
+ If you have Invariant Sections, Front-Cover Texts and Back-Cover
+Texts, replace the “with...Texts.” line with this:
+
+ with the Invariant Sections being LIST THEIR TITLES, with
+ the Front-Cover Texts being LIST, and with the Back-Cover Texts
+ being LIST.
+
+ If you have Invariant Sections without Cover Texts, or some other
+combination of the three, merge those two alternatives to suit the
+situation.
+
+ If your document contains nontrivial examples of program code, we
+recommend releasing these examples in parallel under your choice of free
+software license, such as the GNU General Public License, to permit
+their use in free software.
+
+
+File: dash.info, Node: GPL, Next: Index, Prev: FDL, Up: Top
+
+Appendix B GNU General Public License
+*************************************
+
+ Version 3, 29 June 2007
+
+ Copyright © 2007 Free Software Foundation, Inc.
+
+ Everyone is permitted to copy and distribute verbatim copies of this
+ license document, but changing it is not allowed.
+
+Preamble
+========
+
+The GNU General Public License is a free, copyleft license for software
+and other kinds of works.
+
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program—to make sure it remains free
+software for all its users. We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors. You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+ To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights. Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received. You must make sure that they, too, receive
+or can get the source code. And you must show them these terms so they
+know their rights.
+
+ Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+ For the developers’ and authors’ protection, the GPL clearly explains
+that there is no warranty for this free software. For both users’ and
+authors’ sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+ Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so. This is fundamentally incompatible with the aim of
+protecting users’ freedom to change the software. The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable. Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products. If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+ Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary. To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+TERMS AND CONDITIONS
+====================
+
+ 0. Definitions.
+
+ “This License” refers to version 3 of the GNU General Public
+ License.
+
+ “Copyright” also means copyright-like laws that apply to other
+ kinds of works, such as semiconductor masks.
+
+ “The Program” refers to any copyrightable work licensed under this
+ License. Each licensee is addressed as “you”. “Licensees” and
+ “recipients” may be individuals or organizations.
+
+ To “modify” a work means to copy from or adapt all or part of the
+ work in a fashion requiring copyright permission, other than the
+ making of an exact copy. The resulting work is called a “modified
+ version” of the earlier work or a work “based on” the earlier work.
+
+ A “covered work” means either the unmodified Program or a work
+ based on the Program.
+
+ To “propagate” a work means to do anything with it that, without
+ permission, would make you directly or secondarily liable for
+ infringement under applicable copyright law, except executing it on
+ a computer or modifying a private copy. Propagation includes
+ copying, distribution (with or without modification), making
+ available to the public, and in some countries other activities as
+ well.
+
+ To “convey” a work means any kind of propagation that enables other
+ parties to make or receive copies. Mere interaction with a user
+ through a computer network, with no transfer of a copy, is not
+ conveying.
+
+ An interactive user interface displays “Appropriate Legal Notices”
+ to the extent that it includes a convenient and prominently visible
+ feature that (1) displays an appropriate copyright notice, and (2)
+ tells the user that there is no warranty for the work (except to
+ the extent that warranties are provided), that licensees may convey
+ the work under this License, and how to view a copy of this
+ License. If the interface presents a list of user commands or
+ options, such as a menu, a prominent item in the list meets this
+ criterion.
+
+ 1. Source Code.
+
+ The “source code” for a work means the preferred form of the work
+ for making modifications to it. “Object code” means any non-source
+ form of a work.
+
+ A “Standard Interface” means an interface that either is an
+ official standard defined by a recognized standards body, or, in
+ the case of interfaces specified for a particular programming
+ language, one that is widely used among developers working in that
+ language.
+
+ The “System Libraries” of an executable work include anything,
+ other than the work as a whole, that (a) is included in the normal
+ form of packaging a Major Component, but which is not part of that
+ Major Component, and (b) serves only to enable use of the work with
+ that Major Component, or to implement a Standard Interface for
+ which an implementation is available to the public in source code
+ form. A “Major Component”, in this context, means a major
+ essential component (kernel, window system, and so on) of the
+ specific operating system (if any) on which the executable work
+ runs, or a compiler used to produce the work, or an object code
+ interpreter used to run it.
+
+ The “Corresponding Source” for a work in object code form means all
+ the source code needed to generate, install, and (for an executable
+ work) run the object code and to modify the work, including scripts
+ to control those activities. However, it does not include the
+ work’s System Libraries, or general-purpose tools or generally
+ available free programs which are used unmodified in performing
+ those activities but which are not part of the work. For example,
+ Corresponding Source includes interface definition files associated
+ with source files for the work, and the source code for shared
+ libraries and dynamically linked subprograms that the work is
+ specifically designed to require, such as by intimate data
+ communication or control flow between those subprograms and other
+ parts of the work.
+
+ The Corresponding Source need not include anything that users can
+ regenerate automatically from other parts of the Corresponding
+ Source.
+
+ The Corresponding Source for a work in source code form is that
+ same work.
+
+ 2. Basic Permissions.
+
+ All rights granted under this License are granted for the term of
+ copyright on the Program, and are irrevocable provided the stated
+ conditions are met. This License explicitly affirms your unlimited
+ permission to run the unmodified Program. The output from running
+ a covered work is covered by this License only if the output, given
+ its content, constitutes a covered work. This License acknowledges
+ your rights of fair use or other equivalent, as provided by
+ copyright law.
+
+ You may make, run and propagate covered works that you do not
+ convey, without conditions so long as your license otherwise
+ remains in force. You may convey covered works to others for the
+ sole purpose of having them make modifications exclusively for you,
+ or provide you with facilities for running those works, provided
+ that you comply with the terms of this License in conveying all
+ material for which you do not control copyright. Those thus making
+ or running the covered works for you must do so exclusively on your
+ behalf, under your direction and control, on terms that prohibit
+ them from making any copies of your copyrighted material outside
+ their relationship with you.
+
+ Conveying under any other circumstances is permitted solely under
+ the conditions stated below. Sublicensing is not allowed; section
+ 10 makes it unnecessary.
+
+ 3. Protecting Users’ Legal Rights From Anti-Circumvention Law.
+
+ No covered work shall be deemed part of an effective technological
+ measure under any applicable law fulfilling obligations under
+ article 11 of the WIPO copyright treaty adopted on 20 December
+ 1996, or similar laws prohibiting or restricting circumvention of
+ such measures.
+
+ When you convey a covered work, you waive any legal power to forbid
+ circumvention of technological measures to the extent such
+ circumvention is effected by exercising rights under this License
+ with respect to the covered work, and you disclaim any intention to
+ limit operation or modification of the work as a means of
+ enforcing, against the work’s users, your or third parties’ legal
+ rights to forbid circumvention of technological measures.
+
+ 4. Conveying Verbatim Copies.
+
+ You may convey verbatim copies of the Program’s source code as you
+ receive it, in any medium, provided that you conspicuously and
+ appropriately publish on each copy an appropriate copyright notice;
+ keep intact all notices stating that this License and any
+ non-permissive terms added in accord with section 7 apply to the
+ code; keep intact all notices of the absence of any warranty; and
+ give all recipients a copy of this License along with the Program.
+
+ You may charge any price or no price for each copy that you convey,
+ and you may offer support or warranty protection for a fee.
+
+ 5. Conveying Modified Source Versions.
+
+ You may convey a work based on the Program, or the modifications to
+ produce it from the Program, in the form of source code under the
+ terms of section 4, provided that you also meet all of these
+ conditions:
+
+ a. The work must carry prominent notices stating that you
+ modified it, and giving a relevant date.
+
+ b. The work must carry prominent notices stating that it is
+ released under this License and any conditions added under
+ section 7. This requirement modifies the requirement in
+ section 4 to “keep intact all notices”.
+
+ c. You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable
+ section 7 additional terms, to the whole of the work, and all
+ its parts, regardless of how they are packaged. This License
+ gives no permission to license the work in any other way, but
+ it does not invalidate such permission if you have separately
+ received it.
+
+ d. If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has
+ interactive interfaces that do not display Appropriate Legal
+ Notices, your work need not make them do so.
+
+ A compilation of a covered work with other separate and independent
+ works, which are not by their nature extensions of the covered
+ work, and which are not combined with it such as to form a larger
+ program, in or on a volume of a storage or distribution medium, is
+ called an “aggregate” if the compilation and its resulting
+ copyright are not used to limit the access or legal rights of the
+ compilation’s users beyond what the individual works permit.
+ Inclusion of a covered work in an aggregate does not cause this
+ License to apply to the other parts of the aggregate.
+
+ 6. Conveying Non-Source Forms.
+
+ You may convey a covered work in object code form under the terms
+ of sections 4 and 5, provided that you also convey the
+ machine-readable Corresponding Source under the terms of this
+ License, in one of these ways:
+
+ a. Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+
+ b. Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that
+ product model, to give anyone who possesses the object code
+ either (1) a copy of the Corresponding Source for all the
+ software in the product that is covered by this License, on a
+ durable physical medium customarily used for software
+ interchange, for a price no more than your reasonable cost of
+ physically performing this conveying of source, or (2) access
+ to copy the Corresponding Source from a network server at no
+ charge.
+
+ c. Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially,
+ and only if you received the object code with such an offer,
+ in accord with subsection 6b.
+
+ d. Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to
+ the Corresponding Source in the same way through the same
+ place at no further charge. You need not require recipients
+ to copy the Corresponding Source along with the object code.
+ If the place to copy the object code is a network server, the
+ Corresponding Source may be on a different server (operated by
+ you or a third party) that supports equivalent copying
+ facilities, provided you maintain clear directions next to the
+ object code saying where to find the Corresponding Source.
+ Regardless of what server hosts the Corresponding Source, you
+ remain obligated to ensure that it is available for as long as
+ needed to satisfy these requirements.
+
+ e. Convey the object code using peer-to-peer transmission,
+ provided you inform other peers where the object code and
+ Corresponding Source of the work are being offered to the
+ general public at no charge under subsection 6d.
+
+ A separable portion of the object code, whose source code is
+ excluded from the Corresponding Source as a System Library, need
+ not be included in conveying the object code work.
+
+ A “User Product” is either (1) a “consumer product”, which means
+ any tangible personal property which is normally used for personal,
+ family, or household purposes, or (2) anything designed or sold for
+ incorporation into a dwelling. In determining whether a product is
+ a consumer product, doubtful cases shall be resolved in favor of
+ coverage. For a particular product received by a particular user,
+ “normally used” refers to a typical or common use of that class of
+ product, regardless of the status of the particular user or of the
+ way in which the particular user actually uses, or expects or is
+ expected to use, the product. A product is a consumer product
+ regardless of whether the product has substantial commercial,
+ industrial or non-consumer uses, unless such uses represent the
+ only significant mode of use of the product.
+
+ “Installation Information” for a User Product means any methods,
+ procedures, authorization keys, or other information required to
+ install and execute modified versions of a covered work in that
+ User Product from a modified version of its Corresponding Source.
+ The information must suffice to ensure that the continued
+ functioning of the modified object code is in no case prevented or
+ interfered with solely because modification has been made.
+
+ If you convey an object code work under this section in, or with,
+ or specifically for use in, a User Product, and the conveying
+ occurs as part of a transaction in which the right of possession
+ and use of the User Product is transferred to the recipient in
+ perpetuity or for a fixed term (regardless of how the transaction
+ is characterized), the Corresponding Source conveyed under this
+ section must be accompanied by the Installation Information. But
+ this requirement does not apply if neither you nor any third party
+ retains the ability to install modified object code on the User
+ Product (for example, the work has been installed in ROM).
+
+ The requirement to provide Installation Information does not
+ include a requirement to continue to provide support service,
+ warranty, or updates for a work that has been modified or installed
+ by the recipient, or for the User Product in which it has been
+ modified or installed. Access to a network may be denied when the
+ modification itself materially and adversely affects the operation
+ of the network or violates the rules and protocols for
+ communication across the network.
+
+ Corresponding Source conveyed, and Installation Information
+ provided, in accord with this section must be in a format that is
+ publicly documented (and with an implementation available to the
+ public in source code form), and must require no special password
+ or key for unpacking, reading or copying.
+
+ 7. Additional Terms.
+
+ “Additional permissions” are terms that supplement the terms of
+ this License by making exceptions from one or more of its
+ conditions. Additional permissions that are applicable to the
+ entire Program shall be treated as though they were included in
+ this License, to the extent that they are valid under applicable
+ law. If additional permissions apply only to part of the Program,
+ that part may be used separately under those permissions, but the
+ entire Program remains governed by this License without regard to
+ the additional permissions.
+
+ When you convey a copy of a covered work, you may at your option
+ remove any additional permissions from that copy, or from any part
+ of it. (Additional permissions may be written to require their own
+ removal in certain cases when you modify the work.) You may place
+ additional permissions on material, added by you to a covered work,
+ for which you have or can give appropriate copyright permission.
+
+ Notwithstanding any other provision of this License, for material
+ you add to a covered work, you may (if authorized by the copyright
+ holders of that material) supplement the terms of this License with
+ terms:
+
+ a. Disclaiming warranty or limiting liability differently from
+ the terms of sections 15 and 16 of this License; or
+
+ b. Requiring preservation of specified reasonable legal notices
+ or author attributions in that material or in the Appropriate
+ Legal Notices displayed by works containing it; or
+
+ c. Prohibiting misrepresentation of the origin of that material,
+ or requiring that modified versions of such material be marked
+ in reasonable ways as different from the original version; or
+
+ d. Limiting the use for publicity purposes of names of licensors
+ or authors of the material; or
+
+ e. Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+
+ f. Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified
+ versions of it) with contractual assumptions of liability to
+ the recipient, for any liability that these contractual
+ assumptions directly impose on those licensors and authors.
+
+ All other non-permissive additional terms are considered “further
+ restrictions” within the meaning of section 10. If the Program as
+ you received it, or any part of it, contains a notice stating that
+ it is governed by this License along with a term that is a further
+ restriction, you may remove that term. If a license document
+ contains a further restriction but permits relicensing or conveying
+ under this License, you may add to a covered work material governed
+ by the terms of that license document, provided that the further
+ restriction does not survive such relicensing or conveying.
+
+ If you add terms to a covered work in accord with this section, you
+ must place, in the relevant source files, a statement of the
+ additional terms that apply to those files, or a notice indicating
+ where to find the applicable terms.
+
+ Additional terms, permissive or non-permissive, may be stated in
+ the form of a separately written license, or stated as exceptions;
+ the above requirements apply either way.
+
+ 8. Termination.
+
+ You may not propagate or modify a covered work except as expressly
+ provided under this License. Any attempt otherwise to propagate or
+ modify it is void, and will automatically terminate your rights
+ under this License (including any patent licenses granted under the
+ third paragraph of section 11).
+
+ However, if you cease all violation of this License, then your
+ license from a particular copyright holder is reinstated (a)
+ provisionally, unless and until the copyright holder explicitly and
+ finally terminates your license, and (b) permanently, if the
+ copyright holder fails to notify you of the violation by some
+ reasonable means prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+ reinstated permanently if the copyright holder notifies you of the
+ violation by some reasonable means, this is the first time you have
+ received notice of violation of this License (for any work) from
+ that copyright holder, and you cure the violation prior to 30 days
+ after your receipt of the notice.
+
+ Termination of your rights under this section does not terminate
+ the licenses of parties who have received copies or rights from you
+ under this License. If your rights have been terminated and not
+ permanently reinstated, you do not qualify to receive new licenses
+ for the same material under section 10.
+
+ 9. Acceptance Not Required for Having Copies.
+
+ You are not required to accept this License in order to receive or
+ run a copy of the Program. Ancillary propagation of a covered work
+ occurring solely as a consequence of using peer-to-peer
+ transmission to receive a copy likewise does not require
+ acceptance. However, nothing other than this License grants you
+ permission to propagate or modify any covered work. These actions
+ infringe copyright if you do not accept this License. Therefore,
+ by modifying or propagating a covered work, you indicate your
+ acceptance of this License to do so.
+
+ 10. Automatic Licensing of Downstream Recipients.
+
+ Each time you convey a covered work, the recipient automatically
+ receives a license from the original licensors, to run, modify and
+ propagate that work, subject to this License. You are not
+ responsible for enforcing compliance by third parties with this
+ License.
+
+ An “entity transaction” is a transaction transferring control of an
+ organization, or substantially all assets of one, or subdividing an
+ organization, or merging organizations. If propagation of a
+ covered work results from an entity transaction, each party to that
+ transaction who receives a copy of the work also receives whatever
+ licenses to the work the party’s predecessor in interest had or
+ could give under the previous paragraph, plus a right to possession
+ of the Corresponding Source of the work from the predecessor in
+ interest, if the predecessor has it or can get it with reasonable
+ efforts.
+
+ You may not impose any further restrictions on the exercise of the
+ rights granted or affirmed under this License. For example, you
+ may not impose a license fee, royalty, or other charge for exercise
+ of rights granted under this License, and you may not initiate
+ litigation (including a cross-claim or counterclaim in a lawsuit)
+ alleging that any patent claim is infringed by making, using,
+ selling, offering for sale, or importing the Program or any portion
+ of it.
+
+ 11. Patents.
+
+ A “contributor” is a copyright holder who authorizes use under this
+ License of the Program or a work on which the Program is based.
+ The work thus licensed is called the contributor’s “contributor
+ version”.
+
+ A contributor’s “essential patent claims” are all patent claims
+ owned or controlled by the contributor, whether already acquired or
+ hereafter acquired, that would be infringed by some manner,
+ permitted by this License, of making, using, or selling its
+ contributor version, but do not include claims that would be
+ infringed only as a consequence of further modification of the
+ contributor version. For purposes of this definition, “control”
+ includes the right to grant patent sublicenses in a manner
+ consistent with the requirements of this License.
+
+ Each contributor grants you a non-exclusive, worldwide,
+ royalty-free patent license under the contributor’s essential
+ patent claims, to make, use, sell, offer for sale, import and
+ otherwise run, modify and propagate the contents of its contributor
+ version.
+
+ In the following three paragraphs, a “patent license” is any
+ express agreement or commitment, however denominated, not to
+ enforce a patent (such as an express permission to practice a
+ patent or covenant not to sue for patent infringement). To “grant”
+ such a patent license to a party means to make such an agreement or
+ commitment not to enforce a patent against the party.
+
+ If you convey a covered work, knowingly relying on a patent
+ license, and the Corresponding Source of the work is not available
+ for anyone to copy, free of charge and under the terms of this
+ License, through a publicly available network server or other
+ readily accessible means, then you must either (1) cause the
+ Corresponding Source to be so available, or (2) arrange to deprive
+ yourself of the benefit of the patent license for this particular
+ work, or (3) arrange, in a manner consistent with the requirements
+ of this License, to extend the patent license to downstream
+ recipients. “Knowingly relying” means you have actual knowledge
+ that, but for the patent license, your conveying the covered work
+ in a country, or your recipient’s use of the covered work in a
+ country, would infringe one or more identifiable patents in that
+ country that you have reason to believe are valid.
+
+ If, pursuant to or in connection with a single transaction or
+ arrangement, you convey, or propagate by procuring conveyance of, a
+ covered work, and grant a patent license to some of the parties
+ receiving the covered work authorizing them to use, propagate,
+ modify or convey a specific copy of the covered work, then the
+ patent license you grant is automatically extended to all
+ recipients of the covered work and works based on it.
+
+ A patent license is “discriminatory” if it does not include within
+ the scope of its coverage, prohibits the exercise of, or is
+ conditioned on the non-exercise of one or more of the rights that
+ are specifically granted under this License. You may not convey a
+ covered work if you are a party to an arrangement with a third
+ party that is in the business of distributing software, under which
+ you make payment to the third party based on the extent of your
+ activity of conveying the work, and under which the third party
+ grants, to any of the parties who would receive the covered work
+ from you, a discriminatory patent license (a) in connection with
+ copies of the covered work conveyed by you (or copies made from
+ those copies), or (b) primarily for and in connection with specific
+ products or compilations that contain the covered work, unless you
+ entered into that arrangement, or that patent license was granted,
+ prior to 28 March 2007.
+
+ Nothing in this License shall be construed as excluding or limiting
+ any implied license or other defenses to infringement that may
+ otherwise be available to you under applicable patent law.
+
+ 12. No Surrender of Others’ Freedom.
+
+ If conditions are imposed on you (whether by court order, agreement
+ or otherwise) that contradict the conditions of this License, they
+ do not excuse you from the conditions of this License. If you
+ cannot convey a covered work so as to satisfy simultaneously your
+ obligations under this License and any other pertinent obligations,
+ then as a consequence you may not convey it at all. For example,
+ if you agree to terms that obligate you to collect a royalty for
+ further conveying from those to whom you convey the Program, the
+ only way you could satisfy both those terms and this License would
+ be to refrain entirely from conveying the Program.
+
+ 13. Use with the GNU Affero General Public License.
+
+ Notwithstanding any other provision of this License, you have
+ permission to link or combine any covered work with a work licensed
+ under version 3 of the GNU Affero General Public License into a
+ single combined work, and to convey the resulting work. The terms
+ of this License will continue to apply to the part which is the
+ covered work, but the special requirements of the GNU Affero
+ General Public License, section 13, concerning interaction through
+ a network will apply to the combination as such.
+
+ 14. Revised Versions of this License.
+
+ The Free Software Foundation may publish revised and/or new
+ versions of the GNU General Public License from time to time. Such
+ new versions will be similar in spirit to the present version, but
+ may differ in detail to address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+ Program specifies that a certain numbered version of the GNU
+ General Public License “or any later version” applies to it, you
+ have the option of following the terms and conditions either of
+ that numbered version or of any later version published by the Free
+ Software Foundation. If the Program does not specify a version
+ number of the GNU General Public License, you may choose any
+ version ever published by the Free Software Foundation.
+
+ If the Program specifies that a proxy can decide which future
+ versions of the GNU General Public License can be used, that
+ proxy’s public statement of acceptance of a version permanently
+ authorizes you to choose that version for the Program.
+
+ Later license versions may give you additional or different
+ permissions. However, no additional obligations are imposed on any
+ author or copyright holder as a result of your choosing to follow a
+ later version.
+
+ 15. Disclaimer of Warranty.
+
+ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+ APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE
+ COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM “AS IS”
+ WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED,
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE
+ RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.
+ SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL
+ NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. Limitation of Liability.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+ WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES
+ AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR
+ DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+ CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE
+ THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA
+ BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+ PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+ PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF
+ THE POSSIBILITY OF SUCH DAMAGES.
+
+ 17. Interpretation of Sections 15 and 16.
+
+ If the disclaimer of warranty and limitation of liability provided
+ above cannot be given local legal effect according to their terms,
+ reviewing courts shall apply local law that most closely
+ approximates an absolute waiver of all civil liability in
+ connection with the Program, unless a warranty or assumption of
+ liability accompanies a copy of the Program in return for a fee.
+
+END OF TERMS AND CONDITIONS
+===========================
+
+How to Apply These Terms to Your New Programs
+=============================================
+
+If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these
+terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least the
+“copyright” line and a pointer to where the full notice is found.
+
+ ONE LINE TO GIVE THE PROGRAM'S NAME AND A BRIEF IDEA OF WHAT IT DOES.
+ Copyright (C) YEAR NAME OF AUTHOR
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or (at
+ your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+
+ Also add information on how to contact you by electronic and paper
+mail.
+
+ If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+ PROGRAM Copyright (C) YEAR NAME OF AUTHOR
+ This program comes with ABSOLUTELY NO WARRANTY; for details type ‘show w’.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type ‘show c’ for details.
+
+ The hypothetical commands ‘show w’ and ‘show c’ should show the
+appropriate parts of the General Public License. Of course, your
+program’s commands might be different; for a GUI interface, you would
+use an “about box”.
+
+ You should also get your employer (if you work as a programmer) or
+school, if any, to sign a “copyright disclaimer” for the program, if
+necessary. For more information on this, and how to apply and follow
+the GNU GPL, see .
+
+ The GNU General Public License does not permit incorporating your
+program into proprietary programs. If your program is a subroutine
+library, you may consider it more useful to permit linking proprietary
+applications with the library. If this is what you want to do, use the
+GNU Lesser General Public License instead of this License. But first,
+please read .
+
+
+File: dash.info, Node: Index, Prev: GPL, Up: Top
+
+Index
+*****
+
+ [index ]
+* Menu:
+
+* !cdr: Destructive operations.
+ (line 16)
+* !cons: Destructive operations.
+ (line 8)
+* -->: Threading macros. (line 35)
+* ->: Threading macros. (line 9)
+* ->>: Threading macros. (line 22)
+* -all?: Predicates. (line 20)
+* -andfn: Function combinators.
+ (line 137)
+* -annotate: Maps. (line 84)
+* -any?: Predicates. (line 8)
+* -applify: Function combinators.
+ (line 54)
+* -as->: Threading macros. (line 49)
+* -butlast: Other list operations.
+ (line 350)
+* -clone: Tree operations. (line 122)
+* -common-prefix: Reductions. (line 242)
+* -common-suffix: Reductions. (line 252)
+* -compose: Function combinators.
+ (line 41)
+* -concat: List to list. (line 23)
+* -cons*: Other list operations.
+ (line 30)
+* -cons-pair?: Predicates. (line 126)
+* -const: Function combinators.
+ (line 91)
+* -contains?: Predicates. (line 59)
+* -copy: Maps. (line 139)
+* -count: Reductions. (line 172)
+* -cut: Function combinators.
+ (line 103)
+* -cycle: Other list operations.
+ (line 180)
+* -difference: Set operations. (line 20)
+* -distinct: Set operations. (line 62)
+* -dotimes: Side effects. (line 80)
+* -doto: Threading macros. (line 99)
+* -drop: Sublist selection. (line 147)
+* -drop-last: Sublist selection. (line 161)
+* -drop-while: Sublist selection. (line 192)
+* -each: Side effects. (line 8)
+* -each-indexed: Side effects. (line 38)
+* -each-r: Side effects. (line 52)
+* -each-r-while: Side effects. (line 65)
+* -each-while: Side effects. (line 24)
+* -elem-index: Indexing. (line 9)
+* -elem-indices: Indexing. (line 21)
+* -fifth-item: Other list operations.
+ (line 330)
+* -filter: Sublist selection. (line 8)
+* -find-index: Indexing. (line 32)
+* -find-indices: Indexing. (line 60)
+* -find-last-index: Indexing. (line 46)
+* -first: Other list operations.
+ (line 246)
+* -first-item: Other list operations.
+ (line 287)
+* -fix: Other list operations.
+ (line 390)
+* -fixfn: Function combinators.
+ (line 174)
+* -flatten: List to list. (line 34)
+* -flatten-n: List to list. (line 56)
+* -flip: Function combinators.
+ (line 79)
+* -fourth-item: Other list operations.
+ (line 320)
+* -grade-down: Indexing. (line 81)
+* -grade-up: Indexing. (line 71)
+* -group-by: Partitioning. (line 193)
+* -if-let: Binding. (line 34)
+* -if-let*: Binding. (line 45)
+* -inits: Reductions. (line 222)
+* -insert-at: List to list. (line 110)
+* -interleave: Other list operations.
+ (line 67)
+* -interpose: Other list operations.
+ (line 57)
+* -intersection: Set operations. (line 32)
+* -iota: Other list operations.
+ (line 78)
+* -is-infix?: Predicates. (line 112)
+* -is-prefix?: Predicates. (line 88)
+* -is-suffix?: Predicates. (line 100)
+* -iterate: Unfolding. (line 9)
+* -iteratefn: Function combinators.
+ (line 151)
+* -juxt: Function combinators.
+ (line 30)
+* -keep: List to list. (line 8)
+* -lambda: Binding. (line 247)
+* -last: Other list operations.
+ (line 277)
+* -last-item: Other list operations.
+ (line 340)
+* -let: Binding. (line 61)
+* -let*: Binding. (line 227)
+* -list: Other list operations.
+ (line 373)
+* -map: Maps. (line 10)
+* -map-first: Maps. (line 38)
+* -map-indexed: Maps. (line 66)
+* -map-last: Maps. (line 52)
+* -map-when: Maps. (line 22)
+* -mapcat: Maps. (line 128)
+* -max: Reductions. (line 286)
+* -max-by: Reductions. (line 296)
+* -min: Reductions. (line 262)
+* -min-by: Reductions. (line 272)
+* -non-nil: Sublist selection. (line 94)
+* -none?: Predicates. (line 32)
+* -not: Function combinators.
+ (line 116)
+* -on: Function combinators.
+ (line 65)
+* -only-some?: Predicates. (line 44)
+* -orfn: Function combinators.
+ (line 125)
+* -pad: Other list operations.
+ (line 191)
+* -partial: Function combinators.
+ (line 8)
+* -partition: Partitioning. (line 80)
+* -partition-after-item: Partitioning. (line 183)
+* -partition-after-pred: Partitioning. (line 151)
+* -partition-all: Partitioning. (line 92)
+* -partition-all-in-steps: Partitioning. (line 115)
+* -partition-before-item: Partitioning. (line 173)
+* -partition-before-pred: Partitioning. (line 162)
+* -partition-by: Partitioning. (line 127)
+* -partition-by-header: Partitioning. (line 138)
+* -partition-in-steps: Partitioning. (line 103)
+* -permutations: Set operations. (line 52)
+* -powerset: Set operations. (line 44)
+* -prodfn: Function combinators.
+ (line 208)
+* -product: Reductions. (line 201)
+* -reduce: Reductions. (line 53)
+* -reduce-from: Reductions. (line 8)
+* -reduce-r: Reductions. (line 72)
+* -reduce-r-from: Reductions. (line 26)
+* -reductions: Reductions. (line 136)
+* -reductions-from: Reductions. (line 100)
+* -reductions-r: Reductions. (line 154)
+* -reductions-r-from: Reductions. (line 118)
+* -remove: Sublist selection. (line 26)
+* -remove-at: List to list. (line 146)
+* -remove-at-indices: List to list. (line 159)
+* -remove-first: Sublist selection. (line 43)
+* -remove-item: Sublist selection. (line 83)
+* -remove-last: Sublist selection. (line 64)
+* -repeat: Other list operations.
+ (line 19)
+* -replace: List to list. (line 68)
+* -replace-at: List to list. (line 121)
+* -replace-first: List to list. (line 82)
+* -replace-last: List to list. (line 96)
+* -rotate: Other list operations.
+ (line 8)
+* -rpartial: Function combinators.
+ (line 19)
+* -running-product: Reductions. (line 211)
+* -running-sum: Reductions. (line 190)
+* -same-items?: Predicates. (line 74)
+* -second-item: Other list operations.
+ (line 300)
+* -select-by-indices: Sublist selection. (line 208)
+* -select-column: Sublist selection. (line 238)
+* -select-columns: Sublist selection. (line 219)
+* -separate: Partitioning. (line 69)
+* -setq: Binding. (line 270)
+* -slice: Sublist selection. (line 104)
+* -snoc: Other list operations.
+ (line 43)
+* -some: Other list operations.
+ (line 262)
+* -some-->: Threading macros. (line 86)
+* -some->: Threading macros. (line 62)
+* -some->>: Threading macros. (line 74)
+* -sort: Other list operations.
+ (line 360)
+* -splice: Maps. (line 95)
+* -splice-list: Maps. (line 115)
+* -split-at: Partitioning. (line 8)
+* -split-on: Partitioning. (line 34)
+* -split-when: Partitioning. (line 52)
+* -split-with: Partitioning. (line 23)
+* -sum: Reductions. (line 180)
+* -table: Other list operations.
+ (line 202)
+* -table-flat: Other list operations.
+ (line 221)
+* -tails: Reductions. (line 232)
+* -take: Sublist selection. (line 120)
+* -take-last: Sublist selection. (line 133)
+* -take-while: Sublist selection. (line 175)
+* -third-item: Other list operations.
+ (line 310)
+* -tree-map: Tree operations. (line 28)
+* -tree-map-nodes: Tree operations. (line 39)
+* -tree-mapreduce: Tree operations. (line 84)
+* -tree-mapreduce-from: Tree operations. (line 103)
+* -tree-reduce: Tree operations. (line 52)
+* -tree-reduce-from: Tree operations. (line 69)
+* -tree-seq: Tree operations. (line 8)
+* -unfold: Unfolding. (line 25)
+* -union: Set operations. (line 8)
+* -unzip: Other list operations.
+ (line 158)
+* -update-at: List to list. (line 133)
+* -when-let: Binding. (line 9)
+* -when-let*: Binding. (line 21)
+* -zip: Other list operations.
+ (line 107)
+* -zip-fill: Other list operations.
+ (line 150)
+* -zip-lists: Other list operations.
+ (line 131)
+* -zip-with: Other list operations.
+ (line 91)
+* dash-fontify-mode: Fontification of special variables.
+ (line 6)
+* dash-register-info-lookup: Info symbol lookup. (line 6)
+* global-dash-fontify-mode: Fontification of special variables.
+ (line 12)
+
+
+
+Tag Table:
+Node: Top742
+Node: Installation2397
+Node: Using in a package3112
+Node: Fontification of special variables3457
+Node: Info symbol lookup4247
+Node: Functions4830
+Node: Maps6314
+Ref: -map6611
+Ref: -map-when6984
+Ref: -map-first7559
+Ref: -map-last8034
+Ref: -map-indexed8504
+Ref: -annotate9190
+Ref: -splice9677
+Ref: -splice-list10455
+Ref: -mapcat10914
+Ref: -copy11287
+Node: Sublist selection11475
+Ref: -filter11668
+Ref: -remove12215
+Ref: -remove-first12753
+Ref: -remove-last13595
+Ref: -remove-item14320
+Ref: -non-nil14720
+Ref: -slice14996
+Ref: -take15525
+Ref: -take-last15932
+Ref: -drop16363
+Ref: -drop-last16804
+Ref: -take-while17230
+Ref: -drop-while17845
+Ref: -select-by-indices18461
+Ref: -select-columns18972
+Ref: -select-column19675
+Node: List to list20138
+Ref: -keep20330
+Ref: -concat20894
+Ref: -flatten21188
+Ref: -flatten-n21944
+Ref: -replace22328
+Ref: -replace-first22789
+Ref: -replace-last23284
+Ref: -insert-at23772
+Ref: -replace-at24097
+Ref: -update-at24484
+Ref: -remove-at24972
+Ref: -remove-at-indices25457
+Node: Reductions26036
+Ref: -reduce-from26232
+Ref: -reduce-r-from26956
+Ref: -reduce28219
+Ref: -reduce-r28970
+Ref: -reductions-from30248
+Ref: -reductions-r-from31054
+Ref: -reductions31884
+Ref: -reductions-r32595
+Ref: -count33340
+Ref: -sum33564
+Ref: -running-sum33752
+Ref: -product34073
+Ref: -running-product34281
+Ref: -inits34622
+Ref: -tails34867
+Ref: -common-prefix35111
+Ref: -common-suffix35405
+Ref: -min35699
+Ref: -min-by35925
+Ref: -max36446
+Ref: -max-by36671
+Node: Unfolding37197
+Ref: -iterate37438
+Ref: -unfold37885
+Node: Predicates38690
+Ref: -any?38867
+Ref: -all?39187
+Ref: -none?39517
+Ref: -only-some?39819
+Ref: -contains?40304
+Ref: -same-items?40693
+Ref: -is-prefix?41078
+Ref: -is-suffix?41404
+Ref: -is-infix?41730
+Ref: -cons-pair?42084
+Node: Partitioning42409
+Ref: -split-at42597
+Ref: -split-with43261
+Ref: -split-on43661
+Ref: -split-when44334
+Ref: -separate44971
+Ref: -partition45410
+Ref: -partition-all45859
+Ref: -partition-in-steps46284
+Ref: -partition-all-in-steps46778
+Ref: -partition-by47260
+Ref: -partition-by-header47638
+Ref: -partition-after-pred48239
+Ref: -partition-before-pred48617
+Ref: -partition-before-item49002
+Ref: -partition-after-item49309
+Ref: -group-by49611
+Node: Indexing50044
+Ref: -elem-index50246
+Ref: -elem-indices50641
+Ref: -find-index51021
+Ref: -find-last-index51510
+Ref: -find-indices52014
+Ref: -grade-up52419
+Ref: -grade-down52826
+Node: Set operations53240
+Ref: -union53423
+Ref: -difference53861
+Ref: -intersection54273
+Ref: -powerset54705
+Ref: -permutations54915
+Ref: -distinct55211
+Node: Other list operations55585
+Ref: -rotate55810
+Ref: -repeat56177
+Ref: -cons*56456
+Ref: -snoc56872
+Ref: -interpose57282
+Ref: -interleave57576
+Ref: -iota57942
+Ref: -zip-with58425
+Ref: -zip59139
+Ref: -zip-lists59968
+Ref: -zip-fill60666
+Ref: -unzip60988
+Ref: -cycle61730
+Ref: -pad62129
+Ref: -table62448
+Ref: -table-flat63234
+Ref: -first64239
+Ref: -some64725
+Ref: -last65209
+Ref: -first-item65543
+Ref: -second-item65942
+Ref: -third-item66206
+Ref: -fourth-item66468
+Ref: -fifth-item66734
+Ref: -last-item66996
+Ref: -butlast67287
+Ref: -sort67532
+Ref: -list68018
+Ref: -fix68587
+Node: Tree operations69076
+Ref: -tree-seq69272
+Ref: -tree-map70127
+Ref: -tree-map-nodes70567
+Ref: -tree-reduce71414
+Ref: -tree-reduce-from72296
+Ref: -tree-mapreduce72896
+Ref: -tree-mapreduce-from73755
+Ref: -clone75040
+Node: Threading macros75367
+Ref: ->75592
+Ref: ->>76080
+Ref: -->76583
+Ref: -as->77139
+Ref: -some->77593
+Ref: -some->>77966
+Ref: -some-->78401
+Ref: -doto78950
+Node: Binding79503
+Ref: -when-let79710
+Ref: -when-let*80165
+Ref: -if-let80688
+Ref: -if-let*81048
+Ref: -let81665
+Ref: -let*87737
+Ref: -lambda88674
+Ref: -setq89480
+Node: Side effects90281
+Ref: -each90475
+Ref: -each-while90996
+Ref: -each-indexed91598
+Ref: -each-r92184
+Ref: -each-r-while92620
+Ref: -dotimes93246
+Node: Destructive operations93799
+Ref: !cons94017
+Ref: !cdr94221
+Node: Function combinators94414
+Ref: -partial94618
+Ref: -rpartial95012
+Ref: -juxt95415
+Ref: -compose95845
+Ref: -applify96398
+Ref: -on96827
+Ref: -flip97351
+Ref: -const97662
+Ref: -cut98000
+Ref: -not98480
+Ref: -orfn98789
+Ref: -andfn99222
+Ref: -iteratefn99716
+Ref: -fixfn100418
+Ref: -prodfn101974
+Node: Development103032
+Node: Contribute103321
+Node: Contributors104333
+Node: FDL106426
+Node: GPL131746
+Node: Index169495
+
+End Tag Table
+
+
+Local Variables:
+coding: utf-8
+End:
diff --git a/elpa/dash-2.17.0/dir b/elpa/dash-2.18.0/dir
old mode 100755
new mode 100644
similarity index 99%
rename from elpa/dash-2.17.0/dir
rename to elpa/dash-2.18.0/dir
index 49b1700..7d473f4
--- a/elpa/dash-2.17.0/dir
+++ b/elpa/dash-2.18.0/dir
@@ -15,4 +15,4 @@ File: dir, Node: Top This is the top of the INFO tree
* Menu:
Emacs
-* Dash: (dash.info). A modern list library for GNU Emacs
+* Dash: (dash.info). A modern list library for GNU Emacs.
diff --git a/elpa/dockerfile-mode-1.3/dockerfile-mode-pkg.el b/elpa/dockerfile-mode-1.3/dockerfile-mode-pkg.el
deleted file mode 100755
index 98dec20..0000000
--- a/elpa/dockerfile-mode-1.3/dockerfile-mode-pkg.el
+++ /dev/null
@@ -1,2 +0,0 @@
-;;; Generated package description from /data/data/com.termux/files/home/.emacs.d/elpa/dockerfile-mode-1.3/dockerfile-mode.el -*- no-byte-compile: t -*-
-(define-package "dockerfile-mode" "1.3" "Major mode for editing Docker's Dockerfiles" '((emacs "24") (s "1.12")) :commit "d31f7685ebc5832d957e25070a930aa42984327d" :url "https://github.com/spotify/dockerfile-mode")
diff --git a/elpa/dockerfile-mode-1.3/dockerfile-mode-autoloads.el b/elpa/dockerfile-mode-1.4/dockerfile-mode-autoloads.el
old mode 100755
new mode 100644
similarity index 88%
rename from elpa/dockerfile-mode-1.3/dockerfile-mode-autoloads.el
rename to elpa/dockerfile-mode-1.4/dockerfile-mode-autoloads.el
index 15510a8..7a49a5c
--- a/elpa/dockerfile-mode-1.3/dockerfile-mode-autoloads.el
+++ b/elpa/dockerfile-mode-1.4/dockerfile-mode-autoloads.el
@@ -30,7 +30,9 @@ A major mode to edit Dockerfiles.
\(fn)" t nil)
-(add-to-list 'auto-mode-alist '("Dockerfile\\(?:\\..*\\)?\\'" . dockerfile-mode))
+(add-to-list 'auto-mode-alist '("/Dockerfile\\(?:\\..*\\)?\\'" . dockerfile-mode))
+
+(add-to-list 'auto-mode-alist '("\\.dockerfile\\'" . dockerfile-mode))
(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "dockerfile-mode" '("dockerfile-")))
diff --git a/elpa/dockerfile-mode-1.4/dockerfile-mode-pkg.el b/elpa/dockerfile-mode-1.4/dockerfile-mode-pkg.el
new file mode 100644
index 0000000..385f85a
--- /dev/null
+++ b/elpa/dockerfile-mode-1.4/dockerfile-mode-pkg.el
@@ -0,0 +1,2 @@
+;;; Generated package description from /home/raphael/.emacs.d/elpa/dockerfile-mode-1.4/dockerfile-mode.el -*- no-byte-compile: t -*-
+(define-package "dockerfile-mode" "1.4" "Major mode for editing Docker's Dockerfiles" '((emacs "24")) :commit "ed1d04c89cd8b53963f2dcae7cb3a46967e0abbf" :url "https://github.com/spotify/dockerfile-mode")
diff --git a/elpa/dockerfile-mode-1.3/dockerfile-mode.el b/elpa/dockerfile-mode-1.4/dockerfile-mode.el
old mode 100755
new mode 100644
similarity index 88%
rename from elpa/dockerfile-mode-1.3/dockerfile-mode.el
rename to elpa/dockerfile-mode-1.4/dockerfile-mode.el
index e640db1..369d087
--- a/elpa/dockerfile-mode-1.3/dockerfile-mode.el
+++ b/elpa/dockerfile-mode-1.4/dockerfile-mode.el
@@ -1,9 +1,9 @@
;;; dockerfile-mode.el --- Major mode for editing Docker's Dockerfiles -*- lexical-binding: t -*-
;; Copyright (c) 2013 Spotify AB
-;; Package-Requires: ((emacs "24") (s "1.12"))
-;; Package-Version: 1.3
-;; Package-Commit: d31f7685ebc5832d957e25070a930aa42984327d
+;; Package-Requires: ((emacs "24"))
+;; Package-Version: 1.4
+;; Package-Commit: ed1d04c89cd8b53963f2dcae7cb3a46967e0abbf
;; Homepage: https://github.com/spotify/dockerfile-mode
;;
;; Licensed under the Apache License, Version 2.0 (the "License"); you may not
@@ -28,7 +28,6 @@
(require 'sh-script)
(require 'rx)
-(require 's)
(declare-function cygwin-convert-file-name-to-windows "cygw32.c" (file &optional absolute-p))
@@ -62,6 +61,20 @@ Each element of the list will be passed as a separate
:type '(repeat string)
:group 'dockerfile)
+(defcustom dockerfile-use-buildkit nil
+ "If t use Docker buildkit for building images
+
+This is the new buildsystem for docker, and in time it will replace the old one
+but for now it has to be explicitly enabled to work.
+It is supported from docker 18.09"
+ :type 'boolean)
+
+(defcustom dockerfile-indent-offset (or standard-indent 2)
+ "Dockerfile number of columns for margin-changing functions to indent."
+ :type 'integer
+ :safe #'integerp
+ :group 'dockerfile)
+
(defface dockerfile-image-name
'((t (:inherit (font-lock-type-face bold))))
"Face to highlight the base image name after FROM instruction.")
@@ -125,7 +138,7 @@ Each element of the list will be passed as a separate
"Indent lines in a Dockerfile.
Lines beginning with a keyword are ignored, and any others are
-indented by one `tab-width'."
+indented by one `dockerfile-indent-offset'."
(unless (member (get-text-property (point-at-bol) 'face)
'(font-lock-comment-delimiter-face font-lock-keyword-face))
(save-excursion
@@ -134,7 +147,7 @@ indented by one `tab-width'."
(unless (equal (point) (point-at-eol)) ; Ignore empty lines.
;; Delete existing whitespace.
(delete-char (- (point-at-bol) (point)))
- (indent-to tab-width)))))
+ (indent-to dockerfile-indent-offset)))))
(defun dockerfile-build-arg-string ()
"Create a --build-arg string for each element in `dockerfile-build-args'."
@@ -146,7 +159,8 @@ indented by one `tab-width'."
If in Cygwin environment, uses Cygwin specific function to convert the
file name. Otherwise, uses Emacs' standard conversion function."
(if (fboundp 'cygwin-convert-file-name-to-windows)
- (s-replace "\\" "\\\\" (cygwin-convert-file-name-to-windows file))
+ (replace-regexp-in-string
+ (rx "\\") "\\\\" (cygwin-convert-file-name-to-windows file) t t)
(convert-standard-filename file)))
(defun dockerfile-tag-string (image-name)
@@ -156,7 +170,7 @@ file name. Otherwise, uses Emacs' standard conversion function."
(defvar dockerfile-image-name nil
"Name of the dockerfile currently being used.
This can be set in file or directory-local variables.")
-(define-obsolete-variable-alias 'docker-image-name 'dockerfile-image-name)
+(define-obsolete-variable-alias 'docker-image-name 'dockerfile-image-name "2017-10-22")
(defvar dockerfile-image-name-history nil
"History of image names read by `dockerfile-read-image-name'.")
@@ -178,7 +192,8 @@ The build string will be of the format:
(save-buffer)
(compilation-start
(format
- "%s%s build %s %s %s -f %s %s"
+ "%s%s%s build %s %s %s -f %s %s"
+ (if dockerfile-use-buildkit "DOCKER_BUILDKIT=1 " "")
(if dockerfile-use-sudo "sudo " "")
dockerfile-mode-command
(if no-cache "--no-cache" "")
@@ -228,7 +243,10 @@ returned, otherwise the base image name is used."
(set (make-local-variable 'indent-line-function) #'dockerfile-indent-line-function))
;;;###autoload
-(add-to-list 'auto-mode-alist '("Dockerfile\\(?:\\..*\\)?\\'" . dockerfile-mode))
+(add-to-list 'auto-mode-alist '("/Dockerfile\\(?:\\..*\\)?\\'" . dockerfile-mode))
+
+;;;###autoload
+(add-to-list 'auto-mode-alist '("\\.dockerfile\\'" . dockerfile-mode))
(provide 'dockerfile-mode)
diff --git a/elpa/ivy-0.13.1.signed b/elpa/ivy-0.13.1.signed
new file mode 100644
index 0000000..f46a755
--- /dev/null
+++ b/elpa/ivy-0.13.1.signed
@@ -0,0 +1 @@
+Good signature from 066DAFCB81E42C40 GNU ELPA Signing Agent (2019) (trust undefined) created at 2020-06-22T16:05:01-0500 using RSA
\ No newline at end of file
diff --git a/elpa/ivy-0.13.1/ChangeLog b/elpa/ivy-0.13.1/ChangeLog
new file mode 100644
index 0000000..2a71274
--- /dev/null
+++ b/elpa/ivy-0.13.1/ChangeLog
@@ -0,0 +1,76 @@
+2020-06-22 Oleh Krehel
+
+ Split package ivy into ivy, swiper, counsel
+
+ Publishing them in a single package on GNU ELPA has lead to version
+ conflicts.
+
+2019-10-16 Oleh Krehel
+
+ Merge commit 'cd634c6f51458f81898ecf2821ac3169cb65a1eb' from ivy
+
+2019-07-20 Oleh Krehel
+
+ packages/ivy/dir: Use install-info
+
+2019-07-20 Oleh Krehel
+
+ Merge commit '85d1e2e779ca92e6ef8e47d08f866b13d4d87aee' from ivy
+
+2019-05-13 Stefan Monnier
+
+ * avy/targets/checkdoc.el, ivy/doc/scripts.el: copyright tweak
+
+2019-05-11 Oleh Krehel
+
+ Merge commit '525b2e4887dd839045313f32d3ddeb5cab4c7a7e' from ivy
+
+2018-01-12 Oleh Krehel
+
+ Fix bad git subtree merge for ivy
+
+2017-11-30 Oleh Krehel
+
+ Merge commit '4a2cee03519f98cf95b29905dec2566a39ff717e' from swiper
+
+2017-04-10 Stefan Monnier
+
+ ivy/targets/obsolete-config.el: Satisfy check_copyright
+
+2017-04-10 Oleh Krehel
+
+ Add 'packages/ivy/' from commit
+ 'f4b433436668ac09f3d1815fbfb4b71f3e0690fa'
+
+ git-subtree-dir: packages/ivy git-subtree-mainline:
+ 6f4e442a66d625f647faa51e88e052c3d93e9657 git-subtree-split:
+ f4b433436668ac09f3d1815fbfb4b71f3e0690fa
+
+2017-04-10 Oleh Krehel
+
+ Remove ivy 0.9.0 to add it again with subtree
+
+2017-04-09 Oleh Krehel
+
+ Merge commit 'af746cad0e9c5d010ea530381111372f7daae55b' from swiper
+
+2017-04-08 Oleh Krehel
+
+ Merge commit 'ace01d5603ddf49b025eb811b612af72ec38dcfb' from swiper
+
+2016-07-11 Paul Eggert
+
+ Fix some quoting problems in doc strings
+
+ Most of these are minor issues involving, e.g., quoting `like this'
+ instead of 'like this'. A few involve escaping ` and ' with a preceding
+ \= when the characters should not be turned into curved single quotes.
+
+2016-04-25 Oleh Krehel
+
+ Merge commit 'db005182ad0fd05c07e8e5c085abe6c750e6c578' from ivy
+
+2016-04-25 Oleh Krehel
+
+ Rename swiper -> ivy
+
diff --git a/elpa/ivy-0.13.1/colir.el b/elpa/ivy-0.13.1/colir.el
new file mode 100644
index 0000000..9e61273
--- /dev/null
+++ b/elpa/ivy-0.13.1/colir.el
@@ -0,0 +1,124 @@
+;;; colir.el --- Color blending library -*- lexical-binding: t -*-
+
+;; Copyright (C) 2015-2019 Free Software Foundation, Inc.
+
+;; Author: Oleh Krehel
+
+;; This file is part of GNU Emacs.
+
+;; This file is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 3, or (at your option)
+;; any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; For a full copy of the GNU General Public License
+;; see .
+
+;;; Commentary:
+
+;; This package solves the problem of adding a face with a background
+;; to text which may already have a background. In all conflicting
+;; areas, instead of choosing either the original or the new
+;; background face, their blended sum is used.
+;;
+;; The blend mode functions are taken from URL
+;; `https://en.wikipedia.org/wiki/Blend_modes'.
+
+;;; Code:
+
+(require 'cl-lib)
+(require 'color)
+
+(defcustom colir-compose-method #'colir-compose-alpha
+ "Select a method to compose two color channels."
+ :group 'ivy
+ :type '(radio
+ (function-item colir-compose-alpha)
+ (function-item colir-compose-overlay)
+ (function-item colir-compose-soft-light)))
+
+(defun colir-compose-soft-light (a b)
+ "Compose A and B channels."
+ (if (< b 0.5)
+ (+ (* 2 a b) (* a a (- 1 b b)))
+ (+ (* 2 a (- 1 b)) (* (sqrt a) (- (* 2 b) 1)))))
+
+(defun colir-compose-overlay (a b)
+ "Compose A and B channels."
+ (if (< a 0.5)
+ (* 2 a b)
+ (- 1 (* 2 (- 1 a) (- 1 b)))))
+
+(defun colir-compose-alpha (a b &optional alpha gamma)
+ "Compose A and B channels.
+Optional argument ALPHA is a number between 0.0 and 1.0 which corresponds
+to the influence of A on the result. Default value is 0.5.
+Optional argument GAMMA is used for gamma correction. Default value is 2.2."
+ (setq alpha (or alpha 0.5))
+ (setq gamma (or gamma 2.2))
+ (+ (* (expt a gamma) alpha) (* (expt b gamma) (- 1 alpha))))
+
+(defun colir-blend (c1 c2)
+ "Blend the two colors C1 and C2 using `colir-compose-method'.
+C1 and C2 are triples of floats in [0.0 1.0] range."
+ (apply #'color-rgb-to-hex
+ (cl-mapcar
+ (if (eq (frame-parameter nil 'background-mode) 'dark)
+ ;; this method works nicely for dark themes
+ 'colir-compose-soft-light
+ colir-compose-method)
+ c1 c2)))
+
+(defun colir-color-parse (color)
+ "Convert string COLOR to triple of floats in [0.0 1.0]."
+ (if (string-match "#\\([[:xdigit:]]\\{2\\}\\)\\([[:xdigit:]]\\{2\\}\\)\\([[:xdigit:]]\\{2\\}\\)" color)
+ (mapcar (lambda (v) (/ (string-to-number v 16) 255.0))
+ (list (match-string 1 color) (match-string 2 color) (match-string 3 color)))
+ ;; does not work properly in terminal (maps color to nearest color
+ ;; from available color palette).
+ (color-name-to-rgb color)))
+
+(defun colir--blend-background (start next prevn face object)
+ (let ((background-prev (face-background prevn)))
+ (progn
+ (put-text-property
+ start next 'face
+ (if background-prev
+ (cons `(background-color
+ . ,(colir-blend
+ (colir-color-parse background-prev)
+ (colir-color-parse (face-background face nil t))))
+ prevn)
+ (list face prevn))
+ object))))
+
+(defun colir-blend-face-background (start end face &optional object)
+ "Append to the face property of the text from START to END the face FACE.
+When the text already has a face with a non-plain background,
+blend it with the background of FACE.
+Optional argument OBJECT is the string or buffer containing the text.
+See also `font-lock-append-text-property'."
+ (let (next prev prevn)
+ (while (/= start end)
+ (setq next (next-single-property-change start 'face object end))
+ (setq prev (get-text-property start 'face object))
+ (setq prevn (if (listp prev)
+ (cl-find-if #'atom prev)
+ prev))
+ (cond
+ ((or (keywordp (car-safe prev)) (consp (car-safe prev)))
+ (put-text-property start next 'face (cons face prev) object))
+ ((facep prevn)
+ (colir--blend-background start next prevn face object))
+ (t
+ (put-text-property start next 'face face object)))
+ (setq start next))))
+
+(provide 'colir)
+
+;;; colir.el ends here
diff --git a/elpa/ivy-0.13.1/dir b/elpa/ivy-0.13.1/dir
new file mode 100644
index 0000000..b68b083
--- /dev/null
+++ b/elpa/ivy-0.13.1/dir
@@ -0,0 +1,18 @@
+This is the file .../info/dir, which contains the
+topmost node of the Info hierarchy, called (dir)Top.
+The first time you invoke Info you start off looking at this node.
+
+File: dir, Node: Top This is the top of the INFO tree
+
+ This (the Directory node) gives a menu of major topics.
+ Typing "q" exits, "H" lists all Info commands, "d" returns here,
+ "h" gives a primer for first-timers,
+ "mEmacs" visits the Emacs manual, etc.
+
+ In Emacs, you can click mouse button 2 on a menu item or cross reference
+ to select it.
+
+* Menu:
+
+Emacs
+* Ivy: (ivy). Using Ivy for completion.
diff --git a/elpa/ivy-0.13.1/ivy-autoloads.el b/elpa/ivy-0.13.1/ivy-autoloads.el
new file mode 100644
index 0000000..e584cdc
--- /dev/null
+++ b/elpa/ivy-0.13.1/ivy-autoloads.el
@@ -0,0 +1,168 @@
+;;; ivy-autoloads.el --- automatically extracted autoloads
+;;
+;;; Code:
+
+(add-to-list 'load-path (directory-file-name
+ (or (file-name-directory #$) (car load-path))))
+
+
+;;;### (autoloads nil "colir" "colir.el" (0 0 0 0))
+;;; Generated autoloads from colir.el
+
+(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "colir" '("colir-")))
+
+;;;***
+
+;;;### (autoloads nil "ivy" "ivy.el" (0 0 0 0))
+;;; Generated autoloads from ivy.el
+
+(autoload 'ivy-resume "ivy" "\
+Resume the last completion session." t nil)
+
+(autoload 'ivy-read "ivy" "\
+Read a string in the minibuffer, with completion.
+
+PROMPT is a string, normally ending in a colon and a space.
+`ivy-count-format' is prepended to PROMPT during completion.
+
+COLLECTION is either a list of strings, a function, an alist, or
+a hash table, supplied for `minibuffer-completion-table'.
+
+PREDICATE is applied to filter out the COLLECTION immediately.
+This argument is for compatibility with `completing-read'.
+
+When REQUIRE-MATCH is non-nil, only members of COLLECTION can be
+selected.
+
+If INITIAL-INPUT is non-nil, then insert that input in the
+minibuffer initially.
+
+HISTORY is a name of a variable to hold the completion session
+history.
+
+KEYMAP is composed with `ivy-minibuffer-map'.
+
+PRESELECT, when non-nil, determines which one of the candidates
+matching INITIAL-INPUT to select initially. An integer stands
+for the position of the desired candidate in the collection,
+counting from zero. Otherwise, use the first occurrence of
+PRESELECT in the collection. Comparison is first done with
+`equal'. If that fails, and when applicable, match PRESELECT as
+a regular expression.
+
+DEF is for compatibility with `completing-read'.
+
+UPDATE-FN is called each time the candidate list is re-displayed.
+
+When SORT is non-nil, `ivy-sort-functions-alist' determines how
+to sort candidates before displaying them.
+
+ACTION is a function to call after selecting a candidate.
+It takes one argument, the selected candidate. If COLLECTION is
+an alist, the argument is a cons cell, otherwise it's a string.
+
+MULTI-ACTION, when non-nil, is called instead of ACTION when
+there are marked candidates. It takes the list of candidates as
+its only argument. When it's nil, ACTION is called on each marked
+candidate.
+
+UNWIND is a function of no arguments to call before exiting.
+
+RE-BUILDER is a function transforming input text into a regex
+pattern.
+
+MATCHER is a function which can override how candidates are
+filtered based on user input. It takes a regex pattern and a
+list of candidates, and returns the list of matching candidates.
+
+DYNAMIC-COLLECTION is a boolean specifying whether the list of
+candidates is updated after each input by calling COLLECTION.
+
+EXTRA-PROPS can be used to store collection-specific
+session-specific data.
+
+CALLER is a symbol to uniquely identify the caller to `ivy-read'.
+It is used, along with COLLECTION, to determine which
+customizations apply to the current completion session.
+
+\(fn PROMPT COLLECTION &key PREDICATE REQUIRE-MATCH INITIAL-INPUT HISTORY PRESELECT DEF KEYMAP UPDATE-FN SORT ACTION MULTI-ACTION UNWIND RE-BUILDER MATCHER DYNAMIC-COLLECTION EXTRA-PROPS CALLER)" nil nil)
+
+(autoload 'ivy-completing-read "ivy" "\
+Read a string in the minibuffer, with completion.
+
+This interface conforms to `completing-read' and can be used for
+`completing-read-function'.
+
+PROMPT is a string that normally ends in a colon and a space.
+COLLECTION is either a list of strings, an alist, an obarray, or a hash table.
+PREDICATE limits completion to a subset of COLLECTION.
+REQUIRE-MATCH is a boolean value. See `completing-read'.
+INITIAL-INPUT is a string inserted into the minibuffer initially.
+HISTORY is a list of previously selected inputs.
+DEF is the default value.
+INHERIT-INPUT-METHOD is currently ignored.
+
+\(fn PROMPT COLLECTION &optional PREDICATE REQUIRE-MATCH INITIAL-INPUT HISTORY DEF INHERIT-INPUT-METHOD)" nil nil)
+
+(defvar ivy-mode nil "\
+Non-nil if Ivy mode is enabled.
+See the `ivy-mode' command
+for a description of this minor mode.
+Setting this variable directly does not take effect;
+either customize it (see the info node `Easy Customization')
+or call the function `ivy-mode'.")
+
+(custom-autoload 'ivy-mode "ivy" nil)
+
+(autoload 'ivy-mode "ivy" "\
+Toggle Ivy mode on or off.
+Turn Ivy mode on if ARG is positive, off otherwise.
+Turning on Ivy mode sets `completing-read-function' to
+`ivy-completing-read'.
+
+Global bindings:
+\\{ivy-mode-map}
+
+Minibuffer bindings:
+\\{ivy-minibuffer-map}
+
+\(fn &optional ARG)" t nil)
+
+(autoload 'ivy-switch-buffer "ivy" "\
+Switch to another buffer." t nil)
+
+(autoload 'ivy-switch-view "ivy" "\
+Switch to one of the window views stored by `ivy-push-view'." t nil)
+
+(autoload 'ivy-switch-buffer-other-window "ivy" "\
+Switch to another buffer in another window." t nil)
+
+(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "ivy" '("ivy-" "with-ivy-window")))
+
+;;;***
+
+;;;### (autoloads nil "ivy-hydra" "ivy-hydra.el" (0 0 0 0))
+;;; Generated autoloads from ivy-hydra.el
+
+(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "ivy-hydra" '("hydra-ivy" "ivy-")))
+
+;;;***
+
+;;;### (autoloads nil "ivy-overlay" "ivy-overlay.el" (0 0 0 0))
+;;; Generated autoloads from ivy-overlay.el
+
+(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "ivy-overlay" '("ivy-")))
+
+;;;***
+
+;;;### (autoloads nil nil ("ivy-pkg.el") (0 0 0 0))
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; coding: utf-8
+;; End:
+;;; ivy-autoloads.el ends here
diff --git a/elpa/ivy-0.13.1/ivy-hydra.el b/elpa/ivy-0.13.1/ivy-hydra.el
new file mode 100644
index 0000000..ce31f2b
--- /dev/null
+++ b/elpa/ivy-0.13.1/ivy-hydra.el
@@ -0,0 +1,133 @@
+;;; ivy-hydra.el --- Additional key bindings for Ivy -*- lexical-binding: t -*-
+
+;; Copyright (C) 2015-2019 Free Software Foundation, Inc.
+
+;; Author: Oleh Krehel
+;; URL: https://github.com/abo-abo/swiper
+;; Version: 0.13.0
+;; Package-Requires: ((emacs "24.5") (ivy "0.13.0") (hydra "0.15.0"))
+;; Keywords: convenience
+
+;; This file is part of GNU Emacs.
+
+;; This file is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 3, or (at your option)
+;; any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; For a full copy of the GNU General Public License
+;; see .
+
+;;; Commentary:
+
+;; This package provides the `hydra-ivy/body' command, which is a
+;; quasi-prefix map, with many useful bindings. These bindings are
+;; shorter than usual, using mostly unprefixed keys.
+
+;;; Code:
+
+(require 'ivy)
+(require 'hydra)
+
+(defun ivy--matcher-desc ()
+ "Return description of `ivy--regex-function'."
+ (let ((cell (assq ivy--regex-function ivy-preferred-re-builders)))
+ (if cell
+ (cdr cell)
+ "other")))
+
+(defhydra hydra-ivy (:hint nil
+ :color pink)
+ "
+^ ^ ^ ^ ^ ^ | ^Call^ ^ ^ | ^Cancel^ | ^Options^ | Action _w_/_s_/_a_: %-14s(ivy-action-name)
+^-^-^-^-^-^-+-^-^---------^-^--+-^-^------+-^-^-------+-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---------------------------
+^ ^ _k_ ^ ^ | _f_ollow occ_U_r | _i_nsert | _c_: calling %-5s(if ivy-calling \"on\" \"off\") _C_ase-fold: %-10`ivy-case-fold-search
+_h_ ^+^ _l_ | _d_one ^ ^ | _o_ops | _M_: matcher %-5s(ivy--matcher-desc)^^^^^^^^^^^^ _T_runcate: %-11`truncate-lines
+^ ^ _j_ ^ ^ | _g_o ^ ^ | ^ ^ | _<_/_>_: shrink/grow^^^^^^^^^^^^^^^^^^^^^^^^^^^^ _D_efinition of this menu
+"
+ ;; arrows
+ ("h" ivy-beginning-of-buffer)
+ ("j" ivy-next-line)
+ ("k" ivy-previous-line)
+ ("l" ivy-end-of-buffer)
+ ;; mark
+ ("m" ivy-mark)
+ ("u" ivy-unmark)
+ ("DEL" ivy-unmark-backward)
+ ("t" ivy-toggle-marks)
+ ;; actions
+ ("o" keyboard-escape-quit :exit t)
+ ("r" ivy-dispatching-done-hydra :exit t)
+ ("C-g" keyboard-escape-quit :exit t)
+ ("i" nil)
+ ("C-o" nil)
+ ("f" ivy-alt-done :exit nil)
+ ("C-j" ivy-alt-done :exit nil)
+ ("d" ivy-done :exit t)
+ ("g" ivy-call)
+ ("C-m" ivy-done :exit t)
+ ("c" ivy-toggle-calling)
+ ("M" ivy-rotate-preferred-builders)
+ (">" ivy-minibuffer-grow)
+ ("<" ivy-minibuffer-shrink)
+ ("w" ivy-prev-action)
+ ("s" ivy-next-action)
+ ("a" (let ((ivy-read-action-function #'ivy-read-action-by-key))
+ (ivy-read-action)))
+ ("T" (setq truncate-lines (not truncate-lines)))
+ ("C" ivy-toggle-case-fold)
+ ("U" ivy-occur :exit t)
+ ("D" (ivy-exit-with-action
+ (lambda (_) (find-function 'hydra-ivy/body)))
+ :exit t))
+
+(defvar ivy-dispatching-done-columns 2
+ "Number of columns to use if the hint does not fit on one line.")
+
+(defvar ivy-dispatching-done-idle nil
+ "When non-nil, the hint will be delayed by this many seconds.")
+
+(defvar ivy-dispatching-done-hydra-exit-keys '(("M-o" nil "back")
+ ("C-g" nil))
+ "Keys that can be used to exit `ivy-dispatching-done-hydra'.")
+
+(defun ivy-dispatching-done-hydra ()
+ "Select one of the available actions and call `ivy-done'."
+ (interactive)
+ (let* ((actions (ivy-state-action ivy-last))
+ (extra-actions ivy-dispatching-done-hydra-exit-keys)
+ (doc (concat "action: "
+ (mapconcat
+ (lambda (x) (format "[%s] %s" (nth 0 x) (nth 2 x)))
+ (append (cdr actions)
+ extra-actions) ", ")))
+ (estimated-len (length doc))
+ (n-columns (if (> estimated-len (window-width))
+ ivy-dispatching-done-columns
+ nil))
+ (i 0))
+ (if (null (ivy--actionp actions))
+ (ivy-done)
+ (funcall
+ (eval
+ `(defhydra ivy-read-action (:color teal :columns ,n-columns :idle ,ivy-dispatching-done-idle)
+ "action"
+ ,@(mapcar (lambda (x)
+ (list (nth 0 x)
+ `(progn
+ (setcar (ivy-state-action ivy-last) ,(cl-incf i))
+ (ivy-done))
+ (nth 2 x)))
+ (cdr actions))
+ ,@extra-actions))))))
+
+(setq ivy-read-action-function (lambda (_) (ivy-dispatching-done-hydra)))
+
+(provide 'ivy-hydra)
+
+;;; ivy-hydra.el ends here
diff --git a/elpa/ivy-0.13.1/ivy-overlay.el b/elpa/ivy-0.13.1/ivy-overlay.el
new file mode 100644
index 0000000..7a77bcf
--- /dev/null
+++ b/elpa/ivy-0.13.1/ivy-overlay.el
@@ -0,0 +1,154 @@
+;;; ivy-overlay.el --- Overlay display functions for Ivy -*- lexical-binding: t -*-
+
+;; Copyright (C) 2016-2019 Free Software Foundation, Inc.
+
+;; Author: Oleh Krehel
+;; Keywords: convenience
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program. If not, see .
+
+;;; Commentary:
+
+;; This package allows to setup Ivy's completion at point to actually
+;; show the candidates and the input at point, instead of in the
+;; minibuffer.
+
+;;; Code:
+
+(defface ivy-cursor
+ '((((class color) (background light))
+ :background "black" :foreground "white")
+ (((class color) (background dark))
+ :background "white" :foreground "black"))
+ "Cursor face for inline completion."
+ :group 'ivy-faces)
+
+(defvar ivy--old-cursor-type t)
+
+(defvar ivy-overlay-at nil
+ "Overlay variable for `ivy-display-function-overlay'.")
+
+(declare-function ivy--truncate-string "ivy")
+
+(defun ivy-left-pad (str width)
+ "Return STR, but with each line indented by WIDTH spaces.
+Lines are truncated to the window width."
+ (let ((padding (make-string width ?\s)))
+ (mapconcat (lambda (x)
+ (ivy--truncate-string (concat padding x)
+ (1- (+ (window-width)
+ (window-hscroll)))))
+ (split-string str "\n")
+ "\n")))
+
+(defun ivy-overlay-cleanup ()
+ "Clean up after `ivy-display-function-overlay'."
+ (when (overlayp ivy-overlay-at)
+ (delete-overlay ivy-overlay-at)
+ (setq ivy-overlay-at nil))
+ (unless cursor-type
+ (setq cursor-type ivy--old-cursor-type))
+ (when (fboundp 'company-abort)
+ (company-abort)))
+
+(defvar ivy-height)
+
+(defun ivy-overlay-show-after (str)
+ "Display STR in an overlay at point.
+
+First, fill each line of STR with spaces to the current column.
+Then attach the overlay to the character before point."
+ (if ivy-overlay-at
+ (progn
+ (move-overlay ivy-overlay-at (1- (point)) (line-end-position))
+ (overlay-put ivy-overlay-at 'invisible nil))
+ (let ((available-height (count-lines (point) (window-end nil t))))
+ (unless (>= available-height ivy-height)
+ (recenter (- (window-height) ivy-height 2))))
+ (setq ivy-overlay-at (make-overlay (1- (point)) (line-end-position)))
+ ;; Specify face to avoid clashing with other overlays.
+ (overlay-put ivy-overlay-at 'face 'default)
+ (overlay-put ivy-overlay-at 'priority 9999))
+ (overlay-put ivy-overlay-at 'display str)
+ (overlay-put ivy-overlay-at 'after-string ""))
+
+(declare-function org-current-level "org")
+(declare-function org-at-heading-p "org")
+(defvar org-indent-indentation-per-level)
+(defvar ivy-height)
+(defvar ivy-last)
+(defvar ivy-text)
+(defvar ivy-completion-beg)
+(declare-function ivy-add-face-text-property "ivy")
+(declare-function ivy--get-window "ivy")
+(declare-function ivy-state-current "ivy")
+(declare-function ivy-state-window "ivy")
+(declare-function ivy--remove-prefix "ivy")
+
+(defun ivy-overlay-impossible-p (_str)
+ (or
+ (and (eq major-mode 'org-mode)
+ (plist-get (text-properties-at (point)) 'src-block))
+ (<= (window-height) (+ ivy-height 2))
+ (= (point) (point-min))
+ (< (- (+ (window-width) (window-hscroll)) (current-column))
+ 30)))
+
+(defun ivy-display-function-overlay (str)
+ "Called from the minibuffer, display STR in an overlay in Ivy window.
+Hide the minibuffer contents and cursor."
+ (if (save-selected-window
+ (select-window (ivy-state-window ivy-last))
+ (ivy-overlay-impossible-p str))
+ (let ((buffer-undo-list t))
+ (save-excursion
+ (forward-line 1)
+ (insert str)))
+ (ivy-add-face-text-property (minibuffer-prompt-end) (point-max)
+ '(:foreground "white"))
+ (setq cursor-type nil)
+ (with-selected-window (ivy--get-window ivy-last)
+ (when cursor-type
+ (setq ivy--old-cursor-type cursor-type))
+ (setq cursor-type nil)
+ (let ((overlay-str
+ (apply
+ #'concat
+ (buffer-substring (max (point-min) (1- (point))) (point))
+ ivy-text
+ (and (eolp) " ")
+ (buffer-substring (point) (line-end-position))
+ (and (> (length str) 0)
+ (list "\n"
+ (ivy-left-pad
+ (ivy--remove-prefix "\n" str)
+ (+
+ (if (and (eq major-mode 'org-mode)
+ (bound-and-true-p org-indent-mode))
+ (if (org-at-heading-p)
+ (1- (org-current-level))
+ (* org-indent-indentation-per-level (org-current-level)))
+ 0)
+ (save-excursion
+ (when ivy-completion-beg
+ (goto-char ivy-completion-beg))
+ (current-column)))))))))
+ (let ((cursor-offset (1+ (length ivy-text))))
+ (ivy-add-face-text-property cursor-offset (1+ cursor-offset)
+ 'ivy-cursor overlay-str t))
+ (ivy-overlay-show-after overlay-str)))))
+
+(provide 'ivy-overlay)
+
+;;; ivy-overlay.el ends here
diff --git a/elpa/ivy-0.13.1/ivy-pkg.el b/elpa/ivy-0.13.1/ivy-pkg.el
new file mode 100644
index 0000000..33ff7a9
--- /dev/null
+++ b/elpa/ivy-0.13.1/ivy-pkg.el
@@ -0,0 +1,2 @@
+;; Generated package description from ivy.el -*- no-byte-compile: t -*-
+(define-package "ivy" "0.13.1" "Incremental Vertical completYon" '((emacs "24.5")) :keywords '("matching") :authors '(("Oleh Krehel" . "ohwoeowho@gmail.com")) :maintainer '("Oleh Krehel" . "ohwoeowho@gmail.com") :url "https://github.com/abo-abo/swiper")
diff --git a/elpa/ivy-0.13.1/ivy.el b/elpa/ivy-0.13.1/ivy.el
new file mode 100644
index 0000000..04ef620
--- /dev/null
+++ b/elpa/ivy-0.13.1/ivy.el
@@ -0,0 +1,5056 @@
+;;; ivy.el --- Incremental Vertical completYon -*- lexical-binding: t -*-
+
+;; Copyright (C) 2015-2019 Free Software Foundation, Inc.
+
+;; Author: Oleh Krehel
+;; URL: https://github.com/abo-abo/swiper
+;; Version: 0.13.1
+;; Package-Requires: ((emacs "24.5"))
+;; Keywords: matching
+
+;; This file is part of GNU Emacs.
+
+;; This file is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 3, or (at your option)
+;; any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; For a full copy of the GNU General Public License
+;; see .
+
+;;; Commentary:
+
+;; This package provides `ivy-read' as an alternative to
+;; `completing-read' and similar functions.
+;;
+;; There's no intricate code to determine the best candidate.
+;; Instead, the user can navigate to it with `ivy-next-line' and
+;; `ivy-previous-line'.
+;;
+;; The matching is done by splitting the input text by spaces and
+;; re-building it into a regex.
+;; So "for example" is transformed into "\\(for\\).*\\(example\\)".
+
+;;; Code:
+
+(require 'cl-lib)
+(require 'ivy-overlay)
+(require 'colir)
+(require 'ring)
+
+;;* Customization
+(defgroup ivy nil
+ "Incremental vertical completion."
+ :group 'convenience)
+
+(defgroup ivy-faces nil
+ "Font-lock faces for `ivy'."
+ :group 'ivy
+ :group 'faces)
+
+(defface ivy-current-match
+ '((((class color) (background light))
+ :background "#1a4b77" :foreground "white")
+ (((class color) (background dark))
+ :background "#65a7e2" :foreground "black"))
+ "Face used by Ivy for highlighting the current match.")
+
+(defface ivy-minibuffer-match-highlight
+ '((t :inherit highlight))
+ "Face used by Ivy for highlighting the match under the cursor.")
+
+(defface ivy-minibuffer-match-face-1
+ '((((class color) (background light))
+ :background "#d3d3d3")
+ (((class color) (background dark))
+ :background "#555555"))
+ "The background face for `ivy' minibuffer matches.")
+
+(defface ivy-minibuffer-match-face-2
+ '((((class color) (background light))
+ :background "#e99ce8" :weight bold)
+ (((class color) (background dark))
+ :background "#777777" :weight bold))
+ "Face for `ivy' minibuffer matches numbered 1 modulo 3.")
+
+(defface ivy-minibuffer-match-face-3
+ '((((class color) (background light))
+ :background "#bbbbff" :weight bold)
+ (((class color) (background dark))
+ :background "#7777ff" :weight bold))
+ "Face for `ivy' minibuffer matches numbered 2 modulo 3.")
+
+(defface ivy-minibuffer-match-face-4
+ '((((class color) (background light))
+ :background "#ffbbff" :weight bold)
+ (((class color) (background dark))
+ :background "#8a498a" :weight bold))
+ "Face for `ivy' minibuffer matches numbered 3 modulo 3.")
+
+(defface ivy-confirm-face
+ '((t :foreground "ForestGreen" :inherit minibuffer-prompt))
+ "Face used by Ivy for a confirmation prompt.")
+
+(defface ivy-match-required-face
+ '((t :foreground "red" :inherit minibuffer-prompt))
+ "Face used by Ivy for a match required prompt.")
+
+(defface ivy-subdir
+ '((t :inherit dired-directory))
+ "Face used by Ivy for highlighting subdirs in the alternatives.")
+
+(defface ivy-org
+ '((t :inherit org-level-4))
+ "Face used by Ivy for highlighting Org buffers in the alternatives.")
+
+(defface ivy-modified-buffer
+ '((t :inherit default))
+ "Face used by Ivy for highlighting modified file visiting buffers.")
+
+(defface ivy-modified-outside-buffer
+ '((t :inherit default))
+ "Face used by Ivy for highlighting file visiting buffers modified outside Emacs.")
+
+(defface ivy-remote
+ '((((class color) (background light))
+ :foreground "#110099")
+ (((class color) (background dark))
+ :foreground "#7B6BFF"))
+ "Face used by Ivy for highlighting remotes in the alternatives.")
+
+(defface ivy-virtual
+ '((t :inherit font-lock-builtin-face))
+ "Face used by Ivy for matching virtual buffer names.")
+
+(defface ivy-action
+ '((t :inherit font-lock-builtin-face))
+ "Face used by Ivy for displaying keys in `ivy-read-action'.")
+
+(defface ivy-highlight-face
+ '((t :inherit highlight))
+ "Face used by Ivy to highlight certain candidates.")
+
+(defface ivy-prompt-match
+ '((t :inherit ivy-current-match))
+ "Face used by Ivy for highlighting the selected prompt line.")
+
+(defface ivy-separator
+ '((t :inherit font-lock-doc-face))
+ "Face for multiline source separator.")
+
+(defface ivy-grep-info
+ '((t :inherit compilation-info))
+ "Face for highlighting grep information such as file names.")
+
+(defface ivy-grep-line-number
+ '((t :inherit compilation-line-number))
+ "Face for displaying line numbers in grep messages.")
+
+(defface ivy-completions-annotations
+ '((t :inherit completions-annotations))
+ "Face for displaying completion annotations.")
+
+(defface ivy-yanked-word
+ '((t :inherit highlight))
+ "Face used to highlight yanked word.")
+
+;; Set default customization `:group' to `ivy' for the rest of the file.
+(setcdr (assoc load-file-name custom-current-group-alist) 'ivy)
+
+(defcustom ivy-height 10
+ "Number of lines for the minibuffer window.
+
+See also `ivy-height-alist'."
+ :type 'integer)
+
+(defcustom ivy-count-format "%-4d "
+ "The style to use for displaying the current candidate count for `ivy-read'.
+Set this to \"\" to suppress the count visibility.
+Set this to \"(%d/%d) \" to display both the index and the count."
+ :type '(choice
+ (const :tag "Count disabled" "")
+ (const :tag "Count matches" "%-4d ")
+ (const :tag "Count matches and show current match" "(%d/%d) ")
+ string))
+
+(defcustom ivy-pre-prompt-function nil
+ "When non-nil, add strings before the `ivy-read' prompt."
+ :type '(choice
+ (const :tag "Do nothing" nil)
+ (function :tag "Custom function")))
+
+(defcustom ivy-add-newline-after-prompt nil
+ "When non-nil, add a newline after the `ivy-read' prompt."
+ :type 'boolean)
+
+(defcustom ivy-wrap nil
+ "When non-nil, wrap around after the first and the last candidate."
+ :type 'boolean)
+
+(defcustom ivy-display-style (and (fboundp 'add-face-text-property) 'fancy)
+ "The style for formatting the minibuffer.
+
+By default, the matched strings are copied as is.
+
+The fancy display style highlights matching parts of the regexp,
+a behavior similar to `swiper'.
+
+This setting depends on `add-face-text-property' - a C function
+available since Emacs 24.4. Fancy style will render poorly in
+earlier versions of Emacs."
+ :type '(choice
+ (const :tag "Plain" nil)
+ (const :tag "Fancy" fancy)))
+
+(defcustom ivy-on-del-error-function #'abort-recursive-edit
+ "Function to call when deletion fails during completion.
+The usual reason for `ivy-backward-delete-char' to fail is when
+there is no text left to delete, i.e., when it is called at the
+beginning of the minibuffer.
+The default setting provides a quick exit from completion."
+ :type '(choice
+ (const :tag "Exit completion" abort-recursive-edit)
+ (const :tag "Do nothing" ignore)
+ (function :tag "Custom function")))
+
+(defcustom ivy-extra-directories '("../" "./")
+ "Add this to the front of the list when completing file names.
+Only \"./\" and \"../\" apply here. They appear in reverse order."
+ :type '(repeat :tag "Dirs"
+ (choice
+ (const :tag "Parent Directory" "../")
+ (const :tag "Current Directory" "./"))))
+
+(defcustom ivy-use-virtual-buffers nil
+ "When non-nil, add recent files and/or bookmarks to `ivy-switch-buffer'.
+The value `recentf' includes only recent files to the virtual
+buffers list, whereas the value `bookmarks' does the same for
+bookmarks. Any other non-nil value includes both."
+ :type '(choice
+ (const :tag "Don't use virtual buffers" nil)
+ (const :tag "Recent files" recentf)
+ (const :tag "Bookmarks" bookmarks)
+ (const :tag "All virtual buffers" t)))
+
+(defvar ivy--display-function nil
+ "The display-function is used in current.")
+
+(defvar ivy-display-functions-props
+ '((ivy-display-function-overlay :cleanup ivy-overlay-cleanup))
+ "Map Ivy display functions to their property lists.
+Examples of properties include associated `:cleanup' functions.")
+
+(defcustom ivy-display-functions-alist
+ '((ivy-completion-in-region . ivy-display-function-overlay)
+ (t . nil))
+ "An alist for customizing where to display the candidates.
+
+Each key is a caller symbol. When the value is nil (the default),
+the candidates are shown in the minibuffer. Otherwise, the value
+is a function which takes a string argument comprising the
+current matching candidates and displays it somewhere.
+
+See also `https://github.com/abo-abo/swiper/wiki/ivy-display-function'."
+ :type '(alist
+ :key-type symbol
+ :value-type (choice
+ (const :tag "Minibuffer" nil)
+ (const :tag "LV" ivy-display-function-lv)
+ (const :tag "Popup" ivy-display-function-popup)
+ (const :tag "Overlay" ivy-display-function-overlay)
+ (function :tag "Custom function"))))
+
+(defvar ivy-completing-read-dynamic-collection nil
+ "Run `ivy-completing-read' with `:dynamic-collection t`.")
+
+(defcustom ivy-completing-read-handlers-alist
+ '((tmm-menubar . completing-read-default)
+ (tmm-shortcut . completing-read-default)
+ (bbdb-create . ivy-completing-read-with-empty-string-def)
+ (auto-insert . ivy-completing-read-with-empty-string-def)
+ (Info-on-current-buffer . ivy-completing-read-with-empty-string-def)
+ (Info-follow-reference . ivy-completing-read-with-empty-string-def)
+ (Info-menu . ivy-completing-read-with-empty-string-def)
+ (Info-index . ivy-completing-read-with-empty-string-def)
+ (Info-virtual-index . ivy-completing-read-with-empty-string-def)
+ (info-display-manual . ivy-completing-read-with-empty-string-def))
+ "An alist of handlers to replace `completing-read' in `ivy-mode'."
+ :type '(alist :key-type symbol :value-type function))
+
+(defcustom ivy-height-alist nil
+ "An alist to customize `ivy-height'.
+
+It is a list of (CALLER . HEIGHT). CALLER is a caller of
+`ivy-read' and HEIGHT is the number of lines displayed.
+HEIGHT can also be a function that returns the number of lines."
+ :type '(alist
+ :key-type function
+ :value-type (choice integer function)))
+
+(defvar ivy-completing-read-ignore-handlers-depth -1
+ "Used to avoid infinite recursion.
+
+If `(minibuffer-depth)' equals this, `ivy-completing-read' will
+act as if `ivy-completing-read-handlers-alist' is empty.")
+
+(defvar ivy-highlight-grep-commands nil
+ "List of grep-like commands.")
+
+(defvar ivy--actions-list nil
+ "A list of extra actions per command.")
+
+(defun ivy-set-actions (cmd actions)
+ "Set CMD extra exit points to ACTIONS."
+ (setq ivy--actions-list
+ (plist-put ivy--actions-list cmd actions)))
+
+(defun ivy-add-actions (cmd actions)
+ "Add extra exit points ACTIONS to CMD.
+Existing exit points of CMD are overwritten by those in
+ACTIONS that have the same key."
+ (setq ivy--actions-list
+ (plist-put ivy--actions-list cmd
+ (cl-delete-duplicates
+ (append (plist-get ivy--actions-list cmd) actions)
+ :key #'car :test #'equal))))
+
+(defun ivy--compute-extra-actions (action caller)
+ "Add extra actions to ACTION based on CALLER."
+ (let ((extra-actions (cl-delete-duplicates
+ (append (plist-get ivy--actions-list t)
+ (plist-get ivy--actions-list this-command)
+ (plist-get ivy--actions-list caller))
+ :key #'car :test #'equal)))
+ (if extra-actions
+ (cond ((functionp action)
+ `(1
+ ("o" ,action "default")
+ ,@extra-actions))
+ ((null action)
+ `(1
+ ("o" identity "default")
+ ,@extra-actions))
+ (t
+ (delete-dups (append action extra-actions))))
+ action)))
+
+(defvar ivy--prompts-list nil)
+
+(defun ivy-set-prompt (caller prompt-fn)
+ "Associate CALLER with PROMPT-FN.
+PROMPT-FN is a function of no arguments that returns a prompt string."
+ (setq ivy--prompts-list
+ (plist-put ivy--prompts-list caller prompt-fn)))
+
+(defvar ivy--display-transformers-list nil
+ "A list of str->str transformers per command.")
+
+(defun ivy-set-display-transformer (cmd transformer)
+ "Set CMD a displayed candidate TRANSFORMER.
+
+It's a lambda that takes a string one of the candidates in the
+collection and returns a string for display, the same candidate
+plus some extra information.
+
+This lambda is called only on the `ivy-height' candidates that
+are about to be displayed, not on the whole collection."
+ (setq ivy--display-transformers-list
+ (plist-put ivy--display-transformers-list cmd transformer)))
+
+(defvar ivy--sources-list nil
+ "A list of extra sources per command.")
+
+(defun ivy-set-sources (cmd sources)
+ "Attach to CMD a list of extra SOURCES.
+
+Each static source is a function that takes no argument and
+returns a list of strings.
+
+The (original-source) determines the position of the original
+dynamic source.
+
+Extra dynamic sources aren't supported yet.
+
+Example:
+
+ (defun small-recentf ()
+ (cl-subseq recentf-list 0 20))
+
+ (ivy-set-sources
+ 'counsel-locate
+ '((small-recentf)
+ (original-source)))"
+ (setq ivy--sources-list
+ (plist-put ivy--sources-list cmd sources)))
+
+(defun ivy--compute-extra-candidates (caller)
+ (let ((extra-sources (or (plist-get ivy--sources-list caller)
+ '((original-source))))
+ (result nil))
+ (dolist (source extra-sources)
+ (cond ((equal source '(original-source))
+ (push source result))
+ ((null (cdr source))
+ (push (list (car source) (funcall (car source))) result))))
+ result))
+
+(defvar ivy-current-prefix-arg nil
+ "Prefix arg to pass to actions.
+This is a global variable that is set by ivy functions for use in
+action functions.")
+
+;;* Keymap
+(require 'delsel)
+(defvar ivy-minibuffer-map
+ (let ((map (make-sparse-keymap)))
+ (define-key map (kbd "C-m") 'ivy-done)
+ (define-key map [down-mouse-1] 'ignore)
+ (define-key map [mouse-1] 'ivy-mouse-done)
+ (define-key map [mouse-3] 'ivy-mouse-dispatching-done)
+ (define-key map (kbd "C-M-m") 'ivy-call)
+ (define-key map (kbd "C-j") 'ivy-alt-done)
+ (define-key map (kbd "C-M-j") 'ivy-immediate-done)
+ (define-key map (kbd "TAB") 'ivy-partial-or-done)
+ (define-key map [remap next-line] 'ivy-next-line)
+ (define-key map [remap previous-line] 'ivy-previous-line)
+ (define-key map (kbd "C-s") 'ivy-next-line-or-history)
+ (define-key map (kbd "C-r") 'ivy-reverse-i-search)
+ (define-key map (kbd "SPC") 'self-insert-command)
+ (define-key map [remap delete-backward-char] 'ivy-backward-delete-char)
+ (define-key map [remap backward-delete-char-untabify] 'ivy-backward-delete-char)
+ (define-key map [remap backward-kill-word] 'ivy-backward-kill-word)
+ (define-key map [remap delete-char] 'ivy-delete-char)
+ (define-key map [remap forward-char] 'ivy-forward-char)
+ (define-key map (kbd "") 'ivy-forward-char)
+ (define-key map [remap kill-word] 'ivy-kill-word)
+ (define-key map [remap beginning-of-buffer] 'ivy-beginning-of-buffer)
+ (define-key map [remap end-of-buffer] 'ivy-end-of-buffer)
+ (define-key map (kbd "M-n") 'ivy-next-history-element)
+ (define-key map (kbd "M-p") 'ivy-previous-history-element)
+ (define-key map (kbd "C-g") 'minibuffer-keyboard-quit)
+ (define-key map [remap scroll-up-command] 'ivy-scroll-up-command)
+ (define-key map [remap scroll-down-command] 'ivy-scroll-down-command)
+ (define-key map (kbd "") 'ivy-scroll-up-command)
+ (define-key map (kbd "") 'ivy-scroll-down-command)
+ (define-key map (kbd "C-v") 'ivy-scroll-up-command)
+ (define-key map (kbd "M-v") 'ivy-scroll-down-command)
+ (define-key map (kbd "C-M-n") 'ivy-next-line-and-call)
+ (define-key map (kbd "C-M-p") 'ivy-previous-line-and-call)
+ (define-key map (kbd "M-r") 'ivy-toggle-regexp-quote)
+ (define-key map (kbd "M-j") 'ivy-yank-word)
+ (define-key map (kbd "M-i") 'ivy-insert-current)
+ (define-key map (kbd "C-M-y") 'ivy-insert-current-full)
+ (define-key map (kbd "C-o") 'hydra-ivy/body)
+ (define-key map (kbd "M-o") 'ivy-dispatching-done)
+ (define-key map (kbd "C-M-o") 'ivy-dispatching-call)
+ (define-key map [remap kill-line] 'ivy-kill-line)
+ (define-key map [remap kill-whole-line] 'ivy-kill-whole-line)
+ (define-key map (kbd "S-SPC") 'ivy-restrict-to-matches)
+ (define-key map [remap kill-ring-save] 'ivy-kill-ring-save)
+ (define-key map (kbd "C-'") 'ivy-avy)
+ (define-key map (kbd "C-M-a") 'ivy-read-action)
+ (define-key map (kbd "C-c C-o") 'ivy-occur)
+ (define-key map (kbd "C-c C-a") 'ivy-toggle-ignore)
+ (define-key map (kbd "C-c C-s") 'ivy-rotate-sort)
+ (define-key map [remap describe-mode] 'ivy-help)
+ (define-key map "$" 'ivy-magic-read-file-env)
+ map)
+ "Keymap used in the minibuffer.")
+(autoload 'hydra-ivy/body "ivy-hydra" "" t)
+
+(defvar ivy-mode-map
+ (let ((map (make-sparse-keymap)))
+ (define-key map [remap switch-to-buffer]
+ 'ivy-switch-buffer)
+ (define-key map [remap switch-to-buffer-other-window]
+ 'ivy-switch-buffer-other-window)
+ map)
+ "Keymap for `ivy-mode'.")
+
+;;* Globals
+(cl-defstruct ivy-state
+ prompt collection
+ predicate require-match initial-input
+ history preselect keymap update-fn sort
+ ;; The frame in which `ivy-read' was called
+ frame
+ ;; The window in which `ivy-read' was called
+ window
+ ;; The buffer in which `ivy-read' was called
+ buffer
+ ;; The value of `ivy-text' to be used by `ivy-occur'
+ text
+ action
+ unwind
+ re-builder
+ matcher
+ ;; When this is non-nil, call it for each input change to get new candidates
+ dynamic-collection
+ ;; A lambda that transforms candidates only for display
+ display-transformer-fn
+ directory
+ caller
+ current
+ def
+ ignore
+ multi-action
+ extra-props)
+
+(defvar ivy-last (make-ivy-state)
+ "The last parameters passed to `ivy-read'.
+
+This should eventually become a stack so that you could use
+`ivy-read' recursively.")
+
+(defvar ivy-recursive-last nil)
+
+(defvar ivy-recursive-restore t
+ "When non-nil, restore the above state when exiting the minibuffer.
+This variable is let-bound to nil by functions that take care of
+the restoring themselves.")
+
+(defsubst ivy-set-action (action)
+ "Set the current `ivy-last' field to ACTION."
+ (setf (ivy-state-action ivy-last) action))
+
+(defvar inhibit-message)
+
+(defun ivy-thing-at-point ()
+ "Return a string that corresponds to the current thing at point."
+ (substring-no-properties
+ (cond
+ ((use-region-p)
+ (let* ((beg (region-beginning))
+ (end (region-end))
+ (eol (save-excursion (goto-char beg) (line-end-position))))
+ (buffer-substring-no-properties beg (min end eol))))
+ ((thing-at-point 'url))
+ ((and (eq (ivy-state-collection ivy-last) #'read-file-name-internal)
+ (let ((inhibit-message t))
+ (run-hook-with-args-until-success 'file-name-at-point-functions))))
+ ((let ((s (thing-at-point 'symbol)))
+ (and (stringp s)
+ (if (string-match "\\`[`']?\\(.*?\\)'?\\'" s)
+ (match-string 1 s)
+ s))))
+ ((looking-at "(+\\(\\(?:\\sw\\|\\s_\\)+\\)\\_>")
+ (match-string-no-properties 1))
+ (t
+ ""))))
+
+(defvar ivy-history nil
+ "History list of candidates entered in the minibuffer.
+
+Maximum length of the history list is determined by the value
+of `history-length'.")
+
+(defvar ivy--directory nil
+ "Current directory when completing file names.")
+
+(defvar ivy--length 0
+ "Store the amount of viable candidates.")
+
+(defvar ivy-text ""
+ "Store the user's string as it is typed in.")
+
+(defvar ivy--index 0
+ "Store the index of the current candidate.")
+
+(defvar ivy--window-index 0
+ "Store the index of the current candidate in the minibuffer window.
+
+This means it's between 0 and `ivy-height'.")
+
+(defvar ivy-exit nil
+ "Store `done' if the completion was successfully selected.
+Otherwise, store nil.")
+
+(defvar ivy--all-candidates nil
+ "Store the candidates passed to `ivy-read'.")
+
+(defvar ivy--extra-candidates '((original-source))
+ "Store candidates added by the extra sources.
+
+This is an internal-use alist. Each key is a function name, or
+original-source (which represents where the current dynamic
+candidates should go).
+
+Each value is an evaluation of the function, in case of static
+sources. These values will subsequently be filtered on `ivy-text'.
+
+This variable is set by `ivy-read' and used by `ivy--set-candidates'.")
+
+(defcustom ivy-use-ignore-default t
+ "The default policy for user-configured candidate filtering."
+ :type '(choice
+ (const :tag "Ignore ignored always" always)
+ (const :tag "Ignore ignored when others exist" t)
+ (const :tag "Don't ignore" nil)))
+
+(defvar ivy-use-ignore t
+ "Store policy for user-configured candidate filtering.
+This may be changed dynamically by `ivy-toggle-ignore'.
+Use `ivy-use-ignore-default' for a permanent configuration.")
+
+(defvar ivy--default nil
+ "Default initial input.")
+
+(defvar ivy--prompt nil
+ "Store the format-style prompt.
+When non-nil, it should contain at least one %d.")
+
+(defvar ivy--prompt-extra ""
+ "Temporary modifications to the prompt.")
+
+(defvar ivy--old-re nil
+ "Store the old regexp.
+Either a string or a list for `ivy-re-match'.")
+
+(defvar ivy--old-cands nil
+ "Store the candidates matched by `ivy--old-re'.")
+
+(defvar ivy--regex-function 'ivy--regex
+ "Current function for building a regex.")
+
+(defvar ivy--highlight-function 'ivy--highlight-default
+ "Current function for formatting the candidates.")
+
+(defvar ivy--subexps 0
+ "Number of groups in the current `ivy--regex'.")
+
+(defvar ivy--full-length nil
+ "The total amount of candidates when :dynamic-collection is non-nil.")
+
+(defvar ivy--old-text ""
+ "Store old `ivy-text' for dynamic completion.")
+
+(defvar ivy--trying-to-resume-dynamic-collection nil
+ "Non-nil if resuming from a dynamic collection.
+When non-nil, ivy will wait until the first chunk of asynchronous
+candidates has been received before selecting the last
+preselected candidate.")
+
+(defun ivy--set-index-dynamic-collection ()
+ (when ivy--trying-to-resume-dynamic-collection
+ (let ((preselect-index
+ (ivy--preselect-index (ivy-state-preselect ivy-last) ivy--all-candidates)))
+ (when preselect-index
+ (ivy-set-index preselect-index)))
+ (setq ivy--trying-to-resume-dynamic-collection nil)))
+
+(defcustom ivy-case-fold-search-default
+ (if search-upper-case
+ 'auto
+ case-fold-search)
+ "The default value for `case-fold-search' in Ivy operations.
+The special value `auto' means case folding is performed so long
+as the entire input string comprises lower-case characters. This
+corresponds to the default behaviour of most Emacs search
+functionality, e.g. as seen in `isearch'."
+ :link '(info-link "(emacs)Lax Search")
+ :type '(choice
+ (const :tag "Auto" auto)
+ (const :tag "Always" t)
+ (const :tag "Never" nil)))
+
+(defvar ivy-case-fold-search ivy-case-fold-search-default
+ "Store the current overriding `case-fold-search'.")
+
+(defvar ivy-more-chars-alist
+ '((t . 3))
+ "Map commands to their minimum required input length.
+That is the number of characters prompted for before fetching
+candidates. The special key t is used as a fallback.")
+
+(defun ivy-more-chars ()
+ "Return two fake candidates prompting for at least N input.
+N is obtained from `ivy-more-chars-alist'."
+ (let ((diff (- (ivy-alist-setting ivy-more-chars-alist)
+ (length ivy-text))))
+ (when (> diff 0)
+ (list "" (format "%d chars more" diff)))))
+
+(defun ivy--case-fold-p (string)
+ "Return nil if STRING should be matched case-sensitively."
+ (if (eq ivy-case-fold-search 'auto)
+ (string= string (downcase string))
+ ivy-case-fold-search))
+
+(defun ivy--case-fold-string= (s1 s2)
+ "Like `string=', but obeys `case-fold-search'."
+ (eq t (compare-strings s1 nil nil s2 nil nil case-fold-search)))
+
+(eval-and-compile
+ (unless (fboundp 'defvar-local)
+ (defmacro defvar-local (var val &optional docstring)
+ "Define VAR as a buffer-local variable with default value VAL."
+ (declare (debug defvar) (doc-string 3))
+ (list 'progn (list 'defvar var val docstring)
+ (list 'make-variable-buffer-local (list 'quote var)))))
+ (unless (fboundp 'setq-local)
+ (defmacro setq-local (var val)
+ "Set variable VAR to value VAL in current buffer."
+ (list 'set (list 'make-local-variable (list 'quote var)) val))))
+
+(defmacro ivy-quit-and-run (&rest body)
+ "Quit the minibuffer and run BODY afterwards."
+ (declare (indent 0))
+ `(progn
+ (put 'quit 'error-message "")
+ (run-at-time nil nil
+ (lambda ()
+ (put 'quit 'error-message "Quit")
+ (with-demoted-errors "Error: %S"
+ ,@body)))
+ (abort-recursive-edit)))
+
+(defun ivy-exit-with-action (action)
+ "Quit the minibuffer and call ACTION afterwards."
+ (ivy-set-action
+ `(lambda (x)
+ (funcall ',action x)
+ (ivy-set-action ',(ivy-state-action ivy-last))))
+ (setq ivy-exit 'done)
+ (exit-minibuffer))
+
+(defmacro with-ivy-window (&rest body)
+ "Execute BODY in the window from which `ivy-read' was called."
+ (declare (indent 0)
+ (debug t))
+ `(with-selected-window (ivy--get-window ivy-last)
+ ,@body))
+
+(defun ivy--done (text)
+ "Insert TEXT and exit minibuffer."
+ (if (member (ivy-state-prompt ivy-last) '("Create directory: " "Make directory: "))
+ (ivy-immediate-done)
+ (if (stringp text)
+ (insert
+ (setf (ivy-state-current ivy-last)
+ (if (and ivy--directory
+ (not (eq (ivy-state-history ivy-last) 'grep-files-history)))
+ (expand-file-name text ivy--directory)
+ text))))
+ (setq ivy-exit 'done)
+ (exit-minibuffer)))
+
+(defcustom ivy-use-selectable-prompt nil
+ "When non-nil, make the prompt line selectable like a candidate.
+
+The prompt line can be selected by calling `ivy-previous-line' when the first
+regular candidate is selected. Both actions `ivy-done' and `ivy-alt-done',
+when called on a selected prompt, are forwarded to `ivy-immediate-done', which
+results to the same as calling `ivy-immediate-done' explicitly when a regular
+candidate is selected.
+
+Note that if `ivy-wrap' is set to t, calling `ivy-previous-line' when the
+prompt is selected wraps around to the last candidate, while calling
+`ivy-next-line' on the last candidate wraps around to the first
+candidate, not the prompt."
+ :type 'boolean)
+
+(defvar ivy--use-selectable-prompt nil
+ "Store the effective `ivy-use-selectable-prompt' for current session.")
+
+(defun ivy--prompt-selectable-p ()
+ "Return t if the prompt line is selectable."
+ (and ivy-use-selectable-prompt
+ (or (memq (ivy-state-require-match ivy-last)
+ '(nil confirm confirm-after-completion))
+ ;; :require-match is t, but "" is in the collection
+ (let ((coll (ivy-state-collection ivy-last)))
+ (and (listp coll)
+ (if (consp (car coll))
+ (member '("") coll)
+ (member "" coll)))))))
+
+(defun ivy--prompt-selected-p ()
+ "Return t if the prompt line is selected."
+ (and ivy--use-selectable-prompt
+ (= ivy--index -1)))
+
+;;* Commands
+(defun ivy-done ()
+ "Exit the minibuffer with the selected candidate."
+ (interactive)
+ (if (ivy--prompt-selected-p)
+ (ivy-immediate-done)
+ (setq ivy-current-prefix-arg current-prefix-arg)
+ (delete-minibuffer-contents)
+ (cond ((or (> ivy--length 0)
+ ;; the action from `ivy-dispatching-done' may not need a
+ ;; candidate at all
+ (eq this-command 'ivy-dispatching-done))
+ (ivy--done (ivy-state-current ivy-last)))
+ ((memq (ivy-state-collection ivy-last)
+ '(read-file-name-internal internal-complete-buffer))
+ (if (or (not (eq confirm-nonexistent-file-or-buffer t))
+ (equal " (confirm)" ivy--prompt-extra))
+ (ivy--done ivy-text)
+ (setq ivy--prompt-extra " (confirm)")
+ (insert ivy-text)
+ (ivy--exhibit)))
+ ((memq (ivy-state-require-match ivy-last)
+ '(nil confirm confirm-after-completion))
+ (ivy--done ivy-text))
+ (t
+ (setq ivy--prompt-extra " (match required)")
+ (insert ivy-text)
+ (ivy--exhibit)))))
+
+(defvar ivy-mouse-1-tooltip
+ "Exit the minibuffer with the selected candidate."
+ "The doc visible in the tooltip for mouse-1 binding in the minibuffer")
+(defvar ivy-mouse-3-tooltip
+ "Display alternative actions."
+ "The doc visible in the tooltip for mouse-3 binding in the minibuffer")
+
+(defun ivy-mouse-offset (event)
+ "Compute the offset between the candidate at point and the selected one."
+ (if event
+ (let* ((line-number-at-point
+ (max 2
+ (line-number-at-pos (posn-point (event-start event)))))
+
+ (line-number-candidate ;; convert to 0 based index
+ (- line-number-at-point 2))
+ (offset
+ (- line-number-candidate
+ ivy--window-index)))
+ offset)
+ nil))
+
+(defun ivy-mouse-done (event)
+ (interactive "@e")
+ (let ((offset (ivy-mouse-offset event)))
+ (when offset
+ (ivy-next-line offset)
+ (ivy--exhibit)
+ (ivy-alt-done))))
+
+(defun ivy-mouse-dispatching-done (event)
+ (interactive "@e")
+ (let ((offset (ivy-mouse-offset event)))
+ (when offset
+ (ivy-next-line offset)
+ (ivy--exhibit)
+ (ivy-dispatching-done))))
+
+(defvar ivy-read-action-format-function 'ivy-read-action-format-default
+ "Function used to transform the actions list into a docstring.")
+
+(defun ivy-read-action-format-default (actions)
+ "Create a docstring from ACTIONS.
+
+ACTIONS is a list. Each list item is a list of 3 items:
+key (a string), cmd and doc (a string)."
+ (format "%s\n%s\n"
+ (if (eq this-command 'ivy-read-action)
+ "Select action: "
+ (ivy-state-current ivy-last))
+ (mapconcat
+ (lambda (x)
+ (format "%s: %s"
+ (propertize
+ (car x)
+ 'face 'ivy-action)
+ (nth 2 x)))
+ actions
+ "\n")))
+
+(defcustom ivy-read-action-function #'ivy-read-action-by-key
+ "Function used to read an action."
+ :type '(radio
+ (function-item ivy-read-action-by-key)
+ (function-item ivy-read-action-ivy)
+ (function-item ivy-read-action-hydra)))
+
+(defun ivy-read-action ()
+ "Change the action to one of the available ones.
+
+Return nil for `minibuffer-keyboard-quit' or wrong key during the
+selection, non-nil otherwise."
+ (interactive)
+ (let ((actions (ivy-state-action ivy-last)))
+ (if (not (ivy--actionp actions))
+ t
+ (funcall ivy-read-action-function actions))))
+
+(defun ivy-read-action-by-key (actions)
+ (let* ((hint (funcall ivy-read-action-format-function (cdr actions)))
+ (resize-mini-windows t)
+ (key "")
+ action-idx)
+ (while (and (setq action-idx (cl-position-if
+ (lambda (x)
+ (string-prefix-p key (car x)))
+ (cdr actions)))
+ (not (string= key (car (nth action-idx (cdr actions))))))
+ (setq key (concat key (string (read-key hint)))))
+ (ivy-shrink-after-dispatching)
+ (cond ((member key '("" ""))
+ nil)
+ ((null action-idx)
+ (message "%s is not bound" key)
+ nil)
+ (t
+ (message "")
+ (setcar actions (1+ action-idx))
+ (ivy-set-action actions)))))
+
+(defun ivy-read-action-ivy (actions)
+ "Select an action from ACTIONS using Ivy."
+ (let ((enable-recursive-minibuffers t))
+ (if (and (> (minibuffer-depth) 1)
+ (eq (ivy-state-caller ivy-last) 'ivy-read-action-ivy))
+ (minibuffer-keyboard-quit)
+ (ivy-read (format "action (%s): " (ivy-state-current ivy-last))
+ (cl-mapcar
+ (lambda (a i) (cons (format "[%s] %s" (nth 0 a) (nth 2 a)) i))
+ (cdr actions) (number-sequence 1 (length (cdr actions))))
+ :action (lambda (a)
+ (setcar actions (cdr a))
+ (ivy-set-action actions))
+ :caller 'ivy-read-action-ivy))))
+
+(defun ivy-shrink-after-dispatching ()
+ "Shrink the window after dispatching when action list is too large."
+ (window-resize nil (- ivy-height (window-height))))
+
+(defun ivy-dispatching-done ()
+ "Select one of the available actions and call `ivy-done'."
+ (interactive)
+ (when (ivy-read-action)
+ (ivy-done))
+ (ivy-shrink-after-dispatching))
+
+(defun ivy-dispatching-call ()
+ "Select one of the available actions and call `ivy-call'."
+ (interactive)
+ (setq ivy-current-prefix-arg current-prefix-arg)
+ (let ((actions (copy-sequence (ivy-state-action ivy-last))))
+ (unwind-protect
+ (when (ivy-read-action)
+ (ivy-call))
+ (ivy-set-action actions)))
+ (ivy-shrink-after-dispatching))
+
+(defun ivy-build-tramp-name (x)
+ "Reconstruct X into a path.
+Is is a cons cell, related to `tramp-get-completion-function'."
+ (let ((user (car x))
+ (domain (cadr x)))
+ (if user
+ (concat user "@" domain)
+ domain)))
+
+(declare-function Info-find-node "info")
+(declare-function Info-read-node-name-1 "info")
+(declare-function tramp-get-completion-function "tramp")
+
+(defun ivy-alt-done (&optional arg)
+ "Exit the minibuffer with the selected candidate.
+When ARG is t, exit with current text, ignoring the candidates.
+When the current candidate during file name completion is a
+directory, continue completion from within that directory instead
+of exiting. This function is otherwise like `ivy-done'."
+ (interactive "P")
+ (setq ivy-current-prefix-arg current-prefix-arg)
+ (cond ((or arg
+ (ivy--prompt-selected-p))
+ (ivy-immediate-done))
+ (ivy--directory
+ (ivy--directory-done))
+ ((eq (ivy-state-collection ivy-last) #'Info-read-node-name-1)
+ (if (member (ivy-state-current ivy-last) '("(./)" "(../)"))
+ (ivy-quit-and-run
+ (ivy-read "Go to file: " #'read-file-name-internal
+ :action (lambda (x)
+ (Info-find-node
+ (expand-file-name x ivy--directory)
+ "Top"))))
+ (ivy-done)))
+ (t
+ (ivy-done))))
+
+(defvar ivy-auto-select-single-candidate nil
+ "When non-nil, auto-select the candidate if it is the only one.
+When t, it is the same as if the user were prompted and selected the candidate
+by calling the default action. This variable has no use unless the collection
+contains a single candidate.")
+
+(defun ivy--directory-enter ()
+ (let (dir)
+ (when (and
+ (> ivy--length 0)
+ (not (string= (ivy-state-current ivy-last) "./"))
+ (setq dir (ivy-expand-file-if-directory (ivy-state-current ivy-last))))
+ (ivy--cd dir)
+ (ivy--exhibit))))
+
+(defun ivy--handle-directory (input)
+ "Detect the next directory based on special values of INPUT."
+ (cond ((string= input "/")
+ "/")
+ ((string= input "/sudo::")
+ (concat input ivy--directory))))
+
+(defun ivy--directory-done ()
+ "Handle exit from the minibuffer when completing file names."
+ (let ((dir (ivy--handle-directory ivy-text)))
+ (cond
+ (dir
+ (let ((inhibit-message t))
+ (ivy--cd dir)))
+ ((ivy--directory-enter))
+ ((unless (string= ivy-text "")
+ (let ((file (expand-file-name
+ (if (> ivy--length 0) (ivy-state-current ivy-last) ivy-text)
+ ivy--directory)))
+ (when (ignore-errors (file-exists-p file))
+ (if (file-directory-p file)
+ (ivy--cd (file-name-as-directory file))
+ (ivy-done))
+ ivy-text))))
+ ((or (and (equal ivy--directory "/")
+ (string-match-p "\\`[^/]+:.*:.*\\'" ivy-text))
+ (string-match-p "\\`/[^/]+:.*:.*\\'" ivy-text))
+ (ivy-done))
+ ((or (and (equal ivy--directory "/")
+ (cond ((string-match
+ "\\`\\([^/]+?\\):\\(?:\\(.*\\)@\\)?\\(.*\\)\\'"
+ ivy-text)
+ (setq ivy-text (ivy-state-current ivy-last)))
+ ((string-match
+ "\\`\\([^/]+?\\):\\(?:\\(.*\\)@\\)?\\(.*\\)\\'"
+ (ivy-state-current ivy-last))
+ (setq ivy-text (ivy-state-current ivy-last)))))
+ (string-match
+ "\\`/\\([^/]+?\\):\\(?:\\(.*\\)@\\)?\\(.*\\)\\'"
+ ivy-text))
+ (let ((method (match-string 1 ivy-text))
+ (user (match-string 2 ivy-text))
+ (rest (match-string 3 ivy-text))
+ res)
+ (dolist (x (tramp-get-completion-function method))
+ (setq res (append res (funcall (car x) (cadr x)))))
+ (setq res (delq nil res))
+ (when user
+ (dolist (x res)
+ (setcar x user)))
+ (setq res (delete-dups res))
+ (let* ((old-ivy-last ivy-last)
+ (enable-recursive-minibuffers t)
+ (host (let ((ivy-auto-select-single-candidate nil))
+ (ivy-read "user@host: "
+ (mapcar #'ivy-build-tramp-name res)
+ :initial-input rest))))
+ (setq ivy-last old-ivy-last)
+ (when host
+ (setq ivy--directory "/")
+ (ivy--cd (concat "/" method ":" host ":"))))))
+ (t
+ (ivy-done)))))
+
+(defun ivy-expand-file-if-directory (file-name)
+ "Expand FILE-NAME as directory.
+When this directory doesn't exist, return nil."
+ (when (stringp file-name)
+ (let ((full-name
+ ;; Ignore host name must not match method "ssh"
+ (ignore-errors
+ (file-name-as-directory
+ (expand-file-name file-name ivy--directory)))))
+ (when (and full-name (file-directory-p full-name))
+ full-name))))
+
+(defcustom ivy-tab-space nil
+ "When non-nil, `ivy-partial-or-done' should insert a space."
+ :type 'boolean)
+
+(defun ivy-partial-or-done ()
+ "Complete the minibuffer text as much as possible.
+If the text hasn't changed as a result, forward to `ivy-alt-done'."
+ (interactive)
+ (cond
+ ((and completion-cycle-threshold (< (length ivy--all-candidates) completion-cycle-threshold))
+ (let ((ivy-wrap t))
+ (ivy-next-line)))
+ ((and (eq (ivy-state-collection ivy-last) #'read-file-name-internal)
+ (or (and (equal ivy--directory "/")
+ (string-match-p "\\`[^/]+:.*\\'" ivy-text))
+ (= (string-to-char ivy-text) ?/)))
+ (let ((default-directory ivy--directory)
+ dir)
+ (minibuffer-complete)
+ (setq ivy-text (ivy--input))
+ (when (setq dir (ivy-expand-file-if-directory ivy-text))
+ (ivy--cd dir))))
+ (t
+ (or (ivy-partial)
+ (when (or (eq this-command last-command)
+ (eq ivy--length 1))
+ (ivy-alt-done))))))
+
+(defun ivy--remove-prefix (prefix string)
+ "Compatibility shim for `string-remove-prefix'."
+ (if (string-prefix-p prefix string)
+ (substring string (length prefix))
+ string))
+
+(defun ivy--partial-cd-for-single-directory ()
+ (when (and
+ (eq (ivy-state-collection ivy-last) #'read-file-name-internal)
+ (= 1 (length
+ (ivy--re-filter
+ (funcall ivy--regex-function ivy-text) ivy--all-candidates)))
+ (let ((default-directory ivy--directory))
+ (file-directory-p (ivy-state-current ivy-last))))
+ (ivy--directory-done)))
+
+(defun ivy-partial ()
+ "Complete the minibuffer text as much as possible."
+ (interactive)
+ (let* ((parts (or (ivy--split-spaces ivy-text) (list "")))
+ (tail (last parts))
+ (postfix (car tail))
+ (case-fold-search (ivy--case-fold-p ivy-text))
+ (completion-ignore-case case-fold-search)
+ (new (try-completion (ivy--remove-prefix "^" postfix)
+ (if (ivy-state-dynamic-collection ivy-last)
+ ivy--all-candidates
+ (mapcar (lambda (str)
+ (let ((i (string-match-p postfix str)))
+ (and i (substring str i))))
+ ivy--old-cands)))))
+ (cond ((eq new t) nil)
+ ((string= new ivy-text) nil)
+ ((string= (car tail) (car (ivy--split-spaces new))) nil)
+ (new
+ (delete-region (minibuffer-prompt-end) (point-max))
+ (setcar tail
+ (if (= (string-to-char postfix) ?^)
+ (concat "^" new)
+ new))
+ (insert
+ (setq ivy-text
+ (concat
+ (mapconcat #'identity parts " ")
+ (and ivy-tab-space (not (= (length ivy--old-cands) 1)) " "))))
+ (ivy--partial-cd-for-single-directory)
+ t))))
+
+(defvar ivy-completion-beg nil
+ "Completion bounds start.")
+
+(defvar ivy-completion-end nil
+ "Completion bounds end.")
+
+(defun ivy-immediate-done ()
+ "Exit the minibuffer with current input instead of current candidate."
+ (interactive)
+ (delete-minibuffer-contents)
+ (setf (ivy-state-current ivy-last)
+ (cond ((or (not ivy--directory)
+ (eq (ivy-state-history ivy-last) 'grep-files-history))
+ ivy-text)
+ ((and (string= ivy-text "")
+ (eq (ivy-state-collection ivy-last)
+ #'read-file-name-internal))
+ (if (ivy-state-def ivy-last)
+ (if (and
+ (file-exists-p (ivy-state-def ivy-last))
+ (/= (length ivy--directory)
+ (1+ (length (expand-file-name (ivy-state-def ivy-last))))))
+ ivy--directory
+ (copy-sequence (ivy-state-def ivy-last)))
+ ivy--directory))
+ (t
+ (expand-file-name ivy-text ivy--directory))))
+ (insert (ivy-state-current ivy-last))
+ (setq ivy-completion-beg ivy-completion-end)
+ (setq ivy-exit 'done)
+ (exit-minibuffer))
+
+;;;###autoload
+(defun ivy-resume ()
+ "Resume the last completion session."
+ (interactive)
+ (if (null (ivy-state-action ivy-last))
+ (user-error "The last session isn't compatible with `ivy-resume'")
+ (when (memq (ivy-state-caller ivy-last)
+ '(swiper swiper-isearch swiper-backward swiper-isearch-backward))
+ (switch-to-buffer (ivy-state-buffer ivy-last)))
+ (with-current-buffer (ivy-state-buffer ivy-last)
+ (let ((default-directory (ivy-state-directory ivy-last))
+ (ivy-use-ignore-default (ivy-state-ignore ivy-last)))
+ (ivy-read
+ (ivy-state-prompt ivy-last)
+ (ivy-state-collection ivy-last)
+ :predicate (ivy-state-predicate ivy-last)
+ :require-match (ivy-state-require-match ivy-last)
+ :initial-input ivy-text
+ :history (ivy-state-history ivy-last)
+ :preselect (ivy-state-current ivy-last)
+ :keymap (ivy-state-keymap ivy-last)
+ :update-fn (ivy-state-update-fn ivy-last)
+ :sort (ivy-state-sort ivy-last)
+ :action (ivy-state-action ivy-last)
+ :unwind (ivy-state-unwind ivy-last)
+ :re-builder (ivy-state-re-builder ivy-last)
+ :matcher (ivy-state-matcher ivy-last)
+ :dynamic-collection (ivy-state-dynamic-collection ivy-last)
+ :extra-props (ivy-state-extra-props ivy-last)
+ :caller (ivy-state-caller ivy-last))))))
+
+(defvar-local ivy-calling nil
+ "When non-nil, call the current action when `ivy--index' changes.")
+
+(defun ivy-set-index (index)
+ "Set `ivy--index' to INDEX."
+ (setq ivy--index index)
+ (when ivy-calling
+ (ivy--exhibit)
+ (ivy-call)))
+
+(defun ivy-beginning-of-buffer ()
+ "Select the first completion candidate."
+ (interactive)
+ (ivy-set-index 0))
+
+(defun ivy-end-of-buffer ()
+ "Select the last completion candidate."
+ (interactive)
+ (ivy-set-index (1- ivy--length)))
+
+(defun ivy-scroll-up-command ()
+ "Scroll the candidates upward by the minibuffer height."
+ (interactive)
+ (ivy-set-index (min (1- (+ ivy--index ivy-height))
+ (1- ivy--length))))
+
+(defun ivy-scroll-down-command ()
+ "Scroll the candidates downward by the minibuffer height."
+ (interactive)
+ (ivy-set-index (max (1+ (- ivy--index ivy-height))
+ 0)))
+
+(defun ivy-minibuffer-grow ()
+ "Grow the minibuffer window by 1 line."
+ (interactive)
+ (setq-local max-mini-window-height
+ (cl-incf ivy-height)))
+
+(defun ivy-minibuffer-shrink ()
+ "Shrink the minibuffer window by 1 line."
+ (interactive)
+ (when (> ivy-height 2)
+ (setq-local max-mini-window-height
+ (cl-decf ivy-height))
+ (window-resize nil -1)))
+
+(defun ivy-next-line (&optional arg)
+ "Move cursor vertically down ARG candidates."
+ (interactive "p")
+ (setq arg (or arg 1))
+ (let ((index (+ ivy--index arg)))
+ (if (> index (1- ivy--length))
+ (if ivy-wrap
+ (ivy-beginning-of-buffer)
+ (ivy-set-index (1- ivy--length)))
+ (ivy-set-index index))))
+
+(defun ivy-next-line-or-history (&optional arg)
+ "Move cursor vertically down ARG candidates.
+If the input is empty, select the previous history element instead."
+ (interactive "p")
+ (if (string= ivy-text "")
+ (ivy-previous-history-element 1)
+ (ivy-next-line arg)))
+
+(defun ivy-previous-line (&optional arg)
+ "Move cursor vertically up ARG candidates."
+ (interactive "p")
+ (setq arg (or arg 1))
+ (let ((index (- ivy--index arg))
+ (min-index (if ivy--use-selectable-prompt -1 0)))
+ (if (< index min-index)
+ (if ivy-wrap
+ (ivy-end-of-buffer)
+ (ivy-set-index min-index))
+ (ivy-set-index index))))
+
+(defun ivy-previous-line-or-history (arg)
+ "Move cursor vertically up ARG candidates.
+If the input is empty, select the previous history element instead."
+ (interactive "p")
+ (when (string= ivy-text "")
+ (ivy-previous-history-element 1))
+ (ivy-previous-line arg))
+
+(defun ivy-toggle-calling ()
+ "Flip `ivy-calling'."
+ (interactive)
+ (when (setq ivy-calling (not ivy-calling))
+ (ivy-call)))
+
+(defun ivy-toggle-ignore ()
+ "Toggle user-configured candidate filtering."
+ (interactive)
+ (setq ivy-use-ignore
+ (if ivy-use-ignore
+ nil
+ (or ivy-use-ignore-default t)))
+ (setf (ivy-state-ignore ivy-last) ivy-use-ignore)
+ ;; invalidate cache
+ (setq ivy--old-cands nil))
+
+(defun ivy--get-action (state)
+ "Get the action function from STATE."
+ (let ((action (ivy-state-action state)))
+ (when action
+ (if (functionp action)
+ action
+ (cadr (nth (car action) action))))))
+
+(defun ivy--get-window (state)
+ "Get the window from STATE."
+ (if (ivy-state-p state)
+ (let ((window (ivy-state-window state)))
+ (if (window-live-p window)
+ window
+ (next-window)))
+ (selected-window)))
+
+(defun ivy--actionp (x)
+ "Return non-nil when X is a list of actions."
+ (and (consp x) (not (memq (car x) '(closure lambda)))))
+
+(defcustom ivy-action-wrap nil
+ "When non-nil, `ivy-next-action' and `ivy-prev-action' wrap."
+ :type 'boolean)
+
+(defun ivy-next-action ()
+ "When the current action is a list, scroll it forwards."
+ (interactive)
+ (let ((action (ivy-state-action ivy-last)))
+ (when (ivy--actionp action)
+ (let ((len (1- (length action)))
+ (idx (car action)))
+ (if (>= idx len)
+ (when ivy-action-wrap
+ (setf (car action) 1))
+ (cl-incf (car action)))))))
+
+(defun ivy-prev-action ()
+ "When the current action is a list, scroll it backwards."
+ (interactive)
+ (let ((action (ivy-state-action ivy-last)))
+ (when (ivy--actionp action)
+ (if (<= (car action) 1)
+ (when ivy-action-wrap
+ (setf (car action) (1- (length action))))
+ (cl-decf (car action))))))
+
+(defun ivy-action-name ()
+ "Return the name associated with the current action."
+ (let ((action (ivy-state-action ivy-last)))
+ (if (ivy--actionp action)
+ (format "[%d/%d] %s"
+ (car action)
+ (1- (length action))
+ (nth 2 (nth (car action) action)))
+ "[1/1] default")))
+
+(defvar ivy-inhibit-action nil
+ "When non-nil, `ivy-call' does nothing.
+
+Example use:
+
+ (let* ((ivy-inhibit-action t)
+ (str (ivy-switch-buffer)))
+ ;; do whatever with str - the corresponding buffer will not be opened
+ )")
+
+(defun ivy-recursive-restore ()
+ "Restore the above state when exiting the minibuffer.
+See variable `ivy-recursive-restore' for further information."
+ (when (and ivy-recursive-last
+ ivy-recursive-restore
+ (not (eq ivy-last ivy-recursive-last)))
+ (ivy--reset-state (setq ivy-last ivy-recursive-last))))
+
+(defvar ivy-marked-candidates nil
+ "List of marked candidates.
+Use `ivy-mark' to populate this.
+
+When this list is non-nil at the end of the session, the action
+will be called for each element of this list.")
+
+(defvar ivy-mark-prefix ">"
+ "Prefix used by `ivy-mark'.")
+
+(defun ivy-call ()
+ "Call the current action without exiting completion."
+ (interactive)
+ ;; Testing with `ivy-with' seems to call `ivy-call' again,
+ ;; in which case `this-command' is nil; so check for this.
+ (unless (memq this-command '(nil
+ ivy-done
+ ivy-alt-done
+ ivy-dispatching-done))
+ (setq ivy-current-prefix-arg current-prefix-arg))
+ (let ((action
+ (if (functionp ivy-inhibit-action)
+ ivy-inhibit-action
+ (and (not ivy-inhibit-action)
+ (ivy--get-action ivy-last)))))
+ (when action
+ (let* ((collection (ivy-state-collection ivy-last))
+ (current (ivy-state-current ivy-last))
+ (x (cond
+ ;; Alist type.
+ ((and (consp (car-safe collection))
+ ;; Previously, the cdr of the selected
+ ;; candidate would be returned. Now, the
+ ;; whole candidate is returned.
+ (let ((idx (get-text-property 0 'idx current)))
+ (if idx
+ (nth idx collection)
+ (assoc current collection)))))
+ (ivy--directory
+ (expand-file-name current ivy--directory))
+ ((equal current "")
+ ivy-text)
+ (t
+ current))))
+ (if (eq action #'identity)
+ (prog1 x
+ (ivy-recursive-restore))
+ (select-window (ivy--get-window ivy-last))
+ (set-buffer (ivy-state-buffer ivy-last))
+ (prog1 (unwind-protect
+ (if ivy-marked-candidates
+ (let ((prefix-len (length ivy-mark-prefix)))
+ (setq ivy-marked-candidates
+ (mapcar (lambda (s) (substring s prefix-len))
+ ivy-marked-candidates))
+ (if (ivy-state-multi-action ivy-last)
+ (funcall
+ (ivy-state-multi-action ivy-last)
+ ivy-marked-candidates)
+ (dolist (c ivy-marked-candidates)
+ (let ((default-directory (ivy-state-directory ivy-last)))
+ (funcall action c)))))
+ (funcall action x))
+ (ivy-recursive-restore))
+ (unless (or (eq ivy-exit 'done)
+ (minibuffer-window-active-p (selected-window))
+ (null (active-minibuffer-window)))
+ (select-window (active-minibuffer-window)))))))))
+
+(defun ivy-call-and-recenter ()
+ "Call action and recenter window according to the selected candidate."
+ (interactive)
+ (ivy-call)
+ (with-ivy-window
+ (recenter-top-bottom)))
+
+(defun ivy-next-line-and-call (&optional arg)
+ "Move cursor vertically down ARG candidates.
+Call the permanent action if possible."
+ (interactive "p")
+ (ivy-next-line arg)
+ (ivy--exhibit)
+ (ivy-call))
+
+(defun ivy-previous-line-and-call (&optional arg)
+ "Move cursor vertically up ARG candidates.
+Call the permanent action if possible."
+ (interactive "p")
+ (ivy-previous-line arg)
+ (ivy--exhibit)
+ (ivy-call))
+
+(defun ivy-previous-history-element (arg)
+ "Forward to `previous-history-element' with ARG."
+ (interactive "p")
+ (previous-history-element arg)
+ (ivy--cd-maybe)
+ (move-end-of-line 1)
+ (ivy--maybe-scroll-history))
+
+(defun ivy--insert-symbol-boundaries ()
+ (undo-boundary)
+ (beginning-of-line)
+ (insert "\\_<")
+ (end-of-line)
+ (insert "\\_>"))
+
+(defun ivy-next-history-element (arg)
+ "Forward to `next-history-element' with ARG."
+ (interactive "p")
+ (if (and (= minibuffer-history-position 0)
+ (equal ivy-text ""))
+ (progn
+ (when minibuffer-default
+ (setq ivy--default (car minibuffer-default)))
+ (insert ivy--default)
+ (when (and (with-ivy-window (derived-mode-p 'prog-mode))
+ (eq (ivy-state-caller ivy-last) 'swiper)
+ (not (file-exists-p ivy--default))
+ (not (ivy-ffap-url-p ivy--default))
+ (not (ivy-state-dynamic-collection ivy-last))
+ (> (point) (minibuffer-prompt-end)))
+ (ivy--insert-symbol-boundaries)))
+ (next-history-element arg))
+ (ivy--cd-maybe)
+ (move-end-of-line 1)
+ (ivy--maybe-scroll-history))
+
+(defvar ivy-ffap-url-functions nil
+ "List of functions that check if the point is on a URL.")
+
+(defun ivy--cd-maybe ()
+ "Check if the current input points to a different directory.
+If so, move to that directory, while keeping only the file name."
+ (when ivy--directory
+ (let ((input (ivy--input))
+ url)
+ (if (setq url (or (ivy-ffap-url-p input)
+ (with-ivy-window
+ (cl-reduce
+ (lambda (a b)
+ (or a (funcall b)))
+ ivy-ffap-url-functions
+ :initial-value nil))))
+ (ivy-exit-with-action
+ (lambda (_)
+ (ivy-ffap-url-fetcher url)))
+ (setq input (expand-file-name input))
+ (let ((file (file-name-nondirectory input))
+ (dir (expand-file-name (file-name-directory input))))
+ (if (string= dir ivy--directory)
+ (progn
+ (delete-minibuffer-contents)
+ (insert file))
+ (ivy--cd dir)
+ (insert file)))))))
+
+(defun ivy--maybe-scroll-history ()
+ "If the selected history element has an index, scroll there."
+ (let ((idx (ignore-errors
+ (get-text-property
+ (minibuffer-prompt-end)
+ 'ivy-index))))
+ (when idx
+ (ivy--exhibit)
+ (ivy-set-index idx))))
+
+(declare-function tramp-get-completion-methods "tramp")
+
+(defun ivy--cd (dir)
+ "When completing file names, move to directory DIR."
+ (if (null ivy--directory)
+ (error "Unexpected")
+ (setq ivy--old-cands nil)
+ (setq ivy--old-re nil)
+ (ivy-set-index 0)
+ (setq ivy--all-candidates
+ (append
+ (ivy--sorted-files (setq ivy--directory dir))
+ (when (and (string= dir "/") (featurep 'tramp))
+ (sort
+ (mapcar
+ (lambda (s) (substring s 1))
+ (tramp-get-completion-methods ""))
+ #'string<))))
+ (setq ivy-text "")
+ (setf (ivy-state-directory ivy-last) dir)
+ (delete-minibuffer-contents)))
+
+(defun ivy--parent-dir (filename)
+ "Return parent directory of absolute FILENAME."
+ (file-name-directory (directory-file-name filename)))
+
+(defun ivy-backward-delete-char ()
+ "Forward to `delete-backward-char'.
+Call `ivy-on-del-error-function' if an error occurs, usually when
+there is no more text to delete at the beginning of the
+minibuffer."
+ (interactive)
+ (if (and ivy--directory (= (minibuffer-prompt-end) (point)))
+ (progn
+ (ivy--cd (ivy--parent-dir (expand-file-name ivy--directory)))
+ (ivy--exhibit))
+ (setq prefix-arg current-prefix-arg)
+ (condition-case nil
+ (call-interactively #'delete-backward-char)
+ (error
+ (when ivy-on-del-error-function
+ (funcall ivy-on-del-error-function))))))
+
+(defun ivy-delete-char (arg)
+ "Forward to `delete-char' ARG."
+ (interactive "p")
+ (unless (eolp)
+ (delete-char arg)))
+
+(defun ivy-forward-char (arg)
+ "Forward to `forward-char' ARG."
+ (interactive "p")
+ (unless (eolp)
+ (forward-char arg)))
+
+(defun ivy-kill-word (arg)
+ "Forward to `kill-word' ARG."
+ (interactive "p")
+ (unless (eolp)
+ (kill-word arg)))
+
+(defun ivy-kill-line ()
+ "Forward to `kill-line'."
+ (interactive)
+ (if (eolp)
+ (kill-region (minibuffer-prompt-end) (point))
+ (kill-line)))
+
+(defun ivy-kill-whole-line ()
+ "Forward to `kill-whole-line'."
+ (interactive)
+ (kill-region (minibuffer-prompt-end) (line-end-position)))
+
+(defun ivy-backward-kill-word ()
+ "Forward to `backward-kill-word'."
+ (interactive)
+ (if (and ivy--directory (= (minibuffer-prompt-end) (point)))
+ (progn
+ (ivy--cd (ivy--parent-dir (expand-file-name ivy--directory)))
+ (ivy--exhibit))
+ (ignore-errors
+ (let ((pt (point)))
+ (forward-word -1)
+ (delete-region (point) pt)))))
+
+(defvar ivy--regexp-quote #'regexp-quote
+ "Store the regexp quoting state.")
+
+(defun ivy-toggle-regexp-quote ()
+ "Toggle the regexp quoting."
+ (interactive)
+ (setq ivy--old-re nil)
+ (cl-rotatef ivy--regex-function ivy--regexp-quote))
+
+(defvar avy-all-windows)
+(defvar avy-action)
+(defvar avy-keys)
+(defvar avy-keys-alist)
+(defvar avy-style)
+(defvar avy-styles-alist)
+(declare-function avy-process "ext:avy")
+(declare-function avy--style-fn "ext:avy")
+
+(defcustom ivy-format-functions-alist
+ '((t . ivy-format-function-default))
+ "An alist of functions that transform the list of candidates into a string.
+This string is inserted into the minibuffer."
+ :type '(alist
+ :key-type symbol
+ :value-type
+ (choice
+ (const :tag "Default" ivy-format-function-default)
+ (const :tag "Arrow prefix" ivy-format-function-arrow)
+ (const :tag "Full line" ivy-format-function-line)
+ (function :tag "Custom function"))))
+
+(eval-after-load 'avy
+ '(add-to-list 'avy-styles-alist '(ivy-avy . pre)))
+
+(defun ivy--avy-candidates ()
+ (let (candidates)
+ (save-excursion
+ (save-restriction
+ (narrow-to-region
+ (window-start)
+ (window-end))
+ (goto-char (point-min))
+ (forward-line)
+ (while (< (point) (point-max))
+ (push
+ (cons (point)
+ (selected-window))
+ candidates)
+ (forward-line))))
+ (nreverse candidates)))
+
+(defun ivy--avy-action (pt)
+ (when (number-or-marker-p pt)
+ (let ((bnd (ivy--minibuffer-index-bounds
+ ivy--index ivy--length ivy-height)))
+ (ivy--done
+ (substring-no-properties
+ (nth (+ (car bnd) (- (line-number-at-pos pt) 2)) ivy--old-cands))))))
+
+(defun ivy--avy-handler-function (char)
+ (let (cmd)
+ (cond ((memq char '(27 ?\C-g))
+ ;; exit silently
+ (throw 'done 'abort))
+ ((memq (setq cmd (lookup-key ivy-minibuffer-map (vector char)))
+ '(ivy-scroll-up-command
+ ivy-scroll-down-command))
+ (funcall cmd)
+ (ivy--exhibit)
+ (throw 'done 'exit))
+ ;; ignore wrong key
+ (t
+ (throw 'done 'restart)))))
+
+(defvar avy-handler-function)
+
+(defun ivy-avy ()
+ "Jump to one of the current ivy candidates."
+ (interactive)
+ (unless (require 'avy nil 'noerror)
+ (error "Package avy isn't installed"))
+ (let* ((avy-all-windows nil)
+ (avy-keys (or (cdr (assq 'ivy-avy avy-keys-alist))
+ avy-keys))
+ (avy-style (or (cdr (assq 'ivy-avy avy-styles-alist))
+ avy-style))
+ (avy-action #'identity)
+ (avy-handler-function #'ivy--avy-handler-function)
+ res)
+ (while (eq (setq res (avy-process (ivy--avy-candidates))) t))
+ (when res
+ (ivy--avy-action res))))
+
+(defun ivy-sort-file-function-default (x y)
+ "Compare two files X and Y.
+Prioritize directories."
+ (if (get-text-property 0 'dirp x)
+ (if (get-text-property 0 'dirp y)
+ (string< (directory-file-name x) (directory-file-name y))
+ t)
+ (if (get-text-property 0 'dirp y)
+ nil
+ (string< x y))))
+
+(defun ivy-string< (x y)
+ "Like `string<', but operate on CARs when given cons cells."
+ (string< (if (consp x) (car x) x)
+ (if (consp y) (car y) y)))
+
+(define-obsolete-function-alias 'ivy-sort-file-function-using-ido
+ 'ido-file-extension-lessp "<2019-10-12 Sat>")
+
+(defcustom ivy-sort-functions-alist
+ '((t . ivy-string<))
+ "An alist of sorting functions for each collection function.
+Interactive functions that call completion fit in here as well.
+
+Nil means no sorting, which is useful to turn off the sorting for
+functions that have candidates in the natural buffer order, like
+`org-refile' or `Man-goto-section'.
+
+A list can be used to associate multiple sorting functions with a
+collection. The car of the list is the current sort
+function. This list can be rotated with `ivy-rotate-sort'.
+
+The entry associated with t is used for all fall-through cases.
+
+See also `ivy-sort-max-size'."
+ :type
+ '(alist
+ :key-type (choice
+ (const :tag "Fall-through" t)
+ (symbol :tag "Collection"))
+ :value-type (choice
+ (const :tag "Plain sort" string-lessp)
+ (const :tag "File sort" ivy-sort-file-function-default)
+ (const :tag "File sort using Ido" ido-file-extension-lessp)
+ (const :tag "No sort" nil)
+ (function :tag "Custom function")
+ (repeat (function :tag "Custom function")))))
+
+(defun ivy--sort-function (collection)
+ "Retrieve sort function for COLLECTION from `ivy-sort-functions-alist'."
+ (let ((entry (cdr (or (assq collection ivy-sort-functions-alist)
+ (assq (ivy-state-caller ivy-last) ivy-sort-functions-alist)
+ (assq t ivy-sort-functions-alist)))))
+ (and (or (functionp entry)
+ (functionp (setq entry (car-safe entry))))
+ entry)))
+
+(defun ivy-rotate-sort ()
+ "Rotate through sorting functions available for current collection.
+This only has an effect if multiple sorting functions are
+specified for the current collection in
+`ivy-sort-functions-alist'."
+ (interactive)
+ (let ((cell (or (assq (ivy-state-collection ivy-last) ivy-sort-functions-alist)
+ (assq (ivy-state-caller ivy-last) ivy-sort-functions-alist))))
+ (when (consp (cdr cell))
+ (setcdr cell (nconc (cddr cell) (list (cadr cell))))
+ (ivy--reset-state ivy-last))))
+
+(defvar ivy-index-functions-alist
+ '((t . ivy-recompute-index-zero))
+ "An alist of index recomputing functions for each collection function.
+When the input changes, the appropriate function returns an
+integer - the index of the matched candidate that should be
+selected.")
+
+(defvar ivy-re-builders-alist
+ '((t . ivy--regex-plus))
+ "An alist of regex building functions for each collection function.
+
+Each key is (in order of priority):
+1. The actual collection function, e.g. `read-file-name-internal'.
+2. The symbol passed by :caller into `ivy-read'.
+3. `this-command'.
+4. t.
+
+Each value is a function that should take a string and return a
+valid regex or a regex sequence (see below).
+
+Possible choices: `ivy--regex', `regexp-quote',
+`ivy--regex-plus', `ivy--regex-fuzzy', `ivy--regex-ignore-order'.
+
+If a function returns a list, it should format like this:
+'((\"matching-regexp\" . t) (\"non-matching-regexp\") ...).
+
+The matches will be filtered in a sequence, you can mix the
+regexps that should match and that should not match as you
+like.")
+
+(defvar ivy-highlight-functions-alist
+ '((ivy--regex-ignore-order . ivy--highlight-ignore-order)
+ (ivy--regex-fuzzy . ivy--highlight-fuzzy)
+ (ivy--regex-plus . ivy--highlight-default))
+ "An alist of highlighting functions for each regex builder function.")
+
+(defcustom ivy-initial-inputs-alist
+ '((org-refile . "^")
+ (org-agenda-refile . "^")
+ (org-capture-refile . "^")
+ (Man-completion-table . "^")
+ (woman . "^"))
+ "An alist associating commands with their initial input.
+
+Each cdr is either a string or a function called in the context
+of a call to `ivy-read'."
+ :type '(alist
+ :key-type (symbol)
+ :value-type (choice (string) (function))))
+
+(defcustom ivy-hooks-alist nil
+ "An alist associating commands to setup functions.
+Examples: `toggle-input-method', (lambda () (insert \"^\")), etc.
+May supersede `ivy-initial-inputs-alist'."
+ :type '(alist :key-type symbol :value-type function))
+
+(defvar ivy--occurs-list nil
+ "A list of custom occur generators per command.")
+
+(defun ivy-set-occur (cmd occur)
+ "Assign CMD a custom OCCUR function."
+ (setq ivy--occurs-list
+ (plist-put ivy--occurs-list cmd occur)))
+
+(defcustom ivy-update-fns-alist nil
+ "An alist associating commands to their :update-fn values."
+ :type '(alist
+ :key-type symbol
+ :value-type
+ (radio
+ (const :tag "Off" nil)
+ (const :tag "Call action on change" auto))))
+
+(defvar ivy-unwind-fns-alist nil
+ "An alist associating commands to their :unwind values.")
+
+(defun ivy--alist-set (alist-sym key val)
+ (let ((cell (assoc key (symbol-value alist-sym))))
+ (if cell
+ (setcdr cell val)
+ (set alist-sym (cons (cons key val)
+ (symbol-value alist-sym))))))
+
+(declare-function counsel-set-async-exit-code "counsel")
+
+(cl-defun ivy-configure (caller
+ &key
+ initial-input
+ height
+ occur
+ update-fn
+ unwind-fn
+ index-fn
+ sort-fn
+ format-fn
+ display-transformer-fn
+ more-chars
+ grep-p
+ exit-codes)
+ "Configure `ivy-read' params for CALLER."
+ (declare (indent 1))
+ (when initial-input
+ (ivy--alist-set 'ivy-initial-inputs-alist caller initial-input))
+ (when height
+ (ivy--alist-set 'ivy-height-alist caller height))
+ (when occur
+ (ivy-set-occur caller occur))
+ (when update-fn
+ (ivy--alist-set 'ivy-update-fns-alist caller update-fn))
+ (when unwind-fn
+ (ivy--alist-set 'ivy-unwind-fns-alist caller unwind-fn))
+ (when index-fn
+ (ivy--alist-set 'ivy-index-functions-alist caller index-fn))
+ (when sort-fn
+ (ivy--alist-set 'ivy-sort-functions-alist caller sort-fn))
+ (when format-fn
+ (ivy--alist-set 'ivy-format-functions-alist caller format-fn))
+ (when display-transformer-fn
+ (ivy-set-display-transformer caller display-transformer-fn))
+ (when more-chars
+ (ivy--alist-set 'ivy-more-chars-alist caller more-chars))
+ (when grep-p
+ (cl-pushnew caller ivy-highlight-grep-commands))
+ (when exit-codes
+ (let (code msg)
+ (while (and (setq code (pop exit-codes))
+ (setq msg (pop exit-codes)))
+ (counsel-set-async-exit-code caller code msg)))))
+
+(defcustom ivy-sort-max-size 30000
+ "Sorting won't be done for collections larger than this."
+ :type 'integer)
+
+(defalias 'ivy--dirname-p
+ (if (fboundp 'directory-name-p)
+ #'directory-name-p
+ (lambda (name)
+ "Return non-nil if NAME ends with a directory separator."
+ (string-match-p "/\\'" name))))
+
+(defun ivy--sorted-files (dir)
+ "Return the list of files in DIR.
+Directories come first."
+ (let* ((default-directory dir)
+ (seq (condition-case nil
+ (mapcar (lambda (s) (replace-regexp-in-string "\\$\\$" "$" s))
+ (all-completions "" #'read-file-name-internal
+ (ivy-state-predicate ivy-last)))
+ (error
+ (directory-files dir))))
+ sort-fn)
+ (setq seq (delete "./" (delete "../" seq)))
+ (when (eq (setq sort-fn (ivy--sort-function #'read-file-name-internal))
+ #'ivy-sort-file-function-default)
+ (setq seq (mapcar (lambda (x)
+ (propertize x 'dirp (ivy--dirname-p x)))
+ seq)))
+ (when sort-fn
+ (setq seq (sort seq sort-fn)))
+ (dolist (dir ivy-extra-directories)
+ (push dir seq))
+ (if (string= dir "/")
+ (cl-remove-if (lambda (s) (string-match ":$" s)) (delete "../" seq))
+ seq)))
+
+(defun ivy-alist-setting (alist &optional key)
+ "Return the value associated with KEY in ALIST, using `assq'.
+KEY defaults to the last caller of `ivy-read'; if no entry is
+found, it falls back to the key t."
+ (cdr (or (let ((caller (or key (ivy-state-caller ivy-last))))
+ (and caller (assq caller alist)))
+ (assq t alist))))
+
+(defun ivy--height (caller)
+ (let ((v (or (ivy-alist-setting ivy-height-alist caller)
+ ivy-height)))
+ (if (integerp v)
+ v
+ (if (functionp v)
+ (funcall v caller)
+ (error "Unexpected value: %S" v)))))
+
+(defun ivy--remove-props (str &rest props)
+ "Return STR with text PROPS destructively removed."
+ (ignore-errors
+ (remove-list-of-text-properties 0 (length str) props str))
+ str)
+
+;;** Entry Point
+;;;###autoload
+(cl-defun ivy-read (prompt collection
+ &key
+ predicate require-match initial-input
+ history preselect def keymap update-fn sort
+ action multi-action
+ unwind re-builder matcher
+ dynamic-collection
+ extra-props
+ caller)
+ "Read a string in the minibuffer, with completion.
+
+PROMPT is a string, normally ending in a colon and a space.
+`ivy-count-format' is prepended to PROMPT during completion.
+
+COLLECTION is either a list of strings, a function, an alist, or
+a hash table, supplied for `minibuffer-completion-table'.
+
+PREDICATE is applied to filter out the COLLECTION immediately.
+This argument is for compatibility with `completing-read'.
+
+When REQUIRE-MATCH is non-nil, only members of COLLECTION can be
+selected.
+
+If INITIAL-INPUT is non-nil, then insert that input in the
+minibuffer initially.
+
+HISTORY is a name of a variable to hold the completion session
+history.
+
+KEYMAP is composed with `ivy-minibuffer-map'.
+
+PRESELECT, when non-nil, determines which one of the candidates
+matching INITIAL-INPUT to select initially. An integer stands
+for the position of the desired candidate in the collection,
+counting from zero. Otherwise, use the first occurrence of
+PRESELECT in the collection. Comparison is first done with
+`equal'. If that fails, and when applicable, match PRESELECT as
+a regular expression.
+
+DEF is for compatibility with `completing-read'.
+
+UPDATE-FN is called each time the candidate list is re-displayed.
+
+When SORT is non-nil, `ivy-sort-functions-alist' determines how
+to sort candidates before displaying them.
+
+ACTION is a function to call after selecting a candidate.
+It takes one argument, the selected candidate. If COLLECTION is
+an alist, the argument is a cons cell, otherwise it's a string.
+
+MULTI-ACTION, when non-nil, is called instead of ACTION when
+there are marked candidates. It takes the list of candidates as
+its only argument. When it's nil, ACTION is called on each marked
+candidate.
+
+UNWIND is a function of no arguments to call before exiting.
+
+RE-BUILDER is a function transforming input text into a regex
+pattern.
+
+MATCHER is a function which can override how candidates are
+filtered based on user input. It takes a regex pattern and a
+list of candidates, and returns the list of matching candidates.
+
+DYNAMIC-COLLECTION is a boolean specifying whether the list of
+candidates is updated after each input by calling COLLECTION.
+
+EXTRA-PROPS can be used to store collection-specific
+session-specific data.
+
+CALLER is a symbol to uniquely identify the caller to `ivy-read'.
+It is used, along with COLLECTION, to determine which
+customizations apply to the current completion session."
+ ;; get un-stuck from an existing `read-key' overriding minibuffer keys
+ (when (equal overriding-local-map '(keymap))
+ (keyboard-quit))
+ (setq caller (or caller this-command))
+ (let* ((ivy-recursive-last (and (active-minibuffer-window) ivy-last))
+ (ivy--display-function
+ (when (or ivy-recursive-last
+ (not (window-minibuffer-p)))
+ (ivy-alist-setting ivy-display-functions-alist caller)))
+ result)
+ (setq update-fn (or update-fn (ivy-alist-setting ivy-update-fns-alist caller)))
+ (setq unwind (or unwind (ivy-alist-setting ivy-unwind-fns-alist caller)))
+ (setq ivy-last
+ (make-ivy-state
+ :prompt prompt
+ :collection collection
+ :predicate predicate
+ :require-match require-match
+ :initial-input initial-input
+ :history history
+ :preselect preselect
+ :keymap keymap
+ :update-fn (if (eq update-fn 'auto)
+ (lambda ()
+ (with-ivy-window
+ (funcall
+ (ivy--get-action ivy-last)
+ (if (consp (car-safe (ivy-state-collection ivy-last)))
+ (assoc (ivy-state-current ivy-last)
+ (ivy-state-collection ivy-last))
+ (ivy-state-current ivy-last)))))
+ update-fn)
+ :sort sort
+ :action (ivy--compute-extra-actions action caller)
+ :multi-action multi-action
+ :frame (selected-frame)
+ :window (selected-window)
+ :buffer (current-buffer)
+ :unwind unwind
+ :re-builder re-builder
+ :matcher matcher
+ :dynamic-collection dynamic-collection
+ :display-transformer-fn (plist-get ivy--display-transformers-list caller)
+ :directory default-directory
+ :extra-props extra-props
+ :caller caller
+ :def def))
+ (ivy--reset-state ivy-last)
+ (unwind-protect
+ (minibuffer-with-setup-hook
+ #'ivy--minibuffer-setup
+ (let* ((hist (or history 'ivy-history))
+ (minibuffer-completion-table collection)
+ (minibuffer-completion-predicate predicate)
+ (ivy-height (ivy--height caller))
+ (resize-mini-windows (unless (display-graphic-p)
+ 'grow-only)))
+ (if (and ivy-auto-select-single-candidate
+ ivy--all-candidates
+ (null (cdr ivy--all-candidates)))
+ (progn
+ (setf (ivy-state-current ivy-last)
+ (car ivy--all-candidates))
+ (setq ivy-exit 'done))
+ (read-from-minibuffer
+ prompt
+ (ivy-state-initial-input ivy-last)
+ (make-composed-keymap keymap ivy-minibuffer-map)
+ nil
+ hist))
+ (when (eq ivy-exit 'done)
+ (let ((item (if ivy--directory
+ (ivy-state-current ivy-last)
+ ivy-text)))
+ (unless (equal item "")
+ (set hist (cons (propertize item 'ivy-index ivy--index)
+ (delete item
+ (cdr (symbol-value hist))))))))
+ (setq result (ivy-state-current ivy-last))))
+ (ivy--cleanup))
+ (ivy-call)
+ (ivy--remove-props (ivy-state-current ivy-last) 'idx)
+ result))
+
+(defun ivy--cleanup ()
+ ;; Fixes a bug in ESS, #1660
+ (put 'post-command-hook 'permanent-local nil)
+ (remove-hook 'post-command-hook #'ivy--queue-exhibit)
+ (let ((cleanup (ivy--display-function-prop :cleanup))
+ (unwind (ivy-state-unwind ivy-last)))
+ (when (functionp cleanup)
+ (funcall cleanup))
+ (when unwind
+ (funcall unwind)))
+ (ivy--pulse-cleanup)
+ (unless (eq ivy-exit 'done)
+ (ivy-recursive-restore)))
+
+(defun ivy--display-function-prop (prop)
+ "Return PROP associated with current `ivy--display-function'."
+ (plist-get (cdr (assq ivy--display-function
+ ivy-display-functions-props))
+ prop))
+
+(defvar Info-complete-menu-buffer)
+
+(defun ivy--reset-state (state)
+ "Reset the ivy to STATE.
+This is useful for recursive `ivy-read'."
+ (setq ivy-marked-candidates nil)
+ (unless (equal (selected-frame) (ivy-state-frame state))
+ (select-window (active-minibuffer-window)))
+ (let* ((prompt (or (ivy-state-prompt state) ""))
+ (collection (ivy-state-collection state))
+ (predicate (ivy-state-predicate state))
+ (history (ivy-state-history state))
+ (preselect (ivy-state-preselect state))
+ (re-builder (ivy-state-re-builder state))
+ (dynamic-collection (ivy-state-dynamic-collection state))
+ (require-match (ivy-state-require-match state))
+ (caller (or (ivy-state-caller state) this-command))
+ (sort (or (ivy-state-sort state) (assoc caller ivy-sort-functions-alist)))
+ (initial-input
+ (or (ivy-state-initial-input state)
+ (let ((init (cdr (assq caller ivy-initial-inputs-alist))))
+ (cond ((functionp init)
+ (funcall init))
+ (t
+ init)))))
+ (def (ivy-state-def state)))
+ (setq ivy--extra-candidates (ivy--compute-extra-candidates caller))
+ (setq ivy--directory nil)
+ (setq ivy-case-fold-search ivy-case-fold-search-default)
+ (setq ivy--regex-function
+ (or re-builder
+ (and (functionp collection)
+ (cdr (assq collection ivy-re-builders-alist)))
+ (ivy-alist-setting ivy-re-builders-alist)
+ #'ivy--regex))
+ (setq ivy--subexps 0)
+ (setq ivy--regexp-quote #'regexp-quote)
+ (setq ivy--old-text "")
+ (setq ivy--full-length nil)
+ (setq ivy-text "")
+ (setq ivy--index 0)
+ (setq ivy-calling nil)
+ (setq ivy-use-ignore ivy-use-ignore-default)
+ (setf (ivy-state-ignore state) ivy-use-ignore)
+ (setq ivy--highlight-function
+ (or (cdr (assq ivy--regex-function ivy-highlight-functions-alist))
+ #'ivy--highlight-default))
+ (let (coll sort-fn)
+ (cond ((eq collection #'Info-read-node-name-1)
+ (setq coll
+ (if (equal (bound-and-true-p Info-current-file) "dir")
+ (mapcar (lambda (x) (format "(%s)" x))
+ (delete-dups
+ (all-completions "(" collection predicate)))
+ (all-completions "" collection predicate))))
+ ((eq collection #'read-file-name-internal)
+ (require 'tramp)
+ (when (and (equal def initial-input)
+ (member "./" ivy-extra-directories))
+ (setq def nil))
+ (setq ivy--directory default-directory)
+ (when (and initial-input
+ (not (equal initial-input "")))
+ (cond ((file-directory-p initial-input)
+ (when (equal (file-name-nondirectory initial-input) "")
+ (setf (ivy-state-preselect state) (setq preselect nil))
+ (setq def nil))
+ (setq ivy--directory (file-name-as-directory initial-input))
+ (setq initial-input nil)
+ (when preselect
+ (let ((preselect-directory
+ (file-name-directory preselect)))
+ (when (and preselect-directory
+ (not (equal
+ (expand-file-name
+ preselect-directory)
+ (expand-file-name ivy--directory))))
+ (setf (ivy-state-preselect state)
+ (setq preselect nil))))))
+ ((ignore-errors
+ (file-exists-p (file-name-directory initial-input)))
+ (setq ivy--directory (file-name-directory initial-input))
+ (setf (ivy-state-preselect state)
+ (file-name-nondirectory initial-input)))))
+ (require 'dired)
+ (when preselect
+ (let ((preselect-directory (ivy--parent-dir preselect)))
+ (when (and preselect-directory
+ (not (string= preselect-directory
+ default-directory)))
+ (setq ivy--directory preselect-directory))
+ (setq preselect (file-relative-name preselect
+ preselect-directory))
+ (setf (ivy-state-preselect state) preselect)))
+ (setq sort nil)
+ (setq coll (ivy--sorted-files ivy--directory))
+ (when initial-input
+ (unless (or require-match
+ (equal initial-input default-directory)
+ (equal initial-input ""))
+ (setq coll (cons initial-input coll)))
+ (when (or (not (ivy-state-action ivy-last))
+ (equal (ivy--get-action ivy-last) 'identity))
+ (setq initial-input nil))))
+ ((eq collection #'internal-complete-buffer)
+ (setq prompt
+ (replace-regexp-in-string "RET to end" "C-M-j to end" prompt))
+ (setq coll (ivy--buffer-list
+ ""
+ (and ivy-use-virtual-buffers
+ (member caller '(ivy-switch-buffer
+ ivy-switch-buffer-other-window
+ counsel-switch-buffer)))
+ predicate)))
+ (dynamic-collection
+ (setq coll (funcall collection (or initial-input ""))))
+ ((consp (car-safe collection))
+ (setq collection (cl-remove-if-not predicate collection))
+ (when (and sort (setq sort-fn (ivy--sort-function caller)))
+ (setq collection (sort (copy-sequence collection) sort-fn))
+ (setq sort nil))
+ (setf (ivy-state-collection ivy-last) collection)
+ (setq coll (let ((i -1))
+ (mapcar (lambda (x)
+ (propertize x 'idx (cl-incf i)))
+ (all-completions "" collection)))))
+ ((or (functionp collection)
+ (byte-code-function-p collection)
+ (vectorp collection)
+ (hash-table-p collection)
+ (and (listp collection) (symbolp (car collection))))
+ (let ((Info-complete-menu-buffer
+ ;; FIXME: This is a temporary workaround for issue #1803.
+ (or (bound-and-true-p Info-complete-menu-buffer)
+ (ivy-state-buffer state))))
+ (setq coll (all-completions "" collection predicate))))
+ (t
+ (setq coll (all-completions "" collection predicate))))
+ (unless (ivy-state-dynamic-collection ivy-last)
+ (setq coll (delete "" coll)))
+ (when def
+ (cond ((stringp (car-safe def))
+ (setq coll (cl-union def coll :test #'equal)))
+ ((and (stringp def) (not (member def coll)))
+ (push def coll))))
+ (when (and sort
+ (or (functionp collection)
+ (not (eq history 'org-refile-history)))
+ (setq sort-fn (ivy--sort-function
+ (if (functionp collection) collection caller)))
+ (null (nthcdr ivy-sort-max-size coll)))
+ (setq coll (sort (copy-sequence coll) sort-fn)))
+ (setq coll (ivy--set-candidates coll))
+ (setq ivy--old-re nil)
+ (setq ivy--old-cands nil)
+ (when initial-input
+ ;; Needed for anchor to work
+ (setq ivy--old-cands coll)
+ (setq ivy--old-cands (ivy--filter initial-input coll)))
+ (unless (setq ivy--trying-to-resume-dynamic-collection
+ (and preselect dynamic-collection))
+ (when (integerp preselect)
+ (setq ivy--old-re "")
+ (ivy-set-index preselect)))
+ (setq ivy--all-candidates coll)
+ (unless (integerp preselect)
+ (ivy-set-index (or
+ (and dynamic-collection
+ ivy--index)
+ (and preselect
+ (ivy--preselect-index
+ preselect
+ (if initial-input
+ ivy--old-cands
+ coll)))
+ 0))))
+ (setq ivy-exit nil)
+ (setq ivy--default
+ (if (region-active-p)
+ (buffer-substring (region-beginning) (region-end))
+ (ivy-thing-at-point)))
+ (setq ivy--prompt (ivy-add-prompt-count (ivy--quote-format-string prompt)))
+ (setq ivy--use-selectable-prompt (ivy--prompt-selectable-p))
+ (setf (ivy-state-initial-input ivy-last) initial-input)))
+
+(defun ivy-add-prompt-count (prompt)
+ "Add count information to PROMPT."
+ (cond ((null ivy-count-format)
+ (error
+ "`ivy-count-format' can't be nil. Set it to \"\" instead"))
+ ((string-match "%d.*\\(%d\\)" ivy-count-format)
+ (let* ((w (1+ (floor (log (max 1 (length ivy--all-candidates)) 10))))
+ (s (replace-match (format "%%-%dd" w) t t ivy-count-format 1)))
+ (string-match "%d" s)
+ (concat (replace-match (format "%%%dd" w) t t s)
+ prompt)))
+ ((string-match-p "%.*d" ivy-count-format)
+ (concat ivy-count-format prompt))
+ (ivy--directory
+ prompt)
+ (t
+ prompt)))
+
+(defun ivy--quote-format-string (str)
+ "Make STR suitable for `format' with no extra arguments."
+ (replace-regexp-in-string "%" "%%" str t t))
+
+;;;###autoload
+(defun ivy-completing-read (prompt collection
+ &optional predicate require-match initial-input
+ history def inherit-input-method)
+ "Read a string in the minibuffer, with completion.
+
+This interface conforms to `completing-read' and can be used for
+`completing-read-function'.
+
+PROMPT is a string that normally ends in a colon and a space.
+COLLECTION is either a list of strings, an alist, an obarray, or a hash table.
+PREDICATE limits completion to a subset of COLLECTION.
+REQUIRE-MATCH is a boolean value. See `completing-read'.
+INITIAL-INPUT is a string inserted into the minibuffer initially.
+HISTORY is a list of previously selected inputs.
+DEF is the default value.
+INHERIT-INPUT-METHOD is currently ignored."
+ (let ((handler
+ (and (< ivy-completing-read-ignore-handlers-depth (minibuffer-depth))
+ (assq this-command ivy-completing-read-handlers-alist))))
+ (if handler
+ (let ((completion-in-region-function #'completion--in-region)
+ (ivy-completing-read-ignore-handlers-depth (1+ (minibuffer-depth))))
+ (funcall (cdr handler)
+ prompt collection
+ predicate require-match
+ initial-input history
+ def inherit-input-method))
+ ;; See the doc of `completing-read'.
+ (when (consp history)
+ (when (numberp (cdr history))
+ (setq initial-input (nth (1- (cdr history))
+ (symbol-value (car history)))))
+ (setq history (car history)))
+ (when (consp def)
+ (setq def (car def)))
+ (let ((str (ivy-read
+ prompt collection
+ :predicate predicate
+ :require-match (and collection require-match)
+ :initial-input (cond ((consp initial-input)
+ (car initial-input))
+ ((and (stringp initial-input)
+ (not (eq collection #'read-file-name-internal))
+ (string-match-p "\\+" initial-input))
+ (replace-regexp-in-string
+ "\\+" "\\\\+" initial-input))
+ (t
+ initial-input))
+ :preselect def
+ :def def
+ :history history
+ :keymap nil
+ :dynamic-collection ivy-completing-read-dynamic-collection
+ :caller (if (and collection (symbolp collection))
+ collection
+ this-command))))
+ (if (string= str "")
+ ;; For `completing-read' compat, return the first element of
+ ;; DEFAULT, if it is a list; "", if DEFAULT is nil; or DEFAULT.
+ (or def "")
+ str)))))
+
+(defun ivy-completing-read-with-empty-string-def
+ (prompt collection
+ &optional predicate require-match initial-input
+ history def inherit-input-method)
+ "Same as `ivy-completing-read' but with different handling of DEF.
+
+Specifically, if DEF is nil, it is treated the same as if DEF was
+the empty string. This mimics the behavior of
+`completing-read-default'. This function can therefore be used in
+place of `ivy-completing-read' for commands that rely on this
+behavior."
+ (ivy-completing-read
+ prompt collection predicate require-match initial-input
+ history (or def "") inherit-input-method))
+
+(declare-function mc/all-fake-cursors "ext:multiple-cursors-core")
+
+(defun ivy-completion-in-region-action (str)
+ "Insert STR, erasing the previous one.
+The previous string is between `ivy-completion-beg' and `ivy-completion-end'."
+ (when (consp str)
+ (setq str (cdr str)))
+ (when (stringp str)
+ (let ((fake-cursors (and (require 'multiple-cursors-core nil t)
+ (mc/all-fake-cursors)))
+ (pt (point))
+ (beg ivy-completion-beg)
+ (end ivy-completion-end))
+ (when beg
+ (delete-region beg end))
+ (setq ivy-completion-beg (point))
+ (insert (substring-no-properties str))
+ (completion--done str 'exact)
+ (setq ivy-completion-end (point))
+ (save-excursion
+ (dolist (cursor fake-cursors)
+ (goto-char (overlay-start cursor))
+ (delete-region (+ (point) (- beg pt))
+ (+ (point) (- end pt)))
+ (insert (substring-no-properties str))
+ ;; manually move the fake cursor
+ (move-overlay cursor (point) (1+ (point)))
+ (set-marker (overlay-get cursor 'point) (point))
+ (set-marker (overlay-get cursor 'mark) (point)))))))
+
+(defun ivy-completion-common-length (str)
+ "Return the amount of characters that match in STR.
+
+`completion-all-completions' computes this and returns the result
+via text properties.
+
+The first non-matching part is propertized:
+- either with: (face (completions-first-difference))
+- or: (font-lock-face completions-first-difference)."
+ (let ((char-property-alias-alist '((face font-lock-face)))
+ (i (1- (length str))))
+ (catch 'done
+ (while (>= i 0)
+ (when (equal (get-text-property i 'face str)
+ '(completions-first-difference))
+ (throw 'done i))
+ (cl-decf i))
+ (throw 'done (length str)))))
+
+(defun ivy-completion-in-region (start end collection &optional predicate)
+ "An Ivy function suitable for `completion-in-region-function'.
+The function completes the text between START and END using COLLECTION.
+PREDICATE (a function called with no arguments) says when to exit.
+See `completion-in-region' for further information."
+ (let* ((enable-recursive-minibuffers t)
+ (str (buffer-substring-no-properties start end))
+ (completion-ignore-case (ivy--case-fold-p str))
+ (comps
+ (completion-all-completions str collection predicate (- end start))))
+ (cond ((null comps)
+ (message "No matches"))
+ ((progn
+ (nconc comps nil)
+ (and (null (cdr comps))
+ (string= str (car comps))))
+ (message "Sole match"))
+ (t
+ (when (eq collection 'crm--collection-fn)
+ (setq comps (delete-dups comps)))
+ (let* ((len (ivy-completion-common-length (car comps)))
+ (initial (cond ((= len 0)
+ "")
+ ((let ((str-len (length str)))
+ (when (> len str-len)
+ (setq len str-len)
+ str)))
+ (t
+ (substring str (- len))))))
+ (setq ivy--old-re nil)
+ (unless (ivy--filter initial comps)
+ (setq initial nil))
+ (delete-region (- end len) end)
+ (setq ivy-completion-beg (- end len))
+ (setq ivy-completion-end ivy-completion-beg)
+ (if (null (cdr comps))
+ (progn
+ (unless (minibuffer-window-active-p (selected-window))
+ (setf (ivy-state-window ivy-last) (selected-window)))
+ (ivy-completion-in-region-action
+ (substring-no-properties (car comps))))
+ (dolist (s comps)
+ ;; Remove face `completions-first-difference'.
+ (ivy--remove-props s 'face))
+ (ivy-read (format "(%s): " str) comps
+ ;; Predicate was already applied by
+ ;; `completion-all-completions'.
+ :predicate nil
+ :initial-input initial
+ :action #'ivy-completion-in-region-action
+ :unwind (lambda ()
+ (unless (eq ivy-exit 'done)
+ (goto-char ivy-completion-beg)
+ (when initial
+ (insert initial))))
+ :caller 'ivy-completion-in-region)
+ t))))))
+
+(defun ivy-completion-in-region-prompt ()
+ "Prompt function for `ivy-completion-in-region'.
+See `ivy-set-prompt'."
+ (and (window-minibuffer-p (ivy-state-window ivy-last))
+ (ivy-add-prompt-count (ivy-state-prompt ivy-last))))
+
+(ivy-set-prompt #'ivy-completion-in-region #'ivy-completion-in-region-prompt)
+
+(defcustom ivy-do-completion-in-region t
+ "When non-nil `ivy-mode' will set `completion-in-region-function'."
+ :type 'boolean)
+
+;;;###autoload
+(define-minor-mode ivy-mode
+ "Toggle Ivy mode on or off.
+Turn Ivy mode on if ARG is positive, off otherwise.
+Turning on Ivy mode sets `completing-read-function' to
+`ivy-completing-read'.
+
+Global bindings:
+\\{ivy-mode-map}
+
+Minibuffer bindings:
+\\{ivy-minibuffer-map}"
+ :group 'ivy
+ :global t
+ :keymap ivy-mode-map
+ :lighter " ivy"
+ (if ivy-mode
+ (progn
+ (setq completing-read-function 'ivy-completing-read)
+ (when ivy-do-completion-in-region
+ (setq completion-in-region-function 'ivy-completion-in-region)))
+ (setq completing-read-function 'completing-read-default)
+ (setq completion-in-region-function 'completion--in-region)))
+
+(defun ivy--preselect-index (preselect candidates)
+ "Return the index of PRESELECT in CANDIDATES."
+ (cond ((integerp preselect)
+ (if (integerp (car candidates))
+ (cl-position preselect candidates)
+ preselect))
+ ((cl-position preselect candidates :test #'equal))
+ ((ivy--regex-p preselect)
+ (cl-position preselect candidates :test #'string-match-p))))
+
+;;* Implementation
+;;** Regex
+(defun ivy-re-match (re-seq str)
+ "Return non-nil if RE-SEQ is matched by STR.
+
+RE-SEQ is a list of (RE . MATCH-P).
+
+RE is a regular expression.
+
+MATCH-P is t when RE should match STR and nil when RE should not
+match STR.
+
+Each element of RE-SEQ must match for the function to return true.
+
+This concept is used to generalize regular expressions for
+`ivy--regex-plus' and `ivy--regex-ignore-order'."
+ (let ((res t)
+ re)
+ (while (and res (setq re (pop re-seq)))
+ (setq res
+ (if (cdr re)
+ (string-match-p (car re) str)
+ (not (string-match-p (car re) str)))))
+ res))
+
+(defvar ivy--regex-hash
+ (make-hash-table :test #'equal)
+ "Store pre-computed regex.")
+
+(defun ivy--split (str)
+ "Split STR into list of substrings bounded by spaces.
+Single spaces act as splitting points. Consecutive spaces
+\"quote\" their preceding spaces, i.e., guard them from being
+split. This allows the literal interpretation of N spaces by
+inputting N+1 spaces. Any substring not constituting a valid
+regexp is passed to `regexp-quote'."
+ (let ((len (length str))
+ start0
+ (start1 0)
+ res s
+ match-len)
+ (while (and (string-match " +" str start1)
+ (< start1 len))
+ (if (and (> (match-beginning 0) 2)
+ (string= "[^" (substring
+ str
+ (- (match-beginning 0) 2)
+ (match-beginning 0))))
+ (progn
+ (setq start0 start1)
+ (setq start1 (match-end 0)))
+ (setq match-len (- (match-end 0) (match-beginning 0)))
+ (if (= match-len 1)
+ (progn
+ (when start0
+ (setq start1 start0)
+ (setq start0 nil))
+ (push (substring str start1 (match-beginning 0)) res)
+ (setq start1 (match-end 0)))
+ (setq str (replace-match
+ (make-string (1- match-len) ?\ )
+ nil nil str))
+ (setq start0 (or start0 start1))
+ (setq start1 (1- (match-end 0))))))
+ (if start0
+ (push (substring str start0) res)
+ (setq s (substring str start1))
+ (unless (= (length s) 0)
+ (push s res)))
+ (mapcar #'ivy--regex-or-literal (nreverse res))))
+
+(defun ivy--trim-trailing-re (regex)
+ "Trim incomplete REGEX.
+If REGEX ends with \\|, trim it, since then it matches an empty string."
+ (if (string-match "\\`\\(.*\\)[\\]|\\'" regex)
+ (match-string 1 regex)
+ regex))
+
+(defun ivy--regex (str &optional greedy)
+ "Re-build regex pattern from STR in case it has a space.
+When GREEDY is non-nil, join words in a greedy way."
+ (let ((hashed (unless greedy
+ (gethash str ivy--regex-hash))))
+ (if hashed
+ (progn
+ (setq ivy--subexps (car hashed))
+ (cdr hashed))
+ (when (string-match-p "\\(?:[^\\]\\|^\\)\\\\\\'" str)
+ (setq str (substring str 0 -1)))
+ (setq str (ivy--trim-trailing-re str))
+ (cdr (puthash str
+ (let ((subs (ivy--split str)))
+ (if (= (length subs) 1)
+ (cons
+ (setq ivy--subexps 0)
+ (if (string-match-p "\\`\\.[^.]" (car subs))
+ (concat "\\." (substring (car subs) 1))
+ (car subs)))
+ (cons
+ (setq ivy--subexps (length subs))
+ (mapconcat
+ (lambda (x)
+ (if (string-match-p "\\`\\\\([^?].*\\\\)\\'" x)
+ x
+ (format "\\(%s\\)" x)))
+ subs
+ (if greedy ".*" ".*?")))))
+ ivy--regex-hash)))))
+
+(defun ivy--regex-p (object)
+ "Return OBJECT if it is a valid regular expression, else nil."
+ (ignore-errors (string-match-p object "") object))
+
+(defun ivy--regex-or-literal (str)
+ "If STR isn't a legal regexp, escape it."
+ (or (ivy--regex-p str) (regexp-quote str)))
+
+(defun ivy--split-negation (str)
+ "Split STR into text before and after ! delimiter.
+Do not split if the delimiter is escaped as \\!.
+
+Assumes there is at most one un-escaped delimiter and discards
+text after delimiter if it is empty. Modifies match data."
+ (unless (string= str "")
+ (let ((delim "\\(?:\\`\\|[^\\]\\)\\(!\\)"))
+ (mapcar (lambda (split)
+ ;; Store "\!" as "!".
+ (replace-regexp-in-string "\\\\!" "!" split t t))
+ (if (string-match delim str)
+ ;; Ignore everything past first un-escaped ! rather than
+ ;; crashing. We can't warn or error because the minibuffer is
+ ;; already active.
+ (let* ((i (match-beginning 1))
+ (j (and (string-match delim str (1+ i))
+ (match-beginning 1)))
+ (neg (substring str (1+ i) j)))
+ (cons (substring str 0 i)
+ (and (not (string= neg ""))
+ (list neg))))
+ (list str))))))
+
+(defun ivy--split-spaces (str)
+ "Split STR on spaces, unless they're preceded by \\.
+No un-escaped spaces are left in the output. Any substring not
+constituting a valid regexp is passed to `regexp-quote'."
+ (when str
+ (let ((i 0) ; End of last search.
+ (j 0) ; End of last delimiter.
+ parts)
+ (while (string-match "\\(\\\\ \\)\\| +" str i)
+ (setq i (match-end 0))
+ (if (not (match-beginning 1))
+ ;; Un-escaped space(s).
+ (let ((delim (match-beginning 0)))
+ (when (< j delim)
+ (push (substring str j delim) parts))
+ (setq j i))
+ ;; Store "\ " as " ".
+ (setq str (replace-match " " t t str 1))
+ (setq i (1- i))))
+ (when (< j (length str))
+ (push (substring str j) parts))
+ (mapcar #'ivy--regex-or-literal (nreverse parts)))))
+
+(defun ivy--regex-ignore-order (str)
+ "Re-build regex from STR by splitting at spaces and using ! for negation.
+
+Examples:
+foo -> matches \"foo\"
+foo bar -> matches if both \"foo\" and \"bar\" match (any order)
+foo !bar -> matches if \"foo\" matches and \"bar\" does not match
+foo !bar baz -> matches if \"foo\" matches and neither \"bar\" nor \"baz\" match
+foo[a-z] -> matches \"foo[a-z]\"
+
+Escaping examples:
+foo\\!bar -> matches \"foo!bar\"
+foo\\ bar -> matches \"foo bar\"
+
+Returns a list suitable for `ivy-re-match'."
+ (setq str (ivy--trim-trailing-re str))
+ (let* (regex-parts
+ (raw-parts (ivy--split-negation str)))
+ (dolist (part (ivy--split-spaces (car raw-parts)))
+ (push (cons part t) regex-parts))
+ (when (cdr raw-parts)
+ (dolist (part (ivy--split-spaces (cadr raw-parts)))
+ (push (cons part nil) regex-parts)))
+ (if regex-parts (nreverse regex-parts)
+ "")))
+
+(defun ivy--regex-plus (str)
+ "Build a regex sequence from STR.
+Spaces are wild card characters, everything before \"!\" should
+match. Everything after \"!\" should not match."
+ (let ((parts (ivy--split-negation str)))
+ (cl-case (length parts)
+ (0
+ "")
+ (1
+ (if (= (aref str 0) ?!)
+ (list (cons "" t)
+ (list (ivy--regex (car parts))))
+ (ivy--regex (car parts))))
+ (2
+ (cons
+ (cons (ivy--regex (car parts)) t)
+ (mapcar #'list (split-string (cadr parts) " " t))))
+ (t (error "Unexpected: use only one !")))))
+
+(defun ivy--regex-fuzzy (str)
+ "Build a regex sequence from STR.
+Insert .* between each char."
+ (setq str (ivy--trim-trailing-re str))
+ (if (string-match "\\`\\(\\^?\\)\\(.*?\\)\\(\\$?\\)\\'" str)
+ (prog1
+ (concat (match-string 1 str)
+ (let ((lst (string-to-list (match-string 2 str))))
+ (apply #'concat
+ (cl-mapcar
+ #'concat
+ (cons "" (cdr (mapcar (lambda (c) (format "[^%c\n]*" c))
+ lst)))
+ (mapcar (lambda (x) (format "\\(%s\\)" (regexp-quote (char-to-string x))))
+ lst))))
+ (match-string 3 str))
+ (setq ivy--subexps (length (match-string 2 str))))
+ str))
+
+(defcustom ivy-fixed-height-minibuffer nil
+ "When non nil, fix the height of the minibuffer during ivy completion.
+This effectively sets the minimum height at this level to `ivy-height' and
+tries to ensure that it does not change depending on the number of candidates."
+ :type 'boolean)
+
+;;** Rest
+(defcustom ivy-truncate-lines t
+ "Minibuffer setting for `truncate-lines'."
+ :type 'boolean)
+
+(defun ivy--minibuffer-setup ()
+ "Setup ivy completion in the minibuffer."
+ (setq-local mwheel-scroll-up-function 'ivy-next-line)
+ (setq-local mwheel-scroll-down-function 'ivy-previous-line)
+ (setq-local completion-show-inline-help nil)
+ (setq-local line-spacing nil)
+ (setq-local minibuffer-default-add-function
+ (lambda ()
+ (list ivy--default)))
+ (setq-local inhibit-field-text-motion nil)
+ (setq truncate-lines ivy-truncate-lines)
+ (setq-local max-mini-window-height ivy-height)
+ (let ((height (cond ((and ivy-fixed-height-minibuffer
+ (not (eq (ivy-state-caller ivy-last)
+ #'ivy-completion-in-region)))
+ (+ ivy-height (if ivy-add-newline-after-prompt 1 0)))
+ (ivy-add-newline-after-prompt 2))))
+ (when height
+ (set-window-text-height nil height)))
+ (add-hook 'post-command-hook #'ivy--queue-exhibit nil t)
+ (let ((hook (ivy-alist-setting ivy-hooks-alist)))
+ (when (functionp hook)
+ (funcall hook))))
+
+(defun ivy--input ()
+ "Return the current minibuffer input."
+ ;; assume one-line minibuffer input
+ (save-excursion
+ (goto-char (minibuffer-prompt-end))
+ (let ((inhibit-field-text-motion t))
+ (buffer-substring-no-properties
+ (point)
+ (line-end-position)))))
+
+(defun ivy--minibuffer-cleanup ()
+ "Delete the displayed completion candidates."
+ (save-excursion
+ (goto-char (minibuffer-prompt-end))
+ (delete-region (line-end-position) (point-max))))
+
+(defun ivy-cleanup-string (str)
+ "Destructively remove unwanted text properties from STR."
+ (ivy--remove-props str 'field))
+
+(defvar ivy-set-prompt-text-properties-function
+ #'ivy-set-prompt-text-properties-default
+ "Function to set the text properties of the default ivy prompt.
+Called with two arguments, PROMPT and PROPS, where PROMPT is the
+string to be propertized and PROPS is a plist of default text
+properties that may be applied to PROMPT. The function should
+return the propertized PROMPT, which may be modified in-place.")
+
+(defun ivy-set-prompt-text-properties-default (prompt props)
+ "Propertize (confirm) and (match required) parts of PROMPT.
+PROPS is a plist of default text properties to apply to these
+parts beyond their respective faces `ivy-confirm-face' and
+`ivy-match-required-face'."
+ (dolist (pair '(("confirm" . ivy-confirm-face)
+ ("match required" . ivy-match-required-face)))
+ (let ((i (string-match-p (car pair) prompt)))
+ (when i
+ (add-text-properties i (+ i (length (car pair)))
+ `(face ,(cdr pair) ,@props)
+ prompt))))
+ prompt)
+
+(defun ivy-prompt ()
+ "Return the current prompt."
+ (let* ((caller (ivy-state-caller ivy-last))
+ (fn (plist-get ivy--prompts-list caller)))
+ (if fn
+ (condition-case err
+ (funcall fn)
+ (wrong-number-of-arguments
+ (lwarn 'ivy :error "%s
+ Prompt function set via `ivy-set-prompt' for caller `%s'
+ should take no arguments."
+ (error-message-string err)
+ caller)
+ ;; Old behavior.
+ (funcall fn (ivy-state-prompt ivy-last))))
+ ivy--prompt)))
+
+(defun ivy--insert-prompt ()
+ "Update the prompt according to `ivy--prompt'."
+ (when (setq ivy--prompt (ivy-prompt))
+ (unless (memq this-command '(ivy-done ivy-alt-done ivy-partial-or-done
+ counsel-find-symbol))
+ (setq ivy--prompt-extra ""))
+ (let (head tail)
+ (if (string-match "\\(.*?\\)\\(:? ?\\)\\'" ivy--prompt)
+ (progn
+ (setq head (match-string 1 ivy--prompt))
+ (setq tail (match-string 2 ivy--prompt)))
+ (setq head ivy--prompt)
+ (setq tail ""))
+ (let ((inhibit-read-only t)
+ (std-props '(front-sticky t rear-nonsticky t field t read-only t))
+ (n-str
+ (concat
+ (if (and (bound-and-true-p minibuffer-depth-indicate-mode)
+ (> (minibuffer-depth) 1))
+ (format "[%d] " (minibuffer-depth))
+ "")
+ (concat
+ (if (string-match "%d.*%d" ivy-count-format)
+ (format head
+ (1+ ivy--index)
+ (or (and (ivy-state-dynamic-collection ivy-last)
+ ivy--full-length)
+ ivy--length))
+ (format head
+ (or (and (ivy-state-dynamic-collection ivy-last)
+ ivy--full-length)
+ ivy--length)))
+ ivy--prompt-extra
+ tail)))
+ (d-str (if ivy--directory
+ (abbreviate-file-name ivy--directory)
+ "")))
+ (save-excursion
+ (goto-char (point-min))
+ (delete-region (point-min) (minibuffer-prompt-end))
+ (let ((len-n (length n-str))
+ (len-d (length d-str))
+ (ww (window-width)))
+ (setq n-str
+ (cond ((> (+ len-n len-d) ww)
+ (concat n-str "\n" d-str "\n"))
+ ((> (+ len-n len-d (length ivy-text)) ww)
+ (concat n-str d-str "\n"))
+ (t
+ (concat n-str d-str)))))
+ (when ivy-pre-prompt-function
+ (setq n-str (concat (funcall ivy-pre-prompt-function) n-str)))
+ (when ivy-add-newline-after-prompt
+ (setq n-str (concat n-str "\n")))
+ (let ((regex (format "\\([^\n]\\{%d\\}\\)[^\n]" (window-width))))
+ (while (string-match regex n-str)
+ (setq n-str (replace-match
+ (concat (match-string 1 n-str) "\n")
+ nil t n-str 1))))
+ (set-text-properties 0 (length n-str)
+ `(face minibuffer-prompt ,@std-props)
+ n-str)
+ (setq n-str (funcall ivy-set-prompt-text-properties-function
+ n-str std-props))
+ (insert n-str))
+ ;; Mark prompt as selected if the user moves there or it is the only
+ ;; option left. Since the user input stays put, we have to manually
+ ;; remove the face as well.
+ (when ivy--use-selectable-prompt
+ (if (= ivy--index -1)
+ (ivy-add-face-text-property
+ (minibuffer-prompt-end) (line-end-position) 'ivy-prompt-match)
+ (remove-list-of-text-properties
+ (minibuffer-prompt-end) (line-end-position) '(face))))
+ ;; get out of the prompt area
+ (constrain-to-field nil (point-max))))))
+
+(defun ivy--sort-maybe (collection)
+ "Sort COLLECTION if needed."
+ (let ((sort (ivy-state-sort ivy-last)))
+ (if (and sort
+ (or (functionp sort)
+ (functionp (setq sort (ivy--sort-function
+ (ivy-state-collection ivy-last))))))
+ (sort (copy-sequence collection) sort)
+ collection)))
+
+(defcustom ivy-magic-slash-non-match-action 'ivy-magic-slash-non-match-cd-selected
+ "Action to take when a slash is added to the end of a non existing directory.
+Possible choices are 'ivy-magic-slash-non-match-cd-selected,
+'ivy-magic-slash-non-match-create, or nil"
+ :type '(choice
+ (const :tag "Use currently selected directory"
+ ivy-magic-slash-non-match-cd-selected)
+ (const :tag "Create and use new directory"
+ ivy-magic-slash-non-match-create)
+ (const :tag "Do nothing"
+ nil)))
+
+(defun ivy--create-and-cd (dir)
+ "When completing file names, create directory DIR and move there."
+ (make-directory dir)
+ (ivy--cd dir))
+
+(defun ivy--magic-file-doubleslash-directory ()
+ "Return an appropriate directory for when two slashes are entered."
+ (let (remote)
+ (cond
+ ;; Windows
+ ((string-match "\\`[[:alpha:]]:/" ivy--directory)
+ (match-string 0 ivy--directory))
+ ;; Remote root if on remote
+ ((setq remote (file-remote-p ivy--directory))
+ (concat remote "/"))
+ ;; Local root
+ (t
+ "/"))))
+
+(defun ivy--magic-file-slash ()
+ "Handle slash when completing file names."
+ (when (or (and (eq this-command #'self-insert-command)
+ (eolp))
+ (eq this-command #'ivy-partial-or-done))
+ (let ((canonical (expand-file-name ivy-text ivy--directory))
+ (magic (not (string= ivy-text "/"))))
+ (cond ((member ivy-text ivy--all-candidates)
+ (ivy--cd canonical))
+ ((string-match-p "//\\'" ivy-text)
+ (ivy--cd
+ (ivy--magic-file-doubleslash-directory)))
+ ((string-match-p "\\`/ssh:" ivy-text)
+ (ivy--cd (file-name-directory ivy-text)))
+ ((string-match "[[:alpha:]]:/\\'" ivy-text)
+ (let ((drive-root (match-string 0 ivy-text)))
+ (when (file-exists-p drive-root)
+ (ivy--cd drive-root))))
+ ((and magic (file-directory-p canonical))
+ (ivy--cd canonical))
+ ((let ((default-directory ivy--directory))
+ (and (or (> ivy--index 0)
+ (= ivy--length 1)
+ magic)
+ (not (ivy--prompt-selected-p))
+ (not (equal (ivy-state-current ivy-last) ""))
+ (file-directory-p (ivy-state-current ivy-last))
+ (or (eq ivy-magic-slash-non-match-action
+ 'ivy-magic-slash-non-match-cd-selected)
+ (eq this-command #'ivy-partial-or-done))))
+ (ivy--cd
+ (expand-file-name (ivy-state-current ivy-last) ivy--directory)))
+ ((and (eq ivy-magic-slash-non-match-action
+ 'ivy-magic-slash-non-match-create)
+ magic)
+ (ivy--create-and-cd canonical))))))
+
+(defun ivy-magic-read-file-env ()
+ "If reading filename, jump to environment variable location."
+ (interactive)
+ (if (and ivy--directory
+ (equal ivy-text ""))
+ (let* ((cands (cl-loop for pair in process-environment
+ for (var val) = (split-string pair "=" t)
+ if (and val (not (equal "" val)))
+ if (file-exists-p
+ (if (file-name-absolute-p val)
+ val
+ (setq val
+ (expand-file-name val ivy--directory))))
+ collect (cons var val)))
+ (enable-recursive-minibuffers t)
+ (x (ivy-read "Env: " cands))
+ (path (cdr (assoc x cands))))
+ (insert (if (file-accessible-directory-p path)
+ (file-name-as-directory path)
+ path))
+ (ivy--cd-maybe))
+ (insert last-input-event)))
+
+(defun ivy-make-magic-action (caller key)
+ "Return a command that does the equivalent of `ivy-read-action' and KEY.
+This happens only when the input is empty.
+The intention is to bind the result to keys that are typically
+bound to `self-insert-command'."
+ (let* ((alist (assoc key
+ (plist-get
+ ivy--actions-list
+ caller)))
+ (doc (format "%s (`%S')"
+ (nth 2 alist)
+ (nth 1 alist))))
+ `(lambda (&optional arg)
+ ,doc
+ (interactive "p")
+ (if (string= "" ivy-text)
+ (execute-kbd-macro
+ (kbd ,(concat "M-o " key)))
+ (self-insert-command arg)))))
+
+(defcustom ivy-magic-tilde t
+ "When non-nil, ~ will move home when selecting files.
+Otherwise, ~/ will move home."
+ :type 'boolean)
+
+(defcustom ivy-dynamic-exhibit-delay-ms 0
+ "Delay in ms before dynamic collections are refreshed"
+ :type 'integer)
+
+(defvar ivy--exhibit-timer nil)
+
+(defun ivy--queue-exhibit ()
+ "Insert Ivy completions display, possibly after a timeout for
+dynamic collections.
+Should be run via minibuffer `post-command-hook'."
+ (if (and (> ivy-dynamic-exhibit-delay-ms 0)
+ (ivy-state-dynamic-collection ivy-last))
+ (progn
+ (when ivy--exhibit-timer (cancel-timer ivy--exhibit-timer))
+ (setq ivy--exhibit-timer
+ (run-with-timer
+ (/ ivy-dynamic-exhibit-delay-ms 1000.0)
+ nil
+ 'ivy--exhibit)))
+ (ivy--exhibit)))
+
+(defun ivy--magic-tilde-directory (dir)
+ "Return an appropriate home for DIR for when ~ or ~/ are entered."
+ (expand-file-name
+ (let (remote)
+ (if (and (setq remote (file-remote-p dir))
+ (let ((local (file-local-name dir)))
+ (not (or (string= "/root/" local)
+ (string-match-p "/home/\\([^/]+\\)/\\'" local)))))
+ (concat remote "~/")
+ "~/"))))
+
+(defun ivy-update-candidates (cands)
+ (ivy--insert-minibuffer
+ (ivy--format
+ (setq ivy--all-candidates cands))))
+
+(defun ivy--exhibit ()
+ "Insert Ivy completions display.
+Should be run via minibuffer `post-command-hook'."
+ (when (memq 'ivy--queue-exhibit post-command-hook)
+ (let ((inhibit-field-text-motion nil))
+ (constrain-to-field nil (point-max)))
+ (setq ivy-text (ivy--input))
+ (if (ivy-state-dynamic-collection ivy-last)
+ ;; while-no-input would cause annoying
+ ;; "Waiting for process to die...done" message interruptions
+ (let ((inhibit-message t)
+ coll in-progress)
+ (unless (equal ivy--old-text ivy-text)
+ (while-no-input
+ (setq coll (funcall (ivy-state-collection ivy-last) ivy-text))
+ (when (eq coll 0)
+ (setq coll nil)
+ (setq ivy--old-re nil)
+ (setq in-progress t))
+ (setq ivy--all-candidates (ivy--sort-maybe coll))
+ (setq ivy--old-text ivy-text)))
+ (when (eq ivy--all-candidates 0)
+ (setq ivy--all-candidates nil)
+ (setq ivy--old-re nil)
+ (setq in-progress t))
+ (when (or ivy--all-candidates
+ (and (not (get-process " *counsel*"))
+ (not in-progress)))
+ (ivy--set-index-dynamic-collection)
+ (ivy--insert-minibuffer
+ (ivy--format ivy--all-candidates))))
+ (cond (ivy--directory
+ (cond ((or (string= "~/" ivy-text)
+ (and (string= "~" ivy-text)
+ ivy-magic-tilde))
+ (ivy--cd (ivy--magic-tilde-directory ivy--directory)))
+ ((string-match "/\\'" ivy-text)
+ (ivy--magic-file-slash))))
+ ((eq (ivy-state-collection ivy-last) #'internal-complete-buffer)
+ (when (or (and (string-match "\\` " ivy-text)
+ (not (string-match "\\` " ivy--old-text)))
+ (and (string-match "\\` " ivy--old-text)
+ (not (string-match "\\` " ivy-text))))
+ (setq ivy--all-candidates
+ (if (= (string-to-char ivy-text) ?\s)
+ (ivy--buffer-list " ")
+ (ivy--buffer-list "" ivy-use-virtual-buffers)))
+ (setq ivy--old-re nil))))
+ (ivy--insert-minibuffer
+ (with-current-buffer (ivy-state-buffer ivy-last)
+ (ivy--format
+ (ivy--filter ivy-text ivy--all-candidates))))
+ (setq ivy--old-text ivy-text))))
+
+(defun ivy-display-function-fallback (str)
+ (let ((buffer-undo-list t))
+ (save-excursion
+ (forward-line 1)
+ (insert str))))
+
+(defun ivy--insert-minibuffer (text)
+ "Insert TEXT into minibuffer with appropriate cleanup."
+ (let ((resize-mini-windows nil)
+ (update-fn (ivy-state-update-fn ivy-last))
+ (old-mark (marker-position (mark-marker)))
+ (win (active-minibuffer-window))
+ deactivate-mark)
+ (when win
+ (with-selected-window win
+ (ivy--minibuffer-cleanup)
+ (when update-fn
+ (funcall update-fn))
+ (ivy--insert-prompt)
+ ;; Do nothing if while-no-input was aborted.
+ (when (stringp text)
+ (if ivy--display-function
+ (funcall ivy--display-function text)
+ (ivy-display-function-fallback text)))
+ (ivy--resize-minibuffer-to-fit)
+ ;; prevent region growing due to text remove/add
+ (when (region-active-p)
+ (set-mark old-mark))))))
+
+(defun ivy--resize-minibuffer-to-fit ()
+ "Resize the minibuffer window size to fit the text in the minibuffer."
+ (unless (frame-root-window-p (minibuffer-window))
+ (with-selected-window (minibuffer-window)
+ (if (fboundp 'window-text-pixel-size)
+ (let ((text-height (cdr (window-text-pixel-size)))
+ (body-height (window-body-height nil t)))
+ (when (> text-height body-height)
+ ;; Note: the size increment needs to be at least
+ ;; frame-char-height, otherwise resizing won't do
+ ;; anything.
+ (let ((delta (max (- text-height body-height)
+ (frame-char-height))))
+ (window-resize nil delta nil t t))))
+ (let ((text-height (count-screen-lines))
+ (body-height (window-body-height)))
+ (when (> text-height body-height)
+ (window-resize nil (- text-height body-height) nil t)))))))
+
+(defun ivy--add-face (str face)
+ "Propertize STR with FACE."
+ (let ((len (length str)))
+ (condition-case nil
+ (progn
+ (colir-blend-face-background 0 len face str)
+ (let ((foreground (face-foreground face)))
+ (when foreground
+ (ivy-add-face-text-property
+ 0 len (list :foreground foreground) str))))
+ (error
+ (ignore-errors
+ (font-lock-append-text-property 0 len 'face face str)))))
+ str)
+
+(declare-function flx-make-string-cache "ext:flx")
+(declare-function flx-score "ext:flx")
+
+(defvar ivy--flx-cache nil)
+
+(eval-after-load 'flx
+ '(setq ivy--flx-cache (flx-make-string-cache)))
+
+(defun ivy-toggle-case-fold ()
+ "Toggle `case-fold-search' for Ivy operations.
+
+Instead of modifying `case-fold-search' directly, this command
+toggles `ivy-case-fold-search', which can take on more values
+than the former, between nil and either `auto' or t. See
+`ivy-case-fold-search-default' for the meaning of these values.
+
+In any Ivy completion session, the case folding starts with
+`ivy-case-fold-search-default'."
+ (interactive)
+ (setq ivy-case-fold-search
+ (and (not ivy-case-fold-search)
+ (or ivy-case-fold-search-default 'auto)))
+ ;; Reset cache so that the candidate list updates.
+ (setq ivy--old-re nil))
+
+(defun ivy--re-filter (re candidates &optional mkpred)
+ "Return all RE matching CANDIDATES.
+RE is a list of cons cells, with a regexp car and a boolean cdr.
+When the cdr is t, the car must match.
+Otherwise, the car must not match."
+ (if (equal re "")
+ candidates
+ (ignore-errors
+ (dolist (re (if (stringp re) (list (cons re t)) re))
+ (let* ((re-str (car re))
+ (pred
+ (if mkpred
+ (funcall mkpred re-str)
+ (lambda (x) (string-match-p re-str x)))))
+ (setq candidates
+ (cl-remove nil candidates
+ (if (cdr re) :if-not :if)
+ pred))))
+ candidates)))
+
+(defun ivy--filter (name candidates)
+ "Return all items that match NAME in CANDIDATES.
+CANDIDATES are assumed to be static."
+ (let ((re (funcall ivy--regex-function name)))
+ (if (and
+ ivy--old-re
+ ivy--old-cands
+ (equal re ivy--old-re))
+ ;; quick caching for "C-n", "C-p" etc.
+ ivy--old-cands
+ (let* ((re-str (ivy-re-to-str re))
+ (matcher (ivy-state-matcher ivy-last))
+ (case-fold-search (ivy--case-fold-p name))
+ (cands (cond
+ ((and ivy--old-re
+ (stringp re)
+ (stringp ivy--old-re)
+ (not (string-match-p "\\\\" ivy--old-re))
+ (not (equal ivy--old-re ""))
+ (memq (cl-search
+ (if (string-match-p "\\\\)\\'" ivy--old-re)
+ (substring ivy--old-re 0 -2)
+ ivy--old-re)
+ re)
+ '(0 2))
+ ivy--old-cands
+ (ivy--re-filter re ivy--old-cands)))
+ (matcher
+ (funcall matcher re candidates))
+ (t
+ (ivy--re-filter re candidates)))))
+ (if (memq (cdr (assq (ivy-state-caller ivy-last)
+ ivy-index-functions-alist))
+ '(ivy-recompute-index-swiper
+ ivy-recompute-index-swiper-async
+ ivy-recompute-index-swiper-async-backward
+ ivy-recompute-index-swiper-backward))
+ (progn
+ (ivy--recompute-index name re-str cands)
+ (setq ivy--old-cands (ivy--sort name cands)))
+ (setq ivy--old-cands (ivy--sort name cands))
+ (ivy--recompute-index name re-str ivy--old-cands))
+ (setq ivy--old-re re)
+ ivy--old-cands))))
+
+(defun ivy--set-candidates (x)
+ "Update `ivy--all-candidates' with X."
+ (let (res)
+ (dolist (source ivy--extra-candidates)
+ (if (equal source '(original-source))
+ (if (null res)
+ (setq res x)
+ (setq res (append x res)))
+ (setq ivy--old-re nil)
+ (setq res (append
+ (ivy--filter ivy-text (cadr source))
+ res))))
+ (setq ivy--all-candidates res)))
+
+(defun ivy--shorter-matches-first (_name cands)
+ "Sort CANDS according to their length."
+ (if (< (length cands) ivy-sort-max-size)
+ (cl-sort
+ (copy-sequence cands)
+ (lambda (s1 s2)
+ (< (length s1) (length s2))))
+ cands))
+
+(defcustom ivy-sort-matches-functions-alist
+ '((t . nil)
+ (ivy-completion-in-region . ivy--shorter-matches-first)
+ (ivy-switch-buffer . ivy-sort-function-buffer))
+ "An alist of functions for sorting matching candidates.
+
+Unlike `ivy-sort-functions-alist', which is used to sort the
+whole collection only once, this alist of functions are used to
+sort only matching candidates after each change in input.
+
+The alist KEY is either a collection function or t to match
+previously unmatched collection functions.
+
+The alist VAL is a sorting function with the signature of
+`ivy--prefix-sort'."
+ :type '(alist
+ :key-type (choice
+ (const :tag "Fall-through" t)
+ (symbol :tag "Collection"))
+ :value-type
+ (choice
+ (const :tag "Don't sort" nil)
+ (const :tag "Put prefix matches ahead" ivy--prefix-sort)
+ (function :tag "Custom sort function"))))
+
+(defun ivy--sort-files-by-date (_name candidates)
+ "Re-sort CANDIDATES according to file modification date."
+ (let ((default-directory ivy--directory))
+ (sort (copy-sequence candidates) #'file-newer-than-file-p)))
+
+(defvar ivy--flx-featurep (require 'flx nil 'noerror))
+
+(defun ivy--sort (name candidates)
+ "Re-sort candidates by NAME.
+All CANDIDATES are assumed to match NAME."
+ (let (fun)
+ (cond ((setq fun (ivy-alist-setting ivy-sort-matches-functions-alist))
+ (funcall fun name candidates))
+ ((and ivy--flx-featurep
+ (eq ivy--regex-function 'ivy--regex-fuzzy))
+ (ivy--flx-sort name candidates))
+ (t
+ candidates))))
+
+(defun ivy--prefix-sort (name candidates)
+ "Re-sort candidates by NAME.
+All CANDIDATES are assumed to match NAME.
+Prefix matches to NAME are put ahead of the list."
+ (if (or (string= name "")
+ (= (aref name 0) ?^))
+ candidates
+ (let ((re-prefix (concat "\\`" (funcall ivy--regex-function name)))
+ res-prefix
+ res-noprefix)
+ (dolist (s candidates)
+ (if (string-match-p re-prefix s)
+ (push s res-prefix)
+ (push s res-noprefix)))
+ (nconc
+ (nreverse res-prefix)
+ (nreverse res-noprefix)))))
+
+(defvar ivy--virtual-buffers nil
+ "Store the virtual buffers alist.")
+
+(defun ivy-re-to-str (re)
+ "Transform RE to a string.
+
+Functions like `ivy--regex-ignore-order' return a cons list.
+This function extracts a string from the cons list."
+ (if (consp re) (caar re) re))
+
+(defun ivy-sort-function-buffer (name candidates)
+ "Re-sort candidates by NAME.
+CANDIDATES is a list of buffer names each containing NAME.
+Sort open buffers before virtual buffers, and prefix matches
+before substring matches."
+ (if (or (string= name "")
+ (= (aref name 0) ?^))
+ candidates
+ (let* ((base-re (ivy-re-to-str (funcall ivy--regex-function name)))
+ (re-star-prefix (concat "\\`\\*" base-re))
+ (re-prefix (concat "\\`" base-re))
+ res-prefix
+ res-noprefix
+ res-virtual-prefix
+ res-virtual-noprefix)
+ (dolist (s candidates)
+ (cond
+ ((and (assoc s ivy--virtual-buffers)
+ (or (string-match-p re-star-prefix s)
+ (string-match-p re-prefix s)))
+ (push s res-virtual-prefix))
+ ((assoc s ivy--virtual-buffers)
+ (push s res-virtual-noprefix))
+ ((or (string-match-p re-star-prefix s)
+ (string-match-p re-prefix s))
+ (push s res-prefix))
+ (t
+ (push s res-noprefix))))
+ (nconc
+ (nreverse res-prefix)
+ (nreverse res-noprefix)
+ (nreverse res-virtual-prefix)
+ (nreverse res-virtual-noprefix)))))
+
+(defvar ivy-flx-limit 200
+ "Used to conditionally turn off flx sorting.
+
+When the amount of matching candidates exceeds this limit, then
+no sorting is done.")
+
+(defvar ivy--recompute-index-inhibit nil
+ "When non-nil, `ivy--recompute-index' is a no-op.")
+
+(defun ivy--recompute-index (name re-str cands)
+ "Recompute index of selected candidate matching NAME.
+RE-STR is the regexp, CANDS are the current candidates."
+ (let ((caller (ivy-state-caller ivy-last))
+ (func (or (ivy-alist-setting ivy-index-functions-alist)
+ #'ivy-recompute-index-zero))
+ (case-fold-search (ivy--case-fold-p name))
+ (preselect (ivy-state-preselect ivy-last))
+ (current (ivy-state-current ivy-last))
+ (empty (string= name "")))
+ (unless (or (memq this-command '(ivy-resume ivy-partial-or-done))
+ ivy--recompute-index-inhibit)
+ (ivy-set-index
+ (if (or (string= name "")
+ (and (> (length cands) 10000) (eq func #'ivy-recompute-index-zero)))
+ 0
+ (or
+ (cl-position (ivy--remove-prefix "^" name)
+ cands
+ :test #'ivy--case-fold-string=)
+ (and ivy--directory
+ (cl-position (concat re-str "/")
+ cands
+ :test #'ivy--case-fold-string=))
+ (and (eq caller 'ivy-switch-buffer)
+ (not empty)
+ 0)
+ (and (not empty)
+ (not (eq caller 'swiper))
+ (not (and ivy--flx-featurep
+ (eq ivy--regex-function 'ivy--regex-fuzzy)
+ ;; Limit to configured number of candidates
+ (null (nthcdr ivy-flx-limit cands))))
+ ;; If there was a preselected candidate, don't try to
+ ;; keep it selected even if the regexp still matches it.
+ ;; See issue #1563. See also `ivy--preselect-index',
+ ;; which this logic roughly mirrors.
+ (not (or
+ (and (integerp preselect)
+ (= ivy--index preselect))
+ (equal current preselect)
+ (and (ivy--regex-p preselect)
+ (stringp current)
+ (string-match-p preselect current))))
+ ivy--old-cands
+ (cl-position current cands :test #'equal))
+ (funcall func re-str cands)))))
+ (when (or empty (string= name "^"))
+ (ivy-set-index
+ (or (ivy--preselect-index preselect cands)
+ ivy--index)))))
+
+(defun ivy-recompute-index-swiper (_re-str cands)
+ "Recompute index of selected candidate when using `swiper'.
+CANDS are the current candidates."
+ (condition-case nil
+ (let ((tail (nthcdr ivy--index ivy--old-cands))
+ idx)
+ (if (and tail ivy--old-cands (not (equal "^" ivy--old-re)))
+ (progn
+ (while (and tail (null idx))
+ ;; Compare with eq to handle equal duplicates in cands
+ (setq idx (cl-position (pop tail) cands)))
+ (or
+ idx
+ (1- (length cands))))
+ (if ivy--old-cands
+ ivy--index
+ ;; already in ivy-state-buffer
+ (let ((n (line-number-at-pos))
+ (res 0)
+ (i 0))
+ (dolist (c cands)
+ (when (eq n (get-text-property 0 'swiper-line-number c))
+ (setq res i))
+ (cl-incf i))
+ res))))
+ (error 0)))
+
+(defun ivy-recompute-index-swiper-backward (re-str cands)
+ "Recompute index of selected candidate when using `swiper-backward'.
+CANDS are the current candidates."
+ (let ((idx (ivy-recompute-index-swiper re-str cands)))
+ (if (or (= idx -1)
+ (<= (get-text-property 0 'swiper-line-number (nth idx cands))
+ (line-number-at-pos)))
+ idx
+ (- idx 1))))
+
+(defun ivy-recompute-index-swiper-async (_re-str cands)
+ "Recompute index of selected candidate when using `swiper' asynchronously.
+CANDS are the current candidates."
+ (if (null ivy--old-cands)
+ (let ((ln (with-ivy-window
+ (line-number-at-pos))))
+ (or
+ ;; closest to current line going forwards
+ (cl-position-if (lambda (x)
+ (>= (string-to-number x) ln))
+ cands)
+ ;; closest to current line going backwards
+ (1- (length cands))))
+ (let ((tail (nthcdr ivy--index ivy--old-cands))
+ idx)
+ (if (and tail ivy--old-cands (not (equal "^" ivy--old-re)))
+ (progn
+ (while (and tail (null idx))
+ ;; Compare with `equal', since the collection is re-created
+ ;; each time with `split-string'
+ (setq idx (cl-position (pop tail) cands :test #'equal)))
+ (or idx 0))
+ ivy--index))))
+
+(defun ivy-recompute-index-swiper-async-backward (re-str cands)
+ "Recompute index of selected candidate when using `swiper-backward'
+asynchronously. CANDS are the current candidates."
+ (if (= (length cands) 0)
+ 0
+ (let ((idx (ivy-recompute-index-swiper-async re-str cands)))
+ (if
+ (<= (string-to-number (nth idx cands))
+ (with-ivy-window (line-number-at-pos)))
+ idx
+ (- idx 1)))))
+
+(defun ivy-recompute-index-zero (_re-str _cands)
+ "Recompute index of selected candidate.
+This function serves as a fallback when nothing else is available."
+ 0)
+
+(defcustom ivy-minibuffer-faces
+ '(ivy-minibuffer-match-face-1
+ ivy-minibuffer-match-face-2
+ ivy-minibuffer-match-face-3
+ ivy-minibuffer-match-face-4)
+ "List of `ivy' faces for minibuffer group matches."
+ :type '(repeat :tag "Faces"
+ (choice
+ (const ivy-minibuffer-match-face-1)
+ (const ivy-minibuffer-match-face-2)
+ (const ivy-minibuffer-match-face-3)
+ (const ivy-minibuffer-match-face-4)
+ (face :tag "Other face"))))
+
+(defun ivy--minibuffer-face (n)
+ "Return Nth face from `ivy-minibuffer-faces'.
+N wraps around, but skips the first element of the list."
+ (let ((tail (cdr ivy-minibuffer-faces)))
+ (nth (mod (+ n 2) (length tail)) tail)))
+
+(defun ivy--flx-propertize (x)
+ "X is (cons (flx-score STR ...) STR)."
+ (let ((str (copy-sequence (cdr x)))
+ (i 0)
+ (last-j -2))
+ (dolist (j (cdar x))
+ (unless (eq j (1+ last-j))
+ (cl-incf i))
+ (setq last-j j)
+ (ivy-add-face-text-property j (1+ j) (ivy--minibuffer-face i) str))
+ str))
+
+(defun ivy--flx-sort (name cands)
+ "Sort according to closeness to string NAME the string list CANDS."
+ (condition-case nil
+ (let* ((bolp (= (string-to-char name) ?^))
+ ;; An optimized regex for fuzzy matching
+ ;; "abc" → "^[^a]*a[^b]*b[^c]*c"
+ (fuzzy-regex (concat "\\`"
+ (and bolp (regexp-quote (substring name 1 2)))
+ (mapconcat
+ (lambda (x)
+ (setq x (char-to-string x))
+ (concat "[^" x "]*" (regexp-quote x)))
+ (if bolp (substring name 2) name)
+ "")))
+ ;; Strip off the leading "^" for flx matching
+ (flx-name (if bolp (substring name 1) name))
+ cands-left
+ cands-to-sort)
+
+ ;; Filter out non-matching candidates
+ (dolist (cand cands)
+ (when (string-match-p fuzzy-regex cand)
+ (push cand cands-left)))
+
+ ;; pre-sort the candidates by length before partitioning
+ (setq cands-left (cl-sort cands-left #'< :key #'length))
+
+ ;; partition the candidates into sorted and unsorted groups
+ (dotimes (_ (min (length cands-left) ivy-flx-limit))
+ (push (pop cands-left) cands-to-sort))
+
+ (nconc
+ ;; Compute all of the flx scores in one pass and sort
+ (mapcar #'car
+ (sort (mapcar
+ (lambda (cand)
+ (cons cand
+ (car (flx-score cand flx-name ivy--flx-cache))))
+ cands-to-sort)
+ (lambda (c1 c2)
+ ;; Break ties by length
+ (if (/= (cdr c1) (cdr c2))
+ (> (cdr c1)
+ (cdr c2))
+ (< (length (car c1))
+ (length (car c2)))))))
+
+ ;; Add the unsorted candidates
+ cands-left))
+ (error cands)))
+
+(defun ivy--truncate-string (str width)
+ "Truncate STR to WIDTH."
+ (truncate-string-to-width str width nil nil t))
+
+(defun ivy--format-function-generic (selected-fn other-fn cands separator)
+ "Transform candidates into a string for minibuffer.
+SELECTED-FN is called for the selected candidate, OTHER-FN for the others.
+Both functions take one string argument each. CANDS is a list of candidates
+and SEPARATOR is used to join them."
+ (let ((i -1))
+ (mapconcat
+ (lambda (str)
+ (let ((curr (eq (cl-incf i) ivy--window-index)))
+ (if curr
+ (funcall selected-fn str)
+ (funcall other-fn str))))
+ cands
+ separator)))
+
+(defun ivy-format-function-default (cands)
+ "Transform CANDS into a string for minibuffer."
+ (ivy--format-function-generic
+ (lambda (str)
+ (ivy--add-face str 'ivy-current-match))
+ #'identity
+ cands
+ "\n"))
+
+(defun ivy-format-function-arrow (cands)
+ "Transform CANDS into a string for minibuffer."
+ (ivy--format-function-generic
+ (lambda (str)
+ (concat "> " (ivy--add-face str 'ivy-current-match)))
+ (lambda (str)
+ (concat " " str))
+ cands
+ "\n"))
+
+(defun ivy-format-function-line (cands)
+ "Transform CANDS into a string for minibuffer."
+ (ivy--format-function-generic
+ (lambda (str)
+ (ivy--add-face (concat str "\n") 'ivy-current-match))
+ (lambda (str)
+ (concat str "\n"))
+ cands
+ ""))
+
+(defalias 'ivy-add-face-text-property
+ (if (fboundp 'add-face-text-property)
+ (lambda (start end face &optional object append)
+ (add-face-text-property start end face append object))
+ (lambda (start end face &optional object append)
+ (funcall (if append
+ #'font-lock-append-text-property
+ #'font-lock-prepend-text-property)
+ start end 'face face object)))
+ "Compatibility shim for `add-face-text-property'.
+Fall back on `font-lock-prepend-text-property' in Emacs versions
+prior to 24.4 (`font-lock-append-text-property' when APPEND is
+non-nil).
+Note: The usual last two arguments are flipped for convenience.")
+
+(defun ivy--highlight-ignore-order (str)
+ "Highlight STR, using the ignore-order method."
+ (when (consp ivy--old-re)
+ (let ((i 1))
+ (dolist (re ivy--old-re)
+ (when (string-match (car re) str)
+ (ivy-add-face-text-property
+ (match-beginning 0) (match-end 0)
+ (ivy--minibuffer-face i)
+ str))
+ (cl-incf i))))
+ str)
+
+(defun ivy--highlight-fuzzy (str)
+ "Highlight STR, using the fuzzy method."
+ (if (and ivy--flx-featurep
+ (eq (ivy-alist-setting ivy-re-builders-alist) 'ivy--regex-fuzzy))
+ (let ((flx-name (ivy--remove-prefix "^" ivy-text)))
+ (ivy--flx-propertize
+ (cons (flx-score str flx-name ivy--flx-cache) str)))
+ (ivy--highlight-default str)))
+
+(defun ivy--highlight-default (str)
+ "Highlight STR, using the default method."
+ (unless ivy--old-re
+ (setq ivy--old-re (funcall ivy--regex-function ivy-text)))
+ (let ((regexps
+ (if (listp ivy--old-re)
+ (mapcar #'car (cl-remove-if-not #'cdr ivy--old-re))
+ (list ivy--old-re)))
+ start)
+ (dolist (re regexps)
+ (ignore-errors
+ (while (and (string-match re str start)
+ (> (- (match-end 0) (match-beginning 0)) 0))
+ (setq start (match-end 0))
+ (let ((i 0)
+ (n 0)
+ prev)
+ (while (<= i ivy--subexps)
+ (let ((beg (match-beginning i))
+ (end (match-end i)))
+ (when (and beg end)
+ (unless (and prev (= prev beg))
+ (cl-incf n))
+ (let ((face
+ (cond ((zerop ivy--subexps)
+ (cadr ivy-minibuffer-faces))
+ ((zerop i)
+ (car ivy-minibuffer-faces))
+ (t
+ (ivy--minibuffer-face n)))))
+ (ivy-add-face-text-property beg end face str))
+ (unless (zerop i)
+ (setq prev end))))
+ (cl-incf i)))))))
+ str)
+
+(defun ivy--format-minibuffer-line (str)
+ "Format line STR for use in minibuffer."
+ (let* ((str (ivy-cleanup-string (copy-sequence str)))
+ (str (if (eq ivy-display-style 'fancy)
+ (if (memq (ivy-state-caller ivy-last)
+ ivy-highlight-grep-commands)
+ (let* ((start (if (string-match "\\`[^:]+:\\(?:[^:]+:\\)?" str)
+ (match-end 0) 0))
+ (file (substring str 0 start))
+ (match (substring str start)))
+ (concat file (funcall ivy--highlight-function match)))
+ (funcall ivy--highlight-function str))
+ str))
+ (olen (length str))
+ (annot (plist-get completion-extra-properties :annotation-function)))
+ (add-text-properties
+ 0 olen
+ '(mouse-face
+ ivy-minibuffer-match-highlight
+ help-echo
+ (format
+ (if tooltip-mode
+ "mouse-1: %s\nmouse-3: %s"
+ "mouse-1: %s mouse-3: %s")
+ ivy-mouse-1-tooltip ivy-mouse-3-tooltip))
+ str)
+ (when annot
+ (setq str (concat str (funcall annot str)))
+ (ivy-add-face-text-property
+ olen (length str) 'ivy-completions-annotations str))
+ str))
+
+(defun ivy-read-file-transformer (str)
+ "Transform candidate STR when reading files."
+ (if (ivy--dirname-p str)
+ (propertize str 'face 'ivy-subdir)
+ str))
+
+(defun ivy--minibuffer-index-bounds (idx len wnd-len)
+ (let* ((half-height (/ wnd-len 2))
+ (start (max 0
+ (min (- idx half-height)
+ (- len (1- wnd-len)))))
+ (end (min (+ start (1- wnd-len)) len)))
+ (list start end (- idx start))))
+
+(defun ivy--format (cands)
+ "Return a string for CANDS suitable for display in the minibuffer.
+CANDS is a list of candidates that :display-transformer can turn into strings."
+ (setq ivy--length (length cands))
+ (when (>= ivy--index ivy--length)
+ (ivy-set-index (max (1- ivy--length) 0)))
+ (if (null cands)
+ (setf (ivy-state-current ivy-last) "")
+ (let ((cur (nth ivy--index cands)))
+ (setf (ivy-state-current ivy-last) (if (stringp cur)
+ (copy-sequence cur)
+ cur)))
+ (let* ((bnd (ivy--minibuffer-index-bounds
+ ivy--index ivy--length ivy-height))
+ (wnd-cands (cl-subseq cands (car bnd) (cadr bnd)))
+ (case-fold-search (ivy--case-fold-p ivy-text))
+ transformer-fn)
+ (setq ivy--window-index (nth 2 bnd))
+ (when (setq transformer-fn (ivy-state-display-transformer-fn ivy-last))
+ (with-ivy-window
+ (with-current-buffer (ivy-state-buffer ivy-last)
+ (setq wnd-cands (mapcar transformer-fn wnd-cands)))))
+ (ivy--wnd-cands-to-str wnd-cands))))
+
+(defun ivy--wnd-cands-to-str (wnd-cands)
+ (let ((str (concat "\n"
+ (funcall (ivy-alist-setting ivy-format-functions-alist)
+ (condition-case nil
+ (mapcar
+ #'ivy--format-minibuffer-line
+ wnd-cands)
+ (error wnd-cands))))))
+ (put-text-property 0 (length str) 'read-only nil str)
+ str))
+
+(defvar recentf-list)
+(defvar bookmark-alist)
+
+(defcustom ivy-virtual-abbreviate 'name
+ "The mode of abbreviation for virtual buffer names."
+ :type '(choice
+ (const :tag "Only name" name)
+ (const :tag "Abbreviated path" abbreviate)
+ (const :tag "Full path" full)
+ ;; eventually, uniquify
+ ))
+(declare-function bookmark-maybe-load-default-file "bookmark")
+(declare-function bookmark-get-filename "bookmark")
+
+(defun ivy--virtual-buffers ()
+ "Adapted from `ido-add-virtual-buffers-to-list'."
+ (require 'bookmark)
+ (unless recentf-mode
+ (recentf-mode 1))
+ (bookmark-maybe-load-default-file)
+ (let* ((vb-bkm (delete " - no file -"
+ (delq nil (mapcar #'bookmark-get-filename
+ bookmark-alist))))
+ (vb-list (cond ((eq ivy-use-virtual-buffers 'recentf)
+ recentf-list)
+ ((eq ivy-use-virtual-buffers 'bookmarks)
+ vb-bkm)
+ (ivy-use-virtual-buffers
+ (append recentf-list vb-bkm))
+ (t nil)))
+ virtual-buffers)
+ (dolist (head vb-list)
+ (let* ((file-name (if (stringp head)
+ head
+ (cdr head)))
+ (name (cond ((eq ivy-virtual-abbreviate 'name)
+ (file-name-nondirectory file-name))
+ ((eq ivy-virtual-abbreviate 'abbreviate)
+ (abbreviate-file-name file-name))
+ (t
+ (expand-file-name file-name)))))
+ (when (equal name "")
+ (setq name
+ (if (consp head)
+ (car head)
+ (file-name-nondirectory (directory-file-name file-name)))))
+ (unless (or (equal name "")
+ (get-file-buffer file-name)
+ (assoc name virtual-buffers))
+ (push (cons (copy-sequence name) file-name) virtual-buffers))))
+ (when virtual-buffers
+ (dolist (comp virtual-buffers)
+ (put-text-property 0 (length (car comp))
+ 'face 'ivy-virtual
+ (car comp)))
+ (setq ivy--virtual-buffers (nreverse virtual-buffers))
+ (mapcar #'car ivy--virtual-buffers))))
+
+(defcustom ivy-ignore-buffers '("\\` ")
+ "List of regexps or functions matching buffer names to ignore."
+ :type '(repeat (choice regexp function)))
+
+(defvar ivy-switch-buffer-faces-alist '((dired-mode . ivy-subdir)
+ (org-mode . ivy-org))
+ "Store face customizations for `ivy-switch-buffer'.
+Each KEY is `major-mode', each VALUE is a face name.")
+
+(defun ivy--buffer-list (str &optional virtual predicate)
+ "Return the buffers that match STR.
+If VIRTUAL is non-nil, add virtual buffers.
+If optional argument PREDICATE is non-nil, use it to test each
+possible match. See `all-completions' for further information."
+ (delete-dups
+ (nconc
+ (mapcar
+ (lambda (x)
+ (let* ((buf (get-buffer x))
+ (dir (buffer-local-value 'default-directory buf))
+ (face (if (and dir
+ (ignore-errors
+ (file-remote-p (abbreviate-file-name dir))))
+ 'ivy-remote
+ (cdr (assq (buffer-local-value 'major-mode buf)
+ ivy-switch-buffer-faces-alist)))))
+ (if face
+ (propertize x 'face face)
+ x)))
+ (all-completions str #'internal-complete-buffer predicate))
+ (and virtual
+ (ivy--virtual-buffers)))))
+
+(defvar ivy-views (and nil
+ `(("ivy + *scratch* {}"
+ (vert
+ (file ,(expand-file-name "ivy.el"))
+ (buffer "*scratch*")))
+ ("swiper + *scratch* {}"
+ (horz
+ (file ,(expand-file-name "swiper.el"))
+ (buffer "*scratch*")))))
+ "Store window configurations selectable by `ivy-switch-buffer'.
+
+The default value is given as an example.
+
+Each element is a list of (NAME TREE). NAME is a string, it's
+recommended to end it with a distinctive snippet e.g. \"{}\" so
+that it's easy to distinguish the window configurations.
+
+TREE is a nested list with the following valid cars:
+- vert: split the window vertically
+- horz: split the window horizontally
+- file: open the specified file
+- buffer: open the specified buffer
+
+TREE can be nested multiple times to have multiple window splits.")
+
+(defun ivy-default-view-name ()
+ "Return default name for new view."
+ (let* ((default-view-name
+ (concat "{} "
+ (mapconcat #'identity
+ (sort
+ (mapcar (lambda (w)
+ (let* ((b (window-buffer w))
+ (f (buffer-file-name b)))
+ (if f
+ (file-name-nondirectory f)
+ (buffer-name b))))
+ (window-list))
+ #'string-lessp)
+ " ")))
+ (view-name-re (concat "\\`"
+ (regexp-quote default-view-name)
+ " \\([0-9]+\\)"))
+ old-view)
+ (cond ((setq old-view
+ (cl-find-if
+ (lambda (x)
+ (string-match view-name-re (car x)))
+ ivy-views))
+ (format "%s %d"
+ default-view-name
+ (1+ (string-to-number
+ (match-string 1 (car old-view))))))
+ ((assoc default-view-name ivy-views)
+ (concat default-view-name " 1"))
+ (t
+ default-view-name))))
+
+(defun ivy-push-view (&optional arg)
+ "Push the current window tree on `ivy-views'.
+
+When ARG is non-nil, replace a selected item on `ivy-views'.
+
+Currently, the split configuration (i.e. horizontal or vertical)
+and point positions are saved, but the split positions aren't.
+Use `ivy-pop-view' to delete any item from `ivy-views'."
+ (interactive "P")
+ (let* ((view (cl-labels
+ ((ft (tr)
+ (if (consp tr)
+ (if (eq (car tr) t)
+ (cons 'vert
+ (mapcar #'ft (cddr tr)))
+ (cons 'horz
+ (mapcar #'ft (cddr tr))))
+ (with-current-buffer (window-buffer tr)
+ (cond (buffer-file-name
+ (list 'file buffer-file-name (point)))
+ ((eq major-mode 'dired-mode)
+ (list 'file default-directory (point)))
+ (t
+ (list 'buffer (buffer-name) (point))))))))
+ (ft (car (window-tree)))))
+ (view-name
+ (if arg
+ (ivy-read "Update view: " ivy-views)
+ (ivy-read "Name view: " nil
+ :initial-input (ivy-default-view-name)))))
+ (when view-name
+ (let ((x (assoc view-name ivy-views)))
+ (if x
+ (setcdr x (list view))
+ (push (list view-name view) ivy-views))))))
+
+(defun ivy-pop-view-action (view)
+ "Delete VIEW from `ivy-views'."
+ (setq ivy-views (delete view ivy-views))
+ (setq ivy--all-candidates
+ (delete (car view) ivy--all-candidates))
+ (setq ivy--old-cands nil))
+
+(defun ivy-pop-view ()
+ "Delete a view to delete from `ivy-views'."
+ (interactive)
+ (ivy-read "Pop view: " ivy-views
+ :preselect (caar ivy-views)
+ :action #'ivy-pop-view-action
+ :caller 'ivy-pop-view))
+
+(defun ivy-source-views ()
+ "Return the name of the views saved in `ivy-views'."
+ (mapcar #'car ivy-views))
+
+(ivy-set-sources
+ 'ivy-switch-buffer
+ '((original-source)
+ (ivy-source-views)))
+
+(defun ivy-set-view-recur (view)
+ "Set VIEW recursively."
+ (cond ((eq (car view) 'vert)
+ (let* ((wnd1 (selected-window))
+ (wnd2 (split-window-vertically))
+ (views (cdr view))
+ (v (pop views))
+ (temp-wnd))
+ (with-selected-window wnd1
+ (ivy-set-view-recur v))
+ (while (setq v (pop views))
+ (with-selected-window wnd2
+ (when views
+ (setq temp-wnd (split-window-vertically)))
+ (ivy-set-view-recur v)
+ (when views
+ (setq wnd2 temp-wnd))))))
+ ((eq (car view) 'horz)
+ (let* ((wnd1 (selected-window))
+ (wnd2 (split-window-horizontally))
+ (views (cdr view))
+ (v (pop views))
+ (temp-wnd))
+ (with-selected-window wnd1
+ (ivy-set-view-recur v))
+ (while (setq v (pop views))
+ (with-selected-window wnd2
+ (when views
+ (setq temp-wnd (split-window-horizontally)))
+ (ivy-set-view-recur v)
+ (when views
+ (setq wnd2 temp-wnd))))))
+ ((eq (car view) 'file)
+ (let* ((name (nth 1 view))
+ (virtual (assoc name ivy--virtual-buffers))
+ buffer)
+ (cond ((setq buffer (get-buffer name))
+ (switch-to-buffer buffer nil 'force-same-window))
+ (virtual
+ (find-file (cdr virtual)))
+ ((file-exists-p name)
+ (find-file name))))
+ (when (and (> (length view) 2)
+ (numberp (nth 2 view)))
+ (goto-char (nth 2 view))))
+ ((eq (car view) 'buffer)
+ (switch-to-buffer (nth 1 view))
+ (when (and (> (length view) 2)
+ (numberp (nth 2 view)))
+ (goto-char (nth 2 view))))
+ ((eq (car view) 'sexp)
+ (eval (nth 1 view)))))
+
+(defun ivy--switch-buffer-action (buffer)
+ "Switch to BUFFER.
+BUFFER may be a string or nil."
+ (if (zerop (length buffer))
+ (switch-to-buffer
+ ivy-text nil 'force-same-window)
+ (let ((virtual (assoc buffer ivy--virtual-buffers))
+ (view (assoc buffer ivy-views)))
+ (cond ((and virtual
+ (not (get-buffer buffer)))
+ (find-file (cdr virtual)))
+ (view
+ (delete-other-windows)
+ (let (
+ ;; silence "Directory has changed on disk"
+ (inhibit-message t))
+ (ivy-set-view-recur (cadr view))))
+ (t
+ (switch-to-buffer
+ buffer nil 'force-same-window))))))
+
+(defun ivy--switch-buffer-other-window-action (buffer)
+ "Switch to BUFFER in other window.
+BUFFER may be a string or nil."
+ (if (zerop (length buffer))
+ (switch-to-buffer-other-window ivy-text)
+ (let ((virtual (assoc buffer ivy--virtual-buffers)))
+ (if (and virtual
+ (not (get-buffer buffer)))
+ (find-file-other-window (cdr virtual))
+ (switch-to-buffer-other-window buffer)))))
+
+(defun ivy--rename-buffer-action (buffer)
+ "Rename BUFFER."
+ (let ((new-name (read-string "Rename buffer (to new name): ")))
+ (with-current-buffer buffer
+ (rename-buffer new-name))))
+
+(defun ivy--find-file-action (buffer)
+ "Find file from BUFFER's directory."
+ (let* ((virtual (assoc buffer ivy--virtual-buffers))
+ (default-directory (if virtual
+ (file-name-directory (cdr virtual))
+ (buffer-local-value 'default-directory
+ (or (get-buffer buffer)
+ (current-buffer))))))
+ (call-interactively (if (functionp 'counsel-find-file)
+ #'counsel-find-file
+ #'find-file))))
+
+(defun ivy--kill-buffer-or-virtual (buffer)
+ (if (get-buffer buffer)
+ (kill-buffer buffer)
+ (setq recentf-list (delete
+ (cdr (assoc buffer ivy--virtual-buffers))
+ recentf-list))))
+
+(defun ivy--kill-current-candidate ()
+ (setf (ivy-state-preselect ivy-last) ivy--index)
+ (setq ivy--old-re nil)
+ (setq ivy--all-candidates (delete (ivy-state-current ivy-last) ivy--all-candidates))
+ (let ((ivy--recompute-index-inhibit t))
+ (ivy--exhibit)))
+
+(defun ivy--kill-buffer-action (buffer)
+ "Kill BUFFER."
+ (ivy--kill-buffer-or-virtual buffer)
+ (unless (buffer-live-p (ivy-state-buffer ivy-last))
+ (setf (ivy-state-buffer ivy-last)
+ (with-ivy-window (current-buffer))))
+ (ivy--kill-current-candidate))
+
+(defvar ivy-switch-buffer-map
+ (let ((map (make-sparse-keymap)))
+ (define-key map (kbd "C-k") 'ivy-switch-buffer-kill)
+ map))
+
+(defun ivy-switch-buffer-kill ()
+ "When at end-of-line, kill the current buffer in `ivy-switch-buffer'.
+Otherwise, forward to `ivy-kill-line'."
+ (interactive)
+ (if (not (eolp))
+ (ivy-kill-line)
+ (ivy--kill-buffer-action
+ (ivy-state-current ivy-last))))
+
+(ivy-set-actions
+ 'ivy-switch-buffer
+ '(("f"
+ ivy--find-file-action
+ "find file")
+ ("j"
+ ivy--switch-buffer-other-window-action
+ "other window")
+ ("k"
+ ivy--kill-buffer-action
+ "kill")
+ ("r"
+ ivy--rename-buffer-action
+ "rename")))
+
+(ivy-set-actions
+ t
+ `(("i" ,(lambda (x) (insert (if (stringp x) x (car x)))) "insert")
+ ("w" ,(lambda (x) (kill-new (if (stringp x) x (car x)))) "copy")))
+
+(defun ivy--switch-buffer-matcher (regexp candidates)
+ "Return REGEXP matching CANDIDATES.
+Skip buffers that match `ivy-ignore-buffers'."
+ (let ((res (ivy--re-filter regexp candidates)))
+ (if (or (null ivy-use-ignore)
+ (null ivy-ignore-buffers))
+ res
+ (or (cl-remove-if
+ (lambda (buf)
+ (cl-find-if
+ (lambda (f-or-r)
+ (if (functionp f-or-r)
+ (funcall f-or-r buf)
+ (string-match-p f-or-r buf)))
+ ivy-ignore-buffers))
+ res)
+ (and (eq ivy-use-ignore t)
+ res)))))
+
+(defun ivy-append-face (str face)
+ "Append to STR the property FACE."
+ (setq str (copy-sequence str))
+ (ivy-add-face-text-property 0 (length str) face str t)
+ str)
+
+(defun ivy-switch-buffer-transformer (str)
+ "Transform candidate STR when switching buffers."
+ (let ((b (get-buffer str)))
+ (if (and b (buffer-file-name b))
+ (cond
+ ((and (not (ignore-errors (file-remote-p (buffer-file-name b))))
+ (not (verify-visited-file-modtime b)))
+ (ivy-append-face str 'ivy-modified-outside-buffer))
+ ((buffer-modified-p b)
+ (ivy-append-face str 'ivy-modified-buffer))
+ (t str))
+ str)))
+
+(defun ivy-switch-buffer-occur (cands)
+ "Occur function for `ivy-switch-buffer' using `ibuffer'.
+CANDS are the candidates to be displayed."
+ (unless cands
+ (setq cands (all-completions ivy-text #'internal-complete-buffer)))
+ (ibuffer
+ nil (buffer-name)
+ `((or ,@(cl-mapcan
+ (lambda (cand)
+ (unless (eq (get-text-property 0 'face cand) 'ivy-virtual)
+ `((name . ,(format "\\_<%s\\_>" (regexp-quote cand))))))
+ cands)))))
+
+;;;###autoload
+(defun ivy-switch-buffer ()
+ "Switch to another buffer."
+ (interactive)
+ (ivy-read "Switch to buffer: " #'internal-complete-buffer
+ :keymap ivy-switch-buffer-map
+ :preselect (buffer-name (other-buffer (current-buffer)))
+ :action #'ivy--switch-buffer-action
+ :matcher #'ivy--switch-buffer-matcher
+ :caller 'ivy-switch-buffer))
+
+(ivy-configure 'ivy-switch-buffer
+ :occur #'ivy-switch-buffer-occur
+ :display-transformer-fn #'ivy-switch-buffer-transformer)
+
+;;;###autoload
+(defun ivy-switch-view ()
+ "Switch to one of the window views stored by `ivy-push-view'."
+ (interactive)
+ (let ((ivy-initial-inputs-alist
+ '((ivy-switch-buffer . "{}"))))
+ (ivy-switch-buffer)))
+
+;;;###autoload
+(defun ivy-switch-buffer-other-window ()
+ "Switch to another buffer in another window."
+ (interactive)
+ (ivy-read "Switch to buffer in other window: " #'internal-complete-buffer
+ :matcher #'ivy--switch-buffer-matcher
+ :preselect (buffer-name (other-buffer (current-buffer)))
+ :action #'ivy--switch-buffer-other-window-action
+ :keymap ivy-switch-buffer-map
+ :caller 'ivy-switch-buffer-other-window))
+
+(ivy-configure 'ivy-switch-buffer-other-window
+ :occur #'ivy-switch-buffer-occur)
+
+(defun ivy--yank-handle-case-fold (text)
+ (if (and (> (length ivy-text) 0)
+ (string= (downcase ivy-text) ivy-text))
+ (downcase text)
+ text))
+
+(defun ivy--yank-by (fn &rest args)
+ "Pull buffer text from current line into search string.
+The region to extract is determined by the respective values of
+point before and after applying FN to ARGS."
+ (let (text)
+ (with-ivy-window
+ (let ((beg (point))
+ (bol (line-beginning-position))
+ (eol (line-end-position))
+ end)
+ (unwind-protect
+ (progn (apply fn args)
+ (setq end (goto-char (max bol (min (point) eol))))
+ (setq text (buffer-substring-no-properties beg end))
+ (ivy--pulse-region beg end))
+ (unless text
+ (goto-char beg)))))
+ (when text
+ (insert (replace-regexp-in-string
+ " +" " "
+ (ivy--yank-handle-case-fold text)
+ t t)))))
+
+(defun ivy-yank-word (&optional arg)
+ "Pull next word from buffer into search string.
+If optional ARG is non-nil, pull in the next ARG
+words (previous if ARG is negative)."
+ (interactive "p")
+ (ivy--yank-by #'forward-word arg))
+
+(defun ivy-yank-symbol (&optional arg)
+ "Pull next symbol from buffer into search string.
+If optional ARG is non-nil, pull in the next ARG
+symbols (previous if ARG is negative)."
+ (interactive "p")
+ ;; Emacs < 24.4 compatibility
+ (unless (fboundp 'forward-symbol)
+ (require 'thingatpt))
+ (ivy--yank-by #'forward-symbol (or arg 1)))
+
+(defun ivy-yank-char (&optional arg)
+ "Pull next character from buffer into search string.
+If optional ARG is non-nil, pull in the next ARG
+characters (previous if ARG is negative)."
+ (interactive "p")
+ (ivy--yank-by #'forward-char arg))
+
+(defvar ivy--pulse-overlay nil
+ "Overlay used to highlight yanked word.")
+
+(defvar ivy--pulse-timer nil
+ "Timer used to dispose of `ivy--pulse-overlay'.")
+
+(defcustom ivy-pulse-delay 0.5
+ "Number of seconds to display `ivy-yanked-word' highlight.
+When nil, disable highlighting."
+ :type '(choice
+ (number :tag "Delay in seconds")
+ (const :tag "Disable" nil)))
+
+(defun ivy--pulse-region (start end)
+ "Temporarily highlight text between START and END.
+The \"pulse\" duration is determined by `ivy-pulse-delay'."
+ (when ivy-pulse-delay
+ (if ivy--pulse-overlay
+ (let ((ostart (overlay-start ivy--pulse-overlay))
+ (oend (overlay-end ivy--pulse-overlay)))
+ (when (< end start)
+ (cl-rotatef start end))
+ ;; Extend the existing overlay's region to include START..END,
+ ;; but only if the two regions are contiguous.
+ (move-overlay ivy--pulse-overlay
+ (if (= start oend) ostart start)
+ (if (= end ostart) oend end)))
+ (setq ivy--pulse-overlay (make-overlay start end))
+ (overlay-put ivy--pulse-overlay 'face 'ivy-yanked-word))
+ (when ivy--pulse-timer
+ (cancel-timer ivy--pulse-timer))
+ (setq ivy--pulse-timer
+ (run-at-time ivy-pulse-delay nil #'ivy--pulse-cleanup))))
+
+(defun ivy--pulse-cleanup ()
+ "Cancel `ivy--pulse-timer' and delete `ivy--pulse-overlay'."
+ (when ivy--pulse-timer
+ (cancel-timer ivy--pulse-timer)
+ (setq ivy--pulse-timer nil))
+ (when ivy--pulse-overlay
+ (delete-overlay ivy--pulse-overlay)
+ (setq ivy--pulse-overlay nil)))
+
+(defun ivy-kill-ring-save ()
+ "Store the current candidates into the kill ring.
+If the region is active, forward to `kill-ring-save' instead."
+ (interactive)
+ (if (region-active-p)
+ (call-interactively 'kill-ring-save)
+ (kill-new
+ (mapconcat
+ #'identity
+ ivy--old-cands
+ "\n"))))
+
+(defun ivy-insert-current ()
+ "Make the current candidate into current input.
+Don't finish completion."
+ (interactive)
+ (delete-minibuffer-contents)
+ (let ((end (and ivy--directory
+ (ivy--dirname-p (ivy-state-current ivy-last))
+ -1)))
+ (insert (substring-no-properties
+ (ivy-state-current ivy-last) 0 end))))
+
+(defun ivy-insert-current-full ()
+ "Insert the full Yank the current directory into the minibuffer."
+ (interactive)
+ (insert ivy--directory))
+
+(defcustom ivy-preferred-re-builders
+ '((ivy--regex-plus . "ivy")
+ (ivy--regex-ignore-order . "order")
+ (ivy--regex-fuzzy . "fuzzy"))
+ "Alist of preferred re-builders with display names.
+This list can be rotated with `ivy-rotate-preferred-builders'."
+ :type '(alist :key-type function :value-type string))
+
+(defun ivy-rotate-preferred-builders ()
+ "Switch to the next re builder in `ivy-preferred-re-builders'."
+ (interactive)
+ (when ivy-preferred-re-builders
+ (setq ivy--old-re nil)
+ (setq ivy--regex-function
+ (let ((cell (assq ivy--regex-function ivy-preferred-re-builders)))
+ (car (or (cadr (memq cell ivy-preferred-re-builders))
+ (car ivy-preferred-re-builders)))))))
+
+(defun ivy-toggle-fuzzy ()
+ "Toggle the re builder between `ivy--regex-fuzzy' and `ivy--regex-plus'."
+ (interactive)
+ (setq ivy--old-re nil)
+ (if (eq ivy--regex-function 'ivy--regex-fuzzy)
+ (setq ivy--regex-function 'ivy--regex-plus)
+ (setq ivy--regex-function 'ivy--regex-fuzzy)))
+
+(defvar ivy--reverse-i-search-symbol nil
+ "Store the history symbol.")
+
+(defun ivy-reverse-i-search-kill ()
+ "Remove the current item from history"
+ (interactive)
+ (if (not (eolp))
+ (ivy-kill-line)
+ (let ((current (ivy-state-current ivy-last)))
+ (if (symbolp ivy--reverse-i-search-symbol)
+ (set
+ ivy--reverse-i-search-symbol
+ (delete current (symbol-value ivy--reverse-i-search-symbol)))
+ (ring-remove
+ ivy--reverse-i-search-symbol
+ (ring-member ivy--reverse-i-search-symbol (ivy-state-current ivy-last)))))
+ (ivy--kill-current-candidate)))
+
+(defvar ivy-reverse-i-search-map
+ (let ((map (make-sparse-keymap)))
+ (define-key map (kbd "C-k") 'ivy-reverse-i-search-kill)
+ map))
+
+(defun ivy-history-contents (history)
+ "Copy contents of HISTORY.
+A copy is necessary so that we don't clobber any string attributes.
+Also set `ivy--reverse-i-search-symbol' to HISTORY."
+ (setq ivy--reverse-i-search-symbol history)
+ (cond ((symbolp history)
+ (delete-dups
+ (copy-sequence (symbol-value history))))
+ ((ring-p history)
+ (delete-dups
+ (when (> (ring-size history) 0)
+ (ring-elements history))))
+ ((sequencep history)
+ (delete-dups
+ (copy-sequence history)))
+ (t
+ (error "Expected a symbol, ring, or sequence: %S" history))))
+
+(defun ivy-reverse-i-search ()
+ "Enter a recursive `ivy-read' session using the current history.
+The selected history element will be inserted into the minibuffer.
+\\
+You can also delete an element from history with \\[ivy-reverse-i-search-kill]."
+ (interactive)
+ (cond
+ ((= (minibuffer-depth) 0)
+ (user-error
+ "This command is intended to be called with \"C-r\" from `ivy-read'."))
+ ;; don't recur
+ ((and (> (minibuffer-depth) 1)
+ (eq (ivy-state-caller ivy-last) 'ivy-reverse-i-search)))
+ (t
+ (let ((enable-recursive-minibuffers t)
+ (old-last ivy-last))
+ (ivy-read "Reverse-i-search: "
+ (ivy-history-contents (ivy-state-history ivy-last))
+ :keymap ivy-reverse-i-search-map
+ :action (lambda (x)
+ (ivy--reset-state
+ (setq ivy-last old-last))
+ (delete-minibuffer-contents)
+ (insert (substring-no-properties x))
+ (ivy--cd-maybe))
+ :caller 'ivy-reverse-i-search)))))
+
+(defun ivy-restrict-to-matches ()
+ "Restrict candidates to current input and erase input."
+ (interactive)
+ (delete-minibuffer-contents)
+ (if (ivy-state-dynamic-collection ivy-last)
+ (progn
+ (setf (ivy-state-dynamic-collection ivy-last) nil)
+ (setf (ivy-state-collection ivy-last)
+ (setq ivy--all-candidates ivy--old-cands)))
+ (setq ivy--all-candidates
+ (ivy--filter ivy-text ivy--all-candidates))))
+
+;;* Occur
+(defvar-local ivy-occur-last nil
+ "Buffer-local value of `ivy-last'.
+Can't re-use `ivy-last' because using e.g. `swiper' in the same
+buffer would modify `ivy-last'.")
+
+(defvar ivy-occur-mode-map
+ (let ((map (make-sparse-keymap)))
+ (define-key map [mouse-1] 'ivy-occur-click)
+ (define-key map (kbd "RET") 'ivy-occur-press-and-switch)
+ (define-key map (kbd "j") 'ivy-occur-next-line)
+ (define-key map (kbd "k") 'ivy-occur-previous-line)
+ (define-key map (kbd "h") 'backward-char)
+ (define-key map (kbd "l") 'forward-char)
+ (define-key map (kbd "f") 'ivy-occur-press)
+ (define-key map (kbd "g") 'ivy-occur-revert-buffer)
+ (define-key map (kbd "a") 'ivy-occur-read-action)
+ (define-key map (kbd "o") 'ivy-occur-dispatch)
+ (define-key map (kbd "c") 'ivy-occur-toggle-calling)
+ (define-key map (kbd "q") 'quit-window)
+ (define-key map (kbd "R") 'read-only-mode)
+ (define-key map (kbd "C-d") 'ivy-occur-delete-candidate)
+ map)
+ "Keymap for Ivy Occur mode.")
+
+(defun ivy-occur-toggle-calling ()
+ "Toggle `ivy-calling'."
+ (interactive)
+ (if (setq ivy-calling (not ivy-calling))
+ (progn
+ (setq mode-name "Ivy-Occur [calling]")
+ (ivy-occur-press))
+ (setq mode-name "Ivy-Occur"))
+ (force-mode-line-update))
+
+(defun ivy--find-occur-buffer ()
+ (let ((cb (current-buffer)))
+ (cl-find-if
+ (lambda (b)
+ (with-current-buffer b
+ (and (eq major-mode 'ivy-occur-grep-mode)
+ (equal cb (ivy-state-buffer ivy-occur-last)))))
+ (buffer-list))))
+
+(defun ivy--select-occur-buffer ()
+ (let* ((ob (ivy--find-occur-buffer))
+ (ow (cl-find-if (lambda (w) (equal ob (window-buffer w)))
+ (window-list))))
+ (if ow
+ (select-window ow)
+ (pop-to-buffer ob))))
+
+(defun ivy-occur-next-line (&optional arg)
+ "Move the cursor down ARG lines.
+When `ivy-calling' isn't nil, call `ivy-occur-press'."
+ (interactive "p")
+ (let ((offset (cond ((derived-mode-p 'ivy-occur-grep-mode) 5)
+ ((derived-mode-p 'ivy-occur-mode) 2))))
+ (if offset
+ (progn
+ (if (< (line-number-at-pos) offset)
+ (progn
+ (goto-char (point-min))
+ (forward-line (1- offset)))
+ (forward-line arg)
+ (when (eolp)
+ (forward-line -1)))
+ (when ivy-calling
+ (ivy-occur-press)))
+ (ivy--select-occur-buffer)
+ (ivy-occur-next-line arg)
+ (ivy-occur-press-and-switch))))
+
+(defun ivy-occur-previous-line (&optional arg)
+ "Move the cursor up ARG lines.
+When `ivy-calling' isn't nil, call `ivy-occur-press'."
+ (interactive "p")
+ (let ((offset (cond ((derived-mode-p 'ivy-occur-grep-mode) 5)
+ ((derived-mode-p 'ivy-occur-mode) 2))))
+ (if offset
+ (progn
+ (forward-line (- arg))
+ (when (< (line-number-at-pos) offset)
+ (goto-char (point-min))
+ (forward-line (1- offset)))
+ (when ivy-calling
+ (ivy-occur-press)))
+ (ivy--select-occur-buffer)
+ (ivy-occur-previous-line arg)
+ (ivy-occur-press-and-switch))))
+
+(defun ivy-occur-next-error (n &optional reset)
+ "A `next-error-function' for `ivy-occur-mode'."
+ (interactive "p")
+ (when reset
+ (goto-char (point-min)))
+ (setq n (or n 1))
+ (let ((ivy-calling t))
+ (cond ((< n 0) (ivy-occur-previous-line (- n)))
+ (t (ivy-occur-next-line n)))))
+
+(define-derived-mode ivy-occur-mode fundamental-mode "Ivy-Occur"
+ "Major mode for output from \\[ivy-occur].
+
+\\{ivy-occur-mode-map}"
+ (setq-local view-read-only nil))
+
+(defvar ivy-occur-grep-mode-map
+ (let ((map (copy-keymap ivy-occur-mode-map)))
+ (define-key map (kbd "C-x C-q") 'ivy-wgrep-change-to-wgrep-mode)
+ (define-key map "w" 'ivy-wgrep-change-to-wgrep-mode)
+ map)
+ "Keymap for Ivy Occur Grep mode.")
+
+(defun ivy-occur-delete-candidate ()
+ (interactive)
+ (let ((inhibit-read-only t))
+ (delete-region (line-beginning-position)
+ (1+ (line-end-position)))))
+
+(define-derived-mode ivy-occur-grep-mode grep-mode "Ivy-Occur"
+ "Major mode for output from \\[ivy-occur].
+
+\\{ivy-occur-grep-mode-map}"
+ (setq-local view-read-only nil)
+ (when (fboundp 'wgrep-setup)
+ (wgrep-setup)))
+
+(defun ivy--starts-with-dotslash (str)
+ (string-match-p "\\`\\.[/\\]" str))
+
+(defun ivy--occur-insert-lines (cands)
+ "Insert CANDS into `ivy-occur' buffer."
+ (font-lock-mode -1)
+ (dolist (cand cands)
+ (setq cand
+ (if (string-match "\\`\\(.*:[0-9]+:\\)\\(.*\\)\\'" cand)
+ (let ((file-and-line (match-string 1 cand))
+ (grep-line (match-string 2 cand)))
+ (concat
+ (propertize file-and-line 'face 'ivy-grep-info)
+ (ivy--highlight-fuzzy grep-line)))
+ (ivy--highlight-fuzzy (copy-sequence cand))))
+ (add-text-properties
+ 0 (length cand)
+ '(mouse-face
+ highlight
+ help-echo "mouse-1: call ivy-action")
+ cand)
+ (insert (if (string-match-p "\\`.[/\\]" cand) "" " ")
+ cand ?\n)))
+
+(defun ivy--occur-default (cands)
+ "Insert CANDS into the current occur buffer."
+ (unless cands
+ (let ((coll (ivy-state-collection ivy-last)))
+ (when (arrayp coll)
+ (setq coll (all-completions "" coll (ivy-state-predicate ivy-last))))
+ (setq cands (ivy--filter (ivy-state-text ivy-last) coll))))
+ (ivy-occur-mode)
+ (insert (format "%d candidates:\n" (length cands)))
+ (ivy--occur-insert-lines cands)
+ (read-only-mode))
+
+(defun ivy-occur ()
+ "Stop completion and put the current candidates into a new buffer.
+
+The new buffer remembers current action(s).
+
+While in the *ivy-occur* buffer, selecting a candidate with RET or
+a mouse click will call the appropriate action for that candidate.
+
+There is no limit on the number of *ivy-occur* buffers."
+ (interactive)
+ (if (not (window-minibuffer-p))
+ (user-error "No completion session is active")
+ (let* ((caller (ivy-state-caller ivy-last))
+ (occur-fn (or (plist-get ivy--occurs-list caller)
+ #'ivy--occur-default))
+ (buffer
+ (generate-new-buffer
+ (format "*ivy-occur%s \"%s\"*"
+ (if caller
+ (concat " " (prin1-to-string caller))
+ "")
+ ivy-text))))
+ (with-current-buffer buffer
+ (funcall occur-fn ivy--old-cands)
+ (setf (ivy-state-text ivy-last) ivy-text)
+ (setq ivy-occur-last ivy-last))
+ (ivy-exit-with-action
+ (lambda (_)
+ (pop-to-buffer buffer)
+ (setq next-error-last-buffer buffer)
+ (setq-local next-error-function #'ivy-occur-next-error))))))
+
+(defun ivy-occur-revert-buffer ()
+ "Refresh the buffer making it up-to date with the collection.
+
+Currently only works for `swiper'. In that specific case, the
+*ivy-occur* buffer becomes nearly useless as the original buffer
+is updated, since the line numbers no longer match.
+
+Calling this function is as if you called `ivy-occur' on the
+updated original buffer."
+ (interactive)
+ (let ((caller (ivy-state-caller ivy-occur-last))
+ (ivy-last ivy-occur-last))
+ (let ((inhibit-read-only t)
+ (line (line-number-at-pos)))
+ (erase-buffer)
+ (funcall (or (plist-get ivy--occurs-list caller)
+ #'ivy--occur-default) nil)
+ (goto-char (point-min))
+ (forward-line (1- line)))
+ (setq ivy-occur-last ivy-last)))
+
+(declare-function wgrep-change-to-wgrep-mode "ext:wgrep")
+
+(defun ivy-wgrep-change-to-wgrep-mode ()
+ "Forward to `wgrep-change-to-wgrep-mode'."
+ (interactive)
+ (if (require 'wgrep nil 'noerror)
+ (wgrep-change-to-wgrep-mode)
+ (error "Package wgrep isn't installed")))
+
+(defun ivy-occur-read-action ()
+ "Select one of the available actions as the current one."
+ (interactive)
+ (let ((ivy-last ivy-occur-last))
+ (ivy-read-action)))
+
+(defun ivy-occur-dispatch ()
+ "Call one of the available actions on the current item."
+ (interactive)
+ (let* ((state-action (ivy-state-action ivy-occur-last))
+ (actions (if (symbolp state-action)
+ state-action
+ (copy-sequence state-action))))
+ (unwind-protect
+ (progn
+ (ivy-occur-read-action)
+ (ivy-occur-press))
+ (setf (ivy-state-action ivy-occur-last) actions))))
+
+(defun ivy-occur-click (event)
+ "Execute action for the current candidate.
+EVENT gives the mouse position."
+ (interactive "e")
+ (let ((window (posn-window (event-end event)))
+ (pos (posn-point (event-end event))))
+ (with-current-buffer (window-buffer window)
+ (goto-char pos)
+ (ivy-occur-press))))
+
+(declare-function swiper--cleanup "swiper")
+(declare-function swiper--add-overlays "swiper")
+(defvar ivy-occur-timer nil)
+
+(defun ivy--occur-press-update-window ()
+ (cond
+ ((memq (ivy-state-caller ivy-occur-last)
+ (append '(swiper swiper-isearch) ivy-highlight-grep-commands))
+ (let ((window (ivy-state-window ivy-occur-last))
+ (buffer (ivy-state-buffer ivy-occur-last)))
+ (when (buffer-live-p buffer)
+ (cond ((or (not (window-live-p window))
+ (equal window (selected-window)))
+ (save-selected-window
+ (setf (ivy-state-window ivy-occur-last)
+ (display-buffer buffer))))
+ ((not (equal (window-buffer window) buffer))
+ (with-selected-window window
+ (switch-to-buffer buffer)))))))
+
+ ((memq (ivy-state-caller ivy-occur-last)
+ '(counsel-describe-function counsel-describe-variable))
+ (setf (ivy-state-window ivy-occur-last)
+ (selected-window))
+ (selected-window))))
+
+(defun ivy--occur-press-buffer ()
+ (let ((buffer (ivy-state-buffer ivy-last)))
+ (if (buffer-live-p buffer)
+ buffer
+ (current-buffer))))
+
+(defun ivy-occur-press ()
+ "Execute action for the current candidate."
+ (interactive)
+ (ivy--occur-press-update-window)
+ (when (save-excursion
+ (beginning-of-line)
+ (looking-at "\\(?:./\\| \\)\\(.*\\)$"))
+ (let* ((ivy-last ivy-occur-last)
+ (ivy-text (ivy-state-text ivy-last))
+ (str (buffer-substring
+ (match-beginning 1)
+ (match-end 1)))
+ (offset (or (get-text-property 0 'offset str) 0))
+ (coll (ivy-state-collection ivy-last))
+ (action (ivy--get-action ivy-last))
+ (ivy-exit 'done))
+ (with-ivy-window
+ (with-current-buffer (ivy--occur-press-buffer)
+ (save-restriction
+ (widen)
+ (funcall action
+ (if (and (consp coll)
+ (consp (car coll)))
+ (assoc str coll)
+ (substring str offset)))))
+ (if (memq (ivy-state-caller ivy-last)
+ (append '(swiper swiper-isearch) ivy-highlight-grep-commands))
+ (with-current-buffer (window-buffer (selected-window))
+ (swiper--cleanup)
+ (swiper--add-overlays
+ (ivy--regex ivy-text)
+ (line-beginning-position)
+ (line-end-position)
+ (selected-window))
+ (when (timerp ivy-occur-timer)
+ (cancel-timer ivy-occur-timer))
+ (setq ivy-occur-timer
+ (run-at-time 1.0 nil 'swiper--cleanup))))))))
+
+(defun ivy-occur-press-and-switch ()
+ "Execute action for the current candidate and switch window."
+ (interactive)
+ (ivy-occur-press)
+ (select-window (ivy--get-window ivy-occur-last)))
+
+(defun ivy--marked-p ()
+ (member (ivy-state-current ivy-last) ivy-marked-candidates))
+
+(defun ivy--unmark (cand)
+ (setcar (member cand ivy--all-candidates)
+ (setcar (member cand ivy--old-cands)
+ (substring cand (length ivy-mark-prefix))))
+ (setq ivy-marked-candidates
+ (delete cand ivy-marked-candidates)))
+
+(defun ivy--mark (cand)
+ (let ((marked-cand (concat ivy-mark-prefix cand)))
+ (setcar (member cand ivy--all-candidates)
+ (setcar (member cand ivy--old-cands) marked-cand))
+ (setq ivy-marked-candidates
+ (append ivy-marked-candidates (list marked-cand)))))
+
+(defun ivy-mark ()
+ "Mark the selected candidate and move to the next one.
+
+In `ivy-call', :action will be called in turn for all marked
+candidates.
+
+However, if :multi-action was supplied to `ivy-read', then it
+will be called with `ivy-marked-candidates'. This way, it can
+make decisions based on the whole marked list."
+ (interactive)
+ (unless (ivy--marked-p)
+ (ivy--mark (ivy-state-current ivy-last)))
+ (ivy-next-line))
+
+(defun ivy-unmark ()
+ "Unmark the selected candidate and move to the next one."
+ (interactive)
+ (when (ivy--marked-p)
+ (ivy--unmark (ivy-state-current ivy-last)))
+ (ivy-next-line))
+
+(defun ivy-unmark-backward ()
+ "Move to the previous candidate and unmark it."
+ (interactive)
+ (ivy-previous-line)
+ (ivy--exhibit)
+ (when (ivy--marked-p)
+ (ivy--unmark (ivy-state-current ivy-last))))
+
+(defun ivy-toggle-marks ()
+ "Toggle mark for all narrowed candidates."
+ (interactive)
+ (dolist (cand ivy--old-cands)
+ (if (member cand ivy-marked-candidates)
+ (ivy--unmark cand)
+ (ivy--mark cand))))
+
+(defconst ivy-help-file (let ((default-directory
+ (if load-file-name
+ (file-name-directory load-file-name)
+ default-directory)))
+ (if (file-exists-p "ivy-help.org")
+ (expand-file-name "ivy-help.org")
+ (if (file-exists-p "doc/ivy-help.org")
+ (expand-file-name "doc/ivy-help.org"))))
+ "The file for `ivy-help'.")
+
+(defvar org-hide-emphasis-markers)
+
+(defun ivy-help ()
+ "Help for `ivy'."
+ (interactive)
+ (let ((buf (get-buffer "*Ivy Help*")))
+ (unless buf
+ (setq buf (get-buffer-create "*Ivy Help*"))
+ (with-current-buffer buf
+ (insert-file-contents ivy-help-file)
+ (org-mode)
+ (setq-local org-hide-emphasis-markers t)
+ (view-mode)
+ (goto-char (point-min))
+ (let ((inhibit-message t))
+ (org-cycle '(64)))))
+ (if (eq this-command 'ivy-help)
+ (switch-to-buffer buf)
+ (with-ivy-window
+ (pop-to-buffer buf)))
+ (view-mode)
+ (goto-char (point-min))))
+
+(declare-function ffap-url-p "ffap")
+(defvar ffap-url-fetcher)
+
+(defun ivy-ffap-url-p (string)
+ "Forward to `ffap-url-p'."
+ (require 'ffap)
+ (ffap-url-p string))
+
+(defun ivy-ffap-url-fetcher (url)
+ "Calls `ffap-url-fetcher'."
+ (require 'ffap)
+ (funcall ffap-url-fetcher url))
+
+(ivy-configure 'read-file-name-internal
+ :sort-fn #'ivy-sort-file-function-default
+ :display-transformer-fn #'ivy-read-file-transformer)
+
+(ivy-configure 'internal-complete-buffer
+ :display-transformer-fn #'ivy-switch-buffer-transformer)
+
+(provide 'ivy)
+
+;;; ivy.el ends here
diff --git a/elpa/ivy-0.13.1/ivy.info b/elpa/ivy-0.13.1/ivy.info
new file mode 100644
index 0000000..caa0fd6
--- /dev/null
+++ b/elpa/ivy-0.13.1/ivy.info
@@ -0,0 +1,1954 @@
+This is ivy.info, produced by makeinfo version 6.5 from ivy.texi.
+
+Ivy manual, version 0.13.0
+
+ Ivy is an interactive interface for completion in Emacs. Emacs uses
+completion mechanism in a variety of contexts: code, menus, commands,
+variables, functions, etc. Completion entails listing, sorting,
+filtering, previewing, and applying actions on selected items. When
+active, ‘ivy-mode’ completes the selection process by narrowing
+available choices while previewing in the minibuffer. Selecting the
+final candidate is either through simple keyboard character inputs or
+through powerful regular expressions.
+
+ Copyright (C) 2015-2019 Free Software Foundation, Inc.
+
+ Permission is granted to copy, distribute and/or modify this
+ document under the terms of the GNU Free Documentation License,
+ Version 1.3 or any later version published by the Free Software
+ Foundation; with no Invariant Sections, no Front-Cover Texts, and
+ no Back-Cover Texts. A copy of the license is included in the
+ section entitled "GNU Free Documentation License".
+INFO-DIR-SECTION Emacs
+START-INFO-DIR-ENTRY
+* Ivy: (ivy). Using Ivy for completion.
+END-INFO-DIR-ENTRY
+
+
+File: ivy.info, Node: Top, Next: Introduction, Up: (dir)
+
+Ivy User Manual
+***************
+
+* Menu:
+
+* Introduction::
+* Installation::
+* Getting started::
+* Key bindings::
+* Completion Styles::
+* Customization::
+* Commands::
+* API::
+* Variable Index::
+* Keystroke Index::
+
+— The Detailed Node Listing —
+
+Installation
+
+* Installing from Emacs Package Manager::
+* Installing from the Git repository::
+
+Getting started
+
+* Basic customization::
+
+Key bindings
+
+* Global key bindings::
+* Minibuffer key bindings::
+
+Minibuffer key bindings
+
+* Key bindings for navigation::
+* Key bindings for single selection, action, then exit minibuffer: Key bindings for single selection action then exit minibuffer.
+* Key bindings for multiple selections and actions, keep minibuffer open: Key bindings for multiple selections and actions keep minibuffer open.
+* Key bindings that alter the minibuffer input::
+* Other key bindings::
+* Hydra in the minibuffer::
+* Saving the current completion session to a buffer::
+
+Completion Styles
+
+* ivy--regex-plus::
+* ivy--regex-ignore-order::
+* ivy--regex-fuzzy::
+
+Customization
+
+* Faces::
+* Defcustoms::
+* Actions::
+* Packages::
+
+Actions
+
+* What are actions?::
+* How can different actions be called?::
+* How to modify the actions list?::
+* Example - add two actions to each command::
+* Example - define a new command with several actions::
+
+Example - add two actions to each command
+
+* How to undo adding the two actions::
+* How to add actions to a specific command::
+
+Example - define a new command with several actions
+
+* Test the above function with ivy-occur::
+
+Commands
+
+* File Name Completion::
+* Buffer Name Completion::
+* Counsel commands::
+
+File Name Completion
+
+* Using TRAMP::
+
+API
+
+* Required arguments for ivy-read::
+* Optional arguments for ivy-read::
+* Example - counsel-describe-function::
+* Example - counsel-locate::
+* Example - ivy-read-with-extra-properties::
+
+
+
+File: ivy.info, Node: Introduction, Next: Installation, Prev: Top, Up: Top
+
+1 Introduction
+**************
+
+Ivy is for quick and easy selection from a list. When Emacs prompts for
+a string from a list of several possible choices, Ivy springs into
+action to assist in narrowing and picking the right string from a vast
+number of choices.
+
+ Ivy strives for minimalism, simplicity, customizability and
+discoverability.
+
+Minimalism
+..........
+
+ Uncluttered minibuffer is minimalism. Ivy shows the completion
+ defaults, the number of matches, and 10 candidate matches below the
+ input line. Customize ‘ivy-height’ to adjust the number of
+ candidate matches displayed in the minibuffer.
+
+Simplicity
+..........
+
+ Simplicity is about Ivy’s behavior in the minibuffer. It is also
+ about the code interface to extend Ivy’s functionality. The
+ minibuffer area behaves as close to ‘fundamental-mode’ as possible.
+ ‘SPC’ inserts a space, for example, instead of being bound to the
+ more complex ‘minibuffer-complete-word’. Ivy’s code uses
+ easy-to-examine global variables; avoids needless complications
+ with branch-introducing custom macros.
+
+Customizability
+...............
+
+ Customizability is about being able to use different methods and
+ interfaces of completion to tailor the selection process. For
+ example, adding a custom display function that points to a selected
+ candidate with ‘>’, instead of highlighting the selected candidate
+ with the ‘ivy-current-match’ face (see
+ ‘ivy-format-functions-alist’). Or take the customization of
+ actions, say after the candidate function is selected. ‘RET’ uses
+ ‘counsel-describe-function’ to describe the function, whereas ‘M-o
+ d’ jumps to that function’s definition in the code. The ‘M-o’
+ prefix can be uniformly used with characters like ‘d’ to group
+ similar actions.
+
+Discoverability
+...............
+
+ Ivy displays easily discoverable commands through the hydra
+ facility. ‘C-o’ in the minibuffer displays a hydra menu. It opens
+ up within an expanded minibuffer area. Each menu item comes with
+ short documentation strings and highlighted one-key completions.
+ So discovering even seldom used keys is simply a matter of ‘C-o’ in
+ the minibuffer while in the midst of the Ivy interaction. This
+ discoverability minimizes exiting Ivy interface for documentation
+ look-ups.
+
+
+File: ivy.info, Node: Installation, Next: Getting started, Prev: Introduction, Up: Top
+
+2 Installation
+**************
+
+Install Ivy automatically through Emacs’s package manager, or manually
+from Ivy’s development repository.
+
+ Emacs 24.3 is the oldest version to run Ivy. Emacs 24.4 is the
+oldest version that runs Ivy with fancy faces display.
+
+* Menu:
+
+* Installing from Emacs Package Manager::
+* Installing from the Git repository::
+
+
+File: ivy.info, Node: Installing from Emacs Package Manager, Next: Installing from the Git repository, Up: Installation
+
+2.1 Installing from Emacs Package Manager
+=========================================
+
+‘M-x’ ‘package-install’ ‘RET’ ‘ivy’ ‘RET’
+
+ Ivy is installed as part of ‘ivy’ package, which is available from
+two different package archives, GNU ELPA and MELPA. For the latest
+stable version, use the GNU ELPA archives using the above M-x command.
+
+ For current hourly builds, use the MELPA archives. In MELPA, Ivy is
+split into three packages: ‘ivy’, ‘swiper’ and ‘counsel’; you can simply
+install ‘counsel’ which will bring in the other two as dependencies.
+See the code below for adding MELPA to the list of package archives:
+
+ (require 'package)
+ (add-to-list 'package-archives
+ '("melpa" . "https://melpa.org/packages/"))
+
+ After this do ‘M-x’ ‘package-refresh-contents’ ‘RET’, followed by
+‘M-x’ ‘package-install’ ‘RET’ ‘counsel’ ‘RET’.
+
+ For package manager details, see *note (emacs)Packages::.
+
+
+File: ivy.info, Node: Installing from the Git repository, Prev: Installing from Emacs Package Manager, Up: Installation
+
+2.2 Installing from the Git repository
+======================================
+
+Why install from Git?
+.....................
+
+ • No need to wait for MELPA’s hourly builds
+ • Easy to revert to previous versions
+ • Contribute to Ivy’s development; send patches; pull requests
+
+Configuration steps
+...................
+
+ First clone the Swiper repository with:
+
+ cd ~/git && git clone https://github.com/abo-abo/swiper
+ cd swiper && make compile
+
+ Second, add these lines to the Emacs init file:
+
+ (add-to-list 'load-path "~/git/swiper/")
+ (require 'ivy)
+
+ Then, update the code with:
+
+ git pull
+ make
+
+
+File: ivy.info, Node: Getting started, Next: Key bindings, Prev: Installation, Up: Top
+
+3 Getting started
+*****************
+
+First enable Ivy completion everywhere:
+
+ (ivy-mode 1)
+
+ Note: ‘ivy-mode’ can be toggled on and off with ‘M-x’ ‘ivy-mode’.
+
+* Menu:
+
+* Basic customization::
+
+
+File: ivy.info, Node: Basic customization, Up: Getting started
+
+3.1 Basic customization
+=======================
+
+Here are some basic settings particularly useful for new Ivy users:
+
+ (setq ivy-use-virtual-buffers t)
+ (setq ivy-count-format "(%d/%d) ")
+
+ If you want, you can go without any customizations at all. The above
+settings are the most bang for the buck in terms of customization. So
+users that typically don’t like customize a lot are advised to look at
+these settings first.
+
+ For more advanced customizations, refer to ‘M-x describe-variable’
+documentation.
+
+
+File: ivy.info, Node: Key bindings, Next: Completion Styles, Prev: Getting started, Up: Top
+
+4 Key bindings
+**************
+
+* Menu:
+
+* Global key bindings::
+* Minibuffer key bindings::
+
+
+File: ivy.info, Node: Global key bindings, Next: Minibuffer key bindings, Up: Key bindings
+
+4.1 Global key bindings
+=======================
+
+Here is a list of commands that are useful to be bound globally, along
+with some sample bindings:
+
+Ivy-based interface to standard commands
+........................................
+
+ (global-set-key (kbd "C-s") 'swiper-isearch)
+ (global-set-key (kbd "M-x") 'counsel-M-x)
+ (global-set-key (kbd "C-x C-f") 'counsel-find-file)
+ (global-set-key (kbd "M-y") 'counsel-yank-pop)
+ (global-set-key (kbd " f") 'counsel-describe-function)
+ (global-set-key (kbd " v") 'counsel-describe-variable)
+ (global-set-key (kbd " l") 'counsel-find-library)
+ (global-set-key (kbd " i") 'counsel-info-lookup-symbol)
+ (global-set-key (kbd " u") 'counsel-unicode-char)
+ (global-set-key (kbd " j") 'counsel-set-variable)
+ (global-set-key (kbd "C-x b") 'ivy-switch-buffer)
+ (global-set-key (kbd "C-c v") 'ivy-push-view)
+ (global-set-key (kbd "C-c V") 'ivy-pop-view)
+
+Ivy-based interface to shell and system tools
+.............................................
+
+ (global-set-key (kbd "C-c c") 'counsel-compile)
+ (global-set-key (kbd "C-c g") 'counsel-git)
+ (global-set-key (kbd "C-c j") 'counsel-git-grep)
+ (global-set-key (kbd "C-c L") 'counsel-git-log)
+ (global-set-key (kbd "C-c k") 'counsel-rg)
+ (global-set-key (kbd "C-c m") 'counsel-linux-app)
+ (global-set-key (kbd "C-c n") 'counsel-fzf)
+ (global-set-key (kbd "C-x l") 'counsel-locate)
+ (global-set-key (kbd "C-c J") 'counsel-file-jump)
+ (global-set-key (kbd "C-S-o") 'counsel-rhythmbox)
+ (global-set-key (kbd "C-c w") 'counsel-wmctrl)
+
+Ivy-resume and other commands
+.............................
+
+ ‘ivy-resume’ resumes the last Ivy-based completion.
+
+ (global-set-key (kbd "C-c C-r") 'ivy-resume)
+ (global-set-key (kbd "C-c b") 'counsel-bookmark)
+ (global-set-key (kbd "C-c d") 'counsel-descbinds)
+ (global-set-key (kbd "C-c g") 'counsel-git)
+ (global-set-key (kbd "C-c o") 'counsel-outline)
+ (global-set-key (kbd "C-c t") 'counsel-load-theme)
+ (global-set-key (kbd "C-c F") 'counsel-org-file)
+
+ You can also enable ‘counsel-mode’ to make some global key binding
+remapping for you.
+
+
+File: ivy.info, Node: Minibuffer key bindings, Prev: Global key bindings, Up: Key bindings
+
+4.2 Minibuffer key bindings
+===========================
+
+Ivy includes several minibuffer bindings, which are defined in the
+‘ivy-minibuffer-map’ keymap variable. The most frequently used ones are
+described here.
+
+ ‘swiper’ or ‘counsel-M-x’ add more key bindings through the ‘keymap’
+argument to ‘ivy-read’. These keys, also active in the minibuffer, are
+described under their respective commands.
+
+ A key feature of ‘ivy-minibuffer-map’ is its full editing capability
+where the familiar ‘C-a’, ‘C-f’, ‘M-d’, ‘M-DEL’, ‘M-b’, ‘M-w’, ‘C-k’,
+‘C-y’ key bindings work the same as in ‘fundamental-mode’.
+
+* Menu:
+
+* Key bindings for navigation::
+* Key bindings for single selection, action, then exit minibuffer: Key bindings for single selection action then exit minibuffer.
+* Key bindings for multiple selections and actions, keep minibuffer open: Key bindings for multiple selections and actions keep minibuffer open.
+* Key bindings that alter the minibuffer input::
+* Other key bindings::
+* Hydra in the minibuffer::
+* Saving the current completion session to a buffer::
+
+
+File: ivy.info, Node: Key bindings for navigation, Next: Key bindings for single selection action then exit minibuffer, Up: Minibuffer key bindings
+
+4.2.1 Key bindings for navigation
+---------------------------------
+
+ • ‘C-n’ (‘ivy-next-line’) selects the next candidate
+ • ‘C-p’ (‘ivy-previous-line’) selects the previous candidate
+ • ‘M-<’ (‘ivy-beginning-of-buffer’) selects the first candidate
+ • ‘M->’ (‘ivy-end-of-buffer’) selects the last candidate
+ • ‘C-v’ (‘ivy-scroll-up-command’) scrolls up by ‘ivy-height’ lines
+ • ‘M-v’ (‘ivy-scroll-down-command’) scrolls down by ‘ivy-height’
+ lines
+
+ -- User Option: ivy-wrap
+ Specifies the wrap-around behavior for ‘C-n’ and ‘C-p’. When
+ ‘ivy-wrap’ is set to ‘t’, ‘ivy-next-line’ and ‘ivy-previous-line’
+ will cycle past the last and the first candidates respectively.
+
+ Wrap-around behavior is off by default.
+
+ -- User Option: ivy-height
+ Use this option to adjust the minibuffer height, which also affects
+ scroll size when using ‘C-v’ and ‘M-v’ key bindings.
+
+ ‘ivy-height’ is 10 lines by default.
+
+
+File: ivy.info, Node: Key bindings for single selection action then exit minibuffer, Next: Key bindings for multiple selections and actions keep minibuffer open, Prev: Key bindings for navigation, Up: Minibuffer key bindings
+
+4.2.2 Key bindings for single selection, action, then exit minibuffer
+---------------------------------------------------------------------
+
+Ivy can offer several actions from which to choose which action to run.
+This "calling an action" operates on the selected candidate. For
+example, when viewing a list of files, one action could open it for
+editing, one to view it, another to invoke a special function, and so
+on. Custom actions can be added to this interface. The precise action
+to call on the selected candidate can be delayed until after the
+narrowing is completed. No need to exit the interface if unsure which
+action to run. This delayed flexibility and customization of actions
+extends usability of lists in Emacs.
+
+‘C-m’ or ‘RET’ (‘ivy-done’)
+...........................
+
+ Calls the default action and then exits the minibuffer.
+
+‘M-o’ (‘ivy-dispatching-done’)
+..............................
+
+ Presents valid actions from which to choose. When only one action
+ is available, there is no difference between ‘M-o’ and ‘C-m’.
+
+‘C-j’ (‘ivy-alt-done’)
+......................
+
+ When completing file names, selects the current directory candidate
+ and starts a new completion session there. Otherwise, it is the
+ same as ‘ivy-done’.
+
+‘TAB’ (‘ivy-partial-or-done’)
+.............................
+
+ Attempts partial completion, extending current input as much as
+ possible. ‘TAB TAB’ is the same as ‘C-j’ (‘ivy-alt-done’).
+
+ Example ERT test:
+
+ (should
+ (equal (ivy-with
+ '(progn
+ (ivy-read "Test: " '("can do" "can't, sorry" "other"))
+ ivy-text)
+ "c ")
+ "can"))
+
+‘C-M-j’ (‘ivy-immediate-done’)
+..............................
+
+ Exits with _the current input_ instead of _the current candidate_
+ (like other commands).
+
+ This is useful e.g. when you call ‘find-file’ to create a new
+ file, but the desired name matches an existing file. In that case,
+ using ‘C-j’ would select that existing file, which isn’t what you
+ want - use this command instead.
+
+‘C-'’ (‘ivy-avy’)
+.................
+
+ Uses avy to select one of the candidates on the current candidate
+ page. This can often be faster than multiple ‘C-n’ or ‘C-p’
+ keystrokes followed by ‘C-m’.
+
+
+File: ivy.info, Node: Key bindings for multiple selections and actions keep minibuffer open, Next: Key bindings that alter the minibuffer input, Prev: Key bindings for single selection action then exit minibuffer, Up: Minibuffer key bindings
+
+4.2.3 Key bindings for multiple selections and actions, keep minibuffer open
+----------------------------------------------------------------------------
+
+For repeatedly applying multiple actions or acting on multiple
+candidates, Ivy does not close the minibuffer between commands. It
+keeps the minibuffer open for applying subsequent actions.
+
+ Adding an extra meta key to the normal key chord invokes the special
+version of the regular commands that enables applying multiple actions.
+
+‘C-M-m’ (‘ivy-call’)
+....................
+
+ Is the non-exiting version of ‘C-m’ (‘ivy-done’).
+
+ Instead of closing the minibuffer, ‘C-M-m’ allows selecting another
+ candidate or another action. For example, ‘C-M-m’ on functions
+ list invokes ‘describe-function’. When combined with ‘C-n’,
+ function descriptions can be invoked quickly in succession.
+
+‘C-M-o’ (‘ivy-dispatching-call’)
+................................
+
+ Is the non-exiting version of ‘M-o’ (‘ivy-dispatching-done’).
+
+ For example, during the ‘counsel-rhythmbox’ completion, press
+ ‘C-M-o e’ to en-queue the selected candidate, followed by ‘C-n C-m’
+ to play the next candidate - the current action reverts to the
+ default one after ‘C-M-o’.
+
+‘C-M-n’ (‘ivy-next-line-and-call’)
+..................................
+
+ Combines ‘C-n’ and ‘C-M-m’. Moves to next line and applies an
+ action.
+
+ Comes in handy when opening multiple files from
+ ‘counsel-find-file’, ‘counsel-git-grep’, ‘counsel-ag’,
+ ‘counsel-rg’, or ‘counsel-locate’ lists. Just hold ‘C-M-n’ for
+ rapid-fire default action on each successive element of the list.
+
+‘C-M-p’ (‘ivy-previous-line-and-call’)
+......................................
+
+ Combines ‘C-p’ and ‘C-M-m’.
+
+ Similar to the above except it moves through the list in the other
+ direction.
+
+‘ivy-resume’
+............
+
+ Recalls the state of the completion session just before its last
+ exit.
+
+ Useful after an accidental ‘C-m’ (‘ivy-done’).
+
+
+File: ivy.info, Node: Key bindings that alter the minibuffer input, Next: Other key bindings, Prev: Key bindings for multiple selections and actions keep minibuffer open, Up: Minibuffer key bindings
+
+4.2.4 Key bindings that alter the minibuffer input
+--------------------------------------------------
+
+‘M-n’ (‘ivy-next-history-element’)
+..................................
+
+ Cycles forward through the Ivy command history.
+
+ Ivy updates an internal history list after each action. When this
+ history list is empty, ‘M-n’ inserts symbol (or URL) at point into
+ the minibuffer.
+
+‘M-p’ (‘ivy-previous-history-element’)
+......................................
+
+ Cycles forward through the Ivy command history.
+
+‘M-i’ (‘ivy-insert-current’)
+............................
+
+ Inserts the current candidate into the minibuffer.
+
+ Useful for copying and renaming files, for example: ‘M-i’ to insert
+ the original file name string, edit it, and then ‘C-m’ to complete
+ the renaming.
+
+‘M-j’ (‘ivy-yank-word’)
+.......................
+
+ Inserts the sub-word at point into the minibuffer.
+
+ This is similar to ‘C-s C-w’ with ‘isearch’. Ivy reserves ‘C-w’
+ for ‘kill-region’. See also ‘ivy-yank-symbol’ and ‘ivy-yank-char’.
+
+‘S-SPC’ (‘ivy-restrict-to-matches’)
+...................................
+
+ Deletes the current input, and resets the candidates list to the
+ currently restricted matches.
+
+ This is how Ivy provides narrowing in successive tiers.
+
+‘C-r’ (‘ivy-reverse-i-search’)
+..............................
+
+ Starts a recursive completion session through the command’s
+ history.
+
+ This works just like ‘C-r’ at the bash command prompt, where the
+ completion candidates are the history items. Upon completion, the
+ selected candidate string is inserted into the minibuffer.
+
+
+File: ivy.info, Node: Other key bindings, Next: Hydra in the minibuffer, Prev: Key bindings that alter the minibuffer input, Up: Minibuffer key bindings
+
+4.2.5 Other key bindings
+------------------------
+
+‘M-w’ (‘ivy-kill-ring-save’)
+............................
+
+ Copies selected candidates to the kill ring.
+
+ Copies the region if the region is active.
+
+
+File: ivy.info, Node: Hydra in the minibuffer, Next: Saving the current completion session to a buffer, Prev: Other key bindings, Up: Minibuffer key bindings
+
+4.2.6 Hydra in the minibuffer
+-----------------------------
+
+‘C-o’ (‘hydra-ivy/body’)
+........................
+
+ Invokes the hydra menu with short key bindings.
+
+ When Hydra is active, minibuffer editing is disabled and menus
+display short aliases:
+
+Short Normal Command name
+------------------------------------------------
+‘o’ ‘C-g’ ‘keyboard-escape-quit’
+‘j’ ‘C-n’ ‘ivy-next-line’
+‘k’ ‘C-p’ ‘ivy-previous-line’
+‘h’ ‘M-<’ ‘ivy-beginning-of-buffer’
+‘l’ ‘M->’ ‘ivy-end-of-buffer’
+‘d’ ‘C-m’ ‘ivy-done’
+‘f’ ‘C-j’ ‘ivy-alt-done’
+‘g’ ‘C-M-m’ ‘ivy-call’
+‘u’ ‘C-c C-o’ ‘ivy-occur’
+
+ Hydra reduces key strokes, for example: ‘C-n C-n C-n C-n’ is ‘C-o
+jjjj’ in Hydra.
+
+ Hydra menu offers these additional bindings:
+
+‘c’ (‘ivy-toggle-calling’)
+..........................
+
+ Toggle calling the action after each candidate change. It modifies
+ ‘j’ to ‘jg’, ‘k’ to ‘kg’ etc.
+
+‘m’ (‘ivy-rotate-preferred-builders’)
+.....................................
+
+ Rotate the current regexp matcher.
+
+‘>’ (‘ivy-minibuffer-grow’)
+...........................
+
+ Increase ‘ivy-height’ for the current minibuffer.
+
+‘<’ (‘ivy-minibuffer-shrink’)
+.............................
+
+ Decrease ‘ivy-height’ for the current minibuffer.
+
+‘w’ (‘ivy-prev-action’)
+.......................
+
+ Select the previous action.
+
+‘s’ (‘ivy-next-action’)
+.......................
+
+ Select the next action.
+
+‘a’ (‘ivy-read-action’)
+.......................
+
+ Use a menu to select an action.
+
+‘C’ (‘ivy-toggle-case-fold’)
+............................
+
+ Toggle case folding (match both upper and lower case characters for
+ lower case input).
+
+ Hydra menu also offers bindings for marking multiple candidates:
+
+Key Command name
+--------------------------------
+‘m’ ‘ivy-mark’
+‘u’ ‘ivy-unmark’
+‘DEL’ ‘ivy-unmark-backward’
+‘t’ ‘ivy-toggle-marks’
+
+ The action is called on each marked candidate one by one.
+
+
+File: ivy.info, Node: Saving the current completion session to a buffer, Prev: Hydra in the minibuffer, Up: Minibuffer key bindings
+
+4.2.7 Saving the current completion session to a buffer
+-------------------------------------------------------
+
+‘C-c C-o’ (‘ivy-occur’)
+.......................
+
+ Saves the current candidates to a new buffer and exits completion.
+
+ The new buffer is read-only and has a few useful bindings defined.
+
+‘RET’ or ‘f’ (‘ivy-occur-press’)
+................................
+
+ Call the current action on the selected candidate.
+
+‘mouse-1’ (‘ivy-occur-click’)
+.............................
+
+ Call the current action on the selected candidate.
+
+‘j’ (‘next-line’)
+.................
+
+ Move to next line.
+
+‘k’ (‘previous-line’)
+.....................
+
+ Move to previous line.
+
+‘a’ (‘ivy-occur-read-action’)
+.............................
+
+ Read an action and make it current for this buffer.
+
+‘o’ (‘ivy-occur-dispatch’)
+..........................
+
+ Read an action and call it on the selected candidate.
+
+‘q’ (‘quit-window’)
+...................
+
+ Bury the current buffer.
+
+ Ivy has no limit on the number of active buffers like these.
+
+ Ivy takes care of naming buffers uniquely by constructing descriptive
+names. For example: ‘*ivy-occur counsel-describe-variable "function$*’.
+
+
+File: ivy.info, Node: Completion Styles, Next: Customization, Prev: Key bindings, Up: Top
+
+5 Completion Styles
+*******************
+
+Ivy’s completion functions rely on a regex builder - a function that
+transforms a string input to a string regex. All current candidates
+simply have to match this regex. Each collection can be assigned its
+own regex builder by customizing ‘ivy-re-builders-alist’.
+
+ The keys of this alist are collection names, and the values are one
+of the following:
+ • ‘ivy--regex’
+ • ‘ivy--regex-plus’
+ • ‘ivy--regex-ignore-order’
+ • ‘ivy--regex-fuzzy’
+ • ‘regexp-quote’
+
+ A catch-all key, ‘t’, applies to all collections that don’t have
+their own key.
+
+ The default is:
+
+ (setq ivy-re-builders-alist
+ '((t . ivy--regex-plus)))
+
+ This example shows a custom regex builder assigned to file name
+completion:
+
+ (setq ivy-re-builders-alist
+ '((read-file-name-internal . ivy--regex-fuzzy)
+ (t . ivy--regex-plus)))
+
+ Here, ‘read-file-name-internal’ is a function that is passed as the
+second argument to ‘completing-read’ for file name completion.
+
+ The regex builder resolves as follows (in order of priority):
+ 1. ‘re-builder’ argument passed to ‘ivy-read’.
+ 2. ‘collection’ argument passed to ‘ivy-read’ is a function and has an
+ entry on ‘ivy-re-builders-alist’.
+ 3. ‘caller’ argument passed to ‘ivy-read’ has an entry on
+ ‘ivy-re-builders-alist’.
+ 4. ‘this-command’ has an entry on ‘ivy-re-builders-alist’.
+ 5. ‘t’ has an entry on ‘ivy-re-builders-alist’.
+ 6. ‘ivy--regex’.
+
+* Menu:
+
+* ivy--regex-plus::
+* ivy--regex-ignore-order::
+* ivy--regex-fuzzy::
+
+
+File: ivy.info, Node: ivy--regex-plus, Next: ivy--regex-ignore-order, Up: Completion Styles
+
+5.1 ivy–regex-plus
+==================
+
+‘ivy--regex-plus’ is Ivy’s default completion method.
+
+ ‘ivy--regex-plus’ matches by splitting the input by spaces and
+rebuilding it into a regex.
+
+ As the search string is typed in Ivy’s minibuffer, it is transformed
+into valid regex syntax. If the string is ‘"for example"’, it is
+transformed into
+
+ "\\(for\\).*\\(example\\)"
+
+ which in regex terminology matches ‘"for"’ followed by a wild card
+and then ‘"example"’. Note how Ivy uses the space character to build
+wild cards. To match a literal white space, use an extra space. So to
+match one space type two spaces, to match two spaces type three spaces,
+and so on.
+
+ As Ivy transforms typed characters into regex strings, it provides an
+intuitive feedback through font highlights.
+
+ Ivy supports regexp negation with ‘"!"’. For example, ‘"define key !
+ivy quit"’ first selects everything matching ‘"define.*key"’, then
+removes everything matching ‘"ivy"’, and finally removes everything
+matching ‘"quit"’. What remains is the final result set of the negation
+regexp.
+
+ Since Ivy treats minibuffer input as a regexp, the standard regexp
+identifiers work: ‘"^"’, ‘"$"’, ‘"\b"’ or ‘"[a-z]"’. The exceptions are
+spaces, which translate to ‘".*"’, and ‘"!"’ that signal the beginning
+of a negation group.
+
+
+File: ivy.info, Node: ivy--regex-ignore-order, Next: ivy--regex-fuzzy, Prev: ivy--regex-plus, Up: Completion Styles
+
+5.2 ivy–regex-ignore-order
+==========================
+
+‘ivy--regex-ignore-order’ ignores the order of regexp tokens when
+searching for matching candidates. For instance, the input ‘"for
+example"’ will match ‘"example test for"’.
+
+
+File: ivy.info, Node: ivy--regex-fuzzy, Prev: ivy--regex-ignore-order, Up: Completion Styles
+
+5.3 ivy–regex-fuzzy
+===================
+
+‘ivy--regex-fuzzy’ splits each character with a wild card. Searching
+for ‘"for"’ returns all ‘"f.*o.*r"’ matches, resulting in a large number
+of hits. Yet some searches need these extra hits. Ivy sorts such large
+lists using ‘flx’ package’s scoring mechanism, if it’s installed.
+
+ ‘C-o m’ toggles the current regexp builder.
+
+
+File: ivy.info, Node: Customization, Next: Commands, Prev: Completion Styles, Up: Top
+
+6 Customization
+***************
+
+* Menu:
+
+* Faces::
+* Defcustoms::
+* Actions::
+* Packages::
+
+
+File: ivy.info, Node: Faces, Next: Defcustoms, Up: Customization
+
+6.1 Faces
+=========
+
+‘ivy-current-match’
+...................
+
+ Highlights the currently selected candidate.
+
+‘ivy-minibuffer-match-face-1’
+.............................
+
+ Highlights the background of the match.
+
+‘ivy-minibuffer-match-face-2’
+.............................
+
+ Highlights the first (modulo 3) matched group.
+
+‘ivy-minibuffer-match-face-3’
+.............................
+
+ Highlights the second (modulo 3) matched group.
+
+‘ivy-minibuffer-match-face-4’
+.............................
+
+ Highlights the third (modulo 3) matched group.
+
+‘ivy-confirm-face’
+..................
+
+ Highlights the "(confirm)" part of the prompt.
+
+ When ‘confirm-nonexistent-file-or-buffer’ set to ‘t’, then
+ confirming non-existent files in ‘ivy-mode’ requires an additional
+ ‘RET’.
+
+ The confirmation prompt will use this face.
+
+ For example:
+
+ (setq confirm-nonexistent-file-or-buffer t)
+
+ Then call ‘find-file’, enter "eldorado" and press ‘RET’ - the
+ prompt will be appended with "(confirm)". Press ‘RET’ once more to
+ confirm, or any key to continue the completion.
+
+‘ivy-match-required-face’
+.........................
+
+ Highlights the "(match required)" part of the prompt.
+
+ When completions have to match available candidates and cannot take
+ random input, the "(match required)" prompt signals this
+ constraint.
+
+ For example, call ‘describe-variable’, enter "waldo" and press
+ ‘RET’ - "(match required)" is prompted. Press any key for the
+ prompt to disappear.
+
+‘ivy-subdir’
+............
+
+ Highlights directories when completing file names.
+
+‘ivy-remote’
+............
+
+ Highlights remote files when completing file names.
+
+‘ivy-virtual’
+.............
+
+ Highlights virtual buffers when completing buffer names.
+
+ Virtual buffers correspond to bookmarks and recent files list,
+ ‘recentf’.
+
+ Enable virtual buffers with:
+
+ (setq ivy-use-virtual-buffers t)
+
+‘ivy-modified-buffer’
+.....................
+
+ Highlights modified buffers when switching buffer.
+
+‘ivy-modified-outside-buffer’
+.............................
+
+ Highlights buffers modified outside Emacs when switching buffer.
+
+ This takes precedence over ‘ivy-modified-buffer’.
+
+
+File: ivy.info, Node: Defcustoms, Next: Actions, Prev: Faces, Up: Customization
+
+6.2 Defcustoms
+==============
+
+ -- User Option: ivy-count-format
+ A string that specifies display of number of candidates and current
+ candidate, if one exists.
+
+ The number of matching candidates by default is shown as a right-
+ padded integer value.
+
+ To disable showing the number of candidates:
+
+ (setq ivy-count-format "")
+
+ To also display the current candidate:
+
+ (setq ivy-count-format "(%d/%d) ")
+
+ The ‘format’-style switches this variable uses are described in the
+ ‘format’ documentation.
+
+ -- User Option: ivy-display-style
+ Specifies highlighting candidates in the minibuffer.
+
+ The default setting is ‘'fancy’ in Emacs versions 24.4 or newer.
+
+ Set ‘ivy-display-style’ to ‘nil’ for a plain minibuffer.
+
+ -- User Option: ivy-on-del-error-function
+ Specifies what to do when ‘DEL’ (‘ivy-backward-delete-char’) fails.
+
+ This is usually the case when there is no text left to delete,
+ i.e., when ‘DEL’ is typed at the beginning of the minibuffer.
+
+ The default behavior is to quit the completion after ‘DEL’ – a
+ handy key to invoke after mistakenly triggering a completion.
+
+
+File: ivy.info, Node: Actions, Next: Packages, Prev: Defcustoms, Up: Customization
+
+6.3 Actions
+===========
+
+* Menu:
+
+* What are actions?::
+* How can different actions be called?::
+* How to modify the actions list?::
+* Example - add two actions to each command::
+* Example - define a new command with several actions::
+
+
+File: ivy.info, Node: What are actions?, Next: How can different actions be called?, Up: Actions
+
+6.3.1 What are actions?
+-----------------------
+
+An action is a function that is called after you select a candidate
+during completion. This function takes a single string argument, which
+is the selected candidate.
+
+Window context when calling an action
+.....................................
+
+ Currently, the action is executed in the minibuffer window context.
+ This means e.g. that if you call ‘insert’ the text will be
+ inserted into the minibuffer.
+
+ If you want to execute the action in the initial window from which
+ the completion started, use the ‘with-ivy-window’ wrapper macro.
+
+ (defun ivy-insert-action (x)
+ (with-ivy-window
+ (insert x)))
+
+
+File: ivy.info, Node: How can different actions be called?, Next: How to modify the actions list?, Prev: What are actions?, Up: Actions
+
+6.3.2 How can different actions be called?
+------------------------------------------
+
+ • ‘C-m’ (‘ivy-done’) calls the current action.
+ • ‘M-o’ (‘ivy-dispatching-done’) presents available actions for
+ selection, calls it after selection, and then exits.
+ • ‘C-M-o’ (‘ivy-dispatching-call’) presents available actions for
+ selection, calls it after selection, and then does not exit.
+
+
+File: ivy.info, Node: How to modify the actions list?, Next: Example - add two actions to each command, Prev: How can different actions be called?, Up: Actions
+
+6.3.3 How to modify the actions list?
+-------------------------------------
+
+Currently, you can append any amount of your own actions to the default
+list of actions. This can be done either for a specific command, or for
+all commands at once.
+
+ Usually, the command has only one default action. The convention is
+to use single letters when selecting a command, and the letter ‘o’ is
+designated for the default command. This way, ‘M-o o’ should be always
+equivalent to ‘C-m’.
+
+
+File: ivy.info, Node: Example - add two actions to each command, Next: Example - define a new command with several actions, Prev: How to modify the actions list?, Up: Actions
+
+6.3.4 Example - add two actions to each command
+-----------------------------------------------
+
+The first action inserts the current candidate into the Ivy window - the
+window from which ‘ivy-read’ was called.
+
+ The second action copies the current candidate to the kill ring.
+
+ (defun ivy-yank-action (x)
+ (kill-new x))
+
+ (defun ivy-copy-to-buffer-action (x)
+ (with-ivy-window
+ (insert x)))
+
+ (ivy-set-actions
+ t
+ '(("i" ivy-copy-to-buffer-action "insert")
+ ("y" ivy-yank-action "yank")))
+
+ Then in any completion session, ‘M-o y’ invokes ‘ivy-yank-action’,
+and ‘M-o i’ invokes ‘ivy-copy-to-buffer-action’.
+
+* Menu:
+
+* How to undo adding the two actions::
+* How to add actions to a specific command::
+
+
+File: ivy.info, Node: How to undo adding the two actions, Next: How to add actions to a specific command, Up: Example - add two actions to each command
+
+6.3.4.1 How to undo adding the two actions
+..........................................
+
+Since ‘ivy-set-actions’ modifies the internal dictionary with new data,
+set the extra actions list to ‘nil’ by assigning ‘nil’ value to the ‘t’
+key as follows:
+
+ (ivy-set-actions t nil)
+
+
+File: ivy.info, Node: How to add actions to a specific command, Prev: How to undo adding the two actions, Up: Example - add two actions to each command
+
+6.3.4.2 How to add actions to a specific command
+................................................
+
+Use the command name as the key:
+
+ (ivy-set-actions
+ 'swiper
+ '(("i" ivy-copy-to-buffer-action "insert")
+ ("y" ivy-yank-action "yank")))
+
+
+File: ivy.info, Node: Example - define a new command with several actions, Prev: Example - add two actions to each command, Up: Actions
+
+6.3.5 Example - define a new command with several actions
+---------------------------------------------------------
+
+ (defun my-action-1 (x)
+ (message "action-1: %s" x))
+
+ (defun my-action-2 (x)
+ (message "action-2: %s" x))
+
+ (defun my-action-3 (x)
+ (message "action-3: %s" x))
+
+ (defun my-command-with-3-actions ()
+ (interactive)
+ (ivy-read "test: " '("foo" "bar" "baz")
+ :action '(1
+ ("o" my-action-1 "action 1")
+ ("j" my-action-2 "action 2")
+ ("k" my-action-3 "action 3"))))
+
+ The number 1 above is the index of the default action. Each action
+has its own string description for easy selection.
+
+* Menu:
+
+* Test the above function with ivy-occur::
+
+
+File: ivy.info, Node: Test the above function with ivy-occur, Up: Example - define a new command with several actions
+
+6.3.5.1 Test the above function with ‘ivy-occur’
+................................................
+
+To examine each action with each candidate in a key-efficient way, try:
+
+ • Call ‘my-command-with-3-actions’
+ • Press ‘C-c C-o’ to close the completion window and move to an
+ ivy-occur buffer
+ • Press ‘kkk’ to move to the first candidate, since the point is most
+ likely at the end of the buffer
+ • Press ‘oo’ to call the first action
+ • Press ‘oj’ and ‘ok’ to call the second and the third actions
+ • Press ‘j’ to move to the next candidate
+ • Press ‘oo’, ‘oj’, ‘ok’
+ • Press ‘j’ to move to the next candidate
+ • and so on...
+
+
+File: ivy.info, Node: Packages, Prev: Actions, Up: Customization
+
+6.4 Packages
+============
+
+‘org-mode’
+..........
+
+ ‘org-mode’ versions 8.3.3 or later obey ‘completing-read-function’
+ (which ‘ivy-mode’ sets). Try refiling headings with similar names
+ to appreciate ‘ivy-mode’.
+
+‘magit’
+.......
+
+ Uses ivy by default if Ivy is installed.
+
+‘find-file-in-project’
+......................
+
+ Uses ivy by default if Ivy is installed.
+
+‘projectile’
+............
+
+ Projectile requires this setting for ivy completion:
+
+ (setq projectile-completion-system 'ivy)
+
+‘helm-make’
+...........
+
+ Helm-make requires this setting for ivy completion.
+
+ (setq helm-make-completion-method 'ivy)
+
+automatically integrated packages
+.................................
+
+ Ivy re-uses the following packages if they are installed: ‘avy’,
+ ‘amx’ or ‘smex’, ‘flx’, and ‘wgrep’.
+
+
+File: ivy.info, Node: Commands, Next: API, Prev: Customization, Up: Top
+
+7 Commands
+**********
+
+* Menu:
+
+* File Name Completion::
+* Buffer Name Completion::
+* Counsel commands::
+
+
+File: ivy.info, Node: File Name Completion, Next: Buffer Name Completion, Up: Commands
+
+7.1 File Name Completion
+========================
+
+Since file name completion is ubiquitous, Ivy provides extra bindings
+that work here:
+
+‘C-j’ (‘ivy-alt-done’)
+......................
+
+ On a directory, restarts completion from that directory.
+
+ On a file or ‘./’, exit completion with the selected candidate.
+
+‘DEL’ (‘ivy-backward-delete-char’)
+..................................
+
+ Restart the completion in the parent directory if current input is
+ empty.
+
+‘//’ (‘self-insert-command’)
+............................
+
+ Switch to the root directory.
+
+‘~’ (‘self-insert-command’)
+...........................
+
+ Switch to the home directory.
+
+‘/’ (‘self-insert-command’)
+...........................
+
+ If the current input matches an existing directory name exactly,
+ switch the completion to that directory.
+
+‘M-r’ (‘ivy-toggle-regexp-quote’)
+.................................
+
+ Toggle between input as regexp or not.
+
+ Switch to matching literally since file names include ‘.’, which is
+ for matching any char in regexp mode.
+ -- User Option: ivy-extra-directories
+ Decide if you want to see ‘../’ and ‘./’ during file name
+ completion.
+
+ Reason to remove: ‘../’ is the same as ‘DEL’.
+
+ Reason not to remove: navigate anywhere with only ‘C-n’, ‘C-p’ and
+ ‘C-j’.
+
+ Likewise, ‘./’ can be removed.
+
+History
+.......
+
+ File history works the same with ‘M-p’, ‘M-n’, and ‘C-r’, but uses
+ a custom code for file name completion that cycles through files
+ previously opened. It also works with TRAMP files.
+
+* Menu:
+
+* Using TRAMP::
+
+
+File: ivy.info, Node: Using TRAMP, Up: File Name Completion
+
+7.1.1 Using TRAMP
+-----------------
+
+‘~’ (tilde)
+...........
+
+ Move to the home directory. Either the local or the remote one,
+ depending on the current directory. The boolean option
+ ‘ivy-magic-tilde’ decides whether the binding to do this is ‘~’ or
+ ‘~/’.
+
+‘//’ (double slash)
+...................
+
+ Move to the root directory. Either the local or the remote one,
+ depending on the current directory. Here, you can also select a
+ TRAMP connection method, such as ‘ssh’ or ‘scpx’.
+
+‘/ C-j’
+.......
+
+ Move the the local root directory.
+
+‘~~’
+....
+
+ Move to the local home directory.
+
+ From any directory, with the empty input, inputting ‘/ssh:’ and
+pressing ‘C-j’ (or ‘RET’, which is the same thing) completes for host
+and user names.
+
+ For ‘/ssh:user@’ input, completes the domain name.
+
+ ‘C-i’ works in a similar way to the default completion.
+
+ You can also get sudo access for the current directory by inputting
+‘/sudo::’ ‘RET’. Using ‘/sudo:’ (i.e. single colon instead of double)
+will result in a completion session for the desired user.
+
+ Multi-hopping is possible, although a bit complex.
+
+Example : connect to a remote host ‘cloud’ and open a file with ‘sudo’ there
+............................................................................
+
+ • ‘C-x C-f’ ‘/ssh:cloud|sudo:root:/’.
+
+
+File: ivy.info, Node: Buffer Name Completion, Next: Counsel commands, Prev: File Name Completion, Up: Commands
+
+7.2 Buffer Name Completion
+==========================
+
+ -- User Option: ivy-use-virtual-buffers
+ When non-nil, add ‘recentf-mode’ and bookmarks to
+ ‘ivy-switch-buffer’ completion candidates.
+
+ Adding this to Emacs init file:
+
+ (setq ivy-use-virtual-buffers t)
+ will add additional virtual buffers to the buffers list for recent
+ files. Selecting such virtual buffers, which are highlighted with
+ ‘ivy-virtual’ face, will open the corresponding file.
+
+
+File: ivy.info, Node: Counsel commands, Prev: Buffer Name Completion, Up: Commands
+
+7.3 Counsel commands
+====================
+
+The main advantages of ‘counsel-’ functions over their basic equivalents
+in ‘ivy-mode’ are:
+
+ 1. Multi-actions and non-exiting actions work.
+ 2. ‘ivy-resume’ can resume the last completion session.
+ 3. Customize ‘ivy-set-actions’, ‘ivy-re-builders-alist’.
+ 4. Customize individual keymaps, such as ‘counsel-describe-map’,
+ ‘counsel-git-grep-map’, or ‘counsel-find-file-map’, instead of
+ customizing ‘ivy-minibuffer-map’ that applies to all completion
+ sessions.
+
+
+File: ivy.info, Node: API, Next: Variable Index, Prev: Commands, Up: Top
+
+8 API
+*****
+
+The main (and only) entry point is the ‘ivy-read’ function. It takes
+two required arguments and many optional arguments that can be passed by
+a key. The optional ‘:action’ argument is highly recommended for
+features such as multi-actions, non-exiting actions, ‘ivy-occur’ and
+‘ivy-resume’.
+
+* Menu:
+
+* Required arguments for ivy-read::
+* Optional arguments for ivy-read::
+* Example - counsel-describe-function::
+* Example - counsel-locate::
+* Example - ivy-read-with-extra-properties::
+
+
+File: ivy.info, Node: Required arguments for ivy-read, Next: Optional arguments for ivy-read, Up: API
+
+8.1 Required arguments for ‘ivy-read’
+=====================================
+
+‘prompt’
+........
+
+ A prompt string normally ending in a colon and a space.
+ ‘ivy-count-format’ is prepended to it during completion.
+
+‘collection’
+............
+
+ Either a list of strings, a function, an alist or a hash table.
+
+ If a function, then it has to be compatible with ‘all-completions’.
+
+
+File: ivy.info, Node: Optional arguments for ivy-read, Next: Example - counsel-describe-function, Prev: Required arguments for ivy-read, Up: API
+
+8.2 Optional arguments for ‘ivy-read’
+=====================================
+
+‘predicate’
+...........
+
+ Is a function to filter the initial collection. It has to be
+ compatible with ‘all-completions’. Tip: most of the time, it’s
+ simpler to just apply this filter to the ‘collection’ argument
+ itself, e.g. ‘(cl-remove-if-not predicate collection)’.
+
+‘require-match’
+...............
+
+ When set to a non-nil value, input must match one of the
+ candidates. Custom input is not accepted.
+
+‘initial-input’
+...............
+
+ This string argument is included for compatibility with
+ ‘completing-read’, which inserts it into the minibuffer.
+
+ It’s recommended to use the ‘preselect’ argument instead of this.
+
+‘history’
+.........
+
+ Name of the symbol to store history. See ‘completing-read’.
+
+‘preselect’
+...........
+
+ Determines which one of the candidates to initially select.
+
+ When set to an integer value, select the candidate with that index
+ value.
+
+ When set to any other non-nil value, select the first candidate
+ matching this value. Comparison is first done with ‘equal’. If
+ this fails, and when applicable, match ‘preselect’ as a regular
+ expression.
+
+ Every time the input becomes empty, the item corresponding to
+ ‘preselect’ is selected.
+
+‘keymap’
+........
+
+ A keymap to be composed with ‘ivy-minibuffer-map’. This keymap has
+ priority over ‘ivy-minibuffer-map’ and can be modified at any later
+ stage.
+
+‘update-fn’
+...........
+
+ Is the function called each time the current candidate changes.
+ This function takes no arguments and is called in the minibuffer’s
+ ‘post-command-hook’. See ‘swiper’ for an example usage.
+
+‘sort’
+......
+
+ When non-nil, use ‘ivy-sort-functions-alist’ to sort the collection
+ as long as the collection is not larger than ‘ivy-sort-max-size’.
+
+‘action’
+........
+
+ Is the function to call after selection. It takes a string
+ argument.
+
+‘unwind’
+........
+
+ Is the function to call before exiting completion. It takes no
+ arguments. This function is called even if the completion is
+ interrupted with ‘C-g’. See ‘swiper’ for an example usage.
+
+‘re-builder’
+............
+
+ Is a function that takes a string and returns a valid regex. See
+ ‘Completion Styles’ for details.
+
+‘matcher’
+.........
+
+ Is a function that takes a regex string and a list of strings and
+ returns a list of strings matching the regex. Any ordinary Emacs
+ matching function will suffice, yet finely tuned matching functions
+ can be used. See ‘counsel-find-file’ for an example usage.
+
+‘dynamic-collection’
+....................
+
+ When non-nil, ‘collection’ will be used to dynamically generate the
+ candidates each time the input changes, instead of being used once
+ statically with ‘all-completions’ to generate a list of strings.
+ See ‘counsel-locate’ for an example usage.
+
+‘caller’
+........
+
+ Is a symbol that uniquely identifies the function that called
+ ‘ivy-read’, which may be useful for further customizations.
+
+
+File: ivy.info, Node: Example - counsel-describe-function, Next: Example - counsel-locate, Prev: Optional arguments for ivy-read, Up: API
+
+8.3 Example - ‘counsel-describe-function’
+=========================================
+
+This is a typical example of a function with a non-async collection,
+which is a collection where all the strings in the collection are known
+prior to any input from the user.
+
+ Only the first two arguments (along with ‘action’) are essential -
+the rest of the arguments are for fine-tuning, and could be omitted.
+
+ The ‘action’ argument could also be omitted - but then ‘ivy-read’
+would do nothing except returning the string result, which you could
+later use yourself. However, it’s recommended that you use the ‘action’
+argument.
+
+ (defun counsel-describe-function ()
+ "Forward to `describe-function'."
+ (interactive)
+ (ivy-read "Describe function: "
+ (let (cands)
+ (mapatoms
+ (lambda (x)
+ (when (fboundp x)
+ (push (symbol-name x) cands))))
+ cands)
+ :keymap counsel-describe-map
+ :preselect (ivy-thing-at-point)
+ :history 'counsel-describe-symbol-history
+ :require-match t
+ :action (lambda (x)
+ (describe-function
+ (intern x)))
+ :caller 'counsel-describe-function))
+
+ Here are the interesting features of the above function, in the order
+that they appear:
+
+ • The ‘prompt’ argument is a simple string ending in ": ".
+ • The ‘collection’ argument evaluates to a (large) list of strings.
+ • The ‘keymap’ argument is for a custom keymap to supplement
+ ‘ivy-minibuffer-map’.
+ • The ‘preselect’ is provided by ‘ivy-thing-at-point’, which returns
+ a symbol near the point. Ivy then selects the first candidate from
+ the collection that matches this symbol. To select this
+ pre-selected candidate, a ‘RET’ will suffice. No further user
+ input is necessary.
+ • The ‘history’ argument is for keeping the history of this command
+ separate from the common history in ‘ivy-history’.
+ • The ‘require-match’ is set to ‘t’ since it doesn’t make sense to
+ call ‘describe-function’ on an un-interned symbol.
+ • The ‘action’ argument calls ‘describe-function’ on the interned
+ selected candidate.
+ • The ‘caller’ argument identifies this completion session. This is
+ important, since with the collection being a list of strings and
+ not a function name, the only other way for ‘ivy-read’ to identify
+ "who’s calling" and to apply the appropriate customizations is to
+ examine ‘this-command’. But ‘this-command’ would be modified if
+ another command called ‘counsel-describe-function’.
+
+
+File: ivy.info, Node: Example - counsel-locate, Next: Example - ivy-read-with-extra-properties, Prev: Example - counsel-describe-function, Up: API
+
+8.4 Example - ‘counsel-locate’
+==============================
+
+This is a typical example of a function with an async collection. Since
+the collection function cannot pre-compute all the locatable files in
+memory within reasonable limits (time or memory), it relies on user
+input to filter the universe of possible candidates to a manageable size
+while also continuing to search asynchronously for possible candidates.
+Both the filtering and searching continues with each character change of
+the input with rapid updates to the collection presented without idle
+waiting times. This live update will continue as long as there are
+likely candidates. Eventually updates to the minibuffer will stop after
+user input, filtering, and searching have exhausted looking for possible
+candidates.
+
+ Async collections suit long-running shell commands, such as ‘locate’.
+With each new input, a new process starts while the old process is
+killed. The collection is refreshed anew with each new process.
+Meanwhile the user can provide more input characters (for further
+narrowing) or select a candidate from the visible collection.
+
+ (defun counsel-locate-function (str)
+ (or
+ (ivy-more-chars)
+ (progn
+ (counsel--async-command
+ (format "locate %s '%s'"
+ (mapconcat #'identity counsel-locate-options " ")
+ (counsel--elisp-to-pcre
+ (ivy--regex str))))
+ '("" "working..."))))
+
+ ;;;###autoload
+ (defun counsel-locate (&optional initial-input)
+ "Call the \"locate\" shell command.
+ INITIAL-INPUT can be given as the initial minibuffer input."
+ (interactive)
+ (ivy-read "Locate: " #'counsel-locate-function
+ :initial-input initial-input
+ :dynamic-collection t
+ :history 'counsel-locate-history
+ :action (lambda (file)
+ (with-ivy-window
+ (when file
+ (find-file file))))
+ :unwind #'counsel-delete-process
+ :caller 'counsel-locate))
+
+ Here are the interesting features of the above functions, in the
+order that they appear:
+
+ • ‘counsel-locate-function’ takes a string argument and returns a
+ list of strings. Note that it’s not compatible with
+ ‘all-completions’, but since we’re not using that here, might as
+ well use one argument instead of three.
+ • ‘ivy-more-chars’ is a simple function that returns e.g. ‘'("2
+ chars more")’ asking the user for more input.
+ • ‘counsel--async-command’ is a very easy API simplification that
+ takes a single string argument suitable for
+ ‘shell-command-to-string’. So you could prototype your function as
+ non-async using ‘shell-command-to-string’ and ‘split-string’ to
+ produce a collection, then decide that you want async and simply
+ swap in ‘counsel--async-command’.
+ • ‘counsel-locate’ is an interactive function with an optional
+ ‘initial-input’.
+ • ‘#'counsel-locate-function’ is passed as the ‘collection’ argument.
+ • ‘dynamic-collection’ is set to t, since this is an async
+ collection.
+ • ‘action’ argument uses ‘with-ivy-window’ wrapper, since we want to
+ open the selected file in the same window from which
+ ‘counsel-locate’ was called.
+ • ‘unwind’ argument is set to ‘#'counsel-delete-process’: when we
+ press ‘C-g’ we want to kill the running process created by
+ ‘counsel--async-command’.
+ • ‘caller’ argument identifies this command for easier customization.
+
+
+File: ivy.info, Node: Example - ivy-read-with-extra-properties, Prev: Example - counsel-locate, Up: API
+
+8.5 Example - ‘ivy-read-with-extra-properties’
+==============================================
+
+This is another example to show how to associate additional values to
+each displayed strings.
+
+ (defun find-candidates-function (str pred _)
+ (let ((props '(1 2))
+ (strs '("foo" "foo2")))
+ (cl-mapcar (lambda (s p) (propertize s 'property p))
+ strs
+ props)))
+
+ (defun find-candidates ()
+ (interactive)
+ (ivy-read "Find symbols: "
+ #'find-candidates-function
+ :action (lambda (x)
+ (message "Value: %s" (get-text-property 0 'property x)
+ ))))
+
+ Here are the interesting features of the above function:
+
+ • ‘find-candidates-function’ builds up a list of strings and
+ associates "foo" with the value 1 and "foo2" with 2.
+ • ‘find-candidates’ is an interactive function.
+ • ‘#'find-candidates’ is passed as the ‘collection’ argument.
+ • ‘action’ gets passed the selected string with the associated value.
+ It then retrieves that value and displays it.
+
+
+File: ivy.info, Node: Variable Index, Next: Keystroke Index, Prev: API, Up: Top
+
+Variable Index
+**************
+
+ [index ]
+* Menu:
+
+* ivy-alt-done: Key bindings for single selection action then exit minibuffer.
+ (line 30)
+* ivy-alt-done <1>: File Name Completion. (line 12)
+* ivy-avy: Key bindings for single selection action then exit minibuffer.
+ (line 64)
+* ivy-backward-delete-char: File Name Completion. (line 19)
+* ivy-call: Key bindings for multiple selections and actions keep minibuffer open.
+ (line 16)
+* ivy-confirm-face: Faces. (line 34)
+* ivy-count-format: Defcustoms. (line 6)
+* ivy-current-match: Faces. (line 9)
+* ivy-dispatching-call: Key bindings for multiple selections and actions keep minibuffer open.
+ (line 26)
+* ivy-dispatching-done: Key bindings for single selection action then exit minibuffer.
+ (line 24)
+* ivy-display-style: Defcustoms. (line 24)
+* ivy-done: Key bindings for single selection action then exit minibuffer.
+ (line 19)
+* ivy-extra-directories: File Name Completion. (line 45)
+* ivy-height: Key bindings for navigation.
+ (line 21)
+* ivy-immediate-done: Key bindings for single selection action then exit minibuffer.
+ (line 53)
+* ivy-insert-current: Key bindings that alter the minibuffer input.
+ (line 23)
+* ivy-kill-ring-save: Other key bindings. (line 9)
+* ivy-match-required-face: Faces. (line 53)
+* ivy-minibuffer-grow: Hydra in the minibuffer.
+ (line 45)
+* ivy-minibuffer-map: Minibuffer key bindings.
+ (line 6)
+* ivy-minibuffer-match-face-1: Faces. (line 14)
+* ivy-minibuffer-match-face-2: Faces. (line 19)
+* ivy-minibuffer-match-face-3: Faces. (line 24)
+* ivy-minibuffer-match-face-4: Faces. (line 29)
+* ivy-minibuffer-shrink: Hydra in the minibuffer.
+ (line 50)
+* ivy-modified-buffer: Faces. (line 88)
+* ivy-modified-outside-buffer: Faces. (line 93)
+* ivy-next-action: Hydra in the minibuffer.
+ (line 60)
+* ivy-next-history-element: Key bindings that alter the minibuffer input.
+ (line 9)
+* ivy-next-line-and-call: Key bindings for multiple selections and actions keep minibuffer open.
+ (line 36)
+* ivy-occur: Saving the current completion session to a buffer.
+ (line 9)
+* ivy-occur-click: Saving the current completion session to a buffer.
+ (line 21)
+* ivy-occur-dispatch: Saving the current completion session to a buffer.
+ (line 41)
+* ivy-occur-press: Saving the current completion session to a buffer.
+ (line 16)
+* ivy-occur-read-action: Saving the current completion session to a buffer.
+ (line 36)
+* ivy-on-del-error-function: Defcustoms. (line 31)
+* ivy-partial-or-done: Key bindings for single selection action then exit minibuffer.
+ (line 37)
+* ivy-prev-action: Hydra in the minibuffer.
+ (line 55)
+* ivy-previous-history-element: Key bindings that alter the minibuffer input.
+ (line 18)
+* ivy-previous-line-and-call: Key bindings for multiple selections and actions keep minibuffer open.
+ (line 47)
+* ivy-read-action: Hydra in the minibuffer.
+ (line 65)
+* ivy-remote: Faces. (line 71)
+* ivy-restrict-to-matches: Key bindings that alter the minibuffer input.
+ (line 40)
+* ivy-resume: Key bindings for multiple selections and actions keep minibuffer open.
+ (line 55)
+* ivy-reverse-i-search: Key bindings that alter the minibuffer input.
+ (line 48)
+* ivy-rotate-preferred-builders: Hydra in the minibuffer.
+ (line 40)
+* ivy-subdir: Faces. (line 66)
+* ivy-toggle-calling: Hydra in the minibuffer.
+ (line 34)
+* ivy-toggle-case-fold: Hydra in the minibuffer.
+ (line 70)
+* ivy-toggle-regexp-quote: File Name Completion. (line 41)
+* ivy-use-virtual-buffers: Buffer Name Completion.
+ (line 6)
+* ivy-virtual: Faces. (line 76)
+* ivy-wrap: Key bindings for navigation.
+ (line 14)
+* ivy-yank-word: Key bindings that alter the minibuffer input.
+ (line 32)
+
+
+File: ivy.info, Node: Keystroke Index, Prev: Variable Index, Up: Top
+
+Keystroke Index
+***************
+
+ [index ]
+* Menu:
+
+* /: File Name Completion. (line 35)
+* / C-j: Using TRAMP. (line 24)
+* //: File Name Completion. (line 25)
+* // <1>: Using TRAMP. (line 17)
+* <: Hydra in the minibuffer.
+ (line 50)
+* >: Hydra in the minibuffer.
+ (line 45)
+* ~: File Name Completion. (line 30)
+* ~ <1>: Using TRAMP. (line 9)
+* ~~: Using TRAMP. (line 29)
+* a: Hydra in the minibuffer.
+ (line 65)
+* a <1>: Saving the current completion session to a buffer.
+ (line 36)
+* c: Hydra in the minibuffer.
+ (line 34)
+* C: Hydra in the minibuffer.
+ (line 70)
+* C-': Key bindings for single selection action then exit minibuffer.
+ (line 64)
+* C-c C-o: Saving the current completion session to a buffer.
+ (line 9)
+* C-j: Key bindings for single selection action then exit minibuffer.
+ (line 30)
+* C-j <1>: File Name Completion. (line 12)
+* C-m: Key bindings for single selection action then exit minibuffer.
+ (line 19)
+* C-M-j: Key bindings for single selection action then exit minibuffer.
+ (line 53)
+* C-M-m: Key bindings for multiple selections and actions keep minibuffer open.
+ (line 16)
+* C-M-n: Key bindings for multiple selections and actions keep minibuffer open.
+ (line 36)
+* C-M-o: Key bindings for multiple selections and actions keep minibuffer open.
+ (line 26)
+* C-M-p: Key bindings for multiple selections and actions keep minibuffer open.
+ (line 47)
+* C-o: Hydra in the minibuffer.
+ (line 9)
+* C-r: Key bindings that alter the minibuffer input.
+ (line 48)
+* DEL: File Name Completion. (line 19)
+* f: Saving the current completion session to a buffer.
+ (line 16)
+* j: Saving the current completion session to a buffer.
+ (line 26)
+* k: Saving the current completion session to a buffer.
+ (line 31)
+* m: Hydra in the minibuffer.
+ (line 40)
+* M-i: Key bindings that alter the minibuffer input.
+ (line 23)
+* M-j: Key bindings that alter the minibuffer input.
+ (line 32)
+* M-n: Key bindings that alter the minibuffer input.
+ (line 9)
+* M-o: Key bindings for single selection action then exit minibuffer.
+ (line 24)
+* M-p: Key bindings that alter the minibuffer input.
+ (line 18)
+* M-r: File Name Completion. (line 41)
+* M-w: Other key bindings. (line 9)
+* mouse-1: Saving the current completion session to a buffer.
+ (line 21)
+* o: Saving the current completion session to a buffer.
+ (line 41)
+* q: Saving the current completion session to a buffer.
+ (line 46)
+* RET: Key bindings for single selection action then exit minibuffer.
+ (line 19)
+* RET <1>: Saving the current completion session to a buffer.
+ (line 16)
+* s: Hydra in the minibuffer.
+ (line 60)
+* S-SPC: Key bindings that alter the minibuffer input.
+ (line 40)
+* TAB: Key bindings for single selection action then exit minibuffer.
+ (line 37)
+* w: Hydra in the minibuffer.
+ (line 55)
+
+
+
+Tag Table:
+Node: Top1189
+Node: Introduction3100
+Node: Installation5623
+Node: Installing from Emacs Package Manager6073
+Node: Installing from the Git repository7187
+Node: Getting started8007
+Node: Basic customization8314
+Node: Key bindings8909
+Node: Global key bindings9101
+Node: Minibuffer key bindings11575
+Node: Key bindings for navigation12807
+Node: Key bindings for single selection action then exit minibuffer14014
+Node: Key bindings for multiple selections and actions keep minibuffer open16661
+Node: Key bindings that alter the minibuffer input19053
+Node: Other key bindings20998
+Node: Hydra in the minibuffer21376
+Node: Saving the current completion session to a buffer23794
+Node: Completion Styles25206
+Node: ivy--regex-plus26957
+Node: ivy--regex-ignore-order28443
+Node: ivy--regex-fuzzy28811
+Node: Customization29308
+Node: Faces29494
+Node: Defcustoms31923
+Node: Actions33217
+Node: What are actions?33543
+Node: How can different actions be called?34361
+Node: How to modify the actions list?34932
+Node: Example - add two actions to each command35592
+Node: How to undo adding the two actions36551
+Node: How to add actions to a specific command37003
+Node: Example - define a new command with several actions37419
+Node: Test the above function with ivy-occur38307
+Node: Packages39149
+Node: Commands40114
+Node: File Name Completion40299
+Node: Using TRAMP42095
+Node: Buffer Name Completion43597
+Node: Counsel commands44212
+Node: API44859
+Node: Required arguments for ivy-read45457
+Node: Optional arguments for ivy-read45976
+Node: Example - counsel-describe-function49402
+Node: Example - counsel-locate52260
+Node: Example - ivy-read-with-extra-properties56010
+Node: Variable Index57218
+Node: Keystroke Index64265
+
+End Tag Table
+
+
+Local Variables:
+coding: utf-8
+End:
diff --git a/elpa/ivy-20210216.1611/colir.el b/elpa/ivy-20210216.1611/colir.el
new file mode 100644
index 0000000..9e61273
--- /dev/null
+++ b/elpa/ivy-20210216.1611/colir.el
@@ -0,0 +1,124 @@
+;;; colir.el --- Color blending library -*- lexical-binding: t -*-
+
+;; Copyright (C) 2015-2019 Free Software Foundation, Inc.
+
+;; Author: Oleh Krehel
+
+;; This file is part of GNU Emacs.
+
+;; This file is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 3, or (at your option)
+;; any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; For a full copy of the GNU General Public License
+;; see .
+
+;;; Commentary:
+
+;; This package solves the problem of adding a face with a background
+;; to text which may already have a background. In all conflicting
+;; areas, instead of choosing either the original or the new
+;; background face, their blended sum is used.
+;;
+;; The blend mode functions are taken from URL
+;; `https://en.wikipedia.org/wiki/Blend_modes'.
+
+;;; Code:
+
+(require 'cl-lib)
+(require 'color)
+
+(defcustom colir-compose-method #'colir-compose-alpha
+ "Select a method to compose two color channels."
+ :group 'ivy
+ :type '(radio
+ (function-item colir-compose-alpha)
+ (function-item colir-compose-overlay)
+ (function-item colir-compose-soft-light)))
+
+(defun colir-compose-soft-light (a b)
+ "Compose A and B channels."
+ (if (< b 0.5)
+ (+ (* 2 a b) (* a a (- 1 b b)))
+ (+ (* 2 a (- 1 b)) (* (sqrt a) (- (* 2 b) 1)))))
+
+(defun colir-compose-overlay (a b)
+ "Compose A and B channels."
+ (if (< a 0.5)
+ (* 2 a b)
+ (- 1 (* 2 (- 1 a) (- 1 b)))))
+
+(defun colir-compose-alpha (a b &optional alpha gamma)
+ "Compose A and B channels.
+Optional argument ALPHA is a number between 0.0 and 1.0 which corresponds
+to the influence of A on the result. Default value is 0.5.
+Optional argument GAMMA is used for gamma correction. Default value is 2.2."
+ (setq alpha (or alpha 0.5))
+ (setq gamma (or gamma 2.2))
+ (+ (* (expt a gamma) alpha) (* (expt b gamma) (- 1 alpha))))
+
+(defun colir-blend (c1 c2)
+ "Blend the two colors C1 and C2 using `colir-compose-method'.
+C1 and C2 are triples of floats in [0.0 1.0] range."
+ (apply #'color-rgb-to-hex
+ (cl-mapcar
+ (if (eq (frame-parameter nil 'background-mode) 'dark)
+ ;; this method works nicely for dark themes
+ 'colir-compose-soft-light
+ colir-compose-method)
+ c1 c2)))
+
+(defun colir-color-parse (color)
+ "Convert string COLOR to triple of floats in [0.0 1.0]."
+ (if (string-match "#\\([[:xdigit:]]\\{2\\}\\)\\([[:xdigit:]]\\{2\\}\\)\\([[:xdigit:]]\\{2\\}\\)" color)
+ (mapcar (lambda (v) (/ (string-to-number v 16) 255.0))
+ (list (match-string 1 color) (match-string 2 color) (match-string 3 color)))
+ ;; does not work properly in terminal (maps color to nearest color
+ ;; from available color palette).
+ (color-name-to-rgb color)))
+
+(defun colir--blend-background (start next prevn face object)
+ (let ((background-prev (face-background prevn)))
+ (progn
+ (put-text-property
+ start next 'face
+ (if background-prev
+ (cons `(background-color
+ . ,(colir-blend
+ (colir-color-parse background-prev)
+ (colir-color-parse (face-background face nil t))))
+ prevn)
+ (list face prevn))
+ object))))
+
+(defun colir-blend-face-background (start end face &optional object)
+ "Append to the face property of the text from START to END the face FACE.
+When the text already has a face with a non-plain background,
+blend it with the background of FACE.
+Optional argument OBJECT is the string or buffer containing the text.
+See also `font-lock-append-text-property'."
+ (let (next prev prevn)
+ (while (/= start end)
+ (setq next (next-single-property-change start 'face object end))
+ (setq prev (get-text-property start 'face object))
+ (setq prevn (if (listp prev)
+ (cl-find-if #'atom prev)
+ prev))
+ (cond
+ ((or (keywordp (car-safe prev)) (consp (car-safe prev)))
+ (put-text-property start next 'face (cons face prev) object))
+ ((facep prevn)
+ (colir--blend-background start next prevn face object))
+ (t
+ (put-text-property start next 'face face object)))
+ (setq start next))))
+
+(provide 'colir)
+
+;;; colir.el ends here
diff --git a/elpa/ivy-20210216.1611/dir b/elpa/ivy-20210216.1611/dir
new file mode 100644
index 0000000..b68b083
--- /dev/null
+++ b/elpa/ivy-20210216.1611/dir
@@ -0,0 +1,18 @@
+This is the file .../info/dir, which contains the
+topmost node of the Info hierarchy, called (dir)Top.
+The first time you invoke Info you start off looking at this node.
+
+File: dir, Node: Top This is the top of the INFO tree
+
+ This (the Directory node) gives a menu of major topics.
+ Typing "q" exits, "H" lists all Info commands, "d" returns here,
+ "h" gives a primer for first-timers,
+ "mEmacs" visits the Emacs manual, etc.
+
+ In Emacs, you can click mouse button 2 on a menu item or cross reference
+ to select it.
+
+* Menu:
+
+Emacs
+* Ivy: (ivy). Using Ivy for completion.
diff --git a/elpa/ivy-20210216.1611/elpa.el b/elpa/ivy-20210216.1611/elpa.el
new file mode 100644
index 0000000..e49b8d4
--- /dev/null
+++ b/elpa/ivy-20210216.1611/elpa.el
@@ -0,0 +1,6 @@
+(setq package-user-dir
+ (expand-file-name
+ (format "~/.elpa/%s/elpa"
+ (concat emacs-version (when (getenv "MELPA_STABLE") "-stable")))))
+(package-initialize)
+(add-to-list 'load-path default-directory)
diff --git a/elpa/ivy-20210216.1611/ivy-autoloads.el b/elpa/ivy-20210216.1611/ivy-autoloads.el
new file mode 100644
index 0000000..02ec7e5
--- /dev/null
+++ b/elpa/ivy-20210216.1611/ivy-autoloads.el
@@ -0,0 +1,166 @@
+;;; ivy-autoloads.el --- automatically extracted autoloads
+;;
+;;; Code:
+
+(add-to-list 'load-path (directory-file-name
+ (or (file-name-directory #$) (car load-path))))
+
+
+;;;### (autoloads nil "colir" "colir.el" (0 0 0 0))
+;;; Generated autoloads from colir.el
+
+(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "colir" '("colir-")))
+
+;;;***
+
+;;;### (autoloads nil "ivy" "ivy.el" (0 0 0 0))
+;;; Generated autoloads from ivy.el
+
+(autoload 'ivy-resume "ivy" "\
+Resume the last completion session, or SESSION if non-nil.
+With a prefix arg, try to restore a recorded completion session,
+if one exists.
+
+\(fn &optional SESSION)" t nil)
+
+(autoload 'ivy-read "ivy" "\
+Read a string in the minibuffer, with completion.
+
+PROMPT is a string, normally ending in a colon and a space.
+`ivy-count-format' is prepended to PROMPT during completion.
+
+COLLECTION is either a list of strings, a function, an alist, or
+a hash table, supplied for `minibuffer-completion-table'.
+
+PREDICATE is applied to filter out the COLLECTION immediately.
+This argument is for compatibility with `completing-read'.
+
+When REQUIRE-MATCH is non-nil, only members of COLLECTION can be
+selected.
+
+If INITIAL-INPUT is non-nil, then insert that input in the
+minibuffer initially.
+
+HISTORY is a name of a variable to hold the completion session
+history.
+
+KEYMAP is composed with `ivy-minibuffer-map'.
+
+PRESELECT, when non-nil, determines which one of the candidates
+matching INITIAL-INPUT to select initially. An integer stands
+for the position of the desired candidate in the collection,
+counting from zero. Otherwise, use the first occurrence of
+PRESELECT in the collection. Comparison is first done with
+`equal'. If that fails, and when applicable, match PRESELECT as
+a regular expression.
+
+DEF is for compatibility with `completing-read'.
+
+UPDATE-FN is called each time the candidate list is re-displayed.
+
+When SORT is non-nil, `ivy-sort-functions-alist' determines how
+to sort candidates before displaying them.
+
+ACTION is a function to call after selecting a candidate.
+It takes one argument, the selected candidate. If COLLECTION is
+an alist, the argument is a cons cell, otherwise it's a string.
+
+MULTI-ACTION, when non-nil, is called instead of ACTION when
+there are marked candidates. It takes the list of candidates as
+its only argument. When it's nil, ACTION is called on each marked
+candidate.
+
+UNWIND is a function of no arguments to call before exiting.
+
+RE-BUILDER is a function transforming input text into a regex
+pattern.
+
+MATCHER is a function which can override how candidates are
+filtered based on user input. It takes a regex pattern and a
+list of candidates, and returns the list of matching candidates.
+
+DYNAMIC-COLLECTION is a boolean specifying whether the list of
+candidates is updated after each input by calling COLLECTION.
+
+EXTRA-PROPS is a plist that can be used to store
+collection-specific session-specific data.
+
+CALLER is a symbol to uniquely identify the caller to `ivy-read'.
+It is used, along with COLLECTION, to determine which
+customizations apply to the current completion session.
+
+\(fn PROMPT COLLECTION &key PREDICATE REQUIRE-MATCH INITIAL-INPUT HISTORY PRESELECT DEF KEYMAP UPDATE-FN SORT ACTION MULTI-ACTION UNWIND RE-BUILDER MATCHER DYNAMIC-COLLECTION EXTRA-PROPS CALLER)" nil nil)
+
+(autoload 'ivy-completing-read "ivy" "\
+Read a string in the minibuffer, with completion.
+
+This interface conforms to `completing-read' and can be used for
+`completing-read-function'.
+
+PROMPT is a string that normally ends in a colon and a space.
+COLLECTION is either a list of strings, an alist, an obarray, or a hash table.
+PREDICATE limits completion to a subset of COLLECTION.
+REQUIRE-MATCH is a boolean value or a symbol. See `completing-read'.
+INITIAL-INPUT is a string inserted into the minibuffer initially.
+HISTORY is a list of previously selected inputs.
+DEF is the default value.
+INHERIT-INPUT-METHOD is currently ignored.
+
+\(fn PROMPT COLLECTION &optional PREDICATE REQUIRE-MATCH INITIAL-INPUT HISTORY DEF INHERIT-INPUT-METHOD)" nil nil)
+
+(defvar ivy-mode nil "\
+Non-nil if Ivy mode is enabled.
+See the `ivy-mode' command
+for a description of this minor mode.
+Setting this variable directly does not take effect;
+either customize it (see the info node `Easy Customization')
+or call the function `ivy-mode'.")
+
+(custom-autoload 'ivy-mode "ivy" nil)
+
+(autoload 'ivy-mode "ivy" "\
+Toggle Ivy mode on or off.
+Turn Ivy mode on if ARG is positive, off otherwise.
+Turning on Ivy mode sets `completing-read-function' to
+`ivy-completing-read'.
+
+Global bindings:
+\\{ivy-mode-map}
+
+Minibuffer bindings:
+\\{ivy-minibuffer-map}
+
+\(fn &optional ARG)" t nil)
+
+(autoload 'ivy-switch-buffer "ivy" "\
+Switch to another buffer." t nil)
+
+(autoload 'ivy-switch-view "ivy" "\
+Switch to one of the window views stored by `ivy-push-view'." t nil)
+
+(autoload 'ivy-switch-buffer-other-window "ivy" "\
+Switch to another buffer in another window." t nil)
+
+(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "ivy" '("ivy-" "with-ivy-window")))
+
+;;;***
+
+;;;### (autoloads nil "ivy-overlay" "ivy-overlay.el" (0 0 0 0))
+;;; Generated autoloads from ivy-overlay.el
+
+(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "ivy-overlay" '("ivy-")))
+
+;;;***
+
+;;;### (autoloads nil nil ("elpa.el" "ivy-faces.el" "ivy-pkg.el")
+;;;;;; (0 0 0 0))
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; coding: utf-8
+;; End:
+;;; ivy-autoloads.el ends here
diff --git a/elpa/ivy-20210216.1611/ivy-faces.el b/elpa/ivy-20210216.1611/ivy-faces.el
new file mode 100644
index 0000000..54492c4
--- /dev/null
+++ b/elpa/ivy-20210216.1611/ivy-faces.el
@@ -0,0 +1,138 @@
+;;; ivy-faces.el --- Faces for Ivy -*- lexical-binding: t -*-
+
+;; Copyright (C) 2020 Free Software Foundation, Inc.
+
+;; Author: Oleh Krehel
+;; Keywords: convenience
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program. If not, see .
+
+;;; Commentary:
+
+;;; Code:
+
+(defgroup ivy-faces nil
+ "Font-lock faces for `ivy'."
+ :group 'ivy
+ :group 'faces)
+
+(defface ivy-current-match
+ '((((class color) (background light))
+ :background "#1a4b77" :foreground "white" :extend t)
+ (((class color) (background dark))
+ :background "#65a7e2" :foreground "black" :extend t))
+ "Face used by Ivy for highlighting the current match.")
+
+(defface ivy-minibuffer-match-highlight
+ '((t :inherit highlight))
+ "Face used by Ivy for highlighting the match under the cursor.")
+
+(defface ivy-minibuffer-match-face-1
+ '((((class color) (background light))
+ :background "#d3d3d3")
+ (((class color) (background dark))
+ :background "#555555"))
+ "The background face for `ivy' minibuffer matches.")
+
+(defface ivy-minibuffer-match-face-2
+ '((((class color) (background light))
+ :background "#e99ce8" :weight bold)
+ (((class color) (background dark))
+ :background "#777777" :weight bold))
+ "Face for `ivy' minibuffer matches numbered 1 modulo 3.")
+
+(defface ivy-minibuffer-match-face-3
+ '((((class color) (background light))
+ :background "#bbbbff" :weight bold)
+ (((class color) (background dark))
+ :background "#7777ff" :weight bold))
+ "Face for `ivy' minibuffer matches numbered 2 modulo 3.")
+
+(defface ivy-minibuffer-match-face-4
+ '((((class color) (background light))
+ :background "#ffbbff" :weight bold)
+ (((class color) (background dark))
+ :background "#8a498a" :weight bold))
+ "Face for `ivy' minibuffer matches numbered 3 modulo 3.")
+
+(defface ivy-confirm-face
+ '((t :foreground "ForestGreen" :inherit minibuffer-prompt))
+ "Face used by Ivy for a confirmation prompt.")
+
+(defface ivy-match-required-face
+ '((t :foreground "red" :inherit minibuffer-prompt))
+ "Face used by Ivy for a match required prompt.")
+
+(defface ivy-subdir
+ '((t :inherit dired-directory))
+ "Face used by Ivy for highlighting subdirs in the alternatives.")
+
+(defface ivy-org
+ '((t :inherit org-level-4))
+ "Face used by Ivy for highlighting Org buffers in the alternatives.")
+
+(defface ivy-modified-buffer
+ '((t :inherit default))
+ "Face used by Ivy for highlighting modified file visiting buffers.")
+
+(defface ivy-modified-outside-buffer
+ '((t :inherit default))
+ "Face used by Ivy for highlighting file visiting buffers modified outside Emacs.")
+
+(defface ivy-remote
+ '((((class color) (background light))
+ :foreground "#110099")
+ (((class color) (background dark))
+ :foreground "#7B6BFF"))
+ "Face used by Ivy for highlighting remotes in the alternatives.")
+
+(defface ivy-virtual
+ '((t :inherit font-lock-builtin-face))
+ "Face used by Ivy for matching virtual buffer names.")
+
+(defface ivy-action
+ '((t :inherit font-lock-builtin-face))
+ "Face used by Ivy for displaying keys in `ivy-read-action'.")
+
+(defface ivy-highlight-face
+ '((t :inherit highlight))
+ "Face used by Ivy to highlight certain candidates.")
+
+(defface ivy-prompt-match
+ '((t :inherit ivy-current-match))
+ "Face used by Ivy for highlighting the selected prompt line.")
+
+(defface ivy-separator
+ '((t :inherit font-lock-doc-face))
+ "Face for multiline source separator.")
+
+(defface ivy-grep-info
+ '((t :inherit compilation-info))
+ "Face for highlighting grep information such as file names.")
+
+(defface ivy-grep-line-number
+ '((t :inherit compilation-line-number))
+ "Face for displaying line numbers in grep messages.")
+
+(defface ivy-completions-annotations
+ '((t :inherit completions-annotations))
+ "Face for displaying completion annotations.")
+
+(defface ivy-yanked-word
+ '((t :inherit highlight))
+ "Face used to highlight yanked word.")
+
+(provide 'ivy-faces)
+
+;;; ivy-faces.el ends here
diff --git a/elpa/ivy-20210216.1611/ivy-help.org b/elpa/ivy-20210216.1611/ivy-help.org
new file mode 100644
index 0000000..3a94118
--- /dev/null
+++ b/elpa/ivy-20210216.1611/ivy-help.org
@@ -0,0 +1,138 @@
+* Ivy Generic Help
+
+=ivy= is an Emacs incremental completion framework.
+
+- Narrow the list by typing some pattern,
+- Multiple patterns are allowed by separating with a space,
+- Select with ~C-n~ and ~C-p~, choose with ~RET~.
+
+** Help
+
+- ~C-h m~ :: Pop to this generic help buffer.
+
+** Basic Operations
+*** Key bindings for navigation
+
+- ~C-n~ (=ivy-next-line=) :: next candidate.
+- ~C-p~ (=ivy-previous-line=) :: previous candidate.
+- ~C-v~ (=ivy-scroll-up-command=) :: next page.
+- ~M-v~ (=ivy-scroll-down-command=) :: previous page.
+- ~M-<~ (=ivy-beginning-of-buffer=) :: first candidate.
+- ~M->~ (=ivy-end-of-buffer=) :: last candidate.
+
+*** Key bindings for single selection
+
+When selecting a candidate, an action is called on it. You can think
+of an action as a function that takes the selected candidate as an
+argument and does something with it.
+
+Ivy can offer several actions from which to choose. This can be
+independently composed with whether you want to end completion when
+the action is called. Depending on this, the short term is either
+"calling an action" or "exiting with action".
+
+~C-m~ or ~RET~ (=ivy-done=) - exit with the current action.
+
+~M-o~ (=ivy-dispatching-done=) - select an action and exit with it.
+
+~C-j~ (=ivy-alt-done=) - when the candidate is a directory, enter
+it. Otherwise, exit with the current action.
+
+~TAB~ (=ivy-partial-or-done=) - attempt partial completion, extending
+the current input as much as possible. ~TAB TAB~ is the same as ~C-j~.
+
+~C-M-j~ (=ivy-immediate-done=) - exit with the current action, calling
+it on the /current input/ instead of the current candidate. This is
+useful especially when creating new files or directories - often the
+input will match an existing file, which you don't want to select.
+
+~C-'~ (=ivy-avy=) - select a candidate from the current page with avy
+and exit with the current action.
+
+** Advanced Operations
+*** Key bindings for multiple selection
+
+For repeatedly applying multiple actions or acting on multiple
+candidates, Ivy does not close the minibuffer between commands. It
+keeps the minibuffer open for applying subsequent actions.
+
+Adding an extra meta key to the normal key chord invokes the special
+version of the regular commands that enables applying multiple
+actions.
+
+~C-M-m~ (=ivy-call=) is the non-exiting version of ~C-m~ (=ivy-done=).
+
+~C-M-n~ (=ivy-next-line-and-call=) combines ~C-n~ and ~C-M-m~.
+
+~C-M-p~ (=ivy-previous-line-and-call=) combines ~C-p~ and ~C-M-m~.
+
+~C-M-o~ (=ivy-dispatching-call=) is a non-exiting version of ~M-o~
+(=ivy-dispatching-done=).
+
+*** Key bindings that alter the minibuffer input
+
+~M-n~ (=ivy-next-history-element=) select the next history element or
+symbol/URL at point.
+
+~M-p~ (=ivy-previous-history-element=) select the previous history
+element.
+
+~C-r~ (=ivy-reverse-i-search=) start a recursive completion session to
+select a history element.
+
+~M-i~ (=ivy-insert-current=) insert the current candidate into the
+minibuffer. Useful for copying and renaming files, for example: ~M-i~
+to insert the original file name string, edit it, and then ~C-m~ to
+complete the renaming.
+
+~M-j~ (=ivy-yank-word=) insert the sub-word at point into the
+minibuffer.
+
+~S-SPC~ (=ivy-restrict-to-matches=) deletes the current input, and
+resets the candidates list to the currently restricted matches. This
+is how Ivy provides narrowing in successive tiers.
+
+*** Other key bindings
+
+~M-w~ (=ivy-kill-ring-save=) copies the selected candidates to the
+kill ring; when the region is active, copies the active region.
+
+*** Saving the current completion session to a buffer
+
+~C-c C-o~ (=ivy-occur=) saves the current candidates to a new buffer;
+the list is active in the new buffer.
+
+~RET~ or ~mouse-1~ in the new buffer calls the appropriate action on
+the selected candidate.
+
+Ivy has no limit on the number of active buffers like these.
+
+Ivy takes care of making these buffer names unique. It applies
+descriptive names, for example: =*ivy-occur counsel-describe-variable
+"function$*=.
+
+*** Global key bindings
+
+=ivy-resume= recalls the state of the completion session just before
+its last exit. Useful after an accidental ~C-m~ (=ivy-done=).
+Recommended global binding: ~C-c C-r~.
+
+*** Hydra in the minibuffer
+
+~C-o~ (=hydra-ivy/body=) invokes Hydra menus with key shortcuts.
+
+When in Hydra, ~C-o~ or ~i~ resumes editing.
+
+Hydra reduces key strokes, for example: ~C-n C-n C-n C-n~ is ~C-o
+jjjj~ in Hydra. Besides certain shorter keys, Hydra shows useful info
+such as case folding and the current action.
+
+Additionally, here are the keys that are otherwise not bound:
+
+- ~<~ and ~>~ adjust the height of the minibuffer.
+- ~c~ (=ivy-toggle-calling=) - toggle calling the current action each
+ time a different candidate is selected.
+- ~M~ (=ivy-rotate-preferred-builders=) - rotate regex matcher.
+- ~w~ and ~s~ scroll the actions list.
+
+Minibuffer editing is disabled when Hydra is active.
diff --git a/elpa/ivy-20210216.1611/ivy-overlay.el b/elpa/ivy-20210216.1611/ivy-overlay.el
new file mode 100644
index 0000000..ed77fc0
--- /dev/null
+++ b/elpa/ivy-20210216.1611/ivy-overlay.el
@@ -0,0 +1,155 @@
+;;; ivy-overlay.el --- Overlay display functions for Ivy -*- lexical-binding: t -*-
+
+;; Copyright (C) 2016-2019 Free Software Foundation, Inc.
+
+;; Author: Oleh Krehel
+;; Keywords: convenience
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program. If not, see .
+
+;;; Commentary:
+
+;; This package allows to setup Ivy's completion at point to actually
+;; show the candidates and the input at point, instead of in the
+;; minibuffer.
+
+;;; Code:
+
+(eval-when-compile
+ (require 'subr-x))
+
+(defface ivy-cursor
+ '((((class color) (background light))
+ :background "black" :foreground "white")
+ (((class color) (background dark))
+ :background "white" :foreground "black"))
+ "Cursor face for inline completion."
+ :group 'ivy-faces)
+
+(defvar ivy--old-cursor-type t)
+
+(defvar ivy-overlay-at nil
+ "Overlay variable for `ivy-display-function-overlay'.")
+
+(declare-function ivy--truncate-string "ivy")
+
+(defun ivy-left-pad (str width)
+ "Return STR, but with each line indented by WIDTH spaces.
+Lines are truncated to the window width."
+ (let ((padding (make-string width ?\s)))
+ (mapconcat (lambda (x)
+ (ivy--truncate-string (concat padding x)
+ (1- (+ (window-width)
+ (window-hscroll)))))
+ (split-string str "\n")
+ "\n")))
+
+(defun ivy-overlay-cleanup ()
+ "Clean up after `ivy-display-function-overlay'."
+ (when (overlayp ivy-overlay-at)
+ (delete-overlay ivy-overlay-at)
+ (setq ivy-overlay-at nil))
+ (unless cursor-type
+ (setq cursor-type ivy--old-cursor-type))
+ (when (fboundp 'company-abort)
+ (company-abort)))
+
+(defvar ivy-height)
+
+(defun ivy-overlay-show-after (str)
+ "Display STR in an overlay at point.
+
+First, fill each line of STR with spaces to the current column.
+Then attach the overlay to the character before point."
+ (if ivy-overlay-at
+ (progn
+ (move-overlay ivy-overlay-at (1- (point)) (line-end-position))
+ (overlay-put ivy-overlay-at 'invisible nil))
+ (let ((available-height (- (window-height) (count-lines (window-start) (point)) 1)))
+ (unless (>= available-height ivy-height)
+ (recenter (- (window-height) ivy-height 2))))
+ (setq ivy-overlay-at (make-overlay (1- (point)) (line-end-position)))
+ ;; Specify face to avoid clashing with other overlays.
+ (overlay-put ivy-overlay-at 'face 'default)
+ (overlay-put ivy-overlay-at 'priority 9999))
+ (overlay-put ivy-overlay-at 'display str)
+ (overlay-put ivy-overlay-at 'after-string ""))
+
+(declare-function org-current-level "org")
+(declare-function org-at-heading-p "org")
+(defvar org-indent-indentation-per-level)
+(defvar ivy-height)
+(defvar ivy-last)
+(defvar ivy-text)
+(defvar ivy-completion-beg)
+(declare-function ivy--get-window "ivy")
+(declare-function ivy-state-current "ivy")
+(declare-function ivy-state-window "ivy")
+
+(defun ivy-overlay-impossible-p (_str)
+ (or
+ (and (eq major-mode 'org-mode)
+ (plist-get (text-properties-at (point)) 'src-block))
+ (<= (window-height) (+ ivy-height 2))
+ (= (point) (point-min))
+ (< (- (+ (window-width) (window-hscroll)) (current-column))
+ 30)))
+
+(defun ivy-display-function-overlay (str)
+ "Called from the minibuffer, display STR in an overlay in Ivy window.
+Hide the minibuffer contents and cursor."
+ (if (save-selected-window
+ (select-window (ivy-state-window ivy-last))
+ (ivy-overlay-impossible-p str))
+ (let ((buffer-undo-list t))
+ (save-excursion
+ (forward-line 1)
+ (insert str)))
+ (add-face-text-property (minibuffer-prompt-end) (point-max)
+ '(:foreground "white"))
+ (setq cursor-type nil)
+ (with-selected-window (ivy--get-window ivy-last)
+ (when cursor-type
+ (setq ivy--old-cursor-type cursor-type))
+ (setq cursor-type nil)
+ (let ((overlay-str
+ (apply
+ #'concat
+ (buffer-substring (max (point-min) (1- (point))) (point))
+ ivy-text
+ (and (eolp) " ")
+ (buffer-substring (point) (line-end-position))
+ (and (> (length str) 0)
+ (list "\n"
+ (ivy-left-pad
+ (string-remove-prefix "\n" str)
+ (+
+ (if (and (eq major-mode 'org-mode)
+ (bound-and-true-p org-indent-mode))
+ (if (org-at-heading-p)
+ (1- (org-current-level))
+ (* org-indent-indentation-per-level (or (org-current-level) 1)))
+ 0)
+ (save-excursion
+ (when ivy-completion-beg
+ (goto-char ivy-completion-beg))
+ (current-column)))))))))
+ (let ((cursor-offset (1+ (length ivy-text))))
+ (add-face-text-property cursor-offset (1+ cursor-offset)
+ 'ivy-cursor t overlay-str))
+ (ivy-overlay-show-after overlay-str)))))
+
+(provide 'ivy-overlay)
+
+;;; ivy-overlay.el ends here
diff --git a/elpa/ivy-20210216.1611/ivy-pkg.el b/elpa/ivy-20210216.1611/ivy-pkg.el
new file mode 100644
index 0000000..a188e20
--- /dev/null
+++ b/elpa/ivy-20210216.1611/ivy-pkg.el
@@ -0,0 +1,12 @@
+(define-package "ivy" "20210216.1611" "Incremental Vertical completYon"
+ '((emacs "24.5"))
+ :commit "0965e2375e2539fcc62b44b7b8f680d40c0b535a" :authors
+ '(("Oleh Krehel" . "ohwoeowho@gmail.com"))
+ :maintainer
+ '("Oleh Krehel" . "ohwoeowho@gmail.com")
+ :keywords
+ '("matching")
+ :url "https://github.com/abo-abo/swiper")
+;; Local Variables:
+;; no-byte-compile: t
+;; End:
diff --git a/elpa/ivy-20210216.1611/ivy.el b/elpa/ivy-20210216.1611/ivy.el
new file mode 100644
index 0000000..2c670e6
--- /dev/null
+++ b/elpa/ivy-20210216.1611/ivy.el
@@ -0,0 +1,5295 @@
+;;; ivy.el --- Incremental Vertical completYon -*- lexical-binding: t -*-
+
+;; Copyright (C) 2015-2020 Free Software Foundation, Inc.
+
+;; Author: Oleh Krehel
+;; URL: https://github.com/abo-abo/swiper
+;; Version: 0.13.0
+;; Package-Requires: ((emacs "24.5"))
+;; Keywords: matching
+
+;; This file is part of GNU Emacs.
+
+;; This file is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 3, or (at your option)
+;; any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; For a full copy of the GNU General Public License
+;; see .
+
+;;; Commentary:
+
+;; This package provides `ivy-read' as an alternative to
+;; `completing-read' and similar functions.
+;;
+;; There's no intricate code to determine the best candidate.
+;; Instead, the user can navigate to it with `ivy-next-line' and
+;; `ivy-previous-line'.
+;;
+;; The matching is done by splitting the input text by spaces and
+;; re-building it into a regex.
+;; So "for example" is transformed into "\\(for\\).*\\(example\\)".
+
+;;; Code:
+
+(require 'colir)
+(require 'ivy-overlay)
+(require 'ivy-faces)
+
+(require 'cl-lib)
+(require 'ring)
+
+(eval-when-compile
+ (require 'subr-x))
+
+;;* Customization
+(defgroup ivy nil
+ "Incremental vertical completion."
+ :group 'convenience)
+
+(defcustom ivy-height 10
+ "Number of lines for the minibuffer window.
+
+See also `ivy-height-alist'."
+ :type 'integer)
+
+(defcustom ivy-count-format "%-4d "
+ "The style to use for displaying the current candidate count for `ivy-read'.
+Set this to \"\" to suppress the count visibility.
+Set this to \"(%d/%d) \" to display both the index and the count."
+ :type '(choice
+ (const :tag "Count disabled" "")
+ (const :tag "Count matches" "%-4d ")
+ (const :tag "Count matches and show current match" "(%d/%d) ")
+ string))
+
+(defcustom ivy-pre-prompt-function nil
+ "When non-nil, add strings before the `ivy-read' prompt."
+ :type '(choice
+ (const :tag "Do nothing" nil)
+ (function :tag "Custom function")))
+
+(defcustom ivy-add-newline-after-prompt nil
+ "When non-nil, add a newline after the `ivy-read' prompt."
+ :type 'boolean)
+
+(defcustom ivy-wrap nil
+ "When non-nil, wrap around after the first and the last candidate."
+ :type 'boolean)
+
+(defcustom ivy-display-style 'fancy
+ "The style for formatting the minibuffer.
+
+By default, the matched strings are copied as is.
+
+The fancy display style highlights matching parts of the regexp,
+a behavior similar to `swiper'."
+ :type '(choice
+ (const :tag "Plain" nil)
+ (const :tag "Fancy" fancy)))
+
+(defcustom ivy-on-del-error-function #'abort-recursive-edit
+ "Function to call when deletion fails during completion.
+The usual reason for `ivy-backward-delete-char' to fail is when
+there is no text left to delete, i.e., when it is called at the
+beginning of the minibuffer.
+The default setting provides a quick exit from completion.
+Another common option is `ignore', which does nothing."
+ :type '(choice
+ (const :tag "Exit completion" abort-recursive-edit)
+ (const :tag "Do nothing" ignore)
+ (function :tag "Custom function")))
+
+(defcustom ivy-extra-directories '("../" "./")
+ "Add this to the front of the list when completing file names.
+Only \"./\" and \"../\" apply here. They appear in reverse order."
+ :type '(repeat :tag "Dirs"
+ (choice
+ (const :tag "Parent Directory" "../")
+ (const :tag "Current Directory" "./"))))
+
+(defcustom ivy-use-virtual-buffers nil
+ "When non-nil, add recent files and/or bookmarks to `ivy-switch-buffer'.
+The value `recentf' includes only recent files to the virtual
+buffers list, whereas the value `bookmarks' does the same for
+bookmarks. Any other non-nil value includes both."
+ :type '(choice
+ (const :tag "Don't use virtual buffers" nil)
+ (const :tag "Recent files" recentf)
+ (const :tag "Bookmarks" bookmarks)
+ (const :tag "All virtual buffers" t)))
+
+(defvar ivy--display-function nil
+ "The display-function is used in current.")
+
+(defvar ivy-display-functions-props
+ '((ivy-display-function-overlay :cleanup ivy-overlay-cleanup))
+ "Map Ivy display functions to their property lists.
+Examples of properties include associated `:cleanup' functions.")
+
+(defcustom ivy-display-functions-alist
+ '((ivy-completion-in-region . ivy-display-function-overlay)
+ (t . nil))
+ "An alist for customizing where to display the candidates.
+
+Each key is a caller symbol. When the value is nil (the default),
+the candidates are shown in the minibuffer. Otherwise, the value
+is a function which takes a string argument comprising the
+current matching candidates and displays it somewhere.
+
+See also `https://github.com/abo-abo/swiper/wiki/ivy-display-function'."
+ :type '(alist
+ :key-type symbol
+ :value-type (choice
+ (const :tag "Minibuffer" nil)
+ (const :tag "LV" ivy-display-function-lv)
+ (const :tag "Popup" ivy-display-function-popup)
+ (const :tag "Overlay" ivy-display-function-overlay)
+ (function :tag "Custom function"))))
+
+(defvar ivy-completing-read-dynamic-collection nil
+ "Run `ivy-completing-read' with `:dynamic-collection t`.")
+
+(defcustom ivy-completing-read-handlers-alist
+ '((tmm-menubar . completing-read-default)
+ (tmm-shortcut . completing-read-default)
+ (bbdb-create . ivy-completing-read-with-empty-string-def)
+ (auto-insert . ivy-completing-read-with-empty-string-def)
+ (Info-on-current-buffer . ivy-completing-read-with-empty-string-def)
+ (Info-follow-reference . ivy-completing-read-with-empty-string-def)
+ (Info-menu . ivy-completing-read-with-empty-string-def)
+ (Info-index . ivy-completing-read-with-empty-string-def)
+ (Info-virtual-index . ivy-completing-read-with-empty-string-def)
+ (info-display-manual . ivy-completing-read-with-empty-string-def))
+ "An alist of handlers to replace `completing-read' in `ivy-mode'."
+ :type '(alist :key-type symbol :value-type function))
+
+(defcustom ivy-height-alist nil
+ "An alist to customize `ivy-height'.
+
+It is a list of (CALLER . HEIGHT). CALLER is a caller of
+`ivy-read' and HEIGHT is the number of lines displayed.
+HEIGHT can also be a function that returns the number of lines."
+ :type '(alist
+ :key-type function
+ :value-type (choice integer function)))
+
+(defvar ivy-completing-read-ignore-handlers-depth -1
+ "Used to avoid infinite recursion.
+
+If `(minibuffer-depth)' equals this, `ivy-completing-read' will
+act as if `ivy-completing-read-handlers-alist' is empty.")
+
+(defvar ivy-highlight-grep-commands nil
+ "List of grep-like commands.")
+
+(defvar ivy--actions-list nil
+ "A list of extra actions per command.")
+
+(defun ivy-set-actions (cmd actions)
+ "Set CMD extra exit points to ACTIONS."
+ (setq ivy--actions-list
+ (plist-put ivy--actions-list cmd actions)))
+
+(defun ivy-add-actions (cmd actions)
+ "Add extra exit points ACTIONS to CMD.
+Existing exit points of CMD are overwritten by those in
+ACTIONS that have the same key."
+ (setq ivy--actions-list
+ (plist-put ivy--actions-list cmd
+ (cl-delete-duplicates
+ (append (plist-get ivy--actions-list cmd) actions)
+ :key #'car :test #'equal))))
+
+(defun ivy--compute-extra-actions (action caller)
+ "Add extra actions to ACTION based on CALLER."
+ (let* ((extra-actions (cl-delete-duplicates
+ (append (plist-get ivy--actions-list t)
+ (plist-get ivy--actions-list this-command)
+ (plist-get ivy--actions-list caller))
+ :key #'car :test #'equal))
+ (override-default (assoc "o" extra-actions)))
+ (cond (override-default
+ (cons 1 (cons override-default
+ (cl-delete "o" extra-actions
+ :key #'car :test #'equal))))
+ ((not extra-actions)
+ action)
+ ((functionp action)
+ `(1
+ ("o" ,action "default")
+ ,@extra-actions))
+ ((null action)
+ `(1
+ ("o" identity "default")
+ ,@extra-actions))
+ (t
+ (cons (car action)
+ (cl-delete-duplicates (cdr (append action extra-actions))
+ :key #'car :test #'equal :from-end t))))))
+
+(defvar ivy--prompts-list nil)
+
+(defun ivy-set-prompt (caller prompt-fn)
+ "Associate CALLER with PROMPT-FN.
+PROMPT-FN is a function of no arguments that returns a prompt string."
+ (setq ivy--prompts-list
+ (plist-put ivy--prompts-list caller prompt-fn)))
+
+(defvar ivy--display-transformers-alist nil
+ "A list of str->str transformers per command.")
+
+(defun ivy-set-display-transformer (cmd transformer)
+ "Set CMD a displayed candidate TRANSFORMER.
+
+It's a lambda that takes a string one of the candidates in the
+collection and returns a string for display, the same candidate
+plus some extra information.
+
+This lambda is called only on the `ivy-height' candidates that
+are about to be displayed, not on the whole collection."
+ (declare (obsolete "Use `ivy-configure' :display-transformer-fn" "<2020-05-20 Wed>"))
+ (ivy--alist-set 'ivy--display-transformers-alist cmd transformer))
+
+(defvar ivy--sources-list nil
+ "A list of extra sources per command.")
+
+(defun ivy-set-sources (cmd sources)
+ "Attach to CMD a list of extra SOURCES.
+
+Each static source is a function that takes no argument and
+returns a list of strings.
+
+The (original-source) determines the position of the original
+dynamic source.
+
+Extra dynamic sources aren't supported yet.
+
+Example:
+
+ (defun small-recentf ()
+ (cl-subseq recentf-list 0 20))
+
+ (ivy-set-sources
+ 'counsel-locate
+ '((small-recentf)
+ (original-source)))"
+ (setq ivy--sources-list
+ (plist-put ivy--sources-list cmd sources)))
+
+(defun ivy--compute-extra-candidates (caller)
+ (let ((extra-sources (or (plist-get ivy--sources-list caller)
+ '((original-source))))
+ (result nil))
+ (dolist (source extra-sources)
+ (cond ((equal source '(original-source))
+ (push source result))
+ ((null (cdr source))
+ (push (list (car source) (funcall (car source))) result))))
+ result))
+
+(defvar ivy-current-prefix-arg nil
+ "Prefix arg to pass to actions.
+This is a global variable that is set by ivy functions for use in
+action functions.")
+
+;;* Keymap
+(require 'delsel)
+(defun ivy-define-key (keymap key def)
+ "Forward to (`define-key' KEYMAP KEY DEF).
+Remove DEF from `counsel-M-x' list."
+ (put def 'no-counsel-M-x t)
+ (define-key keymap key def))
+
+(defvar ivy-minibuffer-map
+ (let ((map (make-sparse-keymap)))
+ (ivy-define-key map (kbd "C-m") 'ivy-done)
+ (define-key map [down-mouse-1] 'ignore)
+ (ivy-define-key map [mouse-1] 'ivy-mouse-done)
+ (ivy-define-key map [mouse-3] 'ivy-mouse-dispatching-done)
+ (ivy-define-key map (kbd "C-M-m") 'ivy-call)
+ (ivy-define-key map (kbd "C-j") 'ivy-alt-done)
+ (ivy-define-key map (kbd "C-M-j") 'ivy-immediate-done)
+ (ivy-define-key map (kbd "TAB") 'ivy-partial-or-done)
+ (ivy-define-key map [remap next-line] 'ivy-next-line)
+ (ivy-define-key map [remap previous-line] 'ivy-previous-line)
+ (ivy-define-key map (kbd "C-r") 'ivy-reverse-i-search)
+ (define-key map (kbd "SPC") 'self-insert-command)
+ (ivy-define-key map [remap delete-backward-char] 'ivy-backward-delete-char)
+ (ivy-define-key map [remap backward-delete-char-untabify] 'ivy-backward-delete-char)
+ (ivy-define-key map [remap backward-kill-word] 'ivy-backward-kill-word)
+ (ivy-define-key map [remap delete-char] 'ivy-delete-char)
+ (ivy-define-key map [remap forward-char] 'ivy-forward-char)
+ (ivy-define-key map (kbd "") 'ivy-forward-char)
+ (ivy-define-key map [remap kill-word] 'ivy-kill-word)
+ (ivy-define-key map [remap beginning-of-buffer] 'ivy-beginning-of-buffer)
+ (ivy-define-key map [remap end-of-buffer] 'ivy-end-of-buffer)
+ (ivy-define-key map (kbd "M-n") 'ivy-next-history-element)
+ (ivy-define-key map (kbd "M-p") 'ivy-previous-history-element)
+ (define-key map (kbd "C-g") 'minibuffer-keyboard-quit)
+ (ivy-define-key map [remap scroll-up-command] 'ivy-scroll-up-command)
+ (ivy-define-key map [remap scroll-down-command] 'ivy-scroll-down-command)
+ (ivy-define-key map (kbd "") 'ivy-scroll-up-command)
+ (ivy-define-key map (kbd "") 'ivy-scroll-down-command)
+ (ivy-define-key map (kbd "C-v") 'ivy-scroll-up-command)
+ (ivy-define-key map (kbd "M-v") 'ivy-scroll-down-command)
+ (ivy-define-key map (kbd "C-M-n") 'ivy-next-line-and-call)
+ (ivy-define-key map (kbd "C-M-p") 'ivy-previous-line-and-call)
+ (ivy-define-key map (kbd "M-a") 'ivy-toggle-marks)
+ (ivy-define-key map (kbd "M-r") 'ivy-toggle-regexp-quote)
+ (ivy-define-key map (kbd "M-j") 'ivy-yank-word)
+ (ivy-define-key map (kbd "M-i") 'ivy-insert-current)
+ (ivy-define-key map (kbd "C-M-y") 'ivy-insert-current-full)
+ (ivy-define-key map (kbd "C-o") 'hydra-ivy/body)
+ (ivy-define-key map (kbd "M-o") 'ivy-dispatching-done)
+ (ivy-define-key map (kbd "C-M-o") 'ivy-dispatching-call)
+ (ivy-define-key map [remap kill-line] 'ivy-kill-line)
+ (ivy-define-key map [remap kill-whole-line] 'ivy-kill-whole-line)
+ (ivy-define-key map (kbd "S-SPC") 'ivy-restrict-to-matches)
+ (ivy-define-key map [remap kill-ring-save] 'ivy-kill-ring-save)
+ (ivy-define-key map (kbd "C-M-a") 'ivy-read-action)
+ (ivy-define-key map (kbd "C-c C-o") 'ivy-occur)
+ (ivy-define-key map (kbd "C-c C-a") 'ivy-toggle-ignore)
+ (ivy-define-key map (kbd "C-c C-s") 'ivy-rotate-sort)
+ (ivy-define-key map [remap describe-mode] 'ivy-help)
+ (ivy-define-key map "$" 'ivy-magic-read-file-env)
+ map)
+ "Keymap used in the minibuffer.")
+(autoload 'hydra-ivy/body "ivy-hydra" "" t)
+(autoload 'ivy-hydra-read-action "ivy-hydra" "" t)
+
+(defvar ivy-mode-map
+ (let ((map (make-sparse-keymap)))
+ (ivy-define-key map [remap switch-to-buffer] 'ivy-switch-buffer)
+ (ivy-define-key map [remap switch-to-buffer-other-window] 'ivy-switch-buffer-other-window)
+ map)
+ "Keymap for `ivy-mode'.")
+
+;;* Globals
+(cl-defstruct ivy-state
+ prompt collection
+ predicate require-match initial-input
+ history preselect keymap update-fn sort
+ ;; The frame in which `ivy-read' was called
+ frame
+ ;; The window in which `ivy-read' was called
+ window
+ ;; The buffer in which `ivy-read' was called
+ buffer
+ ;; The value of `ivy-text' to be used by `ivy-occur'
+ text
+ action
+ unwind
+ re-builder
+ matcher
+ ;; When this is non-nil, call it for each input change to get new candidates
+ dynamic-collection
+ ;; A lambda that transforms candidates only for display
+ display-transformer-fn
+ directory
+ caller
+ current
+ def
+ ignore
+ multi-action
+ extra-props)
+
+(defvar ivy-last (make-ivy-state)
+ "The last parameters passed to `ivy-read'.
+
+This should eventually become a stack so that you could use
+`ivy-read' recursively.")
+
+(defvar ivy--sessions nil
+ "Alist mapping session symbols to `ivy-state' objects.")
+
+(defvar ivy-recursive-last nil)
+
+(defvar ivy-recursive-restore t
+ "When non-nil, restore the above state when exiting the minibuffer.
+This variable is let-bound to nil by functions that take care of
+the restoring themselves.")
+
+(defsubst ivy-set-action (action)
+ "Set the current `ivy-last' field to ACTION."
+ (setf (ivy-state-action ivy-last) action))
+
+(defvar inhibit-message)
+
+(defvar ffap-machine-p-known)
+
+(defun ivy-thing-at-point ()
+ "Return a string that corresponds to the current thing at point."
+ (substring-no-properties
+ (cond
+ ((use-region-p)
+ (let* ((beg (region-beginning))
+ (end (region-end))
+ (eol (save-excursion (goto-char beg) (line-end-position))))
+ (buffer-substring-no-properties beg (min end eol))))
+ ((thing-at-point 'url))
+ ((and (eq (ivy-state-collection ivy-last) #'read-file-name-internal)
+ (let ((inhibit-message t)
+ (ffap-machine-p-known 'reject))
+ (run-hook-with-args-until-success 'file-name-at-point-functions))))
+ ((let ((s (thing-at-point 'symbol)))
+ (and (stringp s)
+ (if (string-match "\\`[`']?\\(.*?\\)'?\\'" s)
+ (match-string 1 s)
+ s))))
+ ((looking-at "(+\\(\\(?:\\sw\\|\\s_\\)+\\)\\_>")
+ (match-string-no-properties 1))
+ (t
+ ""))))
+
+(defvar ivy-history nil
+ "History list of candidates entered in the minibuffer.
+
+Maximum length of the history list is determined by the value
+of `history-length'.")
+
+(defvar ivy--directory nil
+ "Current directory when completing file names.")
+
+(defvar ivy--directory-hist nil
+ "Store the history of directories.
+This allows RET to reverse consecutive DEL.")
+
+(defvar ivy--length 0
+ "Store the amount of viable candidates.")
+
+(defvar ivy-text ""
+ "Store the user's string as it is typed in.")
+
+(defvar ivy-regex ""
+ "Store the regex value that corresponds to `ivy-text'.")
+
+(defvar ivy--regex-function 'ivy--regex
+ "Current function for building a regex.")
+
+(defun ivy-set-text (str)
+ "Set `ivy-text' to STR."
+ (setq ivy-text str)
+ (setq ivy-regex (funcall ivy--regex-function ivy-text)))
+
+(defvar ivy--index 0
+ "Store the index of the current candidate.")
+
+(defvar ivy--window-index 0
+ "Store the index of the current candidate in the minibuffer window.
+
+This means it's between 0 and `ivy-height'.")
+
+(defvar ivy-exit nil
+ "Store `done' if the completion was successfully selected.
+Otherwise, store nil.")
+
+(defvar ivy--all-candidates nil
+ "Store the candidates passed to `ivy-read'.")
+
+(defvar ivy--extra-candidates '((original-source))
+ "Store candidates added by the extra sources.
+
+This is an internal-use alist. Each key is a function name, or
+original-source (which represents where the current dynamic
+candidates should go).
+
+Each value is an evaluation of the function, in case of static
+sources. These values will subsequently be filtered on `ivy-text'.
+
+This variable is set by `ivy-read' and used by `ivy--set-candidates'.")
+
+(defcustom ivy-use-ignore-default t
+ "The default policy for user-configured candidate filtering."
+ :type '(choice
+ (const :tag "Ignore ignored always" always)
+ (const :tag "Ignore ignored when others exist" t)
+ (const :tag "Don't ignore" nil)))
+
+(defvar ivy-use-ignore t
+ "Store policy for user-configured candidate filtering.
+This may be changed dynamically by `ivy-toggle-ignore'.
+Use `ivy-use-ignore-default' for a permanent configuration.")
+
+(defvar ivy--default nil
+ "Default initial input.")
+
+(defvar ivy--prompt nil
+ "Store the format-style prompt.
+When non-nil, it should contain at least one %d.")
+
+(defvar ivy--prompt-extra ""
+ "Temporary modifications to the prompt.")
+
+(defvar ivy--old-re nil
+ "Store the old regexp.
+Either a string or a list for `ivy-re-match'.")
+
+(defvar ivy--old-cands nil
+ "Store the candidates matched by `ivy--old-re'.")
+
+(defvar ivy--highlight-function 'ivy--highlight-default
+ "Current function for formatting the candidates.")
+
+(defvar ivy--subexps 0
+ "Number of groups in the current `ivy--regex'.")
+
+(defvar ivy--full-length nil
+ "The total amount of candidates when :dynamic-collection is non-nil.")
+
+(defvar ivy--old-text ""
+ "Store old `ivy-text' for dynamic completion.")
+
+(defvar ivy--trying-to-resume-dynamic-collection nil
+ "Non-nil if resuming from a dynamic collection.
+When non-nil, ivy will wait until the first chunk of asynchronous
+candidates has been received before selecting the last
+preselected candidate.")
+
+(defun ivy--set-index-dynamic-collection ()
+ (when ivy--trying-to-resume-dynamic-collection
+ (let ((preselect-index
+ (ivy--preselect-index (ivy-state-preselect ivy-last) ivy--all-candidates)))
+ (when preselect-index
+ (ivy-set-index preselect-index)))
+ (setq ivy--trying-to-resume-dynamic-collection nil)))
+
+(defcustom ivy-case-fold-search-default
+ (if search-upper-case
+ 'auto
+ case-fold-search)
+ "The default value for `case-fold-search' in Ivy operations.
+The special value `auto' means case folding is performed so long
+as the entire input string comprises lower-case characters. This
+corresponds to the default behaviour of most Emacs search
+functionality, e.g. as seen in `isearch'."
+ :link '(info-link "(emacs)Lax Search")
+ :type '(choice
+ (const :tag "Auto" auto)
+ (const :tag "Always" t)
+ (const :tag "Never" nil)))
+
+(defvar ivy-case-fold-search ivy-case-fold-search-default
+ "Store the current overriding `case-fold-search'.")
+
+(defcustom ivy-more-chars-alist
+ '((t . 3))
+ "Map commands to their minimum required input length.
+That is the number of characters prompted for before fetching
+candidates. The special key t is used as a fallback."
+ :type '(alist :key-type symbol :value-type integer))
+
+(defun ivy-more-chars ()
+ "Return two fake candidates prompting for at least N input.
+N is obtained from `ivy-more-chars-alist'."
+ (let ((diff (- (ivy-alist-setting ivy-more-chars-alist)
+ (length ivy-text))))
+ (when (> diff 0)
+ (list "" (format "%d chars more" diff)))))
+
+(defun ivy--case-fold-p (string)
+ "Return nil if STRING should be matched case-sensitively."
+ (if (eq ivy-case-fold-search 'auto)
+ (string= string (downcase string))
+ ivy-case-fold-search))
+
+(defun ivy--case-fold-string= (s1 s2)
+ "Like `string=', but obeys `case-fold-search'."
+ (eq t (compare-strings s1 nil nil s2 nil nil case-fold-search)))
+
+(defmacro ivy-quit-and-run (&rest body)
+ "Quit the minibuffer and run BODY afterwards."
+ (declare (indent 0))
+ `(progn
+ (put 'quit 'error-message "")
+ (run-at-time nil nil
+ (lambda ()
+ (put 'quit 'error-message "Quit")
+ (with-demoted-errors "Error: %S"
+ ,@body)))
+ (abort-recursive-edit)))
+
+(defun ivy-exit-with-action (action &optional exit-code)
+ "Quit the minibuffer and call ACTION afterwards."
+ (ivy-set-action
+ `(lambda (x)
+ (funcall ',action x)
+ (ivy-set-action ',(ivy-state-action ivy-last))))
+ (setq ivy-exit (or exit-code 'done))
+ (exit-minibuffer))
+
+(defmacro with-ivy-window (&rest body)
+ "Execute BODY in the window from which `ivy-read' was called."
+ (declare (indent 0)
+ (debug t))
+ `(with-selected-window (ivy--get-window ivy-last)
+ ,@body))
+
+(defun ivy--expand-file-name (text)
+ (cond
+ ((eq (ivy-state-history ivy-last) 'grep-files-history)
+ text)
+ (ivy--directory
+ (if (and (string-match-p "^/" text) (file-remote-p ivy--directory))
+ (let ((parts (split-string ivy--directory ":")))
+ (concat (nth 0 parts) ":" (nth 1 parts) ":" text))
+ (expand-file-name text ivy--directory)))
+ (t
+ text)))
+
+(defun ivy--done (text)
+ "Insert TEXT and exit minibuffer."
+ (if (member (ivy-state-prompt ivy-last) '("Create directory: " "Make directory: "))
+ (ivy-immediate-done)
+ (when (stringp text)
+ (insert
+ (setf (ivy-state-current ivy-last)
+ (ivy--expand-file-name text))))
+ (setq ivy-exit 'done)
+ (exit-minibuffer)))
+
+(defcustom ivy-use-selectable-prompt nil
+ "When non-nil, make the prompt line selectable like a candidate.
+
+The prompt line can be selected by calling `ivy-previous-line' when the first
+regular candidate is selected. Both actions `ivy-done' and `ivy-alt-done',
+when called on a selected prompt, are forwarded to `ivy-immediate-done', which
+results to the same as calling `ivy-immediate-done' explicitly when a regular
+candidate is selected.
+
+Note that if `ivy-wrap' is set to t, calling `ivy-previous-line' when the
+prompt is selected wraps around to the last candidate, while calling
+`ivy-next-line' on the last candidate wraps around to the first
+candidate, not the prompt."
+ :type 'boolean)
+
+(defvar ivy--use-selectable-prompt nil
+ "Store the effective `ivy-use-selectable-prompt' for current session.")
+
+(defun ivy--prompt-selectable-p ()
+ "Return t if the prompt line is selectable."
+ (and ivy-use-selectable-prompt
+ (or (memq (ivy-state-require-match ivy-last)
+ '(nil confirm confirm-after-completion))
+ ;; :require-match is t, but "" is in the collection
+ (let ((coll (ivy-state-collection ivy-last)))
+ (and (listp coll)
+ (if (consp (car coll))
+ (member '("") coll)
+ (member "" coll)))))))
+
+(defun ivy--prompt-selected-p ()
+ "Return t if the prompt line is selected."
+ (and ivy--use-selectable-prompt
+ (= ivy--index -1)))
+
+;;* Commands
+(defun ivy-done ()
+ "Exit the minibuffer with the selected candidate."
+ (interactive)
+ (if (ivy--prompt-selected-p)
+ (ivy-immediate-done)
+ (setq ivy-current-prefix-arg current-prefix-arg)
+ (delete-minibuffer-contents)
+ (cond ((and (= ivy--length 0)
+ (eq this-command 'ivy-dispatching-done))
+ (ivy--done ivy-text))
+ ((or (> ivy--length 0)
+ ;; the action from `ivy-dispatching-done' may not need a
+ ;; candidate at all
+ (eq this-command 'ivy-dispatching-done))
+ (ivy--done (ivy-state-current ivy-last)))
+ ((and (memq (ivy-state-collection ivy-last)
+ '(read-file-name-internal internal-complete-buffer))
+ (eq confirm-nonexistent-file-or-buffer t)
+ (not (string= " (confirm)" ivy--prompt-extra)))
+ (setq ivy--prompt-extra " (confirm)")
+ (insert ivy-text)
+ (ivy--exhibit))
+ ((memq (ivy-state-require-match ivy-last)
+ '(nil confirm confirm-after-completion))
+ (ivy--done ivy-text))
+ (t
+ (setq ivy--prompt-extra " (match required)")
+ (insert ivy-text)
+ (ivy--exhibit)))))
+
+(defvar ivy-mouse-1-tooltip
+ "Exit the minibuffer with the selected candidate."
+ "The doc visible in the tooltip for mouse-1 binding in the minibuffer.")
+(defvar ivy-mouse-3-tooltip
+ "Display alternative actions."
+ "The doc visible in the tooltip for mouse-3 binding in the minibuffer.")
+
+(defun ivy-mouse-offset (event)
+ "Compute the offset between the candidate at point and the selected one."
+ (if event
+ (let* ((line-number-at-point
+ (max 2
+ (line-number-at-pos (posn-point (event-start event)))))
+
+ (line-number-candidate ;; convert to 0 based index
+ (- line-number-at-point 2))
+ (offset
+ (- line-number-candidate
+ ivy--window-index)))
+ offset)
+ nil))
+
+(defun ivy-mouse-done (event)
+ (interactive "@e")
+ (let ((offset (ivy-mouse-offset event)))
+ (when offset
+ (ivy-next-line offset)
+ (ivy--exhibit)
+ (ivy-alt-done))))
+
+(defun ivy-mouse-dispatching-done (event)
+ (interactive "@e")
+ (let ((offset (ivy-mouse-offset event)))
+ (when offset
+ (ivy-next-line offset)
+ (ivy--exhibit)
+ (ivy-dispatching-done))))
+
+(defcustom ivy-read-action-format-function 'ivy-read-action-format-default
+ "Function used to transform the actions list into a docstring."
+ :type '(radio
+ (function-item ivy-read-action-format-default)
+ (function-item ivy-read-action-format-columns)))
+
+(defun ivy-read-action-format-default (actions)
+ "Create a docstring from ACTIONS.
+
+ACTIONS is a list. Each list item is a list of 3 items:
+key (a string), cmd and doc (a string)."
+ (format "%s\n%s\n"
+ (if (eq this-command 'ivy-read-action)
+ "Select action: "
+ (ivy-state-current ivy-last))
+ (mapconcat
+ (lambda (x)
+ (format "%s: %s"
+ (propertize
+ (car x)
+ 'face 'ivy-action)
+ (nth 2 x)))
+ actions
+ "\n")))
+
+(defun ivy-read-action-format-columns (actions)
+ "Create a docstring from ACTIONS, using several columns if needed to preserve `ivy-height'.
+
+ACTIONS is a list. Each list item is a list of 3 items: key (a
+string), cmd and doc (a string)."
+ (let ((length (length actions))
+ (i 0)
+ (max-rows (- ivy-height 1))
+ rows cols col lwidth rwidth)
+ (while (< i length)
+ (setq col (cl-subseq actions i (min length (cl-incf i max-rows))))
+ (setq lwidth (apply 'max (mapcar (lambda (x)
+ (length (nth 0 x)))
+ col)))
+ (setq rwidth (apply 'max (mapcar (lambda (x)
+ (length (nth 2 x)))
+ col)))
+ (setq col (mapcar (lambda (x)
+ (format (format "%%%ds: %%-%ds" lwidth rwidth)
+ (propertize (car x) 'face 'ivy-action)
+ (nth 2 x)))
+ col))
+ (cond
+ ((null rows)
+ (setq rows (length col)))
+ ((< (length col) rows)
+ (setq col (append col (make-list (- rows (length col)) "")))))
+ (push col cols))
+ (format "%s\n%s\n"
+ (if (eq this-command 'ivy-read-action)
+ "Select action: "
+ (ivy-state-current ivy-last))
+ (mapconcat 'identity
+ (apply 'cl-mapcar
+ (lambda (&rest args)
+ (mapconcat 'identity args " | "))
+ (nreverse cols))
+ "\n"))))
+
+(defcustom ivy-read-action-function #'ivy-read-action-by-key
+ "Function used to read an action."
+ :type '(radio
+ (function-item ivy-read-action-by-key)
+ (function-item ivy-read-action-ivy)
+ (function-item ivy-hydra-read-action)))
+
+(defun ivy-read-action ()
+ "Change the action to one of the available ones.
+
+Return nil for `minibuffer-keyboard-quit' or wrong key during the
+selection, non-nil otherwise."
+ (interactive)
+ (let ((actions (ivy-state-action ivy-last)))
+ (if (not (ivy--actionp actions))
+ t
+ (let ((ivy--directory ivy--directory))
+ (funcall ivy-read-action-function actions)))))
+
+(defvar set-message-function)
+
+(defun ivy-read-action-by-key (actions)
+ (let* ((set-message-function nil)
+ (hint (funcall ivy-read-action-format-function (cdr actions)))
+ (resize-mini-windows t)
+ (key "")
+ action-idx)
+ (while (and (setq action-idx (cl-position-if
+ (lambda (x)
+ (string-prefix-p key (car x)))
+ (cdr actions)))
+ (not (string= key (car (nth action-idx (cdr actions))))))
+ (setq key (concat key (key-description (vector (read-key hint))))))
+ (ivy-shrink-after-dispatching)
+ (cond ((member key '("ESC" "C-g" "M-o"))
+ nil)
+ ((null action-idx)
+ (message "%s is not bound" key)
+ nil)
+ (t
+ (message "")
+ (setcar actions (1+ action-idx))
+ (ivy-set-action actions)))))
+
+(defvar ivy-marked-candidates nil
+ "List of marked candidates.
+Use `ivy-mark' to populate this.
+
+When this list is non-nil at the end of the session, the action
+will be called for each element of this list.")
+
+(defun ivy-read-action-ivy (actions)
+ "Select an action from ACTIONS using Ivy."
+ (let ((enable-recursive-minibuffers t))
+ (if (and (> (minibuffer-depth) 1)
+ (eq (ivy-state-caller ivy-last) 'ivy-read-action-ivy))
+ (minibuffer-keyboard-quit)
+ (let ((ivy-marked-candidates ivy-marked-candidates))
+ (ivy-read (format "action (%s): " (ivy-state-current ivy-last))
+ (cl-mapcar
+ (lambda (a i) (cons (format "[%s] %s" (nth 0 a) (nth 2 a)) i))
+ (cdr actions) (number-sequence 1 (length (cdr actions))))
+ :action (lambda (a)
+ (setcar actions (cdr a))
+ (ivy-set-action actions))
+ :caller 'ivy-read-action-ivy)))))
+
+(defun ivy-shrink-after-dispatching ()
+ "Shrink the window after dispatching when action list is too large."
+ (when (window-minibuffer-p)
+ (window-resize nil (- ivy-height (window-height)))))
+
+(defun ivy-dispatching-done ()
+ "Select one of the available actions and call `ivy-done'."
+ (interactive)
+ (let ((ivy-exit 'ivy-dispatching-done))
+ (when (ivy-read-action)
+ (ivy-done)))
+ (ivy-shrink-after-dispatching))
+
+(defun ivy-dispatching-call ()
+ "Select one of the available actions and call `ivy-call'."
+ (interactive)
+ (setq ivy-current-prefix-arg current-prefix-arg)
+ (let ((actions (copy-sequence (ivy-state-action ivy-last)))
+ (old-ivy-text ivy-text))
+ (unwind-protect
+ (when (ivy-read-action)
+ (ivy-set-text old-ivy-text)
+ (ivy-call))
+ (ivy-set-action actions)))
+ (ivy-shrink-after-dispatching))
+
+(defun ivy-build-tramp-name (x)
+ "Reconstruct X into a path.
+Is is a cons cell, related to `tramp-get-completion-function'."
+ (let ((user (car x))
+ (domain (cadr x)))
+ (if user
+ (concat user "@" domain)
+ domain)))
+
+(declare-function Info-find-node "info")
+(declare-function Info-read-node-name-1 "info")
+(declare-function tramp-get-completion-function "tramp")
+
+(defcustom ivy-alt-done-functions-alist nil
+ "Customize what `ivy-alt-done' does per-collection."
+ :type '(alist :key-type symbol :value-type function))
+
+(defun ivy--completing-fname-p ()
+ (eq 'file (cdr (assoc
+ 'category
+ (ignore-errors
+ (funcall (ivy-state-collection ivy-last) ivy-text nil 'metadata))))))
+
+(defun ivy-alt-done (&optional arg)
+ "Exit the minibuffer with the selected candidate.
+When ARG is t, exit with current text, ignoring the candidates.
+When the current candidate during file name completion is a
+directory, continue completion from within that directory instead
+of exiting. This function is otherwise like `ivy-done'."
+ (interactive "P")
+ (setq ivy-current-prefix-arg current-prefix-arg)
+ (let (alt-done-fn)
+ (cond ((or arg (ivy--prompt-selected-p))
+ (ivy-immediate-done))
+ ((setq alt-done-fn (ivy-alist-setting ivy-alt-done-functions-alist))
+ (funcall alt-done-fn))
+ ((ivy--completing-fname-p)
+ (ivy--directory-done))
+ (t
+ (ivy-done)))))
+
+(defun ivy--info-alt-done ()
+ (if (member (ivy-state-current ivy-last) '("(./)" "(../)"))
+ (ivy-quit-and-run
+ (ivy-read "Go to file: " #'read-file-name-internal
+ :action (lambda (x)
+ (Info-find-node
+ (expand-file-name x ivy--directory)
+ "Top"))))
+ (ivy-done)))
+
+(defvar ivy-auto-select-single-candidate nil
+ "When non-nil, auto-select the candidate if it is the only one.
+When t, it is the same as if the user were prompted and selected the candidate
+by calling the default action. This variable has no use unless the collection
+contains a single candidate.")
+
+(defun ivy--directory-enter ()
+ (let (dir)
+ (when (and
+ (> ivy--length 0)
+ (not (string= (ivy-state-current ivy-last) "./"))
+ (setq dir (ivy-expand-file-if-directory (ivy-state-current ivy-last))))
+ (ivy--cd dir)
+ (ivy--exhibit))))
+
+(defun ivy--handle-directory (input)
+ "Detect the next directory based on special values of INPUT."
+ (cond ((string= input "/")
+ "/")
+ ((string= input "/sudo::")
+ (concat input ivy--directory))))
+
+(defun ivy--tramp-candidates ()
+ (let ((method (match-string 1 ivy-text))
+ (user (match-string 2 ivy-text))
+ (rest (match-string 3 ivy-text))
+ res)
+ (dolist (x (tramp-get-completion-function method))
+ (setq res (append res (funcall (car x) (cadr x)))))
+ (setq res (delq nil res))
+ (when user
+ (dolist (x res)
+ (setcar x user)))
+ (setq res (delete-dups res))
+ (let* ((old-ivy-last ivy-last)
+ (enable-recursive-minibuffers t)
+ (host (let ((ivy-auto-select-single-candidate nil))
+ (ivy-read "user@host: "
+ (mapcar #'ivy-build-tramp-name res)
+ :initial-input rest))))
+ (setq ivy-last old-ivy-last)
+ (when host
+ (setq ivy--directory "/")
+ (ivy--cd (concat "/" method ":" host ":/"))))))
+
+(defun ivy--directory-done ()
+ "Handle exit from the minibuffer when completing file names."
+ (let ((dir (ivy--handle-directory ivy-text)))
+ (cond ((equal (ivy-state-current ivy-last) (ivy-state-def ivy-last))
+ (ivy-done))
+ ((and (ivy-state-require-match ivy-last)
+ (equal ivy-text "")
+ (null ivy--old-cands))
+ (ivy-immediate-done))
+ (dir
+ (let ((inhibit-message t))
+ (ivy--cd dir)))
+ ((ivy--directory-enter))
+ ((unless (string= ivy-text "")
+ ;; Obsolete since 26.1 and removed in 28.1.
+ (defvar tramp-completion-mode)
+ (with-no-warnings
+ (let* ((tramp-completion-mode t)
+ (file (expand-file-name
+ (if (> ivy--length 0) (ivy-state-current ivy-last) ivy-text)
+ ivy--directory)))
+ (when (ignore-errors (file-exists-p file))
+ (if (file-directory-p file)
+ (ivy--cd (file-name-as-directory file))
+ (ivy-done))
+ ivy-text)))))
+ ((or (and (equal ivy--directory "/")
+ (string-match-p "\\`[^/]+:.*:.*\\'" ivy-text))
+ (string-match-p "\\`/[^/]+:.*:.*\\'" ivy-text))
+ (ivy-done))
+ ((ivy--tramp-prefix-p)
+ (ivy--tramp-candidates))
+ (t
+ (ivy-done)))))
+
+(defun ivy--tramp-prefix-p ()
+ (or (and (equal ivy--directory "/")
+ (cond ((string-match
+ "\\`\\([^/]+?\\):\\(?:\\(.*\\)@\\)?\\(.*\\)\\'"
+ ivy-text)
+ (save-match-data
+ (ivy-set-text (ivy-state-current ivy-last))))
+ ((string-match
+ "\\`\\([^/]+?\\):\\(?:\\(.*\\)@\\)?\\(.*\\)\\'"
+ (ivy-state-current ivy-last))
+ (save-match-data
+ (ivy-set-text (ivy-state-current ivy-last))))))
+ (string-match
+ "\\`/\\([^/]+?\\):\\(?:\\(.*\\)@\\)?\\(.*\\)\\'"
+ ivy-text)))
+
+(defun ivy-expand-file-if-directory (file-name)
+ "Expand FILE-NAME as directory.
+When this directory doesn't exist, return nil."
+ (when (stringp file-name)
+ (let ((full-name
+ ;; Ignore host name must not match method "ssh"
+ (ignore-errors
+ (file-name-as-directory
+ (expand-file-name file-name ivy--directory)))))
+ (when (and full-name (file-directory-p full-name))
+ full-name))))
+
+(defcustom ivy-tab-space nil
+ "When non-nil, `ivy-partial-or-done' should insert a space."
+ :type 'boolean)
+
+(defun ivy-partial-or-done ()
+ "Complete the minibuffer text as much as possible.
+If the text hasn't changed as a result, forward to `ivy-alt-done'."
+ (interactive)
+ (cond
+ ((and (numberp completion-cycle-threshold)
+ (< (length ivy--all-candidates) completion-cycle-threshold))
+ (let ((ivy-wrap t))
+ (ivy-next-line)))
+ ((and (eq (ivy-state-collection ivy-last) #'read-file-name-internal)
+ (or (and (equal ivy--directory "/")
+ (string-match-p "\\`[^/]+:.*\\'" ivy-text))
+ (= (string-to-char ivy-text) ?/)))
+ (let ((default-directory ivy--directory)
+ dir)
+ (minibuffer-complete)
+ (ivy-set-text (ivy--input))
+ (when (setq dir (ivy-expand-file-if-directory ivy-text))
+ (ivy--cd dir))))
+ (t
+ (or (ivy-partial)
+ (when (or (eq this-command last-command)
+ (eq ivy--length 1))
+ (ivy-alt-done))))))
+
+(defun ivy--partial-cd-for-single-directory ()
+ (when (and
+ (eq (ivy-state-collection ivy-last) #'read-file-name-internal)
+ (= 1 (length
+ (ivy--re-filter
+ (funcall ivy--regex-function
+ (concat "^" (string-remove-prefix "^" ivy-text)))
+ ivy--all-candidates)))
+ (let ((default-directory ivy--directory))
+ (file-directory-p (ivy-state-current ivy-last))))
+ (ivy--directory-done)))
+
+(defun ivy-partial ()
+ "Complete the minibuffer text as much as possible."
+ (interactive)
+ (let* ((parts (or (ivy--split-spaces ivy-text) (list "")))
+ (tail (last parts))
+ (postfix (car tail))
+ (case-fold-search (ivy--case-fold-p ivy-text))
+ (completion-ignore-case case-fold-search)
+ (new (try-completion (string-remove-prefix "^" postfix)
+ (if (ivy-state-dynamic-collection ivy-last)
+ ivy--all-candidates
+ (mapcar (lambda (str)
+ (let ((i (string-match-p postfix str)))
+ (and i (substring str i))))
+ ivy--old-cands)))))
+ (cond ((eq new t) nil)
+ ((string= new ivy-text) nil)
+ ((string= (car tail) (car (ivy--split-spaces new))) nil)
+ (new
+ (delete-region (minibuffer-prompt-end) (point-max))
+ (setcar tail
+ (if (= (string-to-char postfix) ?^)
+ (concat "^" new)
+ new))
+ (ivy-set-text
+ (concat
+ (mapconcat #'identity parts " ")
+ (and ivy-tab-space (not (= (length ivy--old-cands) 1)) " ")))
+ (insert ivy-text)
+ (ivy--partial-cd-for-single-directory)
+ t))))
+
+(defvar ivy-completion-beg nil
+ "Completion bounds start.")
+
+(defvar ivy-completion-end nil
+ "Completion bounds end.")
+
+(defun ivy-immediate-done ()
+ "Exit the minibuffer with current input instead of current candidate."
+ (interactive)
+ (delete-minibuffer-contents)
+ (setf (ivy-state-current ivy-last)
+ (cond ((or (not ivy--directory)
+ (eq (ivy-state-history ivy-last) 'grep-files-history))
+ ivy-text)
+ ((and (string= ivy-text "")
+ (eq (ivy-state-collection ivy-last)
+ #'read-file-name-internal))
+ (if (ivy-state-def ivy-last)
+ (if (and
+ (file-exists-p (ivy-state-def ivy-last))
+ (/= (length ivy--directory)
+ (1+ (length (expand-file-name (ivy-state-def ivy-last))))))
+ ivy--directory
+ (copy-sequence (ivy-state-def ivy-last)))
+ ivy--directory))
+ (t
+ (expand-file-name ivy-text ivy--directory))))
+ (insert (ivy-state-current ivy-last))
+ (setq ivy-completion-beg ivy-completion-end)
+ (setq ivy-exit 'done)
+ (exit-minibuffer))
+
+(defun ivy--restore-session (&optional session)
+ "Resume a recorded completion SESSION, if any exists."
+ (when ivy--sessions
+ (unless session
+ (setq session (intern
+ (let ((ivy-last ivy-last)
+ ivy--all-candidates
+ ivy-text)
+ (ivy-read "Choose ivy session: "
+ ivy--sessions
+ :require-match t)))))
+ (setq ivy-last (or (cdr (assq session ivy--sessions))
+ ivy-last)))
+ (let ((data (plist-get (ivy-state-extra-props ivy-last) :ivy-data)))
+ (when data
+ (setq ivy--all-candidates (plist-get data :all-candidates))
+ (setq ivy-text (plist-get data :text)))))
+
+;;;###autoload
+(defun ivy-resume (&optional session)
+ "Resume the last completion session, or SESSION if non-nil.
+With a prefix arg, try to restore a recorded completion session,
+if one exists."
+ (interactive)
+ (when (or current-prefix-arg session)
+ (ivy--restore-session session))
+
+ (if (or (null (ivy-state-action ivy-last))
+ (eq (ivy--get-action ivy-last) #'identity))
+ (user-error "The last session isn't compatible with `ivy-resume'")
+ (when (memq (ivy-state-caller ivy-last)
+ '(swiper
+ swiper-isearch swiper-backward
+ swiper-isearch-backward
+ counsel-grep))
+ (switch-to-buffer (ivy-state-buffer ivy-last)))
+ (with-current-buffer (ivy-state-buffer ivy-last)
+ (let ((default-directory (ivy-state-directory ivy-last))
+ (ivy-use-ignore-default (ivy-state-ignore ivy-last)))
+ (ivy-read
+ (ivy-state-prompt ivy-last)
+ (ivy-state-collection ivy-last)
+ :predicate (ivy-state-predicate ivy-last)
+ :require-match (ivy-state-require-match ivy-last)
+ :initial-input ivy-text
+ :history (ivy-state-history ivy-last)
+ :preselect (ivy-state-current ivy-last)
+ :keymap (ivy-state-keymap ivy-last)
+ :update-fn (ivy-state-update-fn ivy-last)
+ :sort (ivy-state-sort ivy-last)
+ :action (ivy-state-action ivy-last)
+ :unwind (ivy-state-unwind ivy-last)
+ :re-builder (ivy-state-re-builder ivy-last)
+ :matcher (ivy-state-matcher ivy-last)
+ :dynamic-collection (ivy-state-dynamic-collection ivy-last)
+ :extra-props (ivy-state-extra-props ivy-last)
+ :caller (ivy-state-caller ivy-last))))))
+
+(defvar-local ivy-calling nil
+ "When non-nil, call the current action when `ivy--index' changes.")
+
+(defun ivy-set-index (index)
+ "Set `ivy--index' to INDEX."
+ (setq ivy--index index)
+ (when ivy-calling
+ (ivy--exhibit)
+ (ivy-call)))
+
+(defun ivy-beginning-of-buffer ()
+ "Select the first completion candidate."
+ (interactive)
+ (ivy-set-index 0))
+
+(defun ivy-end-of-buffer ()
+ "Select the last completion candidate."
+ (interactive)
+ (ivy-set-index (1- ivy--length)))
+
+(defun ivy-scroll-up-command ()
+ "Scroll the candidates upward by the minibuffer height."
+ (interactive)
+ (ivy-set-index (min (1- (+ ivy--index ivy-height))
+ (1- ivy--length))))
+
+(defun ivy-scroll-down-command ()
+ "Scroll the candidates downward by the minibuffer height."
+ (interactive)
+ (ivy-set-index (max (1+ (- ivy--index ivy-height))
+ 0)))
+
+(defun ivy-next-line (&optional arg)
+ "Move cursor vertically down ARG candidates."
+ (interactive "p")
+ (setq arg (or arg 1))
+ (let ((index (+ ivy--index arg)))
+ (if (> index (1- ivy--length))
+ (if ivy-wrap
+ (ivy-beginning-of-buffer)
+ (ivy-set-index (1- ivy--length)))
+ (ivy-set-index index))))
+
+(defun ivy-next-line-or-history (&optional arg)
+ "Move cursor vertically down ARG candidates.
+If the input is empty, select the previous history element instead."
+ (interactive "p")
+ (let ((orig-index ivy--index))
+ (ivy-next-line arg)
+ (when (and (string= ivy-text "") (= ivy--index orig-index))
+ (ivy-previous-history-element 1))))
+
+(defun ivy-previous-line (&optional arg)
+ "Move cursor vertically up ARG candidates."
+ (interactive "p")
+ (setq arg (or arg 1))
+ (let ((index (- ivy--index arg))
+ (min-index (if ivy--use-selectable-prompt -1 0)))
+ (if (< index min-index)
+ (if ivy-wrap
+ (ivy-end-of-buffer)
+ (ivy-set-index min-index))
+ (ivy-set-index index))))
+
+(defun ivy-previous-line-or-history (arg)
+ "Move cursor vertically up ARG candidates.
+If the input is empty, select the previous history element instead."
+ (interactive "p")
+ (let ((orig-index ivy--index))
+ (ivy-previous-line arg)
+ (when (and (string= ivy-text "") (= ivy--index orig-index))
+ (ivy-previous-history-element 1))))
+
+(defun ivy-toggle-calling ()
+ "Flip `ivy-calling'."
+ (interactive)
+ (when (setq ivy-calling (not ivy-calling))
+ (ivy-call)))
+
+(defun ivy-toggle-ignore ()
+ "Toggle user-configured candidate filtering."
+ (interactive)
+ (setq ivy-use-ignore
+ (if ivy-use-ignore
+ nil
+ (or ivy-use-ignore-default t)))
+ (setf (ivy-state-ignore ivy-last) ivy-use-ignore)
+ ;; invalidate cache
+ (setq ivy--old-cands nil))
+
+(defun ivy--get-action (state)
+ "Get the action function from STATE."
+ (let ((action (ivy-state-action state)))
+ (when action
+ (if (functionp action)
+ action
+ (cadr (nth (car action) action))))))
+
+(defun ivy--get-multi-action (state)
+ "Get the multi-action function from STATE."
+ (let* ((action (ivy-state-action state))
+ (multi-action
+ (and (listp action)
+ (not (eq (car action) 'lambda))
+ (nth 3 (nth (car action) action)))))
+ (if multi-action
+ multi-action
+ (when (eq (car action) 1)
+ (ivy-state-multi-action state)))))
+
+(defun ivy--get-window (state)
+ "Get the window from STATE."
+ (if (ivy-state-p state)
+ (let ((window (ivy-state-window state)))
+ (if (window-live-p window)
+ window
+ (next-window)))
+ (selected-window)))
+
+(defun ivy--actionp (x)
+ "Return non-nil when X is a list of actions."
+ (and (consp x) (not (memq (car x) '(closure lambda)))))
+
+(defcustom ivy-action-wrap nil
+ "When non-nil, `ivy-next-action' and `ivy-prev-action' wrap."
+ :type 'boolean)
+
+(defun ivy-next-action ()
+ "When the current action is a list, scroll it forwards."
+ (interactive)
+ (let ((action (ivy-state-action ivy-last)))
+ (when (ivy--actionp action)
+ (let ((len (1- (length action)))
+ (idx (car action)))
+ (if (>= idx len)
+ (when ivy-action-wrap
+ (setf (car action) 1))
+ (cl-incf (car action)))))))
+
+(defun ivy-prev-action ()
+ "When the current action is a list, scroll it backwards."
+ (interactive)
+ (let ((action (ivy-state-action ivy-last)))
+ (when (ivy--actionp action)
+ (if (<= (car action) 1)
+ (when ivy-action-wrap
+ (setf (car action) (1- (length action))))
+ (cl-decf (car action))))))
+
+(defun ivy-action-name ()
+ "Return the name associated with the current action."
+ (let ((action (ivy-state-action ivy-last)))
+ (if (ivy--actionp action)
+ (format "[%d/%d] %s"
+ (car action)
+ (1- (length action))
+ (nth 2 (nth (car action) action)))
+ "[1/1] default")))
+
+(defvar ivy-inhibit-action nil
+ "When non-nil, `ivy-call' does nothing.
+
+Example use:
+
+ (let* ((ivy-inhibit-action t)
+ (str (ivy-switch-buffer)))
+ ;; do whatever with str - the corresponding buffer will not be opened
+ )")
+
+(defun ivy-recursive-restore ()
+ "Restore the above state when exiting the minibuffer.
+See variable `ivy-recursive-restore' for further information."
+ (when (and ivy-recursive-last
+ ivy-recursive-restore
+ (not (eq ivy-last ivy-recursive-last)))
+ (ivy--reset-state (setq ivy-last ivy-recursive-last))))
+
+(defvar ivy-mark-prefix ">"
+ "Prefix used by `ivy-mark'.")
+
+(defun ivy--call-marked (action)
+ (let* ((prefix-len (length ivy-mark-prefix))
+ (marked-candidates
+ (mapcar
+ (lambda (s)
+ (let ((cand (substring s prefix-len)))
+ (if ivy--directory
+ (expand-file-name cand ivy--directory)
+ cand)))
+ ivy-marked-candidates))
+ (multi-action (ivy--get-multi-action ivy-last)))
+ (if multi-action
+ (let ((default-directory (ivy-state-directory ivy-last)))
+ (funcall multi-action (mapcar #'ivy--call-cand marked-candidates)))
+ (dolist (c marked-candidates)
+ (let ((default-directory (ivy-state-directory ivy-last)))
+ (funcall action (ivy--call-cand c)))))))
+
+(defun ivy--call-cand (current)
+ (let ((collection (ivy-state-collection ivy-last)))
+ (cond
+ ;; Alist type.
+ ((and (consp (car-safe collection))
+ ;; Previously, the cdr of the selected
+ ;; candidate would be returned. Now, the
+ ;; whole candidate is returned.
+ (let ((idx (get-text-property 0 'idx current)))
+ (if idx
+ (progn
+ (ivy--remove-props current 'idx)
+ (nth idx collection))
+ (assoc current collection)))))
+ (ivy--directory
+ (expand-file-name current ivy--directory))
+ ((equal current "")
+ ivy-text)
+ (t
+ current))))
+
+(defun ivy-call ()
+ "Call the current action without exiting completion."
+ (interactive)
+ ;; Testing with `ivy-with' seems to call `ivy-call' again,
+ ;; in which case `this-command' is nil; so check for this.
+ (unless (memq this-command '(nil
+ ivy-done
+ ivy-alt-done
+ ivy-dispatching-done))
+ (setq ivy-current-prefix-arg current-prefix-arg))
+ (let* ((action
+ (if (functionp ivy-inhibit-action)
+ ivy-inhibit-action
+ (and (not ivy-inhibit-action)
+ (ivy--get-action ivy-last))))
+ (current (ivy-state-current ivy-last))
+ (x (ivy--call-cand current))
+ (res
+ (cond
+ ((null action)
+ current)
+ (t
+ (select-window (ivy--get-window ivy-last))
+ (set-buffer (ivy-state-buffer ivy-last))
+ (prog1 (unwind-protect
+ (if ivy-marked-candidates
+ (ivy--call-marked action)
+ (funcall action x))
+ (ivy-recursive-restore))
+ (unless (or (eq ivy-exit 'done)
+ (minibuffer-window-active-p (selected-window))
+ (null (active-minibuffer-window)))
+ (select-window (active-minibuffer-window))))))))
+ (if ivy-inhibit-action
+ res
+ current)))
+
+(defun ivy-call-and-recenter ()
+ "Call action and recenter window according to the selected candidate."
+ (interactive)
+ (ivy-call)
+ (with-ivy-window
+ (recenter-top-bottom)))
+
+(defun ivy-next-line-and-call (&optional arg)
+ "Move cursor vertically down ARG candidates.
+Call the permanent action if possible."
+ (interactive "p")
+ (ivy-next-line arg)
+ (ivy--exhibit)
+ (ivy-call))
+
+(defun ivy-previous-line-and-call (&optional arg)
+ "Move cursor vertically up ARG candidates.
+Call the permanent action if possible."
+ (interactive "p")
+ (ivy-previous-line arg)
+ (ivy--exhibit)
+ (ivy-call))
+
+(defun ivy-previous-history-element (arg)
+ "Forward to `previous-history-element' with ARG."
+ (interactive "p")
+ (previous-history-element arg)
+ (ivy--cd-maybe)
+ (move-end-of-line 1)
+ (ivy--maybe-scroll-history))
+
+(defun ivy--insert-symbol-boundaries ()
+ (undo-boundary)
+ (beginning-of-line)
+ (insert "\\_<")
+ (end-of-line)
+ (insert "\\_>"))
+
+(defun ivy-next-history-element (arg)
+ "Forward to `next-history-element' with ARG."
+ (interactive "p")
+ (if (and (= minibuffer-history-position 0)
+ (equal ivy-text ""))
+ (progn
+ (when minibuffer-default
+ (setq ivy--default (car minibuffer-default)))
+ (insert ivy--default)
+ (when (and (with-ivy-window (derived-mode-p 'prog-mode))
+ (eq (ivy-state-caller ivy-last) 'swiper)
+ (not (file-exists-p ivy--default))
+ (not (ivy-ffap-url-p ivy--default))
+ (not (ivy-state-dynamic-collection ivy-last))
+ (> (point) (minibuffer-prompt-end)))
+ (ivy--insert-symbol-boundaries)))
+ (next-history-element arg))
+ (ivy--cd-maybe)
+ (move-end-of-line 1)
+ (ivy--maybe-scroll-history))
+
+(defvar ivy-ffap-url-functions nil
+ "List of functions that check if the point is on a URL.")
+
+(defun ivy--cd-maybe ()
+ "Check if the current input points to a different directory.
+If so, move to that directory, while keeping only the file name."
+ (when ivy--directory
+ (let ((input (ivy--input))
+ url)
+ (if (setq url (or (ivy-ffap-url-p input)
+ (with-ivy-window
+ (cl-reduce
+ (lambda (a b)
+ (or a (funcall b)))
+ ivy-ffap-url-functions
+ :initial-value nil))))
+ (ivy-exit-with-action
+ (lambda (_)
+ (ivy-ffap-url-fetcher url))
+ 'no-update-history)
+ (setq input (expand-file-name input))
+ (let ((file (file-name-nondirectory input))
+ (dir (expand-file-name (file-name-directory input))))
+ (if (string= dir ivy--directory)
+ (progn
+ (delete-minibuffer-contents)
+ (insert file))
+ (ivy--cd dir)
+ (insert file)))))))
+
+(defun ivy--maybe-scroll-history ()
+ "If the selected history element has an index, scroll there."
+ (let ((idx (ignore-errors
+ (get-text-property
+ (minibuffer-prompt-end)
+ 'ivy-index))))
+ (when idx
+ (ivy--exhibit)
+ (ivy-set-index idx))))
+
+(declare-function tramp-get-completion-methods "tramp")
+
+(defun ivy--cd (dir)
+ "When completing file names, move to directory DIR."
+ (if (ivy--completing-fname-p)
+ (progn
+ (push dir ivy--directory-hist)
+ (setq ivy--old-cands nil)
+ (setq ivy--old-re nil)
+ (ivy-set-index 0)
+ (setq ivy--all-candidates
+ (append
+ (ivy--sorted-files (setq ivy--directory dir))
+ (when (and (string= dir "/") (featurep 'tramp))
+ (sort
+ (mapcar
+ (lambda (s) (substring s 1))
+ (tramp-get-completion-methods ""))
+ #'string<))))
+ (ivy-set-text "")
+ (setf (ivy-state-directory ivy-last) dir)
+ (delete-minibuffer-contents))
+ (error "Unexpected")))
+
+(defun ivy--parent-dir (filename)
+ "Return parent directory of absolute FILENAME."
+ (file-name-directory (directory-file-name filename)))
+
+(defun ivy-backward-delete-char ()
+ "Forward to `delete-backward-char'.
+Call `ivy-on-del-error-function' if an error occurs, usually when
+there is no more text to delete at the beginning of the
+minibuffer."
+ (interactive)
+ (if (and ivy--directory (= (minibuffer-prompt-end) (point)))
+ (progn
+ (ivy--cd (ivy--parent-dir (expand-file-name ivy--directory)))
+ (ivy--exhibit))
+ (setq prefix-arg current-prefix-arg)
+ (condition-case nil
+ (call-interactively #'delete-backward-char)
+ (error
+ (when ivy-on-del-error-function
+ (funcall ivy-on-del-error-function))))))
+
+(defun ivy-delete-char (arg)
+ "Forward to `delete-char' ARG."
+ (interactive "p")
+ (unless (eolp)
+ (delete-char arg)))
+
+(defun ivy-forward-char (arg)
+ "Forward to `forward-char' ARG."
+ (interactive "p")
+ (unless (eolp)
+ (forward-char arg)))
+
+(defun ivy-kill-word (arg)
+ "Forward to `kill-word' ARG."
+ (interactive "p")
+ (unless (eolp)
+ (kill-word arg)))
+
+(defun ivy-kill-line ()
+ "Forward to `kill-line'."
+ (interactive)
+ (if (eolp)
+ (kill-region (minibuffer-prompt-end) (point))
+ (kill-line)))
+
+(defun ivy-kill-whole-line ()
+ "Forward to `kill-whole-line'."
+ (interactive)
+ (kill-region (minibuffer-prompt-end) (line-end-position)))
+
+(defun ivy-backward-kill-word ()
+ "Forward to `backward-kill-word'."
+ (interactive)
+ (if (and ivy--directory (= (minibuffer-prompt-end) (point)))
+ (progn
+ (ivy--cd (ivy--parent-dir (expand-file-name ivy--directory)))
+ (ivy--exhibit))
+ (ignore-errors
+ (let ((pt (point))
+ (last-command (if (eq last-command 'ivy-backward-kill-word)
+ 'kill-region
+ last-command)))
+ (forward-word -1)
+ (kill-region pt (point))))))
+
+(defvar ivy--regexp-quote #'regexp-quote
+ "Store the regexp quoting state.")
+
+(defun ivy-toggle-regexp-quote ()
+ "Toggle the regexp quoting."
+ (interactive)
+ (setq ivy--old-re nil)
+ (cl-rotatef ivy--regex-function ivy--regexp-quote)
+ (setq ivy--old-text "")
+ (setq ivy-regex (funcall ivy--regex-function ivy-text)))
+
+(defcustom ivy-format-functions-alist
+ '((t . ivy-format-function-default))
+ "An alist of functions that transform the list of candidates into a string.
+This string is inserted into the minibuffer."
+ :type '(alist
+ :key-type symbol
+ :value-type
+ (choice
+ (const :tag "Default" ivy-format-function-default)
+ (const :tag "Arrow prefix" ivy-format-function-arrow)
+ (const :tag "Full line" ivy-format-function-line)
+ (function :tag "Custom function"))))
+
+(defun ivy-sort-file-function-default (x y)
+ "Compare two files X and Y.
+Prioritize directories."
+ (if (get-text-property 0 'dirp x)
+ (if (get-text-property 0 'dirp y)
+ (string< (directory-file-name x) (directory-file-name y))
+ t)
+ (if (get-text-property 0 'dirp y)
+ nil
+ (string< x y))))
+
+(defun ivy-string< (x y)
+ "Like `string<', but operate on CARs when given cons cells."
+ (string< (if (consp x) (car x) x)
+ (if (consp y) (car y) y)))
+
+(define-obsolete-function-alias 'ivy-sort-file-function-using-ido
+ 'ido-file-extension-lessp "<2019-10-12 Sat>")
+
+(defcustom ivy-sort-functions-alist
+ '((t . ivy-string<))
+ "An alist of sorting functions for each collection function.
+Interactive functions that call completion fit in here as well.
+
+Nil means no sorting, which is useful to turn off the sorting for
+functions that have candidates in the natural buffer order, like
+`org-refile' or `Man-goto-section'.
+
+A list can be used to associate multiple sorting functions with a
+collection. The car of the list is the current sort
+function. This list can be rotated with `ivy-rotate-sort'.
+
+The entry associated with t is used for all fall-through cases.
+
+See also `ivy-sort-max-size'."
+ :type
+ '(alist
+ :key-type (choice
+ (const :tag "Fall-through" t)
+ (symbol :tag "Collection"))
+ :value-type (choice
+ (const :tag "Plain sort" ivy-string<)
+ (const :tag "File sort" ivy-sort-file-function-default)
+ (const :tag "File sort using Ido" ido-file-extension-lessp)
+ (const :tag "No sort" nil)
+ (function :tag "Custom function")
+ (repeat (function :tag "Custom function")))))
+
+(defun ivy--sort-function (collection)
+ "Retrieve sort function for COLLECTION from `ivy-sort-functions-alist'."
+ (let ((entry (cdr (or (assq collection ivy-sort-functions-alist)
+ (assq (ivy-state-caller ivy-last) ivy-sort-functions-alist)
+ (assq t ivy-sort-functions-alist)))))
+ (and (or (functionp entry)
+ (functionp (setq entry (car-safe entry))))
+ entry)))
+
+(defun ivy-rotate-sort ()
+ "Rotate through sorting functions available for current collection.
+This only has an effect if multiple sorting functions are
+specified for the current collection in
+`ivy-sort-functions-alist'."
+ (interactive)
+ (let ((cell (or (assq (ivy-state-collection ivy-last) ivy-sort-functions-alist)
+ (assq (ivy-state-caller ivy-last) ivy-sort-functions-alist)
+ (assq t ivy-sort-functions-alist))))
+ (when (consp (cdr cell))
+ (setcdr cell (nconc (cddr cell) (list (cadr cell))))
+ (ivy--reset-state ivy-last))))
+
+(defcustom ivy-index-functions-alist
+ '((t . ivy-recompute-index-zero))
+ "An alist of index recomputing functions for each collection function.
+When the input changes, the appropriate function returns an
+integer - the index of the matched candidate that should be
+selected."
+ :type '(alist :key-type symbol :value-type function))
+
+(defvar ivy-re-builders-alist
+ '((t . ivy--regex-plus))
+ "An alist of regex building functions for each collection function.
+
+Each key is (in order of priority):
+1. The actual collection function, e.g. `read-file-name-internal'.
+2. The symbol passed by :caller into `ivy-read'.
+3. `this-command'.
+4. t.
+
+Each value is a function that should take a string and return a
+valid regex or a regex sequence (see below).
+
+Possible choices: `ivy--regex', `regexp-quote',
+`ivy--regex-plus', `ivy--regex-fuzzy', `ivy--regex-ignore-order'.
+
+If a function returns a list, it should format like this:
+'((\"matching-regexp\" . t) (\"non-matching-regexp\") ...).
+
+The matches will be filtered in a sequence, you can mix the
+regexps that should match and that should not match as you
+like.")
+
+(defvar ivy-highlight-functions-alist
+ '((ivy--regex-ignore-order . ivy--highlight-ignore-order)
+ (ivy--regex-fuzzy . ivy--highlight-fuzzy)
+ (ivy--regex-plus . ivy--highlight-default))
+ "An alist of highlighting functions for each regex builder function.")
+
+(defcustom ivy-initial-inputs-alist
+ '((org-refile . "^")
+ (org-agenda-refile . "^")
+ (org-capture-refile . "^")
+ (Man-completion-table . "^")
+ (woman . "^"))
+ "An alist associating commands with their initial input.
+
+Each cdr is either a string or a function called in the context
+of a call to `ivy-read'."
+ :type '(alist
+ :key-type (symbol)
+ :value-type (choice (string) (function))))
+
+(defcustom ivy-hooks-alist nil
+ "An alist associating commands to setup functions.
+Examples: `toggle-input-method', (lambda () (insert \"^\")), etc.
+May supersede `ivy-initial-inputs-alist'."
+ :type '(alist :key-type symbol :value-type function))
+
+(defvar ivy--occurs-list nil
+ "A list of custom occur generators per command.")
+
+(defun ivy-set-occur (cmd occur)
+ "Assign CMD a custom OCCUR function."
+ (setq ivy--occurs-list
+ (plist-put ivy--occurs-list cmd occur)))
+
+(defcustom ivy-update-fns-alist nil
+ "An alist associating commands to their :update-fn values."
+ :type '(alist
+ :key-type symbol
+ :value-type
+ (radio
+ (const :tag "Off" nil)
+ (const :tag "Call action on change" auto))))
+
+(defcustom ivy-unwind-fns-alist nil
+ "An alist associating commands to their :unwind values."
+ :type '(alist :key-type symbol :value-type function))
+
+(defcustom ivy-init-fns-alist nil
+ "An alist associating commands to their :init values.
+An :init is a function with no arguments.
+`ivy-read' calls it to initialize."
+ :type '(alist :key-type symbol :value-type function))
+
+(defun ivy--alist-set (alist-sym key val)
+ (let ((curr-val (symbol-value alist-sym))
+ (customized-val (get alist-sym 'customized-value))
+ (default-val (eval (car (get alist-sym 'standard-value)))))
+ ;; when the value was set by `customize-set-variable', don't touch it
+ (unless customized-val
+ ;; only works if the value wasn't customized by the user
+ (when (or (null default-val) (equal curr-val default-val))
+ (let ((cell (assoc key curr-val)))
+ (if cell
+ (setcdr cell val)
+ (set alist-sym (cons (cons key val)
+ (symbol-value alist-sym)))))
+ (when default-val
+ (put alist-sym 'standard-value
+ (list (list 'quote (symbol-value alist-sym)))))))))
+
+(declare-function counsel-set-async-exit-code "counsel")
+
+(defvar ivy--parents-alist nil
+ "Configure parent caller for child caller.
+The child caller inherits and can override the settings of the parent.")
+
+(cl-defun ivy-configure (caller
+ &key
+ parent
+ initial-input
+ height
+ occur
+ update-fn
+ init-fn
+ unwind-fn
+ index-fn
+ sort-fn
+ format-fn
+ display-fn
+ display-transformer-fn
+ alt-done-fn
+ more-chars
+ grep-p
+ exit-codes)
+ "Configure `ivy-read' params for CALLER."
+ (declare (indent 1))
+ (when parent
+ (ivy--alist-set 'ivy--parents-alist caller parent))
+ (when initial-input
+ (ivy--alist-set 'ivy-initial-inputs-alist caller initial-input))
+ (when height
+ (ivy--alist-set 'ivy-height-alist caller height))
+ (when occur
+ (ivy-set-occur caller occur))
+ (when update-fn
+ (ivy--alist-set 'ivy-update-fns-alist caller update-fn))
+ (when unwind-fn
+ (ivy--alist-set 'ivy-unwind-fns-alist caller unwind-fn))
+ (when init-fn
+ (ivy--alist-set 'ivy-init-fns-alist caller init-fn))
+ (when index-fn
+ (ivy--alist-set 'ivy-index-functions-alist caller index-fn))
+ (when sort-fn
+ (ivy--alist-set 'ivy-sort-functions-alist caller sort-fn))
+ (when format-fn
+ (ivy--alist-set 'ivy-format-functions-alist caller format-fn))
+ (when display-fn
+ (ivy--alist-set 'ivy-display-functions-alist caller display-fn))
+ (when display-transformer-fn
+ (ivy--alist-set 'ivy--display-transformers-alist caller display-transformer-fn))
+ (when alt-done-fn
+ (ivy--alist-set 'ivy-alt-done-functions-alist caller alt-done-fn))
+ (when more-chars
+ (ivy--alist-set 'ivy-more-chars-alist caller more-chars))
+ (when grep-p
+ (cl-pushnew caller ivy-highlight-grep-commands))
+ (when exit-codes
+ (let (code msg)
+ (while (and (setq code (pop exit-codes))
+ (setq msg (pop exit-codes)))
+ (counsel-set-async-exit-code caller code msg)))))
+
+(defcustom ivy-sort-max-size 30000
+ "Sorting won't be done for collections larger than this."
+ :type 'integer)
+
+(defalias 'ivy--dirname-p
+ ;; Added in Emacs 25.1.
+ (if (fboundp 'directory-name-p)
+ #'directory-name-p
+ (lambda (name)
+ "Return non-nil if NAME ends with a directory separator."
+ (string-suffix-p "/" name))))
+
+(defun ivy--sorted-files (dir)
+ "Return the list of files in DIR.
+Directories come first."
+ (let* ((default-directory dir)
+ (seq (condition-case nil
+ (mapcar (lambda (s) (replace-regexp-in-string "\\$\\$" "$" s))
+ (all-completions "" #'read-file-name-internal
+ (ivy-state-predicate ivy-last)))
+ (error
+ (directory-files dir))))
+ sort-fn)
+ (setq seq (delete "./" (delete "../" seq)))
+ (when (eq (setq sort-fn (ivy--sort-function #'read-file-name-internal))
+ #'ivy-sort-file-function-default)
+ (setq seq (mapcar (lambda (x)
+ (propertize x 'dirp (ivy--dirname-p x)))
+ seq)))
+ (when sort-fn
+ (setq seq (sort seq sort-fn)))
+ (dolist (dir ivy-extra-directories)
+ (push dir seq))
+ (if (string= dir "/")
+ (cl-remove-if (lambda (s) (string-match ":$" s)) (delete "../" seq))
+ seq)))
+
+(defun ivy-alist-setting (alist &optional key)
+ "Return the value associated with KEY in ALIST, using `assq'.
+KEY defaults to the last caller of `ivy-read'; if no entry is
+found, it falls back to the key t."
+ (let ((caller (or key (ivy-state-caller ivy-last))))
+ (or
+ (and caller (cdr (assq caller alist)))
+ (let ((parent (cdr (assq caller ivy--parents-alist))))
+ (when parent
+ (ivy-alist-setting alist parent)))
+ (cdr (assq t alist)))))
+
+(defun ivy--height (caller)
+ (let ((v (or (ivy-alist-setting ivy-height-alist caller)
+ ivy-height)))
+ (if (integerp v)
+ v
+ (if (functionp v)
+ (funcall v caller)
+ (error "Unexpected value: %S" v)))))
+
+(defun ivy--remove-props (str &rest props)
+ "Return STR with text PROPS destructively removed."
+ (ignore-errors
+ (remove-list-of-text-properties 0 (length str) props str))
+ str)
+
+(defun ivy--update-prompt (prompt)
+ (cond ((equal prompt "Keyword, C-h: ")
+ ;; auto-insert.el
+ "Keyword (C-M-j to end): ")
+ (t
+ ;; misearch.el
+ (replace-regexp-in-string "RET to end" "C-M-j to end" prompt))))
+
+;;** Entry Point
+;;;###autoload
+(cl-defun ivy-read (prompt collection
+ &key
+ predicate require-match initial-input
+ history preselect def keymap update-fn sort
+ action multi-action
+ unwind re-builder matcher
+ dynamic-collection
+ extra-props
+ caller)
+ "Read a string in the minibuffer, with completion.
+
+PROMPT is a string, normally ending in a colon and a space.
+`ivy-count-format' is prepended to PROMPT during completion.
+
+COLLECTION is either a list of strings, a function, an alist, or
+a hash table, supplied for `minibuffer-completion-table'.
+
+PREDICATE is applied to filter out the COLLECTION immediately.
+This argument is for compatibility with `completing-read'.
+
+When REQUIRE-MATCH is non-nil, only members of COLLECTION can be
+selected.
+
+If INITIAL-INPUT is non-nil, then insert that input in the
+minibuffer initially.
+
+HISTORY is a name of a variable to hold the completion session
+history.
+
+KEYMAP is composed with `ivy-minibuffer-map'.
+
+PRESELECT, when non-nil, determines which one of the candidates
+matching INITIAL-INPUT to select initially. An integer stands
+for the position of the desired candidate in the collection,
+counting from zero. Otherwise, use the first occurrence of
+PRESELECT in the collection. Comparison is first done with
+`equal'. If that fails, and when applicable, match PRESELECT as
+a regular expression.
+
+DEF is for compatibility with `completing-read'.
+
+UPDATE-FN is called each time the candidate list is re-displayed.
+
+When SORT is non-nil, `ivy-sort-functions-alist' determines how
+to sort candidates before displaying them.
+
+ACTION is a function to call after selecting a candidate.
+It takes one argument, the selected candidate. If COLLECTION is
+an alist, the argument is a cons cell, otherwise it's a string.
+
+MULTI-ACTION, when non-nil, is called instead of ACTION when
+there are marked candidates. It takes the list of candidates as
+its only argument. When it's nil, ACTION is called on each marked
+candidate.
+
+UNWIND is a function of no arguments to call before exiting.
+
+RE-BUILDER is a function transforming input text into a regex
+pattern.
+
+MATCHER is a function which can override how candidates are
+filtered based on user input. It takes a regex pattern and a
+list of candidates, and returns the list of matching candidates.
+
+DYNAMIC-COLLECTION is a boolean specifying whether the list of
+candidates is updated after each input by calling COLLECTION.
+
+EXTRA-PROPS is a plist that can be used to store
+collection-specific session-specific data.
+
+CALLER is a symbol to uniquely identify the caller to `ivy-read'.
+It is used, along with COLLECTION, to determine which
+customizations apply to the current completion session."
+ (let ((init-fn (ivy-alist-setting ivy-init-fns-alist caller)))
+ (when init-fn
+ (funcall init-fn)))
+ ;; get un-stuck from an existing `read-key' overriding minibuffer keys
+ (when (equal overriding-local-map '(keymap))
+ (keyboard-quit))
+ (setq caller (or caller this-command))
+ (let* ((ivy-recursive-last (and (active-minibuffer-window) ivy-last))
+ (ivy--display-function
+ (when (or ivy-recursive-last
+ (not (window-minibuffer-p)))
+ (ivy-alist-setting ivy-display-functions-alist caller))))
+ (setq update-fn (or update-fn (ivy-alist-setting ivy-update-fns-alist caller)))
+ (setq unwind (or unwind (ivy-alist-setting ivy-unwind-fns-alist caller)))
+ (setq ivy-last
+ (make-ivy-state
+ :prompt (ivy--update-prompt prompt)
+ :collection collection
+ :predicate predicate
+ :require-match require-match
+ :initial-input initial-input
+ :history history
+ :preselect preselect
+ :keymap keymap
+ :update-fn (if (eq update-fn 'auto)
+ (lambda ()
+ (with-ivy-window
+ (funcall
+ (ivy--get-action ivy-last)
+ (if (consp (car-safe (ivy-state-collection ivy-last)))
+ (assoc (ivy-state-current ivy-last)
+ (ivy-state-collection ivy-last))
+ (ivy-state-current ivy-last)))))
+ update-fn)
+ :sort sort
+ :action (ivy--compute-extra-actions action caller)
+ :multi-action multi-action
+ :frame (selected-frame)
+ :window (selected-window)
+ :buffer (current-buffer)
+ :unwind unwind
+ :re-builder re-builder
+ :matcher matcher
+ :dynamic-collection dynamic-collection
+ :display-transformer-fn (ivy-alist-setting ivy--display-transformers-alist caller)
+ :directory default-directory
+ :extra-props extra-props
+ :caller caller
+ :def def))
+ (ivy--reset-state ivy-last)
+ (unwind-protect
+ (minibuffer-with-setup-hook
+ #'ivy--minibuffer-setup
+ (let* ((hist (or history 'ivy-history))
+ (minibuffer-completion-table collection)
+ (minibuffer-completion-predicate predicate)
+ (ivy-height (ivy--height caller))
+ (resize-mini-windows (unless (display-graphic-p)
+ 'grow-only)))
+ (if (and ivy-auto-select-single-candidate
+ ivy--all-candidates
+ (null (cdr ivy--all-candidates)))
+ (progn
+ (setf (ivy-state-current ivy-last)
+ (car ivy--all-candidates))
+ (setq ivy-exit 'done))
+ (condition-case err
+ (read-from-minibuffer
+ prompt
+ (ivy-state-initial-input ivy-last)
+ (make-composed-keymap keymap ivy-minibuffer-map)
+ nil
+ hist)
+ (error
+ (unless (equal err '(error "Selecting deleted buffer"))
+ (signal (car err) (cdr err))))))
+ (when (eq ivy-exit 'done)
+ (ivy--update-history hist))))
+ (let ((session (or (plist-get extra-props :session)
+ (unless (or (minibufferp)
+ (null (ivy-state-action ivy-last))
+ (eq (ivy--get-action ivy-last) #'identity))
+ caller))))
+ (when session
+ (setf (ivy-state-extra-props ivy-last)
+ (plist-put extra-props :ivy-data `(:all-candidates ,ivy--all-candidates
+ :text ,ivy-text)))
+ (ivy--alist-set 'ivy--sessions session ivy-last)))
+ (ivy--cleanup))
+ (ivy-call)))
+
+(defun ivy--update-history (hist)
+ (let ((item
+ (if (or (string= ivy-text "")
+ (eq
+ (plist-get (ivy-state-extra-props ivy-last) :caller)
+ 'ivy-completing-read)
+ (eq (ivy-state-history ivy-last) 'file-name-history))
+ (ivy-state-current ivy-last)
+ ivy-text)))
+ (cond ((equal item ""))
+ ((stringp item)
+ (set hist (cons (propertize item 'ivy-index ivy--index)
+ (delete item (symbol-value hist))))))))
+
+(defun ivy--cleanup ()
+ ;; Fixes a bug in ESS, #1660
+ (put 'post-command-hook 'permanent-local nil)
+ (remove-hook 'post-command-hook #'ivy--queue-exhibit)
+ (remove-hook 'window-size-change-functions #'ivy--window-size-changed)
+ (let ((cleanup (ivy--display-function-prop :cleanup))
+ (unwind (ivy-state-unwind ivy-last)))
+ (when (functionp cleanup)
+ (funcall cleanup))
+ (when unwind
+ (funcall unwind)))
+ (ivy--pulse-cleanup)
+ (unless (eq ivy-exit 'done)
+ (ivy-recursive-restore)))
+
+(defun ivy--display-function-prop (prop)
+ "Return PROP associated with current `ivy--display-function'."
+ (plist-get (cdr (assq ivy--display-function
+ ivy-display-functions-props))
+ prop))
+
+(defvar Info-complete-menu-buffer)
+
+(defun ivy--reset-state (state)
+ "Reset the ivy to STATE.
+This is useful for recursive `ivy-read'."
+ (setq ivy-marked-candidates nil)
+ (unless (equal (selected-frame) (ivy-state-frame state))
+ (select-window (active-minibuffer-window)))
+ (let* ((prompt (or (ivy-state-prompt state) ""))
+ (collection (ivy-state-collection state))
+ (predicate (ivy-state-predicate state))
+ (history (ivy-state-history state))
+ (preselect (ivy-state-preselect state))
+ (re-builder (ivy-state-re-builder state))
+ (dynamic-collection (ivy-state-dynamic-collection state))
+ (require-match (ivy-state-require-match state))
+ (caller (or (ivy-state-caller state) this-command))
+ (sort (or (ivy-state-sort state) (assoc caller ivy-sort-functions-alist)))
+ (initial-input
+ (or (ivy-state-initial-input state)
+ (let ((init (ivy-alist-setting ivy-initial-inputs-alist caller)))
+ (if (functionp init) (funcall init) init))))
+ (def (ivy-state-def state)))
+ (when (and (eq caller 'swiper-isearch) (buffer-modified-p))
+ (setq preselect nil))
+ (setq ivy--extra-candidates (ivy--compute-extra-candidates caller))
+ (setq ivy--directory nil)
+ (setq ivy--directory-hist (list default-directory))
+ (setq ivy-case-fold-search ivy-case-fold-search-default)
+ (setf (ivy-state-re-builder ivy-last)
+ (setq ivy--regex-function
+ (or re-builder
+ (and (functionp collection)
+ (cdr (assq collection ivy-re-builders-alist)))
+ (ivy-alist-setting ivy-re-builders-alist)
+ #'ivy--regex)))
+ (setq ivy--subexps 0)
+ (setq ivy--regexp-quote #'regexp-quote)
+ (setq ivy--old-text "")
+ (setq ivy--full-length nil)
+ (ivy-set-text (or initial-input ""))
+ (setq ivy--index 0)
+ (setq ivy-calling nil)
+ (setq ivy-use-ignore ivy-use-ignore-default)
+ (setf (ivy-state-ignore state) ivy-use-ignore)
+ (setq ivy--highlight-function
+ (or (cdr (assq (ivy-alist-setting ivy-re-builders-alist)
+ ivy-highlight-functions-alist))
+ #'ivy--highlight-default))
+ (let ((ivy-recursive-restore nil)
+ coll sort-fn)
+ (cond ((eq collection #'Info-read-node-name-1)
+ (setq coll
+ (if (equal (bound-and-true-p Info-current-file) "dir")
+ (mapcar (lambda (x) (format "(%s)" x))
+ (delete-dups
+ (all-completions "(" collection predicate)))
+ (all-completions "" collection predicate))))
+ ((memq collection '(read-file-name-internal ffap-read-file-or-url-internal))
+ (require 'tramp)
+ (when (and (equal def initial-input)
+ (member "./" ivy-extra-directories))
+ (setq def nil))
+ (setq ivy--directory default-directory)
+ (when (and initial-input
+ (not (equal initial-input "")))
+ (cond ((file-directory-p initial-input)
+ (when (equal (file-name-nondirectory initial-input) "")
+ (setf (ivy-state-preselect state) (setq preselect nil))
+ (setq def nil))
+ (setq ivy--directory (file-name-as-directory initial-input))
+ (setq initial-input nil)
+ (when preselect
+ (let ((preselect-directory
+ (file-name-directory preselect)))
+ (when (and preselect-directory
+ (not (equal
+ (expand-file-name
+ preselect-directory)
+ (expand-file-name ivy--directory))))
+ (setf (ivy-state-preselect state)
+ (setq preselect nil))))))
+ ((ignore-errors
+ (file-exists-p (file-name-directory initial-input)))
+ (setq ivy--directory (file-name-directory initial-input))
+ (setf (ivy-state-preselect state)
+ (file-name-nondirectory initial-input)))))
+ (require 'dired)
+ (when preselect
+ (let ((preselect-directory (ivy--parent-dir preselect)))
+ (when (and preselect-directory
+ (not (string= preselect-directory
+ default-directory)))
+ (setq ivy--directory preselect-directory))
+ (setq preselect (file-relative-name preselect
+ preselect-directory))
+ (setf (ivy-state-preselect state) preselect)))
+ (setq sort nil)
+ (setq coll (ivy--sorted-files ivy--directory))
+ (when initial-input
+ (unless (or require-match
+ (equal initial-input default-directory)
+ (equal initial-input ""))
+ (setq coll (cons initial-input coll)))
+ (setq initial-input (file-name-nondirectory initial-input))))
+ ((eq collection #'internal-complete-buffer)
+ (setq coll (ivy--buffer-list
+ ""
+ (and ivy-use-virtual-buffers
+ (member caller '(ivy-switch-buffer
+ ivy-switch-buffer-other-window
+ counsel-switch-buffer)))
+ predicate)))
+ (dynamic-collection
+ (setq coll (if (and (eq this-command 'ivy-resume) (not (buffer-modified-p)))
+ ivy--all-candidates
+ (ivy--dynamic-collection-cands (or initial-input "")))))
+ ((consp (car-safe collection))
+ (setq collection (cl-remove-if-not predicate collection))
+ (when (and sort (setq sort-fn (ivy--sort-function caller)))
+ (setq collection (sort (copy-sequence collection) sort-fn))
+ (setq sort nil))
+ (setf (ivy-state-collection ivy-last) collection)
+ (setq coll (let ((i -1))
+ (mapcar (lambda (x)
+ (propertize x 'idx (cl-incf i)))
+ (all-completions "" collection)))))
+ ((or (functionp collection)
+ (byte-code-function-p collection)
+ (vectorp collection)
+ (hash-table-p collection)
+ (and (listp collection) (symbolp (car collection))))
+ (let ((Info-complete-menu-buffer
+ ;; FIXME: This is a temporary workaround for issue #1803.
+ (or (bound-and-true-p Info-complete-menu-buffer)
+ (ivy-state-buffer state))))
+ (setq coll (all-completions "" collection predicate))))
+ (t
+ (setq coll (all-completions "" collection predicate))))
+ (unless (ivy-state-dynamic-collection ivy-last)
+ (setq coll (delete "" coll)))
+ (when (and sort
+ (or (functionp collection)
+ (not (eq history 'org-refile-history)))
+ (setq sort-fn (ivy--sort-function
+ (if (functionp collection) collection caller)))
+ (listp coll)
+ (null (nthcdr ivy-sort-max-size coll)))
+ (setq coll (sort (copy-sequence coll) sort-fn)))
+ (when def
+ (cond ((stringp (car-safe def))
+ (setq coll
+ (delete-dups
+ (append def coll))))
+ ((and (stringp def) (not (member def coll)))
+ (push def coll))))
+ (setq coll (ivy--set-candidates coll))
+ (setq ivy--old-re nil)
+ (setq ivy--old-cands nil)
+ (when initial-input
+ ;; Needed for anchor to work
+ (setq ivy--old-cands coll)
+ (setq ivy--old-cands (ivy--filter initial-input coll)))
+ (unless (setq ivy--trying-to-resume-dynamic-collection
+ (and preselect dynamic-collection))
+ (when (integerp preselect)
+ (setq ivy--old-re "")
+ (ivy-set-index preselect)))
+ (setq ivy--all-candidates coll)
+ (unless (integerp preselect)
+ (ivy-set-index (or
+ (and dynamic-collection
+ ivy--index)
+ (and preselect
+ (ivy--preselect-index
+ preselect
+ (if initial-input
+ ivy--old-cands
+ coll)))
+ 0))))
+ (setq ivy-exit nil)
+ (setq ivy--default
+ (if (region-active-p)
+ (buffer-substring (region-beginning) (region-end))
+ (ivy-thing-at-point)))
+ (setq ivy--prompt (ivy-add-prompt-count (ivy--quote-format-string prompt)))
+ (setq ivy--use-selectable-prompt (ivy--prompt-selectable-p))
+ (setf (ivy-state-initial-input ivy-last) initial-input)))
+
+(defun ivy-add-prompt-count (prompt)
+ "Add count information to PROMPT."
+ (cond ((null ivy-count-format)
+ (error "`ivy-count-format' must not be nil; set it to \"\" instead"))
+ ((string-match "%d.*\\(%d\\)" ivy-count-format)
+ (let* ((w
+ (if (listp ivy--all-candidates)
+ (1+ (floor (log (max 1 (length ivy--all-candidates)) 10)))
+ 1))
+ (s (replace-match (format "%%-%dd" w) t t ivy-count-format 1)))
+ (string-match "%d" s)
+ (concat (replace-match (format "%%%dd" w) t t s)
+ prompt)))
+ ((string-match-p "%.*d" ivy-count-format)
+ (concat ivy-count-format prompt))
+ (t
+ prompt)))
+
+(defun ivy--quote-format-string (str)
+ "Make STR suitable for `format' with no extra arguments."
+ (replace-regexp-in-string "%" "%%" str t t))
+
+;;;###autoload
+(defun ivy-completing-read (prompt collection
+ &optional predicate require-match initial-input
+ history def inherit-input-method)
+ "Read a string in the minibuffer, with completion.
+
+This interface conforms to `completing-read' and can be used for
+`completing-read-function'.
+
+PROMPT is a string that normally ends in a colon and a space.
+COLLECTION is either a list of strings, an alist, an obarray, or a hash table.
+PREDICATE limits completion to a subset of COLLECTION.
+REQUIRE-MATCH is a boolean value or a symbol. See `completing-read'.
+INITIAL-INPUT is a string inserted into the minibuffer initially.
+HISTORY is a list of previously selected inputs.
+DEF is the default value.
+INHERIT-INPUT-METHOD is currently ignored."
+ (let ((handler
+ (and (< ivy-completing-read-ignore-handlers-depth (minibuffer-depth))
+ (assq this-command ivy-completing-read-handlers-alist))))
+ (if handler
+ (let ((completion-in-region-function #'completion--in-region)
+ (ivy-completing-read-ignore-handlers-depth (1+ (minibuffer-depth))))
+ (funcall (cdr handler)
+ prompt collection
+ predicate require-match
+ initial-input history
+ def inherit-input-method))
+ ;; See the doc of `completing-read'.
+ (when (consp history)
+ (when (numberp (cdr history))
+ (setq initial-input (nth (1- (cdr history))
+ (symbol-value (car history)))))
+ (setq history (car history)))
+ (when (consp def)
+ (setq def (car def)))
+ (let ((str (ivy-read
+ prompt collection
+ :predicate predicate
+ :require-match (when (and collection require-match)
+ require-match)
+ :initial-input (cond ((consp initial-input)
+ (car initial-input))
+ ((and (stringp initial-input)
+ (not (eq collection #'read-file-name-internal))
+ (string-match-p "\\+" initial-input))
+ (replace-regexp-in-string
+ "\\+" "\\\\+" initial-input))
+ (t
+ initial-input))
+ :preselect def
+ :def def
+ :history history
+ :keymap nil
+ :dynamic-collection ivy-completing-read-dynamic-collection
+ :extra-props '(:caller ivy-completing-read)
+ :caller (if (and collection (symbolp collection))
+ collection
+ this-command))))
+ (if (string= str "")
+ ;; For `completing-read' compat, return the first element of
+ ;; DEFAULT, if it is a list; "", if DEFAULT is nil; or DEFAULT.
+ (or def "")
+ str)))))
+
+(defun ivy-completing-read-with-empty-string-def
+ (prompt collection
+ &optional predicate require-match initial-input
+ history def inherit-input-method)
+ "Same as `ivy-completing-read' but with different handling of DEF.
+
+Specifically, if DEF is nil, it is treated the same as if DEF was
+the empty string. This mimics the behavior of
+`completing-read-default'. This function can therefore be used in
+place of `ivy-completing-read' for commands that rely on this
+behavior."
+ (ivy-completing-read
+ prompt collection predicate require-match initial-input
+ history (or def "") inherit-input-method))
+
+(declare-function mc/all-fake-cursors "ext:multiple-cursors-core")
+
+(defun ivy-completion-in-region-action (str)
+ "Insert STR, erasing the previous one.
+The previous string is between `ivy-completion-beg' and `ivy-completion-end'."
+ (when (consp str)
+ (setq str (cdr str)))
+ (when (stringp str)
+ (let ((fake-cursors (and (require 'multiple-cursors-core nil t)
+ (mc/all-fake-cursors)))
+ (pt (point))
+ (beg ivy-completion-beg)
+ (end ivy-completion-end))
+ (when beg
+ (delete-region beg end))
+ (setq ivy-completion-beg (point))
+ (insert (substring-no-properties str))
+ (completion--done str 'exact)
+ (setq ivy-completion-end (point))
+ (save-excursion
+ (dolist (cursor fake-cursors)
+ (goto-char (overlay-start cursor))
+ (delete-region (+ (point) (- beg pt))
+ (+ (point) (- end pt)))
+ (insert (substring-no-properties str))
+ ;; manually move the fake cursor
+ (move-overlay cursor (point) (1+ (point)))
+ (set-marker (overlay-get cursor 'point) (point))
+ (set-marker (overlay-get cursor 'mark) (point)))))))
+
+(defun ivy-completion-common-length (str)
+ "Return the amount of characters that match in STR.
+
+`completion-all-completions' computes this and returns the result
+via text properties.
+
+The first non-matching part is propertized:
+- either with: (face (completions-first-difference))
+- or: (font-lock-face completions-first-difference)."
+ (let ((char-property-alias-alist '((face font-lock-face)))
+ (i (1- (length str))))
+ (catch 'done
+ (while (>= i 0)
+ (when (equal (get-text-property i 'face str)
+ '(completions-first-difference))
+ (throw 'done i))
+ (cl-decf i))
+ (throw 'done (length str)))))
+
+(defun ivy-completion-in-region (start end collection &optional predicate)
+ "An Ivy function suitable for `completion-in-region-function'.
+The function completes the text between START and END using COLLECTION.
+PREDICATE (a function called with no arguments) says when to exit.
+See `completion-in-region' for further information."
+ (let* ((enable-recursive-minibuffers t)
+ (str (buffer-substring-no-properties start end))
+ (completion-ignore-case (ivy--case-fold-p str))
+ (comps
+ (completion-all-completions str collection predicate (- end start))))
+ (cond ((null comps)
+ (message "No matches"))
+ ((progn
+ (nconc comps nil)
+ (and (null (cdr comps))
+ (string= str (car comps))))
+ (message "Sole match"))
+ (t
+ (when (eq collection 'crm--collection-fn)
+ (setq comps (delete-dups comps)))
+ (let* ((len (ivy-completion-common-length (car comps)))
+ (initial (cond ((= len 0)
+ "")
+ ((let ((str-len (length str)))
+ (when (> len str-len)
+ (setq len str-len)
+ str)))
+ (t
+ (substring str (- len))))))
+ (delete-region (- end len) end)
+ (setq ivy-completion-beg (- end len))
+ (setq ivy-completion-end ivy-completion-beg)
+ (if (null (cdr comps))
+ (progn
+ (unless (minibuffer-window-active-p (selected-window))
+ (setf (ivy-state-window ivy-last) (selected-window)))
+ (ivy-completion-in-region-action
+ (substring-no-properties (car comps))))
+ (dolist (s comps)
+ ;; Remove face `completions-first-difference'.
+ (ivy--remove-props s 'face))
+ (setq ivy--old-re nil)
+ (unless (ivy--filter initial comps)
+ (setq initial nil)
+ (setq predicate nil)
+ (setq collection comps))
+ (unless (derived-mode-p #'emacs-lisp-mode)
+ (setq collection comps)
+ (setq predicate nil))
+ (ivy-read (format "(%s): " str) collection
+ :predicate predicate
+ :initial-input (concat
+ (and (derived-mode-p #'emacs-lisp-mode)
+ "^")
+ initial)
+ :action #'ivy-completion-in-region-action
+ :unwind (lambda ()
+ (unless (eq ivy-exit 'done)
+ (goto-char ivy-completion-beg)
+ (when initial
+ (insert initial))))
+ :caller 'ivy-completion-in-region)))
+ ;; Return value should be non-nil on valid completion;
+ ;; see `completion-in-region'.
+ t))))
+
+(defun ivy-completion-in-region-prompt ()
+ "Prompt function for `ivy-completion-in-region'.
+See `ivy-set-prompt'."
+ (and (window-minibuffer-p (ivy-state-window ivy-last))
+ (ivy-add-prompt-count (ivy-state-prompt ivy-last))))
+
+(ivy-set-prompt #'ivy-completion-in-region #'ivy-completion-in-region-prompt)
+
+(defcustom ivy-do-completion-in-region t
+ "When non-nil `ivy-mode' will set `completion-in-region-function'."
+ :type 'boolean)
+
+(defvar ivy--old-crf nil
+ "Store previous value of `completing-read-function'.")
+
+(defvar ivy--old-cirf nil
+ "Store previous value of `completion-in-region-function'.")
+
+;;;###autoload
+(define-minor-mode ivy-mode
+ "Toggle Ivy mode on or off.
+Turn Ivy mode on if ARG is positive, off otherwise.
+Turning on Ivy mode sets `completing-read-function' to
+`ivy-completing-read'.
+
+Global bindings:
+\\{ivy-mode-map}
+
+Minibuffer bindings:
+\\{ivy-minibuffer-map}"
+ :group 'ivy
+ :global t
+ :keymap ivy-mode-map
+ :lighter " ivy"
+ (if ivy-mode
+ (progn
+ (unless (eq completing-read-function #'ivy-completing-read)
+ (setq ivy--old-crf completing-read-function)
+ (setq completing-read-function #'ivy-completing-read))
+ (when ivy-do-completion-in-region
+ (unless (eq completion-in-region-function #'ivy-completion-in-region)
+ (setq ivy--old-cirf completion-in-region-function)
+ (setq completion-in-region-function #'ivy-completion-in-region))))
+ (when (eq completing-read-function #'ivy-completing-read)
+ (setq completing-read-function (or ivy--old-crf
+ #'completing-read-default))
+ (setq ivy--old-crf nil))
+ (when (eq completion-in-region-function #'ivy-completion-in-region)
+ (setq completion-in-region-function (or ivy--old-cirf
+ #'completion--in-region))
+ (setq ivy--old-cirf nil))))
+
+(defun ivy--preselect-index (preselect candidates)
+ "Return the index of PRESELECT in CANDIDATES."
+ (or (cond ((integerp preselect)
+ (if (integerp (car candidates))
+ (cl-position preselect candidates)
+ preselect))
+ ((cl-position preselect candidates :test #'equal))
+ ((ivy--regex-p preselect)
+ (cl-position preselect candidates :test #'string-match-p)))
+ 0))
+
+;;* Implementation
+;;** Regex
+(defun ivy-re-match (re-seq str)
+ "Return non-nil if RE-SEQ is matched by STR.
+
+RE-SEQ is a list of (RE . MATCH-P).
+
+RE is a regular expression.
+
+MATCH-P is t when RE should match STR and nil when RE should not
+match STR.
+
+Each element of RE-SEQ must match for the function to return true.
+
+This concept is used to generalize regular expressions for
+`ivy--regex-plus' and `ivy--regex-ignore-order'."
+ (let ((res t)
+ re)
+ (while (and res (setq re (pop re-seq)))
+ (setq res
+ (if (cdr re)
+ (string-match-p (car re) str)
+ (not (string-match-p (car re) str)))))
+ res))
+
+(defvar ivy--regex-hash
+ (make-hash-table :test #'equal)
+ "Store pre-computed regex.")
+
+(defvar ivy--input-garbage nil)
+
+(defun ivy--split (str)
+ "Split STR into list of substrings bounded by spaces.
+Single spaces act as splitting points. Consecutive spaces
+\"quote\" their preceding spaces, i.e., guard them from being
+split. This allows the literal interpretation of N spaces by
+inputting N+1 spaces. Any substring not constituting a valid
+regexp is passed to `regexp-quote'."
+ (let ((len (length str))
+ (i 0)
+ (start 0)
+ (res nil)
+ match-len
+ end
+ c)
+ (catch 'break
+ (while (< i len)
+ (setq c (aref str i))
+ (cond ((= ?\[ c)
+ (if (setq end (ivy--match-regex-brackets
+ (substring str i)))
+ (cl-incf i end)
+ (setq ivy--input-garbage (substring str i))
+ (throw 'break nil)))
+ ((= ?\\ c)
+ (if (and (< (1+ i) len) (= ?\( (aref str (1+ i))))
+ (progn
+ (when (> i start)
+ (push (substring str start i) res))
+ (if (eq (string-match "\\\\([^\0]*?\\\\)" str i) i)
+ (progn
+ (push (match-string 0 str) res)
+ (setq i (match-end 0))
+ (setq start i))
+ (setq ivy--input-garbage (substring str i))
+ (throw 'break nil)))
+ (cl-incf i)))
+ ((= ?\ c)
+ (string-match " +" str i)
+ (setq match-len (- (match-end 0) (match-beginning 0)))
+ (if (= match-len 1)
+ (progn
+ (when (> i start)
+ (push (substring str start i) res))
+ (setq start (1+ i)))
+ (setq str (replace-match
+ (make-string (1- match-len) ?\ )
+ nil nil str))
+ (setq len (length str))
+ (cl-incf i (1- match-len)))
+ (cl-incf i))
+ (t
+ (cl-incf i)))))
+ (when (< start i)
+ (push (substring str start) res))
+ (mapcar #'ivy--regex-or-literal (nreverse res))))
+
+(defun ivy--match-regex-brackets (str)
+ (let ((len (length str))
+ (i 1)
+ (open-count 1)
+ c)
+ (while (and (< i len)
+ (> open-count 0))
+ (setq c (aref str i))
+ (cond ((= c ?\[)
+ (cl-incf open-count))
+ ((= c ?\])
+ (cl-decf open-count)))
+ (cl-incf i))
+ (when (= open-count 0)
+ (if (eq (string-match "[+*?]" str i) i)
+ (match-end 0)
+ i))))
+
+(defun ivy--trim-trailing-re (regex)
+ "Trim incomplete REGEX.
+If REGEX ends with \\|, trim it, since then it matches an empty string."
+ (if (string-match "\\`\\(.*\\)[\\]|\\'" regex)
+ (match-string 1 regex)
+ regex))
+
+(defun ivy--regex (str &optional greedy)
+ "Re-build regex pattern from STR in case it has a space.
+When GREEDY is non-nil, join words in a greedy way."
+ (let ((hashed (unless greedy
+ (gethash str ivy--regex-hash))))
+ (if hashed
+ (progn
+ (setq ivy--subexps (car hashed))
+ (cdr hashed))
+ (when (string-match-p "\\(?:[^\\]\\|^\\)\\\\\\'" str)
+ (setq str (substring str 0 -1)))
+ (setq str (ivy--trim-trailing-re str))
+ (cdr (puthash str
+ (let ((subs (ivy--split str)))
+ (if (= (length subs) 1)
+ (cons
+ (setq ivy--subexps 0)
+ (if (string-match-p "\\`\\.[^.]" (car subs))
+ (concat "\\." (substring (car subs) 1))
+ (car subs)))
+ (cons
+ (setq ivy--subexps (length subs))
+ (replace-regexp-in-string
+ "\\.\\*\\??\\\\( "
+ "\\( "
+ (mapconcat
+ (lambda (x)
+ (if (string-match-p "\\`\\\\([^?][^\0]*\\\\)\\'" x)
+ x
+ (format "\\(%s\\)" x)))
+ subs
+ (if greedy ".*" ".*?"))
+ nil t))))
+ ivy--regex-hash)))))
+
+(defun ivy--regex-p (object)
+ "Return OBJECT if it is a valid regular expression, else nil."
+ (ignore-errors (string-match-p object "") object))
+
+(defun ivy--regex-or-literal (str)
+ "If STR isn't a legal regexp, escape it."
+ (or (ivy--regex-p str) (regexp-quote str)))
+
+(defun ivy--split-negation (str)
+ "Split STR into text before and after ! delimiter.
+Do not split if the delimiter is escaped as \\!.
+
+Assumes there is at most one un-escaped delimiter and discards
+text after delimiter if it is empty. Modifies match data."
+ (unless (string= str "")
+ (let ((delim "\\(?:\\`\\|[^\\]\\)\\(!\\)"))
+ (mapcar (lambda (split)
+ ;; Store "\!" as "!".
+ (replace-regexp-in-string "\\\\!" "!" split t t))
+ (if (string-match delim str)
+ ;; Ignore everything past first un-escaped ! rather than
+ ;; crashing. We can't warn or error because the minibuffer is
+ ;; already active.
+ (let* ((i (match-beginning 1))
+ (j (and (string-match delim str (1+ i))
+ (match-beginning 1)))
+ (neg (substring str (1+ i) j)))
+ (cons (substring str 0 i)
+ (and (not (string= neg ""))
+ (list neg))))
+ (list str))))))
+
+(defun ivy--split-spaces (str)
+ "Split STR on spaces, unless they're preceded by \\.
+No un-escaped spaces are left in the output. Any substring not
+constituting a valid regexp is passed to `regexp-quote'."
+ (when str
+ (let ((i 0) ; End of last search.
+ (j 0) ; End of last delimiter.
+ parts)
+ (while (string-match "\\(\\\\ \\)\\| +" str i)
+ (setq i (match-end 0))
+ (if (not (match-beginning 1))
+ ;; Un-escaped space(s).
+ (let ((delim (match-beginning 0)))
+ (when (< j delim)
+ (push (substring str j delim) parts))
+ (setq j i))
+ ;; Store "\ " as " ".
+ (setq str (replace-match " " t t str 1))
+ (setq i (1- i))))
+ (when (< j (length str))
+ (push (substring str j) parts))
+ (mapcar #'ivy--regex-or-literal (nreverse parts)))))
+
+(defun ivy--regex-ignore-order (str)
+ "Re-build regex from STR by splitting at spaces and using ! for negation.
+
+Examples:
+foo -> matches \"foo\"
+foo bar -> matches if both \"foo\" and \"bar\" match (any order)
+foo !bar -> matches if \"foo\" matches and \"bar\" does not match
+foo !bar baz -> matches if \"foo\" matches and neither \"bar\" nor \"baz\" match
+foo[a-z] -> matches \"foo[a-z]\"
+
+Escaping examples:
+foo\\!bar -> matches \"foo!bar\"
+foo\\ bar -> matches \"foo bar\"
+
+Returns a list suitable for `ivy-re-match'."
+ (setq str (ivy--trim-trailing-re str))
+ (let* (regex-parts
+ (raw-parts (ivy--split-negation str)))
+ (dolist (part (ivy--split-spaces (car raw-parts)))
+ (push (cons part t) regex-parts))
+ (when (cdr raw-parts)
+ (dolist (part (ivy--split-spaces (cadr raw-parts)))
+ (push (cons part nil) regex-parts)))
+ (if regex-parts (nreverse regex-parts)
+ "")))
+
+(defun ivy--regex-plus (str)
+ "Build a regex sequence from STR.
+Spaces are wild card characters, everything before \"!\" should
+match. Everything after \"!\" should not match."
+ (let ((parts (ivy--split-negation str)))
+ (cl-case (length parts)
+ (0
+ "")
+ (1
+ (if (= (aref str 0) ?!)
+ (list (cons "" t)
+ (list (ivy--regex (car parts))))
+ (ivy--regex (car parts))))
+ (2
+ (cons
+ (cons (ivy--regex (car parts)) t)
+ (mapcar #'list (split-string (cadr parts) " " t))))
+ (t (error "Unexpected: use only one !")))))
+
+(defun ivy--regex-fuzzy (str)
+ "Build a regex sequence from STR.
+Insert .* between each char."
+ (setq str (ivy--trim-trailing-re str))
+ (if (string-match "\\`\\(\\^?\\)\\(.*?\\)\\(\\$?\\)\\'" str)
+ (prog1
+ (concat (match-string 1 str)
+ (let ((lst (string-to-list (match-string 2 str))))
+ (apply #'concat
+ (cl-mapcar
+ #'concat
+ (cons "" (cdr (mapcar (lambda (c) (format "[^%c\n]*" c))
+ lst)))
+ (mapcar (lambda (x) (format "\\(%s\\)" (regexp-quote (char-to-string x))))
+ lst))))
+ (match-string 3 str))
+ (setq ivy--subexps (length (match-string 2 str))))
+ str))
+
+(defcustom ivy-fixed-height-minibuffer nil
+ "When non nil, fix the height of the minibuffer during ivy completion.
+This effectively sets the minimum height at this level to `ivy-height' and
+tries to ensure that it does not change depending on the number of candidates."
+ :type 'boolean)
+
+;;** Rest
+(defcustom ivy-truncate-lines t
+ "Minibuffer setting for `truncate-lines'."
+ :type 'boolean)
+
+(defun ivy--minibuffer-setup ()
+ "Setup ivy completion in the minibuffer."
+ (setq-local mwheel-scroll-up-function 'ivy-next-line)
+ (setq-local mwheel-scroll-down-function 'ivy-previous-line)
+ (setq-local completion-show-inline-help nil)
+ (setq-local line-spacing nil)
+ (setq-local minibuffer-default-add-function
+ (lambda ()
+ (list ivy--default)))
+ (setq-local inhibit-field-text-motion nil)
+ (setq truncate-lines ivy-truncate-lines)
+ (setq-local max-mini-window-height ivy-height)
+ (let ((height (cond ((and ivy-fixed-height-minibuffer
+ (not (eq (ivy-state-caller ivy-last)
+ #'ivy-completion-in-region)))
+ (+ ivy-height (if ivy-add-newline-after-prompt 1 0)))
+ (ivy-add-newline-after-prompt 2))))
+ (when height
+ (set-window-text-height nil height)))
+ (add-hook 'post-command-hook #'ivy--queue-exhibit nil t)
+ (add-hook 'window-size-change-functions #'ivy--window-size-changed nil t)
+ (let ((hook (ivy-alist-setting ivy-hooks-alist)))
+ (when (functionp hook)
+ (funcall hook))))
+
+(defun ivy--input ()
+ "Return the current minibuffer input."
+ ;; assume one-line minibuffer input
+ (save-excursion
+ (goto-char (minibuffer-prompt-end))
+ (let ((inhibit-field-text-motion t))
+ (buffer-substring-no-properties
+ (point)
+ (line-end-position)))))
+
+(defun ivy--minibuffer-cleanup ()
+ "Delete the displayed completion candidates."
+ (save-excursion
+ (goto-char (minibuffer-prompt-end))
+ (delete-region (line-end-position) (point-max))))
+
+(defun ivy-cleanup-string (str)
+ "Destructively remove unwanted text properties from STR."
+ (ivy--remove-props str 'field))
+
+(defvar ivy-set-prompt-text-properties-function
+ #'ivy-set-prompt-text-properties-default
+ "Function to set the text properties of the default ivy prompt.
+Called with two arguments, PROMPT and PROPS, where PROMPT is the
+string to be propertized and PROPS is a plist of default text
+properties that may be applied to PROMPT. The function should
+return the propertized PROMPT, which may be modified in-place.")
+
+(defun ivy-set-prompt-text-properties-default (prompt props)
+ "Propertize (confirm) and (match required) parts of PROMPT.
+PROPS is a plist of default text properties to apply to these
+parts beyond their respective faces `ivy-confirm-face' and
+`ivy-match-required-face'."
+ (dolist (pair '(("confirm" . ivy-confirm-face)
+ ("match required" . ivy-match-required-face)))
+ (let ((i (string-match-p (car pair) prompt)))
+ (when i
+ (add-text-properties i (+ i (length (car pair)))
+ `(face ,(cdr pair) ,@props)
+ prompt))))
+ prompt)
+
+(defun ivy-prompt ()
+ "Return the current prompt."
+ (let* ((caller (ivy-state-caller ivy-last))
+ (fn (plist-get ivy--prompts-list caller)))
+ (if fn
+ (condition-case err
+ (funcall fn)
+ (wrong-number-of-arguments
+ (lwarn 'ivy :error "%s
+ Prompt function set via `ivy-set-prompt' for caller `%s'
+ should take no arguments."
+ (error-message-string err)
+ caller)
+ ;; Old behavior.
+ (funcall fn (ivy-state-prompt ivy-last))))
+ ivy--prompt)))
+
+(defun ivy--insert-prompt ()
+ "Update the prompt according to `ivy--prompt'."
+ (when (setq ivy--prompt (ivy-prompt))
+ (unless (memq this-command '(ivy-done ivy-alt-done ivy-partial-or-done
+ counsel-find-symbol))
+ (setq ivy--prompt-extra ""))
+ (let (head tail)
+ (if (string-match "\\(.*?\\)\\(:? ?\\)\\'" ivy--prompt)
+ (progn
+ (setq head (match-string 1 ivy--prompt))
+ (setq tail (match-string 2 ivy--prompt)))
+ (setq head ivy--prompt)
+ (setq tail ""))
+ (let ((inhibit-read-only t)
+ (std-props '(front-sticky t rear-nonsticky t field t read-only t))
+ (n-str
+ (concat
+ (if (and (bound-and-true-p minibuffer-depth-indicate-mode)
+ (> (minibuffer-depth) 1))
+ (format "[%d] " (minibuffer-depth))
+ "")
+ (concat
+ (if (string-match "%d.*%d" ivy-count-format)
+ (format head
+ (1+ ivy--index)
+ (or (and (ivy-state-dynamic-collection ivy-last)
+ ivy--full-length)
+ ivy--length))
+ (format head
+ (or (and (ivy-state-dynamic-collection ivy-last)
+ ivy--full-length)
+ ivy--length)))
+ ivy--prompt-extra
+ tail)))
+ (d-str (if ivy--directory
+ (abbreviate-file-name ivy--directory)
+ "")))
+ (save-excursion
+ (goto-char (point-min))
+ (delete-region (point-min) (minibuffer-prompt-end))
+ (let ((len-n (length n-str))
+ (len-d (length d-str))
+ (ww (window-width)))
+ (setq n-str
+ (cond ((> (+ len-n len-d) ww)
+ (concat n-str "\n" d-str "\n"))
+ ((> (+ len-n len-d (length ivy-text)) ww)
+ (concat n-str d-str "\n"))
+ (t
+ (concat n-str d-str)))))
+ (when ivy-pre-prompt-function
+ (setq n-str (concat (funcall ivy-pre-prompt-function) n-str)))
+ (when ivy-add-newline-after-prompt
+ (setq n-str (concat n-str "\n")))
+ (let ((regex (format "\\([^\n]\\{%d\\}\\)[^\n]" (window-width))))
+ (while (string-match regex n-str)
+ (setq n-str (replace-match
+ (concat (match-string 1 n-str) "\n")
+ nil t n-str 1))))
+ (set-text-properties 0 (length n-str)
+ `(face minibuffer-prompt ,@std-props)
+ n-str)
+ (setq n-str (funcall ivy-set-prompt-text-properties-function
+ n-str std-props))
+ (insert n-str))
+ ;; Mark prompt as selected if the user moves there or it is the only
+ ;; option left. Since the user input stays put, we have to manually
+ ;; remove the face as well.
+ (when ivy--use-selectable-prompt
+ (if (= ivy--index -1)
+ (add-face-text-property
+ (minibuffer-prompt-end) (line-end-position) 'ivy-prompt-match)
+ (remove-list-of-text-properties
+ (minibuffer-prompt-end) (line-end-position) '(face))))
+ ;; get out of the prompt area
+ (constrain-to-field nil (point-max))))))
+
+(defun ivy--sort-maybe (collection)
+ "Sort COLLECTION if needed."
+ (let ((sort (ivy-state-sort ivy-last)))
+ (if (and sort
+ (or (functionp sort)
+ (functionp (setq sort (ivy--sort-function
+ (ivy-state-collection ivy-last))))))
+ (sort (copy-sequence collection) sort)
+ collection)))
+
+(defcustom ivy-magic-slash-non-match-action 'ivy-magic-slash-non-match-cd-selected
+ "Action to take when a slash is added to the end of a non existing directory.
+Possible choices are 'ivy-magic-slash-non-match-cd-selected,
+'ivy-magic-slash-non-match-create, or nil"
+ :type '(choice
+ (const :tag "Use currently selected directory"
+ ivy-magic-slash-non-match-cd-selected)
+ (const :tag "Create and use new directory"
+ ivy-magic-slash-non-match-create)
+ (const :tag "Do nothing"
+ nil)))
+
+(defun ivy--create-and-cd (dir)
+ "When completing file names, create directory DIR and move there."
+ (make-directory dir)
+ (ivy--cd dir))
+
+(defun ivy--magic-file-doubleslash-directory ()
+ "Return an appropriate directory for when two slashes are entered."
+ (let (remote)
+ (cond
+ ;; Windows
+ ;; ((string-match "\\`[[:alpha:]]:/" ivy--directory)
+ ;; (match-string 0 ivy--directory))
+ ;; Remote root if on remote
+ ((setq remote (file-remote-p ivy--directory))
+ (concat remote "/"))
+ ;; Local root
+ (t
+ "/"))))
+
+(defun ivy--magic-file-slash ()
+ "Handle slash when completing file names."
+ (when (or (and (eq this-command #'self-insert-command)
+ (eolp))
+ (eq this-command #'ivy-partial-or-done))
+ (let ((canonical (expand-file-name ivy-text ivy--directory))
+ (magic (not (string= ivy-text "/"))))
+ (cond ((member ivy-text ivy--all-candidates)
+ (ivy--cd canonical))
+ ((and (eq system-type 'windows-nt) (string= ivy-text "//")))
+ ((string-suffix-p "//" ivy-text)
+ (ivy--cd
+ (ivy--magic-file-doubleslash-directory)))
+ ((string-match-p "\\`/ssh:" ivy-text)
+ (ivy--cd (file-name-directory ivy-text)))
+ ((string-match "[[:alpha:]]:/\\'" ivy-text)
+ (let ((drive-root (match-string 0 ivy-text)))
+ (when (file-exists-p drive-root)
+ (ivy--cd drive-root))))
+ ((and magic (file-directory-p canonical))
+ (ivy--cd canonical))
+ ((let ((default-directory ivy--directory))
+ (and (or (> ivy--index 0)
+ (= ivy--length 1)
+ magic)
+ (not (ivy--prompt-selected-p))
+ (not (equal (ivy-state-current ivy-last) ""))
+ (file-directory-p (ivy-state-current ivy-last))
+ (or (eq ivy-magic-slash-non-match-action
+ 'ivy-magic-slash-non-match-cd-selected)
+ (eq this-command #'ivy-partial-or-done))))
+ (ivy--cd
+ (expand-file-name (ivy-state-current ivy-last) ivy--directory)))
+ ((and (eq ivy-magic-slash-non-match-action
+ 'ivy-magic-slash-non-match-create)
+ magic)
+ (ivy--create-and-cd canonical))))))
+
+(defun ivy-magic-read-file-env ()
+ "If reading filename, jump to environment variable location."
+ (interactive)
+ (if (and ivy--directory
+ (equal ivy-text ""))
+ (let* ((cands (cl-loop for pair in process-environment
+ for (var val) = (split-string pair "=" t)
+ if (and val (not (equal "" val)))
+ if (file-exists-p
+ (if (file-name-absolute-p val)
+ val
+ (setq val
+ (expand-file-name val ivy--directory))))
+ collect (cons var val)))
+ (enable-recursive-minibuffers t)
+ (x (ivy-read "Env: " cands))
+ (path (cdr (assoc x cands))))
+ (insert (if (file-accessible-directory-p path)
+ (file-name-as-directory path)
+ path))
+ (ivy--cd-maybe))
+ (insert last-input-event)))
+
+(defun ivy-make-magic-action (caller key)
+ "Return a command that does the equivalent of `ivy-read-action' and KEY.
+This happens only when the input is empty.
+The intention is to bind the result to keys that are typically
+bound to `self-insert-command'."
+ (let* ((alist (assoc key
+ (plist-get
+ ivy--actions-list
+ caller)))
+ (doc (format "%s (`%S')"
+ (nth 2 alist)
+ (nth 1 alist))))
+ `(lambda (&optional arg)
+ ,doc
+ (interactive "p")
+ (if (string= "" ivy-text)
+ (execute-kbd-macro
+ (kbd ,(concat "M-o " key)))
+ (self-insert-command arg)))))
+
+(defcustom ivy-magic-tilde t
+ "When non-nil, ~ will move home when selecting files.
+Otherwise, ~/ will move home."
+ :type 'boolean)
+
+(defcustom ivy-dynamic-exhibit-delay-ms 0
+ "Delay in ms before dynamic collections are refreshed"
+ :type 'integer)
+
+(defvar ivy--exhibit-timer nil)
+
+(defun ivy--queue-exhibit ()
+ "Insert Ivy completions display, possibly after a timeout for
+dynamic collections.
+Should be run via minibuffer `post-command-hook'."
+ (if (and (> ivy-dynamic-exhibit-delay-ms 0)
+ (ivy-state-dynamic-collection ivy-last))
+ (progn
+ (when ivy--exhibit-timer (cancel-timer ivy--exhibit-timer))
+ (setq ivy--exhibit-timer
+ (run-with-timer
+ (/ ivy-dynamic-exhibit-delay-ms 1000.0)
+ nil
+ 'ivy--exhibit)))
+ (ivy--exhibit)))
+
+(defalias 'ivy--file-local-name
+ (if (fboundp 'file-local-name)
+ #'file-local-name
+ (lambda (file)
+ (or (file-remote-p file 'localname) file)))
+ "Compatibility shim for `file-local-name'.
+The function was added in Emacs 26.1.")
+
+(defun ivy--magic-tilde-directory (dir)
+ "Return an appropriate home for DIR for when ~ or ~/ are entered."
+ (file-name-as-directory
+ (expand-file-name
+ (let* ((home (expand-file-name (concat (file-remote-p dir) "~/")))
+ (dir-path (ivy--file-local-name dir))
+ (home-path (ivy--file-local-name home)))
+ (if (string= dir-path home-path)
+ "~"
+ home)))))
+
+(defun ivy-update-candidates (cands)
+ (ivy--insert-minibuffer
+ (ivy--format
+ (setq ivy--all-candidates cands))))
+
+(defun ivy--exhibit ()
+ "Insert Ivy completions display.
+Should be run via minibuffer `post-command-hook'."
+ (when (memq 'ivy--queue-exhibit post-command-hook)
+ (let ((inhibit-field-text-motion nil))
+ (constrain-to-field nil (point-max)))
+ (ivy-set-text (ivy--input))
+ (let ((new-minibuffer (ivy--update-minibuffer)))
+ (when new-minibuffer
+ (ivy--insert-minibuffer new-minibuffer)))
+ t))
+
+(defun ivy--dynamic-collection-cands (input)
+ (let ((coll (funcall (ivy-state-collection ivy-last) input)))
+ (if (listp coll)
+ (mapcar (lambda (x) (if (consp x) (car x) x)) coll)
+ coll)))
+
+(defun ivy--update-minibuffer ()
+ (prog1
+ (if (ivy-state-dynamic-collection ivy-last)
+ ;; while-no-input would cause annoying
+ ;; "Waiting for process to die...done" message interruptions
+ (let ((inhibit-message t)
+ coll in-progress)
+ (unless (or (equal ivy--old-text ivy-text)
+ (eq this-command 'ivy-resume))
+ (while-no-input
+ (setq coll (ivy--dynamic-collection-cands ivy-text))
+ (when (eq coll 0)
+ (setq coll nil)
+ (setq ivy--old-re nil)
+ (setq in-progress t))
+ (setq ivy--all-candidates (ivy--sort-maybe coll))))
+ (when (eq ivy--all-candidates 0)
+ (setq ivy--all-candidates nil)
+ (setq ivy--old-re nil)
+ (setq in-progress t))
+ (when (or ivy--all-candidates
+ (and (not (get-process " *counsel*"))
+ (not in-progress)))
+ (ivy--set-index-dynamic-collection)
+ (ivy--format ivy--all-candidates)))
+ (cond (ivy--directory
+ (cond ((or (string= "~/" ivy-text)
+ (and (string= "~" ivy-text)
+ ivy-magic-tilde))
+ (ivy--cd (ivy--magic-tilde-directory ivy--directory)))
+ ((string-match "/\\'" ivy-text)
+ (ivy--magic-file-slash))))
+ ((eq (ivy-state-collection ivy-last) #'internal-complete-buffer)
+ (when (or (and (string-match "\\` " ivy-text)
+ (not (string-match "\\` " ivy--old-text)))
+ (and (string-match "\\` " ivy--old-text)
+ (not (string-match "\\` " ivy-text))))
+ (setq ivy--all-candidates
+ (if (= (string-to-char ivy-text) ?\s)
+ (ivy--buffer-list " ")
+ (ivy--buffer-list "" ivy-use-virtual-buffers)))
+ (setq ivy--old-re nil))))
+ (with-current-buffer (ivy-state-buffer ivy-last)
+ (ivy--format
+ (ivy--filter ivy-text ivy--all-candidates))))
+ (setq ivy--old-text ivy-text)))
+
+(defun ivy-display-function-fallback (str)
+ (let ((buffer-undo-list t))
+ (save-excursion
+ (forward-line 1)
+ (insert str))))
+
+(defun ivy--insert-minibuffer (text)
+ "Insert TEXT into minibuffer with appropriate cleanup."
+ (let ((resize-mini-windows nil)
+ (update-fn (ivy-state-update-fn ivy-last))
+ (old-mark (marker-position (mark-marker)))
+ (win (active-minibuffer-window))
+ deactivate-mark)
+ (when win
+ (with-selected-window win
+ (ivy--minibuffer-cleanup)
+ (when update-fn
+ (funcall update-fn))
+ (ivy--insert-prompt)
+ ;; Do nothing if while-no-input was aborted.
+ (when (stringp text)
+ (if ivy--display-function
+ (funcall ivy--display-function text)
+ (ivy-display-function-fallback text)))
+ (ivy--resize-minibuffer-to-fit)
+ ;; prevent region growing due to text remove/add
+ (when (region-active-p)
+ (set-mark old-mark))))))
+
+(defvar ivy-auto-shrink-minibuffer nil
+ "When non-nil and the height < `ivy-height', auto-shrink the minibuffer.")
+
+(make-obsolete-variable 'ivy-auto-shrink-minibuffer
+ 'ivy-auto-shrink-minibuffer-alist
+ "<2020-04-28 Tue>")
+
+(defcustom ivy-auto-shrink-minibuffer-alist nil
+ "An alist to configure auto-shrinking of the minibuffer.
+
+Each key is a caller symbol. When the value is non-nil, and the
+height < `ivy-height', auto-shrink the minibuffer."
+ :type '(alist
+ :key-type symbol
+ :value-type boolean))
+
+(defun ivy--do-shrink-window ()
+ (let ((h (save-excursion
+ (goto-char (minibuffer-prompt-end))
+ (let ((inhibit-field-text-motion t))
+ (line-number-at-pos)))))
+ (shrink-window (-
+ (/ (window-body-height nil t)
+ (frame-char-height))
+ ivy--length h))))
+
+(defun ivy--resize-minibuffer-to-fit ()
+ "Resize the minibuffer window size to fit the text in the minibuffer."
+ (unless (or (frame-root-window-p (minibuffer-window))
+ (memq this-command '(ivy-read-action
+ ivy-dispatching-done
+ ivy-dispatching-call)))
+ (with-selected-window (minibuffer-window)
+ (if (fboundp 'window-text-pixel-size)
+ (let ((text-height (cdr (window-text-pixel-size)))
+ (body-height (window-body-height nil t)))
+ (cond ((> text-height body-height)
+ ;; Note: the size increment needs to be at least
+ ;; frame-char-height, otherwise resizing won't do
+ ;; anything.
+ (let ((delta (max (- text-height body-height)
+ (frame-char-height))))
+ (window-resize nil delta nil t t)))
+ ((and (or ivy-auto-shrink-minibuffer
+ (ivy-alist-setting
+ ivy-auto-shrink-minibuffer-alist))
+ (< ivy--length ivy-height))
+ (ivy--do-shrink-window))))
+ (let ((text-height (count-screen-lines))
+ (body-height (window-body-height)))
+ (when (> text-height body-height)
+ (window-resize nil (- text-height body-height) nil t)))))))
+
+(defun ivy--window-size-changed (&rest _)
+ "Resize ivy window to fit with current frame's size."
+ (when ivy-mode
+ (ivy--resize-minibuffer-to-fit)))
+
+(defun ivy--add-face (str face)
+ "Propertize STR with FACE."
+ (let ((len (length str)))
+ (condition-case nil
+ (progn
+ (colir-blend-face-background 0 len face str)
+ (let ((foreground (face-foreground face)))
+ (when foreground
+ (add-face-text-property
+ 0 len (list :foreground foreground) nil str))))
+ (error
+ (ignore-errors
+ (font-lock-append-text-property 0 len 'face face str)))))
+ str)
+
+(declare-function flx-make-string-cache "ext:flx")
+(declare-function flx-score "ext:flx")
+
+(defvar ivy--flx-cache nil)
+
+(with-eval-after-load 'flx
+ (setq ivy--flx-cache (flx-make-string-cache)))
+
+(defun ivy-toggle-case-fold ()
+ "Toggle `case-fold-search' for Ivy operations.
+
+Instead of modifying `case-fold-search' directly, this command
+toggles `ivy-case-fold-search', which can take on more values
+than the former, between nil and either `auto' or t. See
+`ivy-case-fold-search-default' for the meaning of these values.
+
+In any Ivy completion session, the case folding starts with
+`ivy-case-fold-search-default'."
+ (interactive)
+ (setq ivy-case-fold-search
+ (and (not ivy-case-fold-search)
+ (or ivy-case-fold-search-default 'auto)))
+ ;; Reset cache so that the candidate list updates.
+ (setq ivy--old-re nil))
+
+(defun ivy--re-filter (re candidates &optional mkpred)
+ "Return all RE matching CANDIDATES.
+RE is a list of cons cells, with a regexp car and a boolean cdr.
+When the cdr is t, the car must match.
+Otherwise, the car must not match."
+ (if (equal re "")
+ candidates
+ (ignore-errors
+ (dolist (re (if (stringp re) (list (cons re t)) re))
+ (let* ((re-str (car re))
+ (pred
+ (if mkpred
+ (funcall mkpred re-str)
+ (lambda (x) (string-match-p re-str x)))))
+ (setq candidates
+ (cl-remove nil candidates
+ (if (cdr re) :if-not :if)
+ pred))))
+ candidates)))
+
+(defun ivy--filter (name candidates)
+ "Return all items that match NAME in CANDIDATES.
+CANDIDATES are assumed to be static."
+ (let ((re (funcall ivy--regex-function name)))
+ (if (and
+ ivy--old-re
+ ivy--old-cands
+ (equal re ivy--old-re))
+ ;; quick caching for "C-n", "C-p" etc.
+ ivy--old-cands
+ (let* ((re-str (ivy-re-to-str re))
+ (matcher (ivy-state-matcher ivy-last))
+ (case-fold-search (ivy--case-fold-p name))
+ (cands (cond
+ (matcher
+ (funcall matcher re candidates))
+ ((and ivy--old-re
+ (stringp re)
+ (stringp ivy--old-re)
+ (not (string-match-p "\\\\" ivy--old-re))
+ (not (equal ivy--old-re ""))
+ (memq (cl-search
+ (if (string-match-p "\\\\)\\'" ivy--old-re)
+ (substring ivy--old-re 0 -2)
+ ivy--old-re)
+ re)
+ '(0 2))
+ ivy--old-cands
+ (ivy--re-filter re ivy--old-cands)))
+ (t
+ (ivy--re-filter re candidates)))))
+ (if (memq (cdr (assq (ivy-state-caller ivy-last)
+ ivy-index-functions-alist))
+ '(ivy-recompute-index-swiper
+ ivy-recompute-index-swiper-async
+ ivy-recompute-index-swiper-async-backward
+ ivy-recompute-index-swiper-backward))
+ (progn
+ (ivy--recompute-index re-str cands)
+ (setq ivy--old-cands (ivy--sort name cands)))
+ (setq ivy--old-cands (ivy--sort name cands))
+ (ivy--recompute-index re-str ivy--old-cands))
+ (setq ivy--old-re re)
+ ivy--old-cands))))
+
+(defun ivy--set-candidates (x)
+ "Update `ivy--all-candidates' with X."
+ (let (res
+ ;; (ivy--recompute-index-inhibit t)
+ )
+ (dolist (source ivy--extra-candidates)
+ (if (equal source '(original-source))
+ (if (null res)
+ (setq res x)
+ (setq res (append x res)))
+ (setq ivy--old-re nil)
+ (setq res (append
+ (ivy--filter ivy-text (cadr source))
+ res))))
+ (setq ivy--all-candidates
+ (if (cdr ivy--extra-candidates)
+ (delete-dups res)
+ res))))
+
+(defun ivy--shorter-matches-first (_name cands)
+ "Sort CANDS according to their length."
+ (if (nthcdr ivy-sort-max-size cands)
+ cands
+ (cl-sort (copy-sequence cands) #'< :key #'length)))
+
+(defcustom ivy-sort-matches-functions-alist
+ '((t . nil)
+ (ivy-completion-in-region . ivy--shorter-matches-first)
+ (ivy-switch-buffer . ivy-sort-function-buffer))
+ "An alist of functions for sorting matching candidates.
+
+Unlike `ivy-sort-functions-alist', which is used to sort the
+whole collection only once, this alist of functions are used to
+sort only matching candidates after each change in input.
+
+The alist KEY is either a collection function or t to match
+previously unmatched collection functions.
+
+The alist VAL is a sorting function with the signature of
+`ivy--prefix-sort'."
+ :type '(alist
+ :key-type (choice
+ (const :tag "Fall-through" t)
+ (symbol :tag "Collection"))
+ :value-type
+ (choice
+ (const :tag "Don't sort" nil)
+ (const :tag "Put prefix matches ahead" ivy--prefix-sort)
+ (function :tag "Custom sort function"))))
+
+(defun ivy--sort-files-by-date (_name candidates)
+ "Re-sort CANDIDATES according to file modification date."
+ (let ((default-directory ivy--directory))
+ (sort (copy-sequence candidates) #'file-newer-than-file-p)))
+
+(defvar ivy--flx-featurep (require 'flx nil 'noerror))
+
+(defun ivy--sort (name candidates)
+ "Re-sort candidates by NAME.
+All CANDIDATES are assumed to match NAME."
+ (let (fun)
+ (cond ((setq fun (ivy-alist-setting ivy-sort-matches-functions-alist))
+ (funcall fun name candidates))
+ ((and ivy--flx-featurep
+ (eq ivy--regex-function 'ivy--regex-fuzzy))
+ (ivy--flx-sort name candidates))
+ (t
+ candidates))))
+
+(defun ivy--prefix-sort (name candidates)
+ "Re-sort candidates by NAME.
+All CANDIDATES are assumed to match NAME.
+Prefix matches to NAME are put ahead of the list."
+ (if (or (string= name "")
+ (= (aref name 0) ?^))
+ candidates
+ (let ((re-prefix (concat "\\`" (funcall ivy--regex-function name)))
+ res-prefix
+ res-noprefix)
+ (dolist (s candidates)
+ (if (string-match-p re-prefix s)
+ (push s res-prefix)
+ (push s res-noprefix)))
+ (nconc
+ (nreverse res-prefix)
+ (nreverse res-noprefix)))))
+
+(defvar ivy--virtual-buffers nil
+ "Store the virtual buffers alist.")
+
+(defun ivy-re-to-str (re)
+ "Transform RE to a string.
+
+Functions like `ivy--regex-ignore-order' return a cons list.
+This function extracts a string from the cons list."
+ (if (consp re) (caar re) re))
+
+(defun ivy-sort-function-buffer (name candidates)
+ "Re-sort candidates by NAME.
+CANDIDATES is a list of buffer names each containing NAME.
+Sort open buffers before virtual buffers, and prefix matches
+before substring matches."
+ (if (or (string= name "")
+ (= (aref name 0) ?^))
+ candidates
+ (let* ((base-re (ivy-re-to-str (funcall ivy--regex-function name)))
+ (re-star-prefix (concat "\\`\\*" base-re))
+ (re-prefix (concat "\\`" base-re))
+ res-prefix
+ res-noprefix
+ res-virtual-prefix
+ res-virtual-noprefix)
+ (dolist (s candidates)
+ (cond
+ ((and (assoc s ivy--virtual-buffers)
+ (or (string-match-p re-star-prefix s)
+ (string-match-p re-prefix s)))
+ (push s res-virtual-prefix))
+ ((assoc s ivy--virtual-buffers)
+ (push s res-virtual-noprefix))
+ ((or (string-match-p re-star-prefix s)
+ (string-match-p re-prefix s))
+ (push s res-prefix))
+ (t
+ (push s res-noprefix))))
+ (nconc
+ (nreverse res-prefix)
+ (nreverse res-noprefix)
+ (nreverse res-virtual-prefix)
+ (nreverse res-virtual-noprefix)))))
+
+(defvar ivy-flx-limit 200
+ "Used to conditionally turn off flx sorting.
+
+When the amount of matching candidates exceeds this limit, then
+no sorting is done.")
+
+(defvar ivy--recompute-index-inhibit nil
+ "When non-nil, `ivy--recompute-index' is a no-op.")
+
+(defun ivy--recompute-index (re-str cands)
+ "Recompute index of selected candidate matching RE-STR.
+CANDS are the current candidates."
+ (let ((caller (ivy-state-caller ivy-last))
+ (func (or (ivy-alist-setting ivy-index-functions-alist)
+ #'ivy-recompute-index-zero))
+ (case-fold-search (ivy--case-fold-p re-str))
+ (preselect (ivy-state-preselect ivy-last))
+ (current (ivy-state-current ivy-last))
+ (empty (string= re-str "")))
+ (unless (or (memq this-command '(ivy-resume ivy-partial-or-done))
+ ivy--recompute-index-inhibit)
+ (let ((index (cond
+ ((or empty (string= re-str "^"))
+ (ivy--preselect-index preselect cands))
+ ((and (> (length cands) 10000) (eq func #'ivy-recompute-index-zero))
+ 0)
+ ((cl-position (string-remove-prefix "^" re-str)
+ cands
+ :test #'ivy--case-fold-string=))
+ ((and (ivy--completing-fname-p)
+ (cl-position (concat re-str "/")
+ cands
+ :test #'ivy--case-fold-string=)))
+ ((and (eq caller 'ivy-switch-buffer)
+ (not empty))
+ (or (cl-position current cands :test #'string=)
+ 0))
+ ((and (not empty)
+ (not (eq caller 'swiper))
+ (not (and ivy--flx-featurep
+ (eq ivy--regex-function 'ivy--regex-fuzzy)
+ ;; Limit to configured number of candidates
+ (null (nthcdr ivy-flx-limit cands))))
+ ;; If there was a preselected candidate, don't try to
+ ;; keep it selected even if the regexp still matches it.
+ ;; See issue #1563. See also `ivy--preselect-index',
+ ;; which this logic roughly mirrors.
+ (not (or
+ (and (integerp preselect)
+ (= ivy--index preselect))
+ (equal current preselect)
+ (and (ivy--regex-p preselect)
+ (stringp current)
+ (string-match-p preselect current))))
+ ivy--old-cands
+ (cl-position current cands :test #'equal)))
+ ((funcall func re-str cands))
+ (t 0))))
+ (ivy-set-index index)))))
+
+(defun ivy-recompute-index-swiper (_re-str cands)
+ "Recompute index of selected candidate when using `swiper'.
+CANDS are the current candidates."
+ (condition-case nil
+ (let ((tail (nthcdr ivy--index ivy--old-cands))
+ idx)
+ (if (and tail ivy--old-cands (not (equal "^" ivy--old-re)))
+ (progn
+ (while (and tail (null idx))
+ ;; Compare with eq to handle equal duplicates in cands
+ (setq idx (cl-position (pop tail) cands)))
+ (or
+ idx
+ (1- (length cands))))
+ (if ivy--old-cands
+ ivy--index
+ ;; already in ivy-state-buffer
+ (let ((n (line-number-at-pos))
+ (res 0)
+ (i 0))
+ (dolist (c cands)
+ (when (eq n (get-text-property 0 'swiper-line-number c))
+ (setq res i))
+ (cl-incf i))
+ res))))
+ (error 0)))
+
+(defun ivy-recompute-index-swiper-backward (re-str cands)
+ "Recompute index of selected candidate when using `swiper-backward'.
+CANDS are the current candidates."
+ (let ((idx (ivy-recompute-index-swiper re-str cands)))
+ (if (or (= idx -1)
+ (<= (get-text-property 0 'swiper-line-number (nth idx cands))
+ (line-number-at-pos)))
+ idx
+ (- idx 1))))
+
+(defun ivy-recompute-index-swiper-async (_re-str cands)
+ "Recompute index of selected candidate when using `swiper' asynchronously.
+CANDS are the current candidates."
+ (if (null ivy--old-cands)
+ (let ((ln (with-ivy-window
+ (line-number-at-pos))))
+ (or
+ ;; closest to current line going forwards
+ (cl-position-if (lambda (x)
+ (>= (string-to-number x) ln))
+ cands)
+ ;; closest to current line going backwards
+ (1- (length cands))))
+ (let ((tail (nthcdr ivy--index ivy--old-cands))
+ idx)
+ (if (and tail ivy--old-cands (not (equal "^" ivy--old-re)))
+ (progn
+ (while (and tail (null idx))
+ ;; Compare with `equal', since the collection is re-created
+ ;; each time with `split-string'
+ (setq idx (cl-position (pop tail) cands :test #'equal)))
+ (or idx 0))
+ ivy--index))))
+
+(defun ivy-recompute-index-swiper-async-backward (re-str cands)
+ "Recompute index of selected candidate when using `swiper-backward'
+asynchronously. CANDS are the current candidates."
+ (if (= (length cands) 0)
+ 0
+ (let ((idx (ivy-recompute-index-swiper-async re-str cands)))
+ (if
+ (<= (string-to-number (nth idx cands))
+ (with-ivy-window (line-number-at-pos)))
+ idx
+ (- idx 1)))))
+
+(defun ivy-recompute-index-zero (_re-str _cands)
+ "Recompute index of selected candidate.
+This function serves as a fallback when nothing else is available."
+ 0)
+
+(defcustom ivy-minibuffer-faces
+ '(ivy-minibuffer-match-face-1
+ ivy-minibuffer-match-face-2
+ ivy-minibuffer-match-face-3
+ ivy-minibuffer-match-face-4)
+ "List of `ivy' faces for minibuffer group matches."
+ :type '(repeat :tag "Faces"
+ (choice
+ (const ivy-minibuffer-match-face-1)
+ (const ivy-minibuffer-match-face-2)
+ (const ivy-minibuffer-match-face-3)
+ (const ivy-minibuffer-match-face-4)
+ (face :tag "Other face"))))
+
+(defun ivy--minibuffer-face (n)
+ "Return Nth face from `ivy-minibuffer-faces'.
+N wraps around, but skips the first element of the list."
+ (let ((tail (cdr ivy-minibuffer-faces)))
+ (nth (mod (+ n 2) (length tail)) tail)))
+
+(defun ivy--flx-propertize (x)
+ "X is (cons (flx-score STR ...) STR)."
+ (let ((str (copy-sequence (cdr x)))
+ (i 0)
+ (last-j -2))
+ (dolist (j (cdar x))
+ (unless (eq j (1+ last-j))
+ (cl-incf i))
+ (setq last-j j)
+ (add-face-text-property j (1+ j) (ivy--minibuffer-face i) nil str))
+ str))
+
+(defun ivy--flx-sort (name cands)
+ "Sort according to closeness to string NAME the string list CANDS."
+ (condition-case nil
+ (let* ((bolp (= (string-to-char name) ?^))
+ ;; An optimized regex for fuzzy matching
+ ;; "abc" → "^[^a]*a[^b]*b[^c]*c"
+ (fuzzy-regex (concat "\\`"
+ (and bolp (regexp-quote (substring name 1 2)))
+ (mapconcat
+ (lambda (x)
+ (setq x (char-to-string x))
+ (concat "[^" x "]*" (regexp-quote x)))
+ (if bolp (substring name 2) name)
+ "")))
+ ;; Strip off the leading "^" for flx matching
+ (flx-name (if bolp (substring name 1) name))
+ cands-left
+ cands-to-sort)
+
+ ;; Filter out non-matching candidates
+ (dolist (cand cands)
+ (when (string-match-p fuzzy-regex cand)
+ (push cand cands-left)))
+
+ ;; pre-sort the candidates by length before partitioning
+ (setq cands-left (cl-sort cands-left #'< :key #'length))
+
+ ;; partition the candidates into sorted and unsorted groups
+ (dotimes (_ (min (length cands-left) ivy-flx-limit))
+ (push (pop cands-left) cands-to-sort))
+
+ (nconc
+ ;; Compute all of the flx scores in one pass and sort
+ (mapcar #'car
+ (sort (mapcar
+ (lambda (cand)
+ (cons cand
+ (car (flx-score cand flx-name ivy--flx-cache))))
+ cands-to-sort)
+ (lambda (c1 c2)
+ ;; Break ties by length
+ (if (/= (cdr c1) (cdr c2))
+ (> (cdr c1)
+ (cdr c2))
+ (< (length (car c1))
+ (length (car c2)))))))
+
+ ;; Add the unsorted candidates
+ cands-left))
+ (error cands)))
+
+(defun ivy--truncate-string (str width)
+ "Truncate STR to WIDTH."
+ (truncate-string-to-width str width nil nil t))
+
+(defun ivy--format-function-generic (selected-fn other-fn cands separator)
+ "Transform candidates into a string for minibuffer.
+SELECTED-FN is called for the selected candidate, OTHER-FN for the others.
+Both functions take one string argument each. CANDS is a list of candidates
+and SEPARATOR is used to join them."
+ (let ((i -1))
+ (mapconcat
+ (lambda (str)
+ (let ((curr (eq (cl-incf i) ivy--window-index)))
+ (if curr
+ (funcall selected-fn str)
+ (funcall other-fn str))))
+ cands
+ separator)))
+
+(defun ivy-format-function-default (cands)
+ "Transform CANDS into a string for minibuffer."
+ (ivy--format-function-generic
+ (lambda (str)
+ (ivy--add-face str 'ivy-current-match))
+ #'identity
+ cands
+ "\n"))
+
+(defun ivy-format-function-arrow (cands)
+ "Transform CANDS into a string for minibuffer."
+ (ivy--format-function-generic
+ (lambda (str)
+ (concat "> " (ivy--add-face str 'ivy-current-match)))
+ (lambda (str)
+ (concat " " str))
+ cands
+ "\n"))
+
+(defun ivy-format-function-line (cands)
+ "Transform CANDS into a string for minibuffer.
+Note that since Emacs 27, `ivy-current-match' needs to have :extend t attribute.
+It has it by default, but the current theme also needs to set it."
+ (ivy--format-function-generic
+ (lambda (str)
+ (ivy--add-face (concat str "\n") 'ivy-current-match))
+ (lambda (str)
+ (concat str "\n"))
+ cands
+ ""))
+
+(defun ivy--highlight-ignore-order (str)
+ "Highlight STR, using the ignore-order method."
+ (when (consp ivy--old-re)
+ (let ((i 1))
+ (dolist (re ivy--old-re)
+ (when (string-match (car re) str)
+ (add-face-text-property
+ (match-beginning 0) (match-end 0)
+ (ivy--minibuffer-face i)
+ nil str))
+ (cl-incf i))))
+ str)
+
+(defun ivy--highlight-fuzzy (str)
+ "Highlight STR, using the fuzzy method."
+ (if (and ivy--flx-featurep
+ (eq (ivy-alist-setting ivy-re-builders-alist) 'ivy--regex-fuzzy))
+ (let ((flx-name (string-remove-prefix "^" ivy-text)))
+ (ivy--flx-propertize
+ (cons (flx-score str flx-name ivy--flx-cache) str)))
+ (ivy--highlight-default str)))
+
+(defcustom ivy-use-group-face-if-no-groups t
+ "If t, and the expression has no subgroups, highlight whole match as a group.
+
+It will then use the second face (first of the \"group\" faces)
+of `ivy-minibuffer-faces'. Otherwise, always use the first face
+in this case."
+ :type 'boolean)
+
+(defun ivy--highlight-default (str)
+ "Highlight STR, using the default method."
+ (unless ivy--old-re
+ (setq ivy--old-re ivy-regex))
+ (let ((regexps
+ (if (listp ivy--old-re)
+ (mapcar #'car (cl-remove-if-not #'cdr ivy--old-re))
+ (list ivy--old-re)))
+ start)
+ (dolist (re regexps)
+ (ignore-errors
+ (while (and (string-match re str start)
+ (> (- (match-end 0) (match-beginning 0)) 0))
+ (setq start (match-end 0))
+ (let ((i 0)
+ (n 0)
+ prev)
+ (while (<= i ivy--subexps)
+ (let ((beg (match-beginning i))
+ (end (match-end i)))
+ (when (and beg end)
+ (unless (or (and prev (= prev beg))
+ (zerop i))
+ (cl-incf n))
+ (let ((face
+ (cond ((and ivy-use-group-face-if-no-groups
+ (zerop ivy--subexps))
+ (cadr ivy-minibuffer-faces))
+ ((zerop i)
+ (car ivy-minibuffer-faces))
+ (t
+ (ivy--minibuffer-face n)))))
+ (add-face-text-property beg end face nil str))
+ (unless (zerop i)
+ (setq prev end))))
+ (cl-incf i)))))))
+ str)
+
+(defun ivy--format-minibuffer-line (str)
+ "Format line STR for use in minibuffer."
+ (let* ((str (ivy-cleanup-string (copy-sequence str)))
+ (str (if (eq ivy-display-style 'fancy)
+ (if (memq (ivy-state-caller ivy-last)
+ ivy-highlight-grep-commands)
+ (let* ((start (if (string-match "\\`[^:]+:\\(?:[^:]+:\\)?" str)
+ (match-end 0) 0))
+ (file (substring str 0 start))
+ (match (substring str start)))
+ (concat file (funcall ivy--highlight-function match)))
+ (funcall ivy--highlight-function str))
+ str))
+ (olen (length str))
+ (annot (plist-get completion-extra-properties :annotation-function)))
+ (add-text-properties
+ 0 olen
+ '(mouse-face
+ ivy-minibuffer-match-highlight
+ help-echo
+ (format
+ (if tooltip-mode
+ "mouse-1: %s\nmouse-3: %s"
+ "mouse-1: %s mouse-3: %s")
+ ivy-mouse-1-tooltip ivy-mouse-3-tooltip))
+ str)
+ (when annot
+ (setq str (concat str (funcall annot str)))
+ (add-face-text-property
+ olen (length str) 'ivy-completions-annotations nil str))
+ str))
+
+(defun ivy-read-file-transformer (str)
+ "Transform candidate STR when reading files."
+ (if (ivy--dirname-p str)
+ (propertize str 'face 'ivy-subdir)
+ str))
+
+(defun ivy--minibuffer-index-bounds (idx len wnd-len)
+ (let* ((half-height (/ wnd-len 2))
+ (start (max 0
+ (min (- idx half-height)
+ (- len (1- wnd-len)))))
+ (end (min (+ start (1- wnd-len)) len)))
+ (list start end (- idx start))))
+
+(defun ivy--format (cands)
+ "Return a string for CANDS suitable for display in the minibuffer.
+CANDS is a list of candidates that :display-transformer can turn into strings."
+ (setq ivy--length (length cands))
+ (when (>= ivy--index ivy--length)
+ (ivy-set-index (max (1- ivy--length) 0)))
+ (if (null cands)
+ (setf (ivy-state-current ivy-last) "")
+ (let ((cur (nth ivy--index cands)))
+ (setf (ivy-state-current ivy-last) (if (stringp cur)
+ (copy-sequence cur)
+ cur)))
+ (let* ((bnd (ivy--minibuffer-index-bounds
+ ivy--index ivy--length ivy-height))
+ (wnd-cands (cl-subseq cands (car bnd) (cadr bnd)))
+ (case-fold-search (ivy--case-fold-p ivy-text))
+ transformer-fn)
+ (setq ivy--window-index (nth 2 bnd))
+ (when (setq transformer-fn (ivy-state-display-transformer-fn ivy-last))
+ (with-ivy-window
+ (with-current-buffer (ivy-state-buffer ivy-last)
+ (setq wnd-cands (mapcar transformer-fn wnd-cands)))))
+ (ivy--wnd-cands-to-str wnd-cands))))
+
+(defun ivy--wnd-cands-to-str (wnd-cands)
+ (let ((str (concat "\n"
+ (funcall (ivy-alist-setting ivy-format-functions-alist)
+ (condition-case nil
+ (mapcar
+ #'ivy--format-minibuffer-line
+ wnd-cands)
+ (error wnd-cands))))))
+ (put-text-property 0 (length str) 'read-only nil str)
+ str))
+
+(defvar recentf-list)
+(defvar bookmark-alist)
+
+(defcustom ivy-virtual-abbreviate 'name
+ "The mode of abbreviation for virtual buffer names."
+ :type '(choice
+ (const :tag "Only name" name)
+ (const :tag "Abbreviated path" abbreviate)
+ (const :tag "Full path" full)
+ ;; eventually, uniquify
+ ))
+(declare-function bookmark-maybe-load-default-file "bookmark")
+(declare-function bookmark-get-filename "bookmark")
+
+(defun ivy--virtual-buffers ()
+ "Adapted from `ido-add-virtual-buffers-to-list'."
+ (require 'bookmark)
+ (unless recentf-mode
+ (recentf-mode 1))
+ (bookmark-maybe-load-default-file)
+ (let* ((vb-bkm (delete " - no file -"
+ (delq nil (mapcar #'bookmark-get-filename
+ bookmark-alist))))
+ (vb-list (cond ((eq ivy-use-virtual-buffers 'recentf)
+ recentf-list)
+ ((eq ivy-use-virtual-buffers 'bookmarks)
+ vb-bkm)
+ (ivy-use-virtual-buffers
+ (append recentf-list vb-bkm))
+ (t nil)))
+ virtual-buffers)
+ (dolist (head vb-list)
+ (let* ((file-name (if (stringp head)
+ head
+ (cdr head)))
+ (name (cond ((eq ivy-virtual-abbreviate 'name)
+ (file-name-nondirectory file-name))
+ ((eq ivy-virtual-abbreviate 'abbreviate)
+ (abbreviate-file-name file-name))
+ (t
+ (expand-file-name file-name)))))
+ (when (equal name "")
+ (setq name
+ (if (consp head)
+ (car head)
+ (file-name-nondirectory (directory-file-name file-name)))))
+ (unless (or (equal name "")
+ (get-file-buffer file-name)
+ (assoc name virtual-buffers))
+ (push (cons (copy-sequence name) file-name) virtual-buffers))))
+ (when virtual-buffers
+ (dolist (comp virtual-buffers)
+ (put-text-property 0 (length (car comp))
+ 'face 'ivy-virtual
+ (car comp)))
+ (setq ivy--virtual-buffers (nreverse virtual-buffers))
+ (mapcar #'car ivy--virtual-buffers))))
+
+(defcustom ivy-ignore-buffers '("\\` " "\\`\\*tramp/")
+ "List of regexps or functions matching buffer names to ignore."
+ :type '(repeat (choice regexp function)))
+
+(defvar ivy-switch-buffer-faces-alist '((dired-mode . ivy-subdir)
+ (org-mode . ivy-org))
+ "Store face customizations for `ivy-switch-buffer'.
+Each KEY is `major-mode', each VALUE is a face name.")
+
+(defun ivy--buffer-list (str &optional virtual predicate)
+ "Return the buffers that match STR.
+If VIRTUAL is non-nil, add virtual buffers.
+If optional argument PREDICATE is non-nil, use it to test each
+possible match. See `all-completions' for further information."
+ (delete-dups
+ (nconc
+ (all-completions str #'internal-complete-buffer predicate)
+ (and virtual
+ (ivy--virtual-buffers)))))
+
+(defvar ivy-views (and nil
+ `(("ivy + *scratch* {}"
+ (vert
+ (file ,(expand-file-name "ivy.el"))
+ (buffer "*scratch*")))
+ ("swiper + *scratch* {}"
+ (horz
+ (file ,(expand-file-name "swiper.el"))
+ (buffer "*scratch*")))))
+ "Store window configurations selectable by `ivy-switch-buffer'.
+
+The default value is given as an example.
+
+Each element is a list of (NAME VIEW). NAME is a string, it's
+recommended to end it with a distinctive snippet e.g. \"{}\" so
+that it's easy to distinguish the window configurations.
+
+VIEW is either a TREE or a window-configuration (see
+`ivy--get-view-config').
+
+TREE is a nested list with the following valid cars:
+- vert: split the window vertically
+- horz: split the window horizontally
+- file: open the specified file
+- buffer: open the specified buffer
+
+TREE can be nested multiple times to have multiple window splits.")
+
+(defun ivy-default-view-name ()
+ "Return default name for new view."
+ (let* ((default-view-name
+ (concat "{} "
+ (mapconcat #'identity
+ (sort
+ (mapcar (lambda (w)
+ (let* ((b (window-buffer w))
+ (f (buffer-file-name b)))
+ (if f
+ (file-name-nondirectory f)
+ (buffer-name b))))
+ (window-list))
+ #'string-lessp)
+ " ")))
+ (view-name-re (concat "\\`"
+ (regexp-quote default-view-name)
+ " \\([0-9]+\\)"))
+ old-view)
+ (cond ((setq old-view
+ (cl-find-if
+ (lambda (x)
+ (string-match view-name-re (car x)))
+ ivy-views))
+ (format "%s %d"
+ default-view-name
+ (1+ (string-to-number
+ (match-string 1 (car old-view))))))
+ ((assoc default-view-name ivy-views)
+ (concat default-view-name " 1"))
+ (t
+ default-view-name))))
+
+(defun ivy--get-view-config ()
+ "Get `current-window-configuration' for `ivy-views'."
+ (dolist (w (window-list))
+ (set-window-parameter w 'ivy-view-data
+ (with-current-buffer (window-buffer w)
+ (cond (buffer-file-name
+ (list 'file buffer-file-name (point)))
+ ((eq major-mode 'dired-mode)
+ (list 'file default-directory (point)))
+ (t
+ (list 'buffer (buffer-name) (point)))))))
+ (let ((window-persistent-parameters
+ (append window-persistent-parameters
+ (list (cons 'ivy-view-data t)))))
+ (current-window-configuration)))
+
+(defun ivy-push-view (&optional arg)
+ "Push the current window tree on `ivy-views'.
+
+When ARG is non-nil, replace a selected item on `ivy-views'.
+
+Currently, the split configuration (i.e. horizontal or vertical)
+and point positions are saved, but the split positions aren't.
+Use `ivy-pop-view' to delete any item from `ivy-views'."
+ (interactive "P")
+ (let* ((view (ivy--get-view-config))
+ (view-name
+ (if arg
+ (ivy-read "Update view: " ivy-views)
+ (ivy-read "Name view: " nil
+ :initial-input (ivy-default-view-name)))))
+ (when view-name
+ (let ((x (assoc view-name ivy-views)))
+ (if x
+ (setcdr x (list view))
+ (push (list view-name view) ivy-views))))))
+
+(defun ivy-pop-view-action (view)
+ "Delete VIEW from `ivy-views'."
+ (setq ivy-views (delete view ivy-views))
+ (setq ivy--all-candidates
+ (delete (car view) ivy--all-candidates))
+ (setq ivy--old-cands nil))
+
+(defun ivy-pop-view ()
+ "Delete a view to delete from `ivy-views'."
+ (interactive)
+ (ivy-read "Pop view: " ivy-views
+ :preselect (caar ivy-views)
+ :action #'ivy-pop-view-action
+ :caller 'ivy-pop-view))
+
+(defun ivy-source-views ()
+ "Return the name of the views saved in `ivy-views'."
+ (mapcar #'car ivy-views))
+
+(ivy-set-sources
+ 'ivy-switch-buffer
+ '((original-source)
+ (ivy-source-views)))
+
+(defun ivy-set-view-recur (view)
+ "Set VIEW recursively."
+ (cond ((window-configuration-p view)
+ (set-window-configuration view)
+ (dolist (w (window-list))
+ (with-selected-window w
+ (ivy-set-view-recur
+ (window-parameter w 'ivy-view-data)))))
+ ((eq (car view) 'vert)
+ (let* ((wnd1 (selected-window))
+ (wnd2 (split-window-vertically))
+ (views (cdr view))
+ (v (pop views))
+ (temp-wnd))
+ (with-selected-window wnd1
+ (ivy-set-view-recur v))
+ (while (setq v (pop views))
+ (with-selected-window wnd2
+ (when views
+ (setq temp-wnd (split-window-vertically)))
+ (ivy-set-view-recur v)
+ (when views
+ (setq wnd2 temp-wnd))))))
+ ((eq (car view) 'horz)
+ (let* ((wnd1 (selected-window))
+ (wnd2 (split-window-horizontally))
+ (views (cdr view))
+ (v (pop views))
+ (temp-wnd))
+ (with-selected-window wnd1
+ (ivy-set-view-recur v))
+ (while (setq v (pop views))
+ (with-selected-window wnd2
+ (when views
+ (setq temp-wnd (split-window-horizontally)))
+ (ivy-set-view-recur v)
+ (when views
+ (setq wnd2 temp-wnd))))))
+ ((eq (car view) 'file)
+ (let* ((name (nth 1 view))
+ (virtual (assoc name ivy--virtual-buffers))
+ buffer)
+ (cond ((setq buffer (get-buffer name))
+ (switch-to-buffer buffer nil 'force-same-window))
+ (virtual
+ (find-file (cdr virtual)))
+ ((file-exists-p name)
+ (find-file name))))
+ (when (and (> (length view) 2)
+ (numberp (nth 2 view)))
+ (goto-char (nth 2 view))))
+ ((eq (car view) 'buffer)
+ (switch-to-buffer (nth 1 view))
+ (when (and (> (length view) 2)
+ (numberp (nth 2 view)))
+ (goto-char (nth 2 view))))
+ ((eq (car view) 'sexp)
+ (eval (nth 1 view)))))
+
+(defun ivy--switch-buffer-action (buffer)
+ "Switch to BUFFER.
+BUFFER may be a string or nil."
+ (if (zerop (length buffer))
+ (switch-to-buffer
+ ivy-text nil 'force-same-window)
+ (let ((virtual (assoc buffer ivy--virtual-buffers))
+ (view (assoc buffer ivy-views)))
+ (cond ((and virtual
+ (not (get-buffer buffer)))
+ (find-file (cdr virtual)))
+ (view
+ (delete-other-windows)
+ (let (
+ ;; silence "Directory has changed on disk"
+ (inhibit-message t))
+ (ivy-set-view-recur (cadr view))))
+ (t
+ (switch-to-buffer
+ buffer nil 'force-same-window))))))
+
+(defun ivy--switch-buffer-other-window-action (buffer)
+ "Switch to BUFFER in other window.
+BUFFER may be a string or nil."
+ (if (zerop (length buffer))
+ (switch-to-buffer-other-window ivy-text)
+ (let ((virtual (assoc buffer ivy--virtual-buffers)))
+ (if (and virtual
+ (not (get-buffer buffer)))
+ (find-file-other-window (cdr virtual))
+ (switch-to-buffer-other-window buffer)))))
+
+(defun ivy--rename-buffer-action (buffer)
+ "Rename BUFFER."
+ (let ((new-name (read-string "Rename buffer (to new name): ")))
+ (with-current-buffer buffer
+ (rename-buffer new-name))))
+
+(defun ivy--find-file-action (buffer)
+ "Find file from BUFFER's directory."
+ (let* ((virtual (assoc buffer ivy--virtual-buffers))
+ (default-directory (if virtual
+ (file-name-directory (cdr virtual))
+ (buffer-local-value 'default-directory
+ (or (get-buffer buffer)
+ (current-buffer))))))
+ (call-interactively (if (functionp 'counsel-find-file)
+ #'counsel-find-file
+ #'find-file))))
+
+(defun ivy--kill-buffer-or-virtual (buffer)
+ (if (get-buffer buffer)
+ (kill-buffer buffer)
+ (setq recentf-list (delete
+ (cdr (assoc buffer ivy--virtual-buffers))
+ recentf-list))))
+
+(defun ivy--kill-current-candidate ()
+ (setf (ivy-state-preselect ivy-last) ivy--index)
+ (setq ivy--old-re nil)
+ (setq ivy--all-candidates (delete (ivy-state-current ivy-last) ivy--all-candidates))
+ (let ((ivy--recompute-index-inhibit t))
+ (ivy--exhibit)))
+
+(defun ivy--kill-current-candidate-buffer ()
+ (setf (ivy-state-preselect ivy-last) ivy--index)
+ (setq ivy--old-re nil)
+ (setq ivy--all-candidates (ivy--buffer-list "" ivy-use-virtual-buffers nil))
+ (let ((ivy--recompute-index-inhibit t))
+ (ivy--exhibit)))
+
+(defun ivy--kill-buffer-action (buffer)
+ "Kill BUFFER."
+ (ivy--kill-buffer-or-virtual buffer)
+ (unless (buffer-live-p (ivy-state-buffer ivy-last))
+ (setf (ivy-state-buffer ivy-last)
+ (with-ivy-window (current-buffer))))
+ (ivy--kill-current-candidate-buffer))
+
+(defvar ivy-switch-buffer-map
+ (let ((map (make-sparse-keymap)))
+ (ivy-define-key map (kbd "C-k") 'ivy-switch-buffer-kill)
+ map))
+
+(defun ivy-switch-buffer-kill ()
+ "When at end-of-line, kill the current buffer in `ivy-switch-buffer'.
+Otherwise, forward to `ivy-kill-line'."
+ (interactive)
+ (if (not (eolp))
+ (ivy-kill-line)
+ (ivy--kill-buffer-action
+ (ivy-state-current ivy-last))))
+
+(ivy-set-actions
+ 'ivy-switch-buffer
+ '(("f"
+ ivy--find-file-action
+ "find file")
+ ("j"
+ ivy--switch-buffer-other-window-action
+ "other window")
+ ("k"
+ ivy--kill-buffer-action
+ "kill")
+ ("r"
+ ivy--rename-buffer-action
+ "rename")))
+
+(ivy-set-actions
+ t
+ '(("i" ivy--action-insert "insert")
+ ("w" ivy--action-copy "copy")))
+
+(defun ivy--trim-grep-line-number (x)
+ (if (string-match ":[0-9]+:" x)
+ (substring x (match-end 0))
+ x))
+
+(defun ivy--action-insert (x)
+ (insert
+ (if (stringp x)
+ (ivy--trim-grep-line-number x)
+ x (car x))))
+
+(defun ivy--action-copy (x)
+ (kill-new
+ (if (stringp x)
+ (ivy--trim-grep-line-number x)
+ (car x))))
+
+(defun ivy--switch-buffer-matcher (regexp candidates)
+ "Return REGEXP matching CANDIDATES.
+Skip buffers that match `ivy-ignore-buffers'."
+ (if (string-match-p "^:" ivy-text)
+ (delete-dups
+ (cl-remove-if-not
+ (lambda (s)
+ (let ((b (get-buffer s)))
+ (and b
+ (string-match-p regexp (buffer-local-value 'default-directory b))
+ (not (string-match-p "^\\*" s)))))
+ candidates))
+ (let ((res (ivy--re-filter regexp candidates)))
+ (if (or (null ivy-use-ignore)
+ (null ivy-ignore-buffers))
+ res
+ (or (cl-remove-if
+ (lambda (buf)
+ (cl-find-if
+ (lambda (f-or-r)
+ (if (functionp f-or-r)
+ (funcall f-or-r buf)
+ (string-match-p f-or-r buf)))
+ ivy-ignore-buffers))
+ res)
+ (and (eq ivy-use-ignore t)
+ res))))))
+
+(defun ivy-append-face (str face)
+ "Append to STR the property FACE."
+ (when face
+ (setq str (copy-sequence str))
+ (add-face-text-property 0 (length str) face t str))
+ str)
+
+(defun ivy--remote-buffer-p (buffer)
+ "Return non-nil if BUFFER object is visiting a remote file.
+If that is the case, value is a string identifying the remote
+connection."
+ (let ((dir (buffer-local-value 'default-directory buffer)))
+ (ignore-errors (file-remote-p dir))))
+
+(defun ivy-switch-buffer-transformer (str)
+ "Transform candidate STR when switching buffers."
+ (let ((buf (get-buffer str)))
+ (cond ((not buf) str)
+ ((let ((remote (ivy--remote-buffer-p buf)))
+ (when remote
+ (format "%s (%s)" (ivy-append-face str 'ivy-remote) remote))))
+ ((not (verify-visited-file-modtime buf))
+ (ivy-append-face str 'ivy-modified-outside-buffer))
+ ((buffer-modified-p buf)
+ (ivy-append-face str 'ivy-modified-buffer))
+ (t
+ (let* ((mode (buffer-local-value 'major-mode buf))
+ (face (cdr (assq mode ivy-switch-buffer-faces-alist))))
+ (ivy-append-face str face))))))
+
+(defun ivy-switch-buffer-occur (cands)
+ "Occur function for `ivy-switch-buffer' using `ibuffer'.
+CANDS are the candidates to be displayed."
+ (unless cands
+ (setq cands (all-completions ivy-text #'internal-complete-buffer)))
+ (ibuffer
+ nil (buffer-name)
+ `((or ,@(cl-mapcan
+ (lambda (cand)
+ (unless (eq (get-text-property 0 'face cand) 'ivy-virtual)
+ `((name . ,(format "\\_<%s\\_>" (regexp-quote cand))))))
+ cands)))))
+
+;;;###autoload
+(defun ivy-switch-buffer ()
+ "Switch to another buffer."
+ (interactive)
+ (ivy-read "Switch to buffer: " #'internal-complete-buffer
+ :keymap ivy-switch-buffer-map
+ :preselect (buffer-name (other-buffer (current-buffer)))
+ :action #'ivy--switch-buffer-action
+ :matcher #'ivy--switch-buffer-matcher
+ :caller 'ivy-switch-buffer))
+
+(ivy-configure 'ivy-switch-buffer
+ :parent 'internal-complete-buffer
+ :occur #'ivy-switch-buffer-occur)
+
+;;;###autoload
+(defun ivy-switch-view ()
+ "Switch to one of the window views stored by `ivy-push-view'."
+ (interactive)
+ (let ((ivy-initial-inputs-alist
+ '((ivy-switch-buffer . "{}"))))
+ (ivy-switch-buffer)))
+
+;;;###autoload
+(defun ivy-switch-buffer-other-window ()
+ "Switch to another buffer in another window."
+ (interactive)
+ (ivy-read "Switch to buffer in other window: " #'internal-complete-buffer
+ :matcher #'ivy--switch-buffer-matcher
+ :preselect (buffer-name (other-buffer (current-buffer)))
+ :action #'ivy--switch-buffer-other-window-action
+ :keymap ivy-switch-buffer-map
+ :caller 'ivy-switch-buffer-other-window))
+
+(ivy-configure 'ivy-switch-buffer-other-window
+ :parent 'ivy-switch-buffer)
+
+(defun ivy--yank-handle-case-fold (text)
+ (if (and (> (length ivy-text) 0)
+ (string= (downcase ivy-text) ivy-text))
+ (downcase text)
+ text))
+
+(defun ivy--yank-by (fn &rest args)
+ "Pull buffer text from current line into search string.
+The region to extract is determined by the respective values of
+point before and after applying FN to ARGS."
+ (let (text)
+ (with-ivy-window
+ (let ((beg (point))
+ (bol (line-beginning-position))
+ (eol (line-end-position))
+ end)
+ (unwind-protect
+ (progn (apply fn args)
+ (setq end (goto-char (max bol (min (point) eol))))
+ (setq text (buffer-substring-no-properties beg end))
+ (ivy--pulse-region beg end))
+ (unless text
+ (goto-char beg)))))
+ (when text
+ (insert (replace-regexp-in-string
+ " +" " "
+ (ivy--yank-handle-case-fold text)
+ t t)))))
+
+(defun ivy-yank-word (&optional arg)
+ "Pull next word from buffer into search string.
+If optional ARG is non-nil, pull in the next ARG
+words (previous if ARG is negative)."
+ (interactive "p")
+ (ivy--yank-by #'forward-word arg))
+
+(defun ivy-yank-symbol (&optional arg)
+ "Pull next symbol from buffer into search string.
+If optional ARG is non-nil, pull in the next ARG
+symbols (previous if ARG is negative)."
+ (interactive "p")
+ (ivy--yank-by #'forward-symbol (or arg 1)))
+
+(defun ivy-yank-char (&optional arg)
+ "Pull next character from buffer into search string.
+If optional ARG is non-nil, pull in the next ARG
+characters (previous if ARG is negative)."
+ (interactive "p")
+ (ivy--yank-by #'forward-char arg))
+
+(defvar ivy--pulse-overlay nil
+ "Overlay used to highlight yanked word.")
+
+(defvar ivy--pulse-timer nil
+ "Timer used to dispose of `ivy--pulse-overlay'.")
+
+(defcustom ivy-pulse-delay 0.5
+ "Number of seconds to display `ivy-yanked-word' highlight.
+When nil, disable highlighting."
+ :type '(choice
+ (number :tag "Delay in seconds")
+ (const :tag "Disable" nil)))
+
+(defun ivy--pulse-region (start end)
+ "Temporarily highlight text between START and END.
+The \"pulse\" duration is determined by `ivy-pulse-delay'."
+ (when ivy-pulse-delay
+ (if ivy--pulse-overlay
+ (let ((ostart (overlay-start ivy--pulse-overlay))
+ (oend (overlay-end ivy--pulse-overlay)))
+ (when (< end start)
+ (cl-rotatef start end))
+ ;; Extend the existing overlay's region to include START..END,
+ ;; but only if the two regions are contiguous.
+ (move-overlay ivy--pulse-overlay
+ (if (= start oend) ostart start)
+ (if (= end ostart) oend end)))
+ (setq ivy--pulse-overlay (make-overlay start end))
+ (overlay-put ivy--pulse-overlay 'face 'ivy-yanked-word))
+ (when ivy--pulse-timer
+ (cancel-timer ivy--pulse-timer))
+ (setq ivy--pulse-timer
+ (run-at-time ivy-pulse-delay nil #'ivy--pulse-cleanup))))
+
+(defun ivy--pulse-cleanup ()
+ "Cancel `ivy--pulse-timer' and delete `ivy--pulse-overlay'."
+ (when ivy--pulse-timer
+ (cancel-timer ivy--pulse-timer)
+ (setq ivy--pulse-timer nil))
+ (when ivy--pulse-overlay
+ (delete-overlay ivy--pulse-overlay)
+ (setq ivy--pulse-overlay nil)))
+
+(defun ivy-kill-ring-save ()
+ "Store the current candidates into the kill ring.
+If the region is active, forward to `kill-ring-save' instead."
+ (interactive)
+ (if (region-active-p)
+ (call-interactively 'kill-ring-save)
+ (kill-new
+ (mapconcat
+ #'identity
+ ivy--old-cands
+ "\n"))))
+
+(defun ivy-insert-current ()
+ "Make the current candidate into current input.
+Don't finish completion."
+ (interactive)
+ (delete-minibuffer-contents)
+ (let ((end (and ivy--directory
+ (ivy--dirname-p (ivy-state-current ivy-last))
+ -1)))
+ (insert (substring-no-properties
+ (ivy-state-current ivy-last) 0 end))))
+
+(defun ivy-insert-current-full ()
+ "Insert the full Yank the current directory into the minibuffer."
+ (interactive)
+ (insert ivy--directory))
+
+(defcustom ivy-preferred-re-builders
+ '((ivy--regex-plus . "ivy")
+ (ivy--regex-ignore-order . "order")
+ (ivy--regex-fuzzy . "fuzzy"))
+ "Alist of preferred re-builders with display names.
+This list can be rotated with `ivy-rotate-preferred-builders'."
+ :type '(alist :key-type function :value-type string))
+
+(defun ivy-rotate-preferred-builders ()
+ "Switch to the next re builder in `ivy-preferred-re-builders'."
+ (interactive)
+ (when ivy-preferred-re-builders
+ (setq ivy--old-re nil)
+ (setq ivy--regex-function
+ (let ((cell (assq ivy--regex-function ivy-preferred-re-builders)))
+ (car (or (cadr (memq cell ivy-preferred-re-builders))
+ (car ivy-preferred-re-builders)))))))
+
+(defun ivy-toggle-fuzzy ()
+ "Toggle the re builder between `ivy--regex-fuzzy' and `ivy--regex-plus'."
+ (interactive)
+ (setq ivy--old-re nil)
+ (if (eq ivy--regex-function 'ivy--regex-fuzzy)
+ (setq ivy--regex-function 'ivy--regex-plus)
+ (setq ivy--regex-function 'ivy--regex-fuzzy)))
+
+(defun ivy--label-and-delete-dups (entries)
+ "Label ENTRIES with history indices."
+ (let ((ht (make-hash-table :test 'equal))
+ (idx 0)
+ entry
+ accum)
+ (while (setq entry (pop entries))
+ (unless (gethash entry ht)
+ (puthash entry t ht)
+ (push `(,entry . ,idx) accum))
+ (cl-incf idx))
+ (nreverse accum)))
+
+(defvar ivy--reverse-i-search-symbol nil
+ "Store the history symbol.")
+
+(defun ivy-reverse-i-search-kill ()
+ "Remove the current item from history"
+ (interactive)
+ (if (not (eolp))
+ (ivy-kill-line)
+ (let ((current (ivy-state-current ivy-last)))
+ (if (symbolp ivy--reverse-i-search-symbol)
+ (set
+ ivy--reverse-i-search-symbol
+ (delete current (symbol-value ivy--reverse-i-search-symbol)))
+ (ring-remove
+ ivy--reverse-i-search-symbol
+ (ring-member ivy--reverse-i-search-symbol (ivy-state-current ivy-last)))))
+ (ivy--kill-current-candidate)))
+
+(defvar ivy-reverse-i-search-map
+ (let ((map (make-sparse-keymap)))
+ (ivy-define-key map (kbd "C-k") 'ivy-reverse-i-search-kill)
+ map))
+
+(defun ivy-history-contents (history)
+ "Copy contents of HISTORY.
+A copy is necessary so that we don't clobber any string attributes.
+Also set `ivy--reverse-i-search-symbol' to HISTORY."
+ (setq ivy--reverse-i-search-symbol history)
+ (cond ((symbolp history)
+ (ivy--label-and-delete-dups
+ (copy-sequence (symbol-value history))))
+ ((ring-p history)
+ (ivy--label-and-delete-dups
+ (when (> (ring-size history) 0)
+ (ring-elements history))))
+ ((sequencep history)
+ (ivy--label-and-delete-dups
+ (copy-sequence history)))
+ (t
+ (error "Expected a symbol, ring, or sequence: %S" history))))
+
+(defun ivy-reverse-i-search ()
+ "Enter a recursive `ivy-read' session using the current history.
+The selected history element will be inserted into the minibuffer.
+\\
+You can also delete an element from history with \\[ivy-reverse-i-search-kill]."
+ (interactive)
+ (cond
+ ((= (minibuffer-depth) 0)
+ (user-error
+ "This command is intended to be called from within `ivy-read'"))
+ ;; don't recur
+ ((and (> (minibuffer-depth) 1)
+ (eq (ivy-state-caller ivy-last) 'ivy-reverse-i-search)))
+ (t
+ (let ((enable-recursive-minibuffers t)
+ (old-last ivy-last))
+ (ivy-read "Reverse-i-search: "
+ (ivy-history-contents (ivy-state-history ivy-last))
+ :keymap ivy-reverse-i-search-map
+ :action (lambda (x)
+ (ivy--reset-state
+ (setq ivy-last old-last))
+ (delete-minibuffer-contents)
+ (insert (substring-no-properties (car x)))
+ (ivy--cd-maybe))
+ :caller 'ivy-reverse-i-search)))))
+
+(defun ivy-restrict-to-matches ()
+ "Restrict candidates to current input and erase input."
+ (interactive)
+ (delete-minibuffer-contents)
+ (if (ivy-state-dynamic-collection ivy-last)
+ (progn
+ (setf (ivy-state-dynamic-collection ivy-last) nil)
+ (setf (ivy-state-collection ivy-last)
+ (setq ivy--all-candidates ivy--old-cands)))
+ (setq ivy--all-candidates
+ (ivy--filter ivy-text ivy--all-candidates))))
+
+;;* Occur
+(defvar-local ivy-occur-last nil
+ "Buffer-local value of `ivy-last'.
+Can't re-use `ivy-last' because using e.g. `swiper' in the same
+buffer would modify `ivy-last'.")
+
+(defvar ivy-occur-mode-map
+ (let ((map (make-sparse-keymap)))
+ (ivy-define-key map [mouse-1] 'ivy-occur-click)
+ (ivy-define-key map (kbd "RET") 'ivy-occur-press-and-switch)
+ (ivy-define-key map (kbd "j") 'ivy-occur-next-line)
+ (ivy-define-key map (kbd "k") 'ivy-occur-previous-line)
+ (define-key map (kbd "h") 'backward-char)
+ (define-key map (kbd "l") 'forward-char)
+ (ivy-define-key map (kbd "f") 'ivy-occur-press)
+ (ivy-define-key map (kbd "g") 'ivy-occur-revert-buffer)
+ (ivy-define-key map (kbd "a") 'ivy-occur-read-action)
+ (ivy-define-key map (kbd "o") 'ivy-occur-dispatch)
+ (ivy-define-key map (kbd "c") 'ivy-occur-toggle-calling)
+ (define-key map (kbd "q") 'quit-window)
+ (define-key map (kbd "R") 'read-only-mode)
+ (ivy-define-key map (kbd "C-d") 'ivy-occur-delete-candidate)
+ map)
+ "Keymap for Ivy Occur mode.")
+
+(defun ivy-occur-toggle-calling ()
+ "Toggle `ivy-calling'."
+ (interactive)
+ (if (setq ivy-calling (not ivy-calling))
+ (progn
+ (setq mode-name "Ivy-Occur [calling]")
+ (ivy-occur-press))
+ (setq mode-name "Ivy-Occur"))
+ (force-mode-line-update))
+
+(defun ivy--find-occur-buffer ()
+ (let ((cb (current-buffer)))
+ (cl-find-if
+ (lambda (b)
+ (with-current-buffer b
+ (and (eq major-mode 'ivy-occur-grep-mode)
+ (equal cb (ivy-state-buffer ivy-occur-last)))))
+ (buffer-list))))
+
+(defun ivy--select-occur-buffer ()
+ (let* ((ob (ivy--find-occur-buffer))
+ (ow (cl-find-if (lambda (w) (equal ob (window-buffer w)))
+ (window-list))))
+ (if ow
+ (select-window ow)
+ (pop-to-buffer ob))))
+
+(defun ivy-occur-next-line (&optional arg)
+ "Move the cursor down ARG lines.
+When `ivy-calling' isn't nil, call `ivy-occur-press'."
+ (interactive "p")
+ (let ((offset (cond ((derived-mode-p 'ivy-occur-grep-mode) 5)
+ ((derived-mode-p 'ivy-occur-mode) 2))))
+ (if offset
+ (progn
+ (if (< (line-number-at-pos) offset)
+ (progn
+ (goto-char (point-min))
+ (forward-line (1- offset)))
+ (forward-line arg)
+ (when (eolp)
+ (forward-line -1)))
+ (when ivy-calling
+ (ivy-occur-press)))
+ (ivy--select-occur-buffer)
+ (ivy-occur-next-line arg)
+ (ivy-occur-press-and-switch))))
+
+(defun ivy-occur-previous-line (&optional arg)
+ "Move the cursor up ARG lines.
+When `ivy-calling' isn't nil, call `ivy-occur-press'."
+ (interactive "p")
+ (let ((offset (cond ((derived-mode-p 'ivy-occur-grep-mode) 5)
+ ((derived-mode-p 'ivy-occur-mode) 2))))
+ (if offset
+ (progn
+ (forward-line (- arg))
+ (when (< (line-number-at-pos) offset)
+ (goto-char (point-min))
+ (forward-line (1- offset)))
+ (when ivy-calling
+ (ivy-occur-press)))
+ (ivy--select-occur-buffer)
+ (ivy-occur-previous-line arg)
+ (ivy-occur-press-and-switch))))
+
+(defun ivy-occur-next-error (n &optional reset)
+ "A `next-error-function' for `ivy-occur-mode'."
+ (interactive "p")
+ (when reset
+ (goto-char (point-min)))
+ (setq n (or n 1))
+ (let ((ivy-calling t))
+ (cond ((< n 0) (ivy-occur-previous-line (- n)))
+ (t (ivy-occur-next-line n))))
+ ;; The window's point overrides the buffer's point every time it's redisplayed
+ (dolist (window (get-buffer-window-list nil nil t))
+ (set-window-point window (point))))
+
+(define-derived-mode ivy-occur-mode fundamental-mode "Ivy-Occur"
+ "Major mode for output from \\[ivy-occur].
+
+\\{ivy-occur-mode-map}"
+ (setq-local view-read-only nil))
+
+(defvar ivy-occur-grep-mode-map
+ (let ((map (copy-keymap ivy-occur-mode-map)))
+ (ivy-define-key map (kbd "C-x C-q") 'ivy-wgrep-change-to-wgrep-mode)
+ (ivy-define-key map "w" 'ivy-wgrep-change-to-wgrep-mode)
+ map)
+ "Keymap for Ivy Occur Grep mode.")
+
+(defun ivy-occur-delete-candidate ()
+ (interactive)
+ (let ((inhibit-read-only t))
+ (delete-region (line-beginning-position)
+ (1+ (line-end-position)))))
+
+(define-derived-mode ivy-occur-grep-mode grep-mode "Ivy-Occur"
+ "Major mode for output from \\[ivy-occur].
+
+\\{ivy-occur-grep-mode-map}"
+ (setq-local view-read-only nil)
+ (when (fboundp 'wgrep-setup)
+ (wgrep-setup)))
+
+(defun ivy--starts-with-dotslash (str)
+ (string-match-p "\\`\\.[/\\]" str))
+
+(defun ivy--occur-insert-lines (cands)
+ "Insert CANDS into `ivy-occur' buffer."
+ (font-lock-mode -1)
+ (dolist (cand cands)
+ (setq cand
+ (if (string-match "\\`\\(.*:[0-9]+:\\)\\(.*\\)\\'" cand)
+ (let ((file-and-line (match-string 1 cand))
+ (grep-line (match-string 2 cand)))
+ (concat
+ (propertize file-and-line 'face 'ivy-grep-info)
+ (ivy--highlight-fuzzy grep-line)))
+ (ivy--highlight-fuzzy (copy-sequence cand))))
+ (add-text-properties
+ 0 (length cand)
+ '(mouse-face
+ highlight
+ help-echo "mouse-1: call ivy-action")
+ cand)
+ (insert (if (ivy--starts-with-dotslash cand) "" " ")
+ cand ?\n)))
+
+(defun ivy--occur-default (cands)
+ "Insert CANDS into the current occur buffer."
+ (unless cands
+ (let ((coll (ivy-state-collection ivy-last)))
+ (when (arrayp coll)
+ (setq coll (all-completions "" coll (ivy-state-predicate ivy-last))))
+ (setq cands (ivy--filter (ivy-state-text ivy-last) coll))))
+ (ivy-occur-mode)
+ (insert (format "%d candidates:\n" (length cands)))
+ (ivy--occur-insert-lines cands)
+ (read-only-mode))
+
+(defun ivy-occur ()
+ "Stop completion and put the current candidates into a new buffer.
+
+The new buffer remembers current action(s).
+
+While in the *ivy-occur* buffer, selecting a candidate with RET or
+a mouse click will call the appropriate action for that candidate.
+
+There is no limit on the number of *ivy-occur* buffers."
+ (interactive)
+ (if (not (window-minibuffer-p))
+ (user-error "No completion session is active")
+ (let* ((caller (ivy-state-caller ivy-last))
+ (occur-fn (or (plist-get ivy--occurs-list caller)
+ #'ivy--occur-default))
+ (buffer
+ (generate-new-buffer
+ (format "*ivy-occur%s \"%s\"*"
+ (if caller
+ (concat " " (prin1-to-string caller))
+ "")
+ ivy-text))))
+ (with-current-buffer buffer
+ (funcall occur-fn ivy--old-cands)
+ (setf (ivy-state-text ivy-last) ivy-text)
+ (setq ivy-occur-last ivy-last))
+ (ivy-exit-with-action
+ (lambda (_)
+ (pop-to-buffer buffer)
+ (setq next-error-last-buffer buffer)
+ (setq-local next-error-function #'ivy-occur-next-error))))))
+
+(defun ivy-occur-revert-buffer ()
+ "Refresh the buffer making it up-to date with the collection.
+
+Currently only works for `swiper'. In that specific case, the
+*ivy-occur* buffer becomes nearly useless as the original buffer
+is updated, since the line numbers no longer match.
+
+Calling this function is as if you called `ivy-occur' on the
+updated original buffer."
+ (interactive)
+ (let ((caller (ivy-state-caller ivy-occur-last))
+ (ivy-last ivy-occur-last))
+ (let ((inhibit-read-only t)
+ (line (line-number-at-pos)))
+ (erase-buffer)
+ (funcall (or (plist-get ivy--occurs-list caller)
+ #'ivy--occur-default) nil)
+ (goto-char (point-min))
+ (forward-line (1- line)))
+ (setq ivy-occur-last ivy-last)))
+
+(declare-function wgrep-change-to-wgrep-mode "ext:wgrep")
+
+(defun ivy-wgrep-change-to-wgrep-mode ()
+ "Forward to `wgrep-change-to-wgrep-mode'."
+ (interactive)
+ (if (require 'wgrep nil 'noerror)
+ (wgrep-change-to-wgrep-mode)
+ (error "Package wgrep isn't installed")))
+
+(defun ivy-occur-read-action ()
+ "Select one of the available actions as the current one."
+ (interactive)
+ (let ((ivy-last ivy-occur-last))
+ (ivy-read-action)))
+
+(defun ivy-occur-dispatch ()
+ "Call one of the available actions on the current item."
+ (interactive)
+ (let* ((state-action (ivy-state-action ivy-occur-last))
+ (actions (if (symbolp state-action)
+ state-action
+ (copy-sequence state-action))))
+ (unwind-protect
+ (progn
+ (ivy-occur-read-action)
+ (ivy-occur-press))
+ (setf (ivy-state-action ivy-occur-last) actions))))
+
+(defun ivy-occur-click (event)
+ "Execute action for the current candidate.
+EVENT gives the mouse position."
+ (interactive "e")
+ (let ((window (posn-window (event-end event)))
+ (pos (posn-point (event-end event))))
+ (with-current-buffer (window-buffer window)
+ (goto-char pos)
+ (ivy-occur-press))))
+
+(declare-function swiper--cleanup "swiper")
+(declare-function swiper--add-overlays "swiper")
+(defvar ivy-occur-timer nil)
+
+(defun ivy--occur-press-update-window ()
+ (cond
+ ((memq (ivy-state-caller ivy-occur-last)
+ (append '(swiper swiper-isearch) ivy-highlight-grep-commands))
+ (let ((window (ivy-state-window ivy-occur-last))
+ (buffer (ivy-state-buffer ivy-occur-last)))
+ (when (buffer-live-p buffer)
+ (cond ((or (not (window-live-p window))
+ (equal window (selected-window)))
+ (save-selected-window
+ (setf (ivy-state-window ivy-occur-last)
+ (display-buffer buffer))))
+ ((not (equal (window-buffer window) buffer))
+ (with-selected-window window
+ (switch-to-buffer buffer)))))))
+
+ ((memq (ivy-state-caller ivy-occur-last)
+ '(counsel-describe-function
+ counsel-describe-variable
+ counsel-describe-symbol))
+ (setf (ivy-state-window ivy-occur-last)
+ (selected-window))
+ (selected-window))))
+
+(defun ivy--occur-press-buffer ()
+ (let ((buffer (ivy-state-buffer ivy-last)))
+ (if (buffer-live-p buffer)
+ buffer
+ (current-buffer))))
+
+(defun ivy-occur-press ()
+ "Execute action for the current candidate."
+ (interactive)
+ (ivy--occur-press-update-window)
+ (when (save-excursion
+ (beginning-of-line)
+ (looking-at "\\(?:.[/\\]\\| \\)\\(.*\\)$"))
+ (let* ((ivy-last ivy-occur-last)
+ (ivy-text (ivy-state-text ivy-last))
+ (str (buffer-substring
+ (match-beginning 1)
+ (match-end 1)))
+ (offset (or (get-text-property 0 'offset str) 0))
+ (coll (ivy-state-collection ivy-last))
+ (action (ivy--get-action ivy-last))
+ (ivy-exit 'done))
+ (with-ivy-window
+ (with-current-buffer (ivy--occur-press-buffer)
+ (save-restriction
+ (widen)
+ (funcall action
+ (if (and (consp coll)
+ (consp (car coll)))
+ (assoc str coll)
+ (substring str offset)))))
+ (if (memq (ivy-state-caller ivy-last)
+ (append '(swiper swiper-isearch) ivy-highlight-grep-commands))
+ (with-current-buffer (window-buffer (selected-window))
+ (swiper--cleanup)
+ (swiper--add-overlays
+ (ivy--regex ivy-text)
+ (line-beginning-position)
+ (line-end-position)
+ (selected-window))
+ (when (timerp ivy-occur-timer)
+ (cancel-timer ivy-occur-timer))
+ (setq ivy-occur-timer
+ (run-at-time 1.0 nil 'swiper--cleanup))))))))
+
+(defun ivy-occur-press-and-switch ()
+ "Execute action for the current candidate and switch window."
+ (interactive)
+ (ivy-occur-press)
+ (select-window (ivy--get-window ivy-occur-last)))
+
+(defun ivy--marked-p ()
+ (member (ivy-state-current ivy-last) ivy-marked-candidates))
+
+(defun ivy--unmark (cand)
+ (setcar (member cand ivy--all-candidates)
+ (setcar (member cand ivy--old-cands)
+ (substring cand (length ivy-mark-prefix))))
+ (setq ivy-marked-candidates
+ (delete cand ivy-marked-candidates)))
+
+(defun ivy--mark (cand)
+ (let ((marked-cand (concat ivy-mark-prefix cand)))
+ (setcar (member cand ivy--all-candidates)
+ (setcar (member cand ivy--old-cands) marked-cand))
+ (setq ivy-marked-candidates
+ (append ivy-marked-candidates (list marked-cand)))))
+
+(defun ivy-mark ()
+ "Mark the selected candidate and move to the next one.
+
+In `ivy-call', :action will be called in turn for all marked
+candidates.
+
+However, if :multi-action was supplied to `ivy-read', then it
+will be called with `ivy-marked-candidates'. This way, it can
+make decisions based on the whole marked list."
+ (interactive)
+ (unless (ivy--marked-p)
+ (ivy--mark (ivy-state-current ivy-last)))
+ (ivy-next-line))
+
+(defun ivy-unmark ()
+ "Unmark the selected candidate and move to the next one."
+ (interactive)
+ (when (ivy--marked-p)
+ (ivy--unmark (ivy-state-current ivy-last)))
+ (ivy-next-line))
+
+(defun ivy-unmark-backward ()
+ "Move to the previous candidate and unmark it."
+ (interactive)
+ (ivy-previous-line)
+ (ivy--exhibit)
+ (when (ivy--marked-p)
+ (ivy--unmark (ivy-state-current ivy-last))))
+
+(defun ivy-toggle-marks ()
+ "Toggle mark for all narrowed candidates."
+ (interactive)
+ (dolist (cand ivy--old-cands)
+ (if (member cand ivy-marked-candidates)
+ (ivy--unmark cand)
+ (ivy--mark cand))))
+
+(defconst ivy-help-file (let ((default-directory
+ (if load-file-name
+ (file-name-directory load-file-name)
+ default-directory)))
+ (if (file-exists-p "ivy-help.org")
+ (expand-file-name "ivy-help.org")
+ (if (file-exists-p "doc/ivy-help.org")
+ (expand-file-name "doc/ivy-help.org"))))
+ "The file for `ivy-help'.")
+
+(defvar org-hide-emphasis-markers)
+
+(defun ivy-help ()
+ "Help for `ivy'."
+ (interactive)
+ (let ((buf (get-buffer "*Ivy Help*"))
+ (inhibit-read-only t))
+ (unless buf
+ (setq buf (get-buffer-create "*Ivy Help*"))
+ (cl-letf (((symbol-function #'help-buffer) (lambda () buf)))
+ (describe-mode))
+ (with-current-buffer buf
+ (goto-char (point-min))
+ (insert "* describe-mode\n")
+ (goto-char (point-min))
+ (insert-file-contents ivy-help-file)
+ (org-mode)
+ (setq-local org-hide-emphasis-markers t)
+ (view-mode)
+ (goto-char (point-min))
+ (let ((inhibit-message t))
+ (org-cycle '(64)))))
+ (if (eq this-command 'ivy-help)
+ (switch-to-buffer buf)
+ (with-ivy-window
+ (pop-to-buffer buf)))
+ (view-mode)
+ (goto-char (point-min))))
+
+(declare-function ffap-url-p "ffap")
+(defvar ffap-url-fetcher)
+
+(defun ivy-ffap-url-p (string)
+ "Forward to `ffap-url-p'."
+ (require 'ffap)
+ (ffap-url-p string))
+
+(defun ivy-ffap-url-fetcher (url)
+ "Calls `ffap-url-fetcher'."
+ (require 'ffap)
+ (funcall ffap-url-fetcher url))
+
+(ivy-configure 'read-file-name-internal
+ :sort-fn #'ivy-sort-file-function-default
+ :display-transformer-fn #'ivy-read-file-transformer
+ :alt-done-fn #'ivy--directory-done)
+
+(ivy-configure 'internal-complete-buffer
+ :display-transformer-fn #'ivy-switch-buffer-transformer)
+
+(ivy-configure 'Info-read-node-name-1
+ :alt-done-fn #'ivy--info-alt-done)
+
+(provide 'ivy)
+
+;;; ivy.el ends here
diff --git a/elpa/ivy-20210216.1611/ivy.info b/elpa/ivy-20210216.1611/ivy.info
new file mode 100644
index 0000000..c1f52aa
--- /dev/null
+++ b/elpa/ivy-20210216.1611/ivy.info
@@ -0,0 +1,1972 @@
+This is ivy.info, produced by makeinfo version 6.5 from ivy.texi.
+
+Ivy manual, version 0.13.0
+
+ Ivy is an interactive interface for completion in Emacs. Emacs uses
+completion mechanism in a variety of contexts: code, menus, commands,
+variables, functions, etc. Completion entails listing, sorting,
+filtering, previewing, and applying actions on selected items. When
+active, ‘ivy-mode’ completes the selection process by narrowing
+available choices while previewing in the minibuffer. Selecting the
+final candidate is either through simple keyboard character inputs or
+through powerful regular expressions.
+
+ Copyright (C) 2015-2019 Free Software Foundation, Inc.
+
+ Permission is granted to copy, distribute and/or modify this
+ document under the terms of the GNU Free Documentation License,
+ Version 1.3 or any later version published by the Free Software
+ Foundation; with no Invariant Sections, no Front-Cover Texts, and
+ no Back-Cover Texts. A copy of the license is included in the
+ section entitled "GNU Free Documentation License".
+
+INFO-DIR-SECTION Emacs
+START-INFO-DIR-ENTRY
+* Ivy: (ivy). Using Ivy for completion.
+END-INFO-DIR-ENTRY
+
+
+File: ivy.info, Node: Top, Next: Introduction, Up: (dir)
+
+Ivy User Manual
+***************
+
+* Menu:
+
+* Introduction::
+* Installation::
+* Getting started::
+* Key bindings::
+* Completion Styles::
+* Customization::
+* Commands::
+* API::
+* Variable Index::
+* Keystroke Index::
+
+— The Detailed Node Listing —
+
+Installation
+
+* Installing from Emacs Package Manager::
+* Installing from the Git repository::
+
+Getting started
+
+* Basic customization::
+
+Key bindings
+
+* Global key bindings::
+* Minibuffer key bindings::
+
+Minibuffer key bindings
+
+* Key bindings for navigation::
+* Key bindings for single selection, action, then exit minibuffer: Key bindings for single selection action then exit minibuffer.
+* Key bindings for multiple selections and actions, keep minibuffer open: Key bindings for multiple selections and actions keep minibuffer open.
+* Key bindings that alter the minibuffer input::
+* Other key bindings::
+* Hydra in the minibuffer::
+* Saving the current completion session to a buffer::
+
+Completion Styles
+
+* ivy--regex-plus::
+* ivy--regex-ignore-order::
+* ivy--regex-fuzzy::
+
+Customization
+
+* Faces::
+* Defcustoms::
+* Actions::
+* Packages::
+
+Actions
+
+* What are actions?::
+* How can different actions be called?::
+* How to modify the actions list?::
+* Example - add two actions to each command::
+* Example - define a new command with several actions::
+
+Example - add two actions to each command
+
+* How to undo adding the two actions::
+* How to add actions to a specific command::
+
+Example - define a new command with several actions
+
+* Test the above function with ivy-occur::
+
+Commands
+
+* File Name Completion::
+* Buffer Name Completion::
+* Counsel commands::
+
+File Name Completion
+
+* Using TRAMP::
+
+API
+
+* Required arguments for ivy-read::
+* Optional arguments for ivy-read::
+* Example - counsel-describe-function::
+* Example - counsel-locate::
+* Example - ivy-read-with-extra-properties::
+
+
+
+File: ivy.info, Node: Introduction, Next: Installation, Prev: Top, Up: Top
+
+1 Introduction
+**************
+
+Ivy is for quick and easy selection from a list. When Emacs prompts for
+a string from a list of several possible choices, Ivy springs into
+action to assist in narrowing and picking the right string from a vast
+number of choices.
+
+ Ivy strives for minimalism, simplicity, customizability and
+discoverability.
+
+Minimalism
+..........
+
+ Uncluttered minibuffer is minimalism. Ivy shows the completion
+ defaults, the number of matches, and 10 candidate matches below the
+ input line. Customize ‘ivy-height’ to adjust the number of
+ candidate matches displayed in the minibuffer.
+
+Simplicity
+..........
+
+ Simplicity is about Ivy’s behavior in the minibuffer. It is also
+ about the code interface to extend Ivy’s functionality. The
+ minibuffer area behaves as close to ‘fundamental-mode’ as possible.
+ ‘SPC’ inserts a space, for example, instead of being bound to the
+ more complex ‘minibuffer-complete-word’. Ivy’s code uses
+ easy-to-examine global variables; avoids needless complications
+ with branch-introducing custom macros.
+
+Customizability
+...............
+
+ Customizability is about being able to use different methods and
+ interfaces of completion to tailor the selection process. For
+ example, adding a custom display function that points to a selected
+ candidate with ‘>’, instead of highlighting the selected candidate
+ with the ‘ivy-current-match’ face (see
+ ‘ivy-format-functions-alist’). Or take the customization of
+ actions, say after the candidate function is selected. ‘RET’ uses
+ ‘counsel-describe-function’ to describe the function, whereas ‘M-o
+ d’ jumps to that function’s definition in the code. The ‘M-o’
+ prefix can be uniformly used with characters like ‘d’ to group
+ similar actions.
+
+Discoverability
+...............
+
+ Ivy displays easily discoverable commands through the hydra
+ facility. ‘C-o’ in the minibuffer displays a hydra menu. It opens
+ up within an expanded minibuffer area. Each menu item comes with
+ short documentation strings and highlighted one-key completions.
+ So discovering even seldom used keys is simply a matter of ‘C-o’ in
+ the minibuffer while in the midst of the Ivy interaction. This
+ discoverability minimizes exiting Ivy interface for documentation
+ look-ups.
+
+
+File: ivy.info, Node: Installation, Next: Getting started, Prev: Introduction, Up: Top
+
+2 Installation
+**************
+
+Install Ivy automatically through Emacs’s package manager, or manually
+from Ivy’s development repository.
+
+ Emacs 24.3 is the oldest version to run Ivy. Emacs 24.4 is the
+oldest version that runs Ivy with fancy faces display.
+
+* Menu:
+
+* Installing from Emacs Package Manager::
+* Installing from the Git repository::
+
+
+File: ivy.info, Node: Installing from Emacs Package Manager, Next: Installing from the Git repository, Up: Installation
+
+2.1 Installing from Emacs Package Manager
+=========================================
+
+‘M-x’ ‘package-install’ ‘RET’ ‘counsel’ ‘RET’
+
+ Ivy is installed as part of the ‘counsel’ package, which is available
+from two different package archives, GNU ELPA and MELPA. For the latest
+stable version, use the GNU ELPA archives. For current hourly builds,
+use the MELPA archives.
+
+ Ivy is split into three packages: ‘ivy’, ‘swiper’ and ‘counsel’; by
+installing ‘counsel’, the other two are brought in as dependencies. If
+you are not interested in the extra functionality provided by ‘swiper’
+and ‘counsel’, you can install only ‘ivy’.
+
+ See the code below for adding MELPA to the list of package archives:
+
+ (require 'package)
+ (add-to-list 'package-archives
+ '("melpa" . "https://melpa.org/packages/"))
+
+ After this do ‘M-x’ ‘package-refresh-contents’ ‘RET’, followed by
+‘M-x’ ‘package-install’ ‘RET’ ‘counsel’ ‘RET’.
+
+ For package manager details, see *note (emacs)Packages::.
+
+
+File: ivy.info, Node: Installing from the Git repository, Prev: Installing from Emacs Package Manager, Up: Installation
+
+2.2 Installing from the Git repository
+======================================
+
+Why install from Git?
+.....................
+
+ • No need to wait for MELPA’s hourly builds
+ • Easy to revert to previous versions
+ • Contribute to Ivy’s development; send patches; pull requests
+
+Configuration steps
+...................
+
+ First clone the Swiper repository with:
+
+ cd ~/git && git clone https://github.com/abo-abo/swiper
+ cd swiper && make compile
+
+ Second, add these lines to the Emacs init file:
+
+ (add-to-list 'load-path "~/git/swiper/")
+ (require 'ivy)
+
+ Then, update the code with:
+
+ git pull
+ make
+
+
+File: ivy.info, Node: Getting started, Next: Key bindings, Prev: Installation, Up: Top
+
+3 Getting started
+*****************
+
+First enable Ivy completion everywhere:
+
+ (ivy-mode 1)
+
+ Note: ‘ivy-mode’ can be toggled on and off with ‘M-x’ ‘ivy-mode’.
+
+* Menu:
+
+* Basic customization::
+
+
+File: ivy.info, Node: Basic customization, Up: Getting started
+
+3.1 Basic customization
+=======================
+
+Here are some basic settings particularly useful for new Ivy users:
+
+ (setq ivy-use-virtual-buffers t)
+ (setq ivy-count-format "(%d/%d) ")
+
+ If you want, you can go without any customizations at all. The above
+settings are the most bang for the buck in terms of customization. So
+users that typically don’t like customize a lot are advised to look at
+these settings first.
+
+ For more advanced customizations, refer to ‘M-x describe-variable’
+documentation.
+
+
+File: ivy.info, Node: Key bindings, Next: Completion Styles, Prev: Getting started, Up: Top
+
+4 Key bindings
+**************
+
+* Menu:
+
+* Global key bindings::
+* Minibuffer key bindings::
+
+
+File: ivy.info, Node: Global key bindings, Next: Minibuffer key bindings, Up: Key bindings
+
+4.1 Global key bindings
+=======================
+
+Here is a list of commands that are useful to be bound globally, along
+with some sample bindings:
+
+Ivy-based interface to standard commands
+........................................
+
+ (global-set-key (kbd "C-s") 'swiper-isearch)
+ (global-set-key (kbd "M-x") 'counsel-M-x)
+ (global-set-key (kbd "C-x C-f") 'counsel-find-file)
+ (global-set-key (kbd "M-y") 'counsel-yank-pop)
+ (global-set-key (kbd " f") 'counsel-describe-function)
+ (global-set-key (kbd " v") 'counsel-describe-variable)
+ (global-set-key (kbd " l") 'counsel-find-library)
+ (global-set-key (kbd " i") 'counsel-info-lookup-symbol)
+ (global-set-key (kbd " u") 'counsel-unicode-char)
+ (global-set-key (kbd " j") 'counsel-set-variable)
+ (global-set-key (kbd "C-x b") 'ivy-switch-buffer)
+ (global-set-key (kbd "C-c v") 'ivy-push-view)
+ (global-set-key (kbd "C-c V") 'ivy-pop-view)
+
+Ivy-based interface to shell and system tools
+.............................................
+
+ (global-set-key (kbd "C-c c") 'counsel-compile)
+ (global-set-key (kbd "C-c g") 'counsel-git)
+ (global-set-key (kbd "C-c j") 'counsel-git-grep)
+ (global-set-key (kbd "C-c L") 'counsel-git-log)
+ (global-set-key (kbd "C-c k") 'counsel-rg)
+ (global-set-key (kbd "C-c m") 'counsel-linux-app)
+ (global-set-key (kbd "C-c n") 'counsel-fzf)
+ (global-set-key (kbd "C-x l") 'counsel-locate)
+ (global-set-key (kbd "C-c J") 'counsel-file-jump)
+ (global-set-key (kbd "C-S-o") 'counsel-rhythmbox)
+ (global-set-key (kbd "C-c w") 'counsel-wmctrl)
+
+Ivy-resume and other commands
+.............................
+
+ ‘ivy-resume’ resumes the last Ivy-based completion.
+
+ (global-set-key (kbd "C-c C-r") 'ivy-resume)
+ (global-set-key (kbd "C-c b") 'counsel-bookmark)
+ (global-set-key (kbd "C-c d") 'counsel-descbinds)
+ (global-set-key (kbd "C-c g") 'counsel-git)
+ (global-set-key (kbd "C-c o") 'counsel-outline)
+ (global-set-key (kbd "C-c t") 'counsel-load-theme)
+ (global-set-key (kbd "C-c F") 'counsel-org-file)
+
+ You can also enable ‘counsel-mode’ to make some global key binding
+remapping for you.
+
+
+File: ivy.info, Node: Minibuffer key bindings, Prev: Global key bindings, Up: Key bindings
+
+4.2 Minibuffer key bindings
+===========================
+
+Ivy includes several minibuffer bindings, which are defined in the
+‘ivy-minibuffer-map’ keymap variable. The most frequently used ones are
+described here.
+
+ ‘swiper’ or ‘counsel-M-x’ add more key bindings through the ‘keymap’
+argument to ‘ivy-read’. These keys, also active in the minibuffer, are
+described under their respective commands.
+
+ A key feature of ‘ivy-minibuffer-map’ is its full editing capability
+where the familiar ‘C-a’, ‘C-f’, ‘M-d’, ‘M-DEL’, ‘M-b’, ‘M-w’, ‘C-k’,
+‘C-y’ key bindings work the same as in ‘fundamental-mode’.
+
+* Menu:
+
+* Key bindings for navigation::
+* Key bindings for single selection, action, then exit minibuffer: Key bindings for single selection action then exit minibuffer.
+* Key bindings for multiple selections and actions, keep minibuffer open: Key bindings for multiple selections and actions keep minibuffer open.
+* Key bindings that alter the minibuffer input::
+* Other key bindings::
+* Hydra in the minibuffer::
+* Saving the current completion session to a buffer::
+
+
+File: ivy.info, Node: Key bindings for navigation, Next: Key bindings for single selection action then exit minibuffer, Up: Minibuffer key bindings
+
+4.2.1 Key bindings for navigation
+---------------------------------
+
+ • ‘C-n’ (‘ivy-next-line’) selects the next candidate
+ • ‘C-p’ (‘ivy-previous-line’) selects the previous candidate
+ • ‘M-<’ (‘ivy-beginning-of-buffer’) selects the first candidate
+ • ‘M->’ (‘ivy-end-of-buffer’) selects the last candidate
+ • ‘C-v’ (‘ivy-scroll-up-command’) scrolls up by ‘ivy-height’ lines
+ • ‘M-v’ (‘ivy-scroll-down-command’) scrolls down by ‘ivy-height’
+ lines
+
+ -- User Option: ivy-wrap
+ Specifies the wrap-around behavior for ‘C-n’ and ‘C-p’. When
+ ‘ivy-wrap’ is set to ‘t’, ‘ivy-next-line’ and ‘ivy-previous-line’
+ will cycle past the last and the first candidates respectively.
+
+ Wrap-around behavior is off by default.
+
+ -- User Option: ivy-height
+ Use this option to adjust the minibuffer height, which also affects
+ scroll size when using ‘C-v’ and ‘M-v’ key bindings.
+
+ ‘ivy-height’ is 10 lines by default.
+
+
+File: ivy.info, Node: Key bindings for single selection action then exit minibuffer, Next: Key bindings for multiple selections and actions keep minibuffer open, Prev: Key bindings for navigation, Up: Minibuffer key bindings
+
+4.2.2 Key bindings for single selection, action, then exit minibuffer
+---------------------------------------------------------------------
+
+Ivy can offer several actions from which to choose which action to run.
+This "calling an action" operates on the selected candidate. For
+example, when viewing a list of files, one action could open it for
+editing, one to view it, another to invoke a special function, and so
+on. Custom actions can be added to this interface. The precise action
+to call on the selected candidate can be delayed until after the
+narrowing is completed. No need to exit the interface if unsure which
+action to run. This delayed flexibility and customization of actions
+extends usability of lists in Emacs.
+
+‘C-m’ or ‘RET’ (‘ivy-done’)
+...........................
+
+ Calls the default action and then exits the minibuffer.
+
+‘M-o’ (‘ivy-dispatching-done’)
+..............................
+
+ Presents valid actions from which to choose. When only one action
+ is available, there is no difference between ‘M-o’ and ‘C-m’.
+
+‘C-j’ (‘ivy-alt-done’)
+......................
+
+ When completing file names, selects the current directory candidate
+ and starts a new completion session there. Otherwise, it is the
+ same as ‘ivy-done’.
+
+‘TAB’ (‘ivy-partial-or-done’)
+.............................
+
+ Attempts partial completion, extending current input as much as
+ possible. ‘TAB TAB’ is the same as ‘C-j’ (‘ivy-alt-done’).
+
+ Example ERT test:
+
+ (should
+ (equal (ivy-with
+ '(progn
+ (ivy-read "Test: " '("can do" "can't, sorry" "other"))
+ ivy-text)
+ "c ")
+ "can"))
+
+‘C-M-j’ (‘ivy-immediate-done’)
+..............................
+
+ Exits with _the current input_ instead of _the current candidate_
+ (like other commands).
+
+ This is useful e.g. when you call ‘find-file’ to create a new
+ file, but the desired name matches an existing file. In that case,
+ using ‘C-j’ would select that existing file, which isn’t what you
+ want - use this command instead.
+
+‘C-'’ (‘ivy-avy’)
+.................
+
+ Uses avy to select one of the candidates on the current candidate
+ page. This can often be faster than multiple ‘C-n’ or ‘C-p’
+ keystrokes followed by ‘C-m’.
+
+
+File: ivy.info, Node: Key bindings for multiple selections and actions keep minibuffer open, Next: Key bindings that alter the minibuffer input, Prev: Key bindings for single selection action then exit minibuffer, Up: Minibuffer key bindings
+
+4.2.3 Key bindings for multiple selections and actions, keep minibuffer open
+----------------------------------------------------------------------------
+
+For repeatedly applying multiple actions or acting on multiple
+candidates, Ivy does not close the minibuffer between commands. It
+keeps the minibuffer open for applying subsequent actions.
+
+ Adding an extra meta key to the normal key chord invokes the special
+version of the regular commands that enables applying multiple actions.
+
+ Note that these operations are supported only by completion sessions
+that use the ‘ivy-read’ API, rather than the built-in ‘completing-read’.
+
+‘C-M-m’ (‘ivy-call’)
+....................
+
+ Is the non-exiting version of ‘C-m’ (‘ivy-done’).
+
+ Instead of closing the minibuffer, ‘C-M-m’ allows selecting another
+ candidate or another action. For example, ‘C-M-m’ on functions
+ list invokes ‘describe-function’. When combined with ‘C-n’,
+ function descriptions can be invoked quickly in succession.
+
+‘C-M-o’ (‘ivy-dispatching-call’)
+................................
+
+ Is the non-exiting version of ‘M-o’ (‘ivy-dispatching-done’).
+
+ For example, during the ‘counsel-rhythmbox’ completion, press
+ ‘C-M-o e’ to en-queue the selected candidate, followed by ‘C-n C-m’
+ to play the next candidate - the current action reverts to the
+ default one after ‘C-M-o’.
+
+‘C-M-n’ (‘ivy-next-line-and-call’)
+..................................
+
+ Combines ‘C-n’ and ‘C-M-m’. Moves to next line and applies an
+ action.
+
+ Comes in handy when opening multiple files from
+ ‘counsel-find-file’, ‘counsel-git-grep’, ‘counsel-ag’,
+ ‘counsel-rg’, or ‘counsel-locate’ lists. Just hold ‘C-M-n’ for
+ rapid-fire default action on each successive element of the list.
+
+‘C-M-p’ (‘ivy-previous-line-and-call’)
+......................................
+
+ Combines ‘C-p’ and ‘C-M-m’.
+
+ Similar to the above except it moves through the list in the other
+ direction.
+
+‘ivy-resume’
+............
+
+ Recalls the state of the completion session just before its last
+ exit.
+
+ Useful after an accidental ‘C-m’ (‘ivy-done’). Use it with
+ ‘universal-argument’ to resume any previous session.
+
+
+File: ivy.info, Node: Key bindings that alter the minibuffer input, Next: Other key bindings, Prev: Key bindings for multiple selections and actions keep minibuffer open, Up: Minibuffer key bindings
+
+4.2.4 Key bindings that alter the minibuffer input
+--------------------------------------------------
+
+‘M-n’ (‘ivy-next-history-element’)
+..................................
+
+ Cycles forward through the Ivy command history.
+
+ Ivy updates an internal history list after each action. When this
+ history list is empty, ‘M-n’ inserts symbol (or URL) at point into
+ the minibuffer.
+
+‘M-p’ (‘ivy-previous-history-element’)
+......................................
+
+ Cycles forward through the Ivy command history.
+
+‘M-i’ (‘ivy-insert-current’)
+............................
+
+ Inserts the current candidate into the minibuffer.
+
+ Useful for copying and renaming files, for example: ‘M-i’ to insert
+ the original file name string, edit it, and then ‘C-m’ to complete
+ the renaming.
+
+‘M-j’ (‘ivy-yank-word’)
+.......................
+
+ Inserts the sub-word at point into the minibuffer.
+
+ This is similar to ‘C-s C-w’ with ‘isearch’. Ivy reserves ‘C-w’
+ for ‘kill-region’. See also ‘ivy-yank-symbol’ and ‘ivy-yank-char’.
+
+‘S-SPC’ (‘ivy-restrict-to-matches’)
+...................................
+
+ Deletes the current input, and resets the candidates list to the
+ currently restricted matches.
+
+ This is how Ivy provides narrowing in successive tiers.
+
+‘C-r’ (‘ivy-reverse-i-search’)
+..............................
+
+ Starts a recursive completion session through the command’s
+ history.
+
+ This works just like ‘C-r’ at the bash command prompt, where the
+ completion candidates are the history items. Upon completion, the
+ selected candidate string is inserted into the minibuffer.
+
+
+File: ivy.info, Node: Other key bindings, Next: Hydra in the minibuffer, Prev: Key bindings that alter the minibuffer input, Up: Minibuffer key bindings
+
+4.2.5 Other key bindings
+------------------------
+
+‘M-w’ (‘ivy-kill-ring-save’)
+............................
+
+ Copies selected candidates to the kill ring.
+
+ Copies the region if the region is active.
+
+
+File: ivy.info, Node: Hydra in the minibuffer, Next: Saving the current completion session to a buffer, Prev: Other key bindings, Up: Minibuffer key bindings
+
+4.2.6 Hydra in the minibuffer
+-----------------------------
+
+‘C-o’ (‘hydra-ivy/body’)
+........................
+
+ Invokes the hydra menu with short key bindings.
+
+ When Hydra is active, minibuffer editing is disabled and menus
+display short aliases:
+
+Short Normal Command name
+------------------------------------------------
+‘o’ ‘C-g’ ‘keyboard-escape-quit’
+‘j’ ‘C-n’ ‘ivy-next-line’
+‘k’ ‘C-p’ ‘ivy-previous-line’
+‘h’ ‘M-<’ ‘ivy-beginning-of-buffer’
+‘l’ ‘M->’ ‘ivy-end-of-buffer’
+‘d’ ‘C-m’ ‘ivy-done’
+‘f’ ‘C-j’ ‘ivy-alt-done’
+‘g’ ‘C-M-m’ ‘ivy-call’
+‘u’ ‘C-c C-o’ ‘ivy-occur’
+
+ Hydra reduces key strokes, for example: ‘C-n C-n C-n C-n’ is ‘C-o
+jjjj’ in Hydra.
+
+ Hydra menu offers these additional bindings:
+
+‘c’ (‘ivy-toggle-calling’)
+..........................
+
+ Toggle calling the action after each candidate change. It modifies
+ ‘j’ to ‘jg’, ‘k’ to ‘kg’ etc.
+
+‘m’ (‘ivy-rotate-preferred-builders’)
+.....................................
+
+ Rotate the current regexp matcher.
+
+‘>’ (‘ivy-minibuffer-grow’)
+...........................
+
+ Increase ‘ivy-height’ for the current minibuffer.
+
+‘<’ (‘ivy-minibuffer-shrink’)
+.............................
+
+ Decrease ‘ivy-height’ for the current minibuffer.
+
+‘w’ (‘ivy-prev-action’)
+.......................
+
+ Select the previous action.
+
+‘s’ (‘ivy-next-action’)
+.......................
+
+ Select the next action.
+
+‘a’ (‘ivy-read-action’)
+.......................
+
+ Use a menu to select an action.
+
+‘C’ (‘ivy-toggle-case-fold’)
+............................
+
+ Toggle case folding (match both upper and lower case characters for
+ lower case input).
+
+ Hydra menu also offers bindings for marking multiple candidates:
+
+Key Command name
+--------------------------------
+‘m’ ‘ivy-mark’
+‘u’ ‘ivy-unmark’
+‘DEL’ ‘ivy-unmark-backward’
+‘t’ ‘ivy-toggle-marks’
+
+ The action is called on each marked candidate one by one.
+
+
+File: ivy.info, Node: Saving the current completion session to a buffer, Prev: Hydra in the minibuffer, Up: Minibuffer key bindings
+
+4.2.7 Saving the current completion session to a buffer
+-------------------------------------------------------
+
+‘C-c C-o’ (‘ivy-occur’)
+.......................
+
+ Saves the current candidates to a new buffer and exits completion.
+
+ The new buffer is read-only and has a few useful bindings defined.
+
+‘RET’ or ‘f’ (‘ivy-occur-press’)
+................................
+
+ Call the current action on the selected candidate.
+
+‘mouse-1’ (‘ivy-occur-click’)
+.............................
+
+ Call the current action on the selected candidate.
+
+‘j’ (‘next-line’)
+.................
+
+ Move to next line.
+
+‘k’ (‘previous-line’)
+.....................
+
+ Move to previous line.
+
+‘a’ (‘ivy-occur-read-action’)
+.............................
+
+ Read an action and make it current for this buffer.
+
+‘o’ (‘ivy-occur-dispatch’)
+..........................
+
+ Read an action and call it on the selected candidate.
+
+‘q’ (‘quit-window’)
+...................
+
+ Bury the current buffer.
+
+ Ivy has no limit on the number of active buffers like these.
+
+ Ivy takes care of naming buffers uniquely by constructing descriptive
+names. For example: ‘*ivy-occur counsel-describe-variable "function$*’.
+
+
+File: ivy.info, Node: Completion Styles, Next: Customization, Prev: Key bindings, Up: Top
+
+5 Completion Styles
+*******************
+
+Ivy’s completion functions rely on a regex builder - a function that
+transforms a string input to a string regex. All current candidates
+simply have to match this regex. Each collection can be assigned its
+own regex builder by customizing ‘ivy-re-builders-alist’.
+
+ The keys of this alist are collection names, and the values are one
+of the following:
+ • ‘ivy--regex’
+ • ‘ivy--regex-plus’
+ • ‘ivy--regex-ignore-order’
+ • ‘ivy--regex-fuzzy’
+ • ‘regexp-quote’
+
+ A catch-all key, ‘t’, applies to all collections that don’t have
+their own key.
+
+ The default is:
+
+ (setq ivy-re-builders-alist
+ '((t . ivy--regex-plus)))
+
+ This example shows a custom regex builder assigned to file name
+completion:
+
+ (setq ivy-re-builders-alist
+ '((read-file-name-internal . ivy--regex-fuzzy)
+ (t . ivy--regex-plus)))
+
+ Here, ‘read-file-name-internal’ is a function that is passed as the
+second argument to ‘completing-read’ for file name completion.
+
+ The regex builder resolves as follows (in order of priority):
+ 1. ‘re-builder’ argument passed to ‘ivy-read’.
+ 2. ‘collection’ argument passed to ‘ivy-read’ is a function and has an
+ entry on ‘ivy-re-builders-alist’.
+ 3. ‘caller’ argument passed to ‘ivy-read’ has an entry on
+ ‘ivy-re-builders-alist’.
+ 4. ‘this-command’ has an entry on ‘ivy-re-builders-alist’.
+ 5. ‘t’ has an entry on ‘ivy-re-builders-alist’.
+ 6. ‘ivy--regex’.
+
+* Menu:
+
+* ivy--regex-plus::
+* ivy--regex-ignore-order::
+* ivy--regex-fuzzy::
+
+
+File: ivy.info, Node: ivy--regex-plus, Next: ivy--regex-ignore-order, Up: Completion Styles
+
+5.1 ivy–regex-plus
+==================
+
+‘ivy--regex-plus’ is Ivy’s default completion method.
+
+ ‘ivy--regex-plus’ matches by splitting the input by spaces and
+rebuilding it into a regex.
+
+ As the search string is typed in Ivy’s minibuffer, it is transformed
+into valid regex syntax. If the string is ‘"for example"’, it is
+transformed into
+
+ "\\(for\\).*\\(example\\)"
+
+ which in regex terminology matches ‘"for"’ followed by a wild card
+and then ‘"example"’. Note how Ivy uses the space character to build
+wild cards. To match a literal white space, use an extra space. So to
+match one space type two spaces, to match two spaces type three spaces,
+and so on.
+
+ As Ivy transforms typed characters into regex strings, it provides an
+intuitive feedback through font highlights.
+
+ Ivy supports regexp negation with ‘"!"’. For example, ‘"define key !
+ivy quit"’ first selects everything matching ‘"define.*key"’, then
+removes everything matching ‘"ivy"’, and finally removes everything
+matching ‘"quit"’. What remains is the final result set of the negation
+regexp.
+
+ Since Ivy treats minibuffer input as a regexp, the standard regexp
+identifiers work: ‘"^"’, ‘"$"’, ‘"\b"’ or ‘"[a-z]"’. The exceptions are
+spaces, which translate to ‘".*"’, and ‘"!"’ that signal the beginning
+of a negation group.
+
+
+File: ivy.info, Node: ivy--regex-ignore-order, Next: ivy--regex-fuzzy, Prev: ivy--regex-plus, Up: Completion Styles
+
+5.2 ivy–regex-ignore-order
+==========================
+
+‘ivy--regex-ignore-order’ ignores the order of regexp tokens when
+searching for matching candidates. For instance, the input ‘"for
+example"’ will match ‘"example test for"’.
+
+
+File: ivy.info, Node: ivy--regex-fuzzy, Prev: ivy--regex-ignore-order, Up: Completion Styles
+
+5.3 ivy–regex-fuzzy
+===================
+
+‘ivy--regex-fuzzy’ splits each character with a wild card. Searching
+for ‘"for"’ returns all ‘"f.*o.*r"’ matches, resulting in a large number
+of hits. Yet some searches need these extra hits. Ivy sorts such large
+lists using ‘flx’ package’s scoring mechanism, if it’s installed.
+
+ ‘C-o m’ toggles the current regexp builder.
+
+
+File: ivy.info, Node: Customization, Next: Commands, Prev: Completion Styles, Up: Top
+
+6 Customization
+***************
+
+* Menu:
+
+* Faces::
+* Defcustoms::
+* Actions::
+* Packages::
+
+
+File: ivy.info, Node: Faces, Next: Defcustoms, Up: Customization
+
+6.1 Faces
+=========
+
+‘ivy-current-match’
+...................
+
+ Highlights the currently selected candidate.
+
+‘ivy-minibuffer-match-face-1’
+.............................
+
+ Highlights the background of the match.
+
+‘ivy-minibuffer-match-face-2’
+.............................
+
+ Highlights the first (modulo 3) matched group.
+
+‘ivy-minibuffer-match-face-3’
+.............................
+
+ Highlights the second (modulo 3) matched group.
+
+‘ivy-minibuffer-match-face-4’
+.............................
+
+ Highlights the third (modulo 3) matched group.
+
+‘ivy-confirm-face’
+..................
+
+ Highlights the "(confirm)" part of the prompt.
+
+ When ‘confirm-nonexistent-file-or-buffer’ set to ‘t’, then
+ confirming non-existent files in ‘ivy-mode’ requires an additional
+ ‘RET’.
+
+ The confirmation prompt will use this face.
+
+ For example:
+
+ (setq confirm-nonexistent-file-or-buffer t)
+
+ Then call ‘find-file’, enter "eldorado" and press ‘RET’ - the
+ prompt will be appended with "(confirm)". Press ‘RET’ once more to
+ confirm, or any key to continue the completion.
+
+‘ivy-match-required-face’
+.........................
+
+ Highlights the "(match required)" part of the prompt.
+
+ When completions have to match available candidates and cannot take
+ random input, the "(match required)" prompt signals this
+ constraint.
+
+ For example, call ‘describe-variable’, enter "waldo" and press
+ ‘RET’ - "(match required)" is prompted. Press any key for the
+ prompt to disappear.
+
+‘ivy-subdir’
+............
+
+ Highlights directories when completing file names.
+
+‘ivy-remote’
+............
+
+ Highlights remote files when completing file names.
+
+‘ivy-virtual’
+.............
+
+ Highlights virtual buffers when completing buffer names.
+
+ Virtual buffers correspond to bookmarks and recent files list,
+ ‘recentf’.
+
+ Enable virtual buffers with:
+
+ (setq ivy-use-virtual-buffers t)
+
+‘ivy-modified-buffer’
+.....................
+
+ Highlights modified buffers when switching buffer.
+
+‘ivy-modified-outside-buffer’
+.............................
+
+ Highlights buffers modified outside Emacs when switching buffer.
+
+ This takes precedence over ‘ivy-modified-buffer’.
+
+
+File: ivy.info, Node: Defcustoms, Next: Actions, Prev: Faces, Up: Customization
+
+6.2 Defcustoms
+==============
+
+ -- User Option: ivy-count-format
+ A string that specifies display of number of candidates and current
+ candidate, if one exists.
+
+ The number of matching candidates by default is shown as a right-
+ padded integer value.
+
+ To disable showing the number of candidates:
+
+ (setq ivy-count-format "")
+
+ To also display the current candidate:
+
+ (setq ivy-count-format "(%d/%d) ")
+
+ The ‘format’-style switches this variable uses are described in the
+ ‘format’ documentation.
+
+ -- User Option: ivy-display-style
+ Specifies highlighting candidates in the minibuffer.
+
+ The default setting is ‘'fancy’ in Emacs versions 24.4 or newer.
+
+ Set ‘ivy-display-style’ to ‘nil’ for a plain minibuffer.
+
+ -- User Option: ivy-on-del-error-function
+ Specifies what to do when ‘DEL’ (‘ivy-backward-delete-char’) fails.
+
+ This is usually the case when there is no text left to delete,
+ i.e., when ‘DEL’ is typed at the beginning of the minibuffer.
+
+ The default behavior is to quit the completion after ‘DEL’ – a
+ handy key to invoke after mistakenly triggering a completion.
+
+ Another common option is ‘ignore’, which does nothing.
+
+
+File: ivy.info, Node: Actions, Next: Packages, Prev: Defcustoms, Up: Customization
+
+6.3 Actions
+===========
+
+* Menu:
+
+* What are actions?::
+* How can different actions be called?::
+* How to modify the actions list?::
+* Example - add two actions to each command::
+* Example - define a new command with several actions::
+
+
+File: ivy.info, Node: What are actions?, Next: How can different actions be called?, Up: Actions
+
+6.3.1 What are actions?
+-----------------------
+
+An action is a function that is called after you select a candidate
+during completion. This function takes a single string argument, which
+is the selected candidate.
+
+Window context when calling an action
+.....................................
+
+ Currently, the action is executed in the minibuffer window context.
+ This means e.g. that if you call ‘insert’ the text will be
+ inserted into the minibuffer.
+
+ If you want to execute the action in the initial window from which
+ the completion started, use the ‘with-ivy-window’ wrapper macro.
+
+ (defun ivy-insert-action (x)
+ (with-ivy-window
+ (insert x)))
+
+
+File: ivy.info, Node: How can different actions be called?, Next: How to modify the actions list?, Prev: What are actions?, Up: Actions
+
+6.3.2 How can different actions be called?
+------------------------------------------
+
+ • ‘C-m’ (‘ivy-done’) calls the current action.
+ • ‘M-o’ (‘ivy-dispatching-done’) presents available actions for
+ selection, calls it after selection, and then exits.
+ • ‘C-M-o’ (‘ivy-dispatching-call’) presents available actions for
+ selection, calls it after selection, and then does not exit.
+
+
+File: ivy.info, Node: How to modify the actions list?, Next: Example - add two actions to each command, Prev: How can different actions be called?, Up: Actions
+
+6.3.3 How to modify the actions list?
+-------------------------------------
+
+Currently, you can append any amount of your own actions to the default
+list of actions. This can be done either for a specific command, or for
+all commands at once.
+
+ Usually, the command has only one default action. The convention is
+to use single letters when selecting a command, and the letter ‘o’ is
+designated for the default command. This way, ‘M-o o’ should be always
+equivalent to ‘C-m’.
+
+
+File: ivy.info, Node: Example - add two actions to each command, Next: Example - define a new command with several actions, Prev: How to modify the actions list?, Up: Actions
+
+6.3.4 Example - add two actions to each command
+-----------------------------------------------
+
+The first action inserts the current candidate into the Ivy window - the
+window from which ‘ivy-read’ was called.
+
+ The second action copies the current candidate to the kill ring.
+
+ (defun ivy-yank-action (x)
+ (kill-new x))
+
+ (defun ivy-copy-to-buffer-action (x)
+ (with-ivy-window
+ (insert x)))
+
+ (ivy-set-actions
+ t
+ '(("i" ivy-copy-to-buffer-action "insert")
+ ("y" ivy-yank-action "yank")))
+
+ Then in any completion session, ‘M-o y’ invokes ‘ivy-yank-action’,
+and ‘M-o i’ invokes ‘ivy-copy-to-buffer-action’.
+
+* Menu:
+
+* How to undo adding the two actions::
+* How to add actions to a specific command::
+
+
+File: ivy.info, Node: How to undo adding the two actions, Next: How to add actions to a specific command, Up: Example - add two actions to each command
+
+6.3.4.1 How to undo adding the two actions
+..........................................
+
+Since ‘ivy-set-actions’ modifies the internal dictionary with new data,
+set the extra actions list to ‘nil’ by assigning ‘nil’ value to the ‘t’
+key as follows:
+
+ (ivy-set-actions t nil)
+
+
+File: ivy.info, Node: How to add actions to a specific command, Prev: How to undo adding the two actions, Up: Example - add two actions to each command
+
+6.3.4.2 How to add actions to a specific command
+................................................
+
+Use the command name as the key:
+
+ (ivy-set-actions
+ 'swiper
+ '(("i" ivy-copy-to-buffer-action "insert")
+ ("y" ivy-yank-action "yank")))
+
+
+File: ivy.info, Node: Example - define a new command with several actions, Prev: Example - add two actions to each command, Up: Actions
+
+6.3.5 Example - define a new command with several actions
+---------------------------------------------------------
+
+ (defun my-action-1 (x)
+ (message "action-1: %s" x))
+
+ (defun my-action-2 (x)
+ (message "action-2: %s" x))
+
+ (defun my-action-3 (x)
+ (message "action-3: %s" x))
+
+ (defun my-command-with-3-actions ()
+ (interactive)
+ (ivy-read "test: " '("foo" "bar" "baz")
+ :action '(1
+ ("o" my-action-1 "action 1")
+ ("j" my-action-2 "action 2")
+ ("k" my-action-3 "action 3"))))
+
+ The number 1 above is the index of the default action. Each action
+has its own string description for easy selection.
+
+* Menu:
+
+* Test the above function with ivy-occur::
+
+
+File: ivy.info, Node: Test the above function with ivy-occur, Up: Example - define a new command with several actions
+
+6.3.5.1 Test the above function with ‘ivy-occur’
+................................................
+
+To examine each action with each candidate in a key-efficient way, try:
+
+ • Call ‘my-command-with-3-actions’
+ • Press ‘C-c C-o’ to close the completion window and move to an
+ ivy-occur buffer
+ • Press ‘kkk’ to move to the first candidate, since the point is most
+ likely at the end of the buffer
+ • Press ‘oo’ to call the first action
+ • Press ‘oj’ and ‘ok’ to call the second and the third actions
+ • Press ‘j’ to move to the next candidate
+ • Press ‘oo’, ‘oj’, ‘ok’
+ • Press ‘j’ to move to the next candidate
+ • and so on...
+
+
+File: ivy.info, Node: Packages, Prev: Actions, Up: Customization
+
+6.4 Packages
+============
+
+‘org-mode’
+..........
+
+ ‘org-mode’ versions 8.3.3 or later obey ‘completing-read-function’
+ (which ‘ivy-mode’ sets). Try refiling headings with similar names
+ to appreciate ‘ivy-mode’.
+
+‘magit’
+.......
+
+ Uses ivy by default if Ivy is installed.
+
+‘find-file-in-project’
+......................
+
+ Uses ivy by default if Ivy is installed.
+
+‘projectile’
+............
+
+ Projectile requires this setting for ivy completion:
+
+ (setq projectile-completion-system 'ivy)
+
+‘helm-make’
+...........
+
+ Helm-make requires this setting for ivy completion.
+
+ (setq helm-make-completion-method 'ivy)
+
+automatically integrated packages
+.................................
+
+ Ivy re-uses the following packages if they are installed: ‘avy’,
+ ‘amx’ or ‘smex’, ‘flx’, and ‘wgrep’.
+
+
+File: ivy.info, Node: Commands, Next: API, Prev: Customization, Up: Top
+
+7 Commands
+**********
+
+* Menu:
+
+* File Name Completion::
+* Buffer Name Completion::
+* Counsel commands::
+
+
+File: ivy.info, Node: File Name Completion, Next: Buffer Name Completion, Up: Commands
+
+7.1 File Name Completion
+========================
+
+Since file name completion is ubiquitous, Ivy provides extra bindings
+that work here:
+
+‘C-j’ (‘ivy-alt-done’)
+......................
+
+ On a directory, restarts completion from that directory.
+
+ On a file or ‘./’, exit completion with the selected candidate.
+
+‘DEL’ (‘ivy-backward-delete-char’)
+..................................
+
+ Restart the completion in the parent directory if current input is
+ empty.
+
+‘//’ (‘self-insert-command’)
+............................
+
+ Switch to the root directory.
+
+‘~’ (‘self-insert-command’)
+...........................
+
+ Switch to the home directory.
+
+‘/’ (‘self-insert-command’)
+...........................
+
+ If the current input matches an existing directory name exactly,
+ switch the completion to that directory.
+
+‘C-M-y’ (‘ivy-insert-current-full’)
+...................................
+
+ Insert the current full path, in case you want to edit a part of
+ it.
+
+‘M-r’ (‘ivy-toggle-regexp-quote’)
+.................................
+
+ Toggle between input as regexp or not.
+
+ Switch to matching literally since file names include ‘.’, which is
+ for matching any char in regexp mode.
+ -- User Option: ivy-extra-directories
+ Decide if you want to see ‘../’ and ‘./’ during file name
+ completion.
+
+ Reason to remove: ‘../’ is the same as ‘DEL’.
+
+ Reason not to remove: navigate anywhere with only ‘C-n’, ‘C-p’ and
+ ‘C-j’.
+
+ Likewise, ‘./’ can be removed.
+
+History
+.......
+
+ File history works the same with ‘M-p’, ‘M-n’, and ‘C-r’, but uses
+ a custom code for file name completion that cycles through files
+ previously opened. It also works with TRAMP files.
+
+* Menu:
+
+* Using TRAMP::
+
+
+File: ivy.info, Node: Using TRAMP, Up: File Name Completion
+
+7.1.1 Using TRAMP
+-----------------
+
+‘~’ (tilde)
+...........
+
+ Move to the home directory. Either the local or the remote one,
+ depending on the current directory. The boolean option
+ ‘ivy-magic-tilde’ decides whether the binding to do this is ‘~’ or
+ ‘~/’.
+
+‘//’ (double slash)
+...................
+
+ Move to the root directory. Either the local or the remote one,
+ depending on the current directory. Here, you can also select a
+ TRAMP connection method, such as ‘ssh’ or ‘scpx’.
+
+‘/ C-j’
+.......
+
+ Move the the local root directory.
+
+‘~~’
+....
+
+ Move to the local home directory.
+
+ From any directory, with the empty input, inputting ‘/ssh:’ and
+pressing ‘C-j’ (or ‘RET’, which is the same thing) completes for host
+and user names.
+
+ For ‘/ssh:user@’ input, completes the domain name.
+
+ ‘C-i’ works in a similar way to the default completion.
+
+ You can also get sudo access for the current directory by inputting
+‘/sudo::’ ‘RET’. Using ‘/sudo:’ (i.e. single colon instead of double)
+will result in a completion session for the desired user.
+
+ Multi-hopping is possible, although a bit complex.
+
+Example : connect to a remote host ‘cloud’ and open a file with ‘sudo’ there
+............................................................................
+
+ • ‘C-x C-f’ ‘/ssh:cloud|sudo:root:/’.
+
+
+File: ivy.info, Node: Buffer Name Completion, Next: Counsel commands, Prev: File Name Completion, Up: Commands
+
+7.2 Buffer Name Completion
+==========================
+
+ -- User Option: ivy-use-virtual-buffers
+ When non-nil, add ‘recentf-mode’ and bookmarks to
+ ‘ivy-switch-buffer’ completion candidates.
+
+ Adding this to Emacs init file:
+
+ (setq ivy-use-virtual-buffers t)
+ will add additional virtual buffers to the buffers list for recent
+ files. Selecting such virtual buffers, which are highlighted with
+ ‘ivy-virtual’ face, will open the corresponding file.
+
+
+File: ivy.info, Node: Counsel commands, Prev: Buffer Name Completion, Up: Commands
+
+7.3 Counsel commands
+====================
+
+The main advantages of ‘counsel-’ functions over their basic equivalents
+in ‘ivy-mode’ are:
+
+ 1. Multi-actions and non-exiting actions work.
+ 2. ‘ivy-resume’ can resume the last completion session.
+ 3. Customize ‘ivy-set-actions’, ‘ivy-re-builders-alist’.
+ 4. Customize individual keymaps, such as ‘counsel-describe-map’,
+ ‘counsel-git-grep-map’, or ‘counsel-find-file-map’, instead of
+ customizing ‘ivy-minibuffer-map’ that applies to all completion
+ sessions.
+
+
+File: ivy.info, Node: API, Next: Variable Index, Prev: Commands, Up: Top
+
+8 API
+*****
+
+The main (and only) entry point is the ‘ivy-read’ function. It takes
+two required arguments and many optional arguments that can be passed by
+a key. The optional ‘:action’ argument is highly recommended for
+features such as multi-actions, non-exiting actions, ‘ivy-occur’ and
+‘ivy-resume’.
+
+* Menu:
+
+* Required arguments for ivy-read::
+* Optional arguments for ivy-read::
+* Example - counsel-describe-function::
+* Example - counsel-locate::
+* Example - ivy-read-with-extra-properties::
+
+
+File: ivy.info, Node: Required arguments for ivy-read, Next: Optional arguments for ivy-read, Up: API
+
+8.1 Required arguments for ‘ivy-read’
+=====================================
+
+‘prompt’
+........
+
+ A prompt string normally ending in a colon and a space.
+ ‘ivy-count-format’ is prepended to it during completion.
+
+‘collection’
+............
+
+ Either a list of strings, a function, an alist or a hash table.
+
+ If a function, then it has to be compatible with ‘all-completions’.
+
+
+File: ivy.info, Node: Optional arguments for ivy-read, Next: Example - counsel-describe-function, Prev: Required arguments for ivy-read, Up: API
+
+8.2 Optional arguments for ‘ivy-read’
+=====================================
+
+‘predicate’
+...........
+
+ Is a function to filter the initial collection. It has to be
+ compatible with ‘all-completions’. Tip: most of the time, it’s
+ simpler to just apply this filter to the ‘collection’ argument
+ itself, e.g. ‘(cl-remove-if-not predicate collection)’.
+
+‘require-match’
+...............
+
+ When set to a non-nil value, input must match one of the
+ candidates. Custom input is not accepted.
+
+‘initial-input’
+...............
+
+ This string argument is included for compatibility with
+ ‘completing-read’, which inserts it into the minibuffer.
+
+ It’s recommended to use the ‘preselect’ argument instead of this.
+
+‘history’
+.........
+
+ Name of the symbol to store history. See ‘completing-read’.
+
+‘preselect’
+...........
+
+ Determines which one of the candidates to initially select.
+
+ When set to an integer value, select the candidate with that index
+ value.
+
+ When set to any other non-nil value, select the first candidate
+ matching this value. Comparison is first done with ‘equal’. If
+ this fails, and when applicable, match ‘preselect’ as a regular
+ expression.
+
+ Every time the input becomes empty, the item corresponding to
+ ‘preselect’ is selected.
+
+‘keymap’
+........
+
+ A keymap to be composed with ‘ivy-minibuffer-map’. This keymap has
+ priority over ‘ivy-minibuffer-map’ and can be modified at any later
+ stage.
+
+‘update-fn’
+...........
+
+ Is the function called each time the current candidate changes.
+ This function takes no arguments and is called in the minibuffer’s
+ ‘post-command-hook’. See ‘swiper’ for an example usage.
+
+‘sort’
+......
+
+ When non-nil, use ‘ivy-sort-functions-alist’ to sort the collection
+ as long as the collection is not larger than ‘ivy-sort-max-size’.
+
+‘action’
+........
+
+ Is the function to call after selection. It takes a string
+ argument.
+
+‘unwind’
+........
+
+ Is the function to call before exiting completion. It takes no
+ arguments. This function is called even if the completion is
+ interrupted with ‘C-g’. See ‘swiper’ for an example usage.
+
+‘re-builder’
+............
+
+ Is a function that takes a string and returns a valid regex. See
+ ‘Completion Styles’ for details.
+
+‘matcher’
+.........
+
+ Is a function that takes a regex string and a list of strings and
+ returns a list of strings matching the regex. Any ordinary Emacs
+ matching function will suffice, yet finely tuned matching functions
+ can be used. See ‘counsel-find-file’ for an example usage.
+
+‘dynamic-collection’
+....................
+
+ When non-nil, ‘collection’ will be used to dynamically generate the
+ candidates each time the input changes, instead of being used once
+ statically with ‘all-completions’ to generate a list of strings.
+ See ‘counsel-locate’ for an example usage.
+
+‘caller’
+........
+
+ Is a symbol that uniquely identifies the function that called
+ ‘ivy-read’, which may be useful for further customizations.
+
+
+File: ivy.info, Node: Example - counsel-describe-function, Next: Example - counsel-locate, Prev: Optional arguments for ivy-read, Up: API
+
+8.3 Example - ‘counsel-describe-function’
+=========================================
+
+This is a typical example of a function with a non-async collection,
+which is a collection where all the strings in the collection are known
+prior to any input from the user.
+
+ Only the first two arguments (along with ‘action’) are essential -
+the rest of the arguments are for fine-tuning, and could be omitted.
+
+ The ‘action’ argument could also be omitted - but then ‘ivy-read’
+would do nothing except returning the string result, which you could
+later use yourself. However, it’s recommended that you use the ‘action’
+argument.
+
+ (defun counsel-describe-function ()
+ "Forward to `describe-function'."
+ (interactive)
+ (ivy-read "Describe function: "
+ (let (cands)
+ (mapatoms
+ (lambda (x)
+ (when (fboundp x)
+ (push (symbol-name x) cands))))
+ cands)
+ :keymap counsel-describe-map
+ :preselect (ivy-thing-at-point)
+ :history 'counsel-describe-symbol-history
+ :require-match t
+ :action (lambda (x)
+ (describe-function
+ (intern x)))
+ :caller 'counsel-describe-function))
+
+ Here are the interesting features of the above function, in the order
+that they appear:
+
+ • The ‘prompt’ argument is a simple string ending in ": ".
+ • The ‘collection’ argument evaluates to a (large) list of strings.
+ • The ‘keymap’ argument is for a custom keymap to supplement
+ ‘ivy-minibuffer-map’.
+ • The ‘preselect’ is provided by ‘ivy-thing-at-point’, which returns
+ a symbol near the point. Ivy then selects the first candidate from
+ the collection that matches this symbol. To select this
+ pre-selected candidate, a ‘RET’ will suffice. No further user
+ input is necessary.
+ • The ‘history’ argument is for keeping the history of this command
+ separate from the common history in ‘ivy-history’.
+ • The ‘require-match’ is set to ‘t’ since it doesn’t make sense to
+ call ‘describe-function’ on an un-interned symbol.
+ • The ‘action’ argument calls ‘describe-function’ on the interned
+ selected candidate.
+ • The ‘caller’ argument identifies this completion session. This is
+ important, since with the collection being a list of strings and
+ not a function name, the only other way for ‘ivy-read’ to identify
+ "who’s calling" and to apply the appropriate customizations is to
+ examine ‘this-command’. But ‘this-command’ would be modified if
+ another command called ‘counsel-describe-function’.
+
+
+File: ivy.info, Node: Example - counsel-locate, Next: Example - ivy-read-with-extra-properties, Prev: Example - counsel-describe-function, Up: API
+
+8.4 Example - ‘counsel-locate’
+==============================
+
+This is a typical example of a function with an async collection. Since
+the collection function cannot pre-compute all the locatable files in
+memory within reasonable limits (time or memory), it relies on user
+input to filter the universe of possible candidates to a manageable size
+while also continuing to search asynchronously for possible candidates.
+Both the filtering and searching continues with each character change of
+the input with rapid updates to the collection presented without idle
+waiting times. This live update will continue as long as there are
+likely candidates. Eventually updates to the minibuffer will stop after
+user input, filtering, and searching have exhausted looking for possible
+candidates.
+
+ Async collections suit long-running shell commands, such as ‘locate’.
+With each new input, a new process starts while the old process is
+killed. The collection is refreshed anew with each new process.
+Meanwhile the user can provide more input characters (for further
+narrowing) or select a candidate from the visible collection.
+
+ (defun counsel-locate-function (str)
+ (or
+ (ivy-more-chars)
+ (progn
+ (counsel--async-command
+ (format "locate %s '%s'"
+ (mapconcat #'identity counsel-locate-options " ")
+ (counsel--elisp-to-pcre
+ (ivy--regex str))))
+ '("" "working..."))))
+
+ ;;;###autoload
+ (defun counsel-locate (&optional initial-input)
+ "Call the \"locate\" shell command.
+ INITIAL-INPUT can be given as the initial minibuffer input."
+ (interactive)
+ (ivy-read "Locate: " #'counsel-locate-function
+ :initial-input initial-input
+ :dynamic-collection t
+ :history 'counsel-locate-history
+ :action (lambda (file)
+ (with-ivy-window
+ (when file
+ (find-file file))))
+ :unwind #'counsel-delete-process
+ :caller 'counsel-locate))
+
+ Here are the interesting features of the above functions, in the
+order that they appear:
+
+ • ‘counsel-locate-function’ takes a string argument and returns a
+ list of strings. Note that it’s not compatible with
+ ‘all-completions’, but since we’re not using that here, might as
+ well use one argument instead of three.
+ • ‘ivy-more-chars’ is a simple function that returns e.g. ‘'("2
+ chars more")’ asking the user for more input.
+ • ‘counsel--async-command’ is a very easy API simplification that
+ takes a single string argument suitable for
+ ‘shell-command-to-string’. So you could prototype your function as
+ non-async using ‘shell-command-to-string’ and ‘split-string’ to
+ produce a collection, then decide that you want async and simply
+ swap in ‘counsel--async-command’.
+ • ‘counsel-locate’ is an interactive function with an optional
+ ‘initial-input’.
+ • ‘#'counsel-locate-function’ is passed as the ‘collection’ argument.
+ • ‘dynamic-collection’ is set to t, since this is an async
+ collection.
+ • ‘action’ argument uses ‘with-ivy-window’ wrapper, since we want to
+ open the selected file in the same window from which
+ ‘counsel-locate’ was called.
+ • ‘unwind’ argument is set to ‘#'counsel-delete-process’: when we
+ press ‘C-g’ we want to kill the running process created by
+ ‘counsel--async-command’.
+ • ‘caller’ argument identifies this command for easier customization.
+
+
+File: ivy.info, Node: Example - ivy-read-with-extra-properties, Prev: Example - counsel-locate, Up: API
+
+8.5 Example - ‘ivy-read-with-extra-properties’
+==============================================
+
+This is another example to show how to associate additional values to
+each displayed strings.
+
+ (defun find-candidates-function (str pred _)
+ (let ((props '(1 2))
+ (strs '("foo" "foo2")))
+ (cl-mapcar (lambda (s p) (propertize s 'property p))
+ strs
+ props)))
+
+ (defun find-candidates ()
+ (interactive)
+ (ivy-read "Find symbols: "
+ #'find-candidates-function
+ :action (lambda (x)
+ (message "Value: %s" (get-text-property 0 'property x)
+ ))))
+
+ Here are the interesting features of the above function:
+
+ • ‘find-candidates-function’ builds up a list of strings and
+ associates "foo" with the value 1 and "foo2" with 2.
+ • ‘find-candidates’ is an interactive function.
+ • ‘#'find-candidates’ is passed as the ‘collection’ argument.
+ • ‘action’ gets passed the selected string with the associated value.
+ It then retrieves that value and displays it.
+
+
+File: ivy.info, Node: Variable Index, Next: Keystroke Index, Prev: API, Up: Top
+
+9 Variable Index
+****************
+
+ [index ]
+* Menu:
+
+* ivy-alt-done: Key bindings for single selection action then exit minibuffer.
+ (line 30)
+* ivy-alt-done <1>: File Name Completion. (line 12)
+* ivy-avy: Key bindings for single selection action then exit minibuffer.
+ (line 64)
+* ivy-backward-delete-char: File Name Completion. (line 19)
+* ivy-call: Key bindings for multiple selections and actions keep minibuffer open.
+ (line 19)
+* ivy-confirm-face: Faces. (line 34)
+* ivy-count-format: Defcustoms. (line 6)
+* ivy-current-match: Faces. (line 9)
+* ivy-dispatching-call: Key bindings for multiple selections and actions keep minibuffer open.
+ (line 29)
+* ivy-dispatching-done: Key bindings for single selection action then exit minibuffer.
+ (line 24)
+* ivy-display-style: Defcustoms. (line 24)
+* ivy-done: Key bindings for single selection action then exit minibuffer.
+ (line 19)
+* ivy-extra-directories: File Name Completion. (line 51)
+* ivy-height: Key bindings for navigation.
+ (line 21)
+* ivy-immediate-done: Key bindings for single selection action then exit minibuffer.
+ (line 53)
+* ivy-insert-current: Key bindings that alter the minibuffer input.
+ (line 23)
+* ivy-insert-current-full: File Name Completion. (line 41)
+* ivy-kill-ring-save: Other key bindings. (line 9)
+* ivy-match-required-face: Faces. (line 53)
+* ivy-minibuffer-grow: Hydra in the minibuffer.
+ (line 45)
+* ivy-minibuffer-map: Minibuffer key bindings.
+ (line 6)
+* ivy-minibuffer-match-face-1: Faces. (line 14)
+* ivy-minibuffer-match-face-2: Faces. (line 19)
+* ivy-minibuffer-match-face-3: Faces. (line 24)
+* ivy-minibuffer-match-face-4: Faces. (line 29)
+* ivy-minibuffer-shrink: Hydra in the minibuffer.
+ (line 50)
+* ivy-modified-buffer: Faces. (line 88)
+* ivy-modified-outside-buffer: Faces. (line 93)
+* ivy-next-action: Hydra in the minibuffer.
+ (line 60)
+* ivy-next-history-element: Key bindings that alter the minibuffer input.
+ (line 9)
+* ivy-next-line-and-call: Key bindings for multiple selections and actions keep minibuffer open.
+ (line 39)
+* ivy-occur: Saving the current completion session to a buffer.
+ (line 9)
+* ivy-occur-click: Saving the current completion session to a buffer.
+ (line 21)
+* ivy-occur-dispatch: Saving the current completion session to a buffer.
+ (line 41)
+* ivy-occur-press: Saving the current completion session to a buffer.
+ (line 16)
+* ivy-occur-read-action: Saving the current completion session to a buffer.
+ (line 36)
+* ivy-on-del-error-function: Defcustoms. (line 31)
+* ivy-partial-or-done: Key bindings for single selection action then exit minibuffer.
+ (line 37)
+* ivy-prev-action: Hydra in the minibuffer.
+ (line 55)
+* ivy-previous-history-element: Key bindings that alter the minibuffer input.
+ (line 18)
+* ivy-previous-line-and-call: Key bindings for multiple selections and actions keep minibuffer open.
+ (line 50)
+* ivy-read-action: Hydra in the minibuffer.
+ (line 65)
+* ivy-remote: Faces. (line 71)
+* ivy-restrict-to-matches: Key bindings that alter the minibuffer input.
+ (line 40)
+* ivy-resume: Key bindings for multiple selections and actions keep minibuffer open.
+ (line 58)
+* ivy-reverse-i-search: Key bindings that alter the minibuffer input.
+ (line 48)
+* ivy-rotate-preferred-builders: Hydra in the minibuffer.
+ (line 40)
+* ivy-subdir: Faces. (line 66)
+* ivy-toggle-calling: Hydra in the minibuffer.
+ (line 34)
+* ivy-toggle-case-fold: Hydra in the minibuffer.
+ (line 70)
+* ivy-toggle-regexp-quote: File Name Completion. (line 47)
+* ivy-use-virtual-buffers: Buffer Name Completion.
+ (line 6)
+* ivy-virtual: Faces. (line 76)
+* ivy-wrap: Key bindings for navigation.
+ (line 14)
+* ivy-yank-word: Key bindings that alter the minibuffer input.
+ (line 32)
+
+
+File: ivy.info, Node: Keystroke Index, Prev: Variable Index, Up: Top
+
+10 Keystroke Index
+******************
+
+ [index ]
+* Menu:
+
+* /: File Name Completion. (line 35)
+* / C-j: Using TRAMP. (line 24)
+* //: File Name Completion. (line 25)
+* // <1>: Using TRAMP. (line 17)
+* <: Hydra in the minibuffer.
+ (line 50)
+* >: Hydra in the minibuffer.
+ (line 45)
+* ~: File Name Completion. (line 30)
+* ~ <1>: Using TRAMP. (line 9)
+* ~~: Using TRAMP. (line 29)
+* a: Hydra in the minibuffer.
+ (line 65)
+* a <1>: Saving the current completion session to a buffer.
+ (line 36)
+* c: Hydra in the minibuffer.
+ (line 34)
+* C: Hydra in the minibuffer.
+ (line 70)
+* C-': Key bindings for single selection action then exit minibuffer.
+ (line 64)
+* C-c C-o: Saving the current completion session to a buffer.
+ (line 9)
+* C-j: Key bindings for single selection action then exit minibuffer.
+ (line 30)
+* C-j <1>: File Name Completion. (line 12)
+* C-m: Key bindings for single selection action then exit minibuffer.
+ (line 19)
+* C-M-j: Key bindings for single selection action then exit minibuffer.
+ (line 53)
+* C-M-m: Key bindings for multiple selections and actions keep minibuffer open.
+ (line 19)
+* C-M-n: Key bindings for multiple selections and actions keep minibuffer open.
+ (line 39)
+* C-M-o: Key bindings for multiple selections and actions keep minibuffer open.
+ (line 29)
+* C-M-p: Key bindings for multiple selections and actions keep minibuffer open.
+ (line 50)
+* C-M-y: File Name Completion. (line 41)
+* C-o: Hydra in the minibuffer.
+ (line 9)
+* C-r: Key bindings that alter the minibuffer input.
+ (line 48)
+* DEL: File Name Completion. (line 19)
+* f: Saving the current completion session to a buffer.
+ (line 16)
+* j: Saving the current completion session to a buffer.
+ (line 26)
+* k: Saving the current completion session to a buffer.
+ (line 31)
+* m: Hydra in the minibuffer.
+ (line 40)
+* M-i: Key bindings that alter the minibuffer input.
+ (line 23)
+* M-j: Key bindings that alter the minibuffer input.
+ (line 32)
+* M-n: Key bindings that alter the minibuffer input.
+ (line 9)
+* M-o: Key bindings for single selection action then exit minibuffer.
+ (line 24)
+* M-p: Key bindings that alter the minibuffer input.
+ (line 18)
+* M-r: File Name Completion. (line 47)
+* M-w: Other key bindings. (line 9)
+* mouse-1: Saving the current completion session to a buffer.
+ (line 21)
+* o: Saving the current completion session to a buffer.
+ (line 41)
+* q: Saving the current completion session to a buffer.
+ (line 46)
+* RET: Key bindings for single selection action then exit minibuffer.
+ (line 19)
+* RET <1>: Saving the current completion session to a buffer.
+ (line 16)
+* s: Hydra in the minibuffer.
+ (line 60)
+* S-SPC: Key bindings that alter the minibuffer input.
+ (line 40)
+* TAB: Key bindings for single selection action then exit minibuffer.
+ (line 37)
+* w: Hydra in the minibuffer.
+ (line 55)
+
+
+
+Tag Table:
+Node: Top1190
+Node: Introduction3101
+Node: Installation5624
+Node: Installing from Emacs Package Manager6074
+Node: Installing from the Git repository7284
+Node: Getting started8104
+Node: Basic customization8411
+Node: Key bindings9006
+Node: Global key bindings9198
+Node: Minibuffer key bindings11672
+Node: Key bindings for navigation12904
+Node: Key bindings for single selection action then exit minibuffer14111
+Node: Key bindings for multiple selections and actions keep minibuffer open16758
+Node: Key bindings that alter the minibuffer input19379
+Node: Other key bindings21324
+Node: Hydra in the minibuffer21702
+Node: Saving the current completion session to a buffer24120
+Node: Completion Styles25532
+Node: ivy--regex-plus27283
+Node: ivy--regex-ignore-order28769
+Node: ivy--regex-fuzzy29137
+Node: Customization29634
+Node: Faces29820
+Node: Defcustoms32249
+Node: Actions33608
+Node: What are actions?33934
+Node: How can different actions be called?34752
+Node: How to modify the actions list?35323
+Node: Example - add two actions to each command35983
+Node: How to undo adding the two actions36942
+Node: How to add actions to a specific command37394
+Node: Example - define a new command with several actions37810
+Node: Test the above function with ivy-occur38698
+Node: Packages39540
+Node: Commands40505
+Node: File Name Completion40690
+Node: Using TRAMP42647
+Node: Buffer Name Completion44149
+Node: Counsel commands44764
+Node: API45411
+Node: Required arguments for ivy-read46009
+Node: Optional arguments for ivy-read46528
+Node: Example - counsel-describe-function49954
+Node: Example - counsel-locate52812
+Node: Example - ivy-read-with-extra-properties56562
+Node: Variable Index57770
+Node: Keystroke Index64894
+
+End Tag Table
+
+
+Local Variables:
+coding: utf-8
+End:
diff --git a/elpa/language-id-0.10/language-id-autoloads.el b/elpa/language-id-0.12/language-id-autoloads.el
similarity index 100%
rename from elpa/language-id-0.10/language-id-autoloads.el
rename to elpa/language-id-0.12/language-id-autoloads.el
diff --git a/elpa/language-id-0.10/language-id-pkg.el b/elpa/language-id-0.12/language-id-pkg.el
similarity index 60%
rename from elpa/language-id-0.10/language-id-pkg.el
rename to elpa/language-id-0.12/language-id-pkg.el
index f88bc07..528a5fb 100644
--- a/elpa/language-id-0.10/language-id-pkg.el
+++ b/elpa/language-id-0.12/language-id-pkg.el
@@ -1,2 +1,2 @@
-;;; Generated package description from /home/raphael/.emacs.d/elpa/language-id-0.10/language-id.el -*- no-byte-compile: t -*-
-(define-package "language-id" "0.10" "Library to work with programming language identifiers" '((emacs "24") (cl-lib "0.5")) :commit "3f0ad28202207c266bd8fc7904b224db69ceccf6" :authors '(("Lassi Kortela" . "lassi@lassi.io")) :maintainer '("Lassi Kortela" . "lassi@lassi.io") :keywords '("languages" "util") :url "https://github.com/lassik/emacs-language-id")
+;;; Generated package description from /home/raphael/.emacs.d/elpa/language-id-0.12/language-id.el -*- no-byte-compile: t -*-
+(define-package "language-id" "0.12" "Library to work with programming language identifiers" '((emacs "24") (cl-lib "0.5")) :commit "2c99ce29b86fc635649f4e89723912dc1cc4f36c" :authors '(("Lassi Kortela" . "lassi@lassi.io")) :maintainer '("Lassi Kortela" . "lassi@lassi.io") :keywords '("languages" "util") :url "https://github.com/lassik/emacs-language-id")
diff --git a/elpa/language-id-0.10/language-id.el b/elpa/language-id-0.12/language-id.el
similarity index 95%
rename from elpa/language-id-0.10/language-id.el
rename to elpa/language-id-0.12/language-id.el
index f8a2306..c5db246 100644
--- a/elpa/language-id-0.10/language-id.el
+++ b/elpa/language-id-0.12/language-id.el
@@ -2,9 +2,9 @@
;;
;; Author: Lassi Kortela
;; URL: https://github.com/lassik/emacs-language-id
-;; Package-Version: 0.10
-;; Package-Commit: 3f0ad28202207c266bd8fc7904b224db69ceccf6
-;; Version: 0.10
+;; Package-Version: 0.12
+;; Package-Commit: 2c99ce29b86fc635649f4e89723912dc1cc4f36c
+;; Version: 0.12
;; Package-Requires: ((emacs "24") (cl-lib "0.5"))
;; Keywords: languages util
;; SPDX-License-Identifier: ISC
@@ -70,6 +70,13 @@
(web-mode-engine "none")
(language-id--file-name-extension ".ts")))
+ ;; ReScript needs to come before Reason because in reason-mode
+ ;; we can tell them apart by file name extension only.
+ ("ReScript"
+ (reason-mode
+ (language-id--file-name-extension ".res")))
+ ("Reason" reason-mode)
+
;; vue-html-mode is derived from html-mode.
("Vue"
vue-mode
@@ -83,6 +90,7 @@
("Bazel" bazel-mode)
("BibTeX" bibtex-mode)
("C" c-mode)
+ ("C#" csharp-mode)
("C++" c++-mode)
("Cabal Config" haskell-cabal-mode)
("Clojure" clojurescript-mode clojurec-mode clojure-mode)
@@ -136,7 +144,6 @@
("Python" python-mode)
("R" ess-r-mode (ess-mode (ess-dialect "R")))
("Racket" racket-mode)
- ("Reason" reason-mode)
("Ruby" enh-ruby-mode ruby-mode)
("Rust" rust-mode rustic-mode)
("Scala" scala-mode)
diff --git a/elpa/markdown-mode-20210123.1547/markdown-mode-pkg.el b/elpa/markdown-mode-20210123.1547/markdown-mode-pkg.el
deleted file mode 100644
index 467d994..0000000
--- a/elpa/markdown-mode-20210123.1547/markdown-mode-pkg.el
+++ /dev/null
@@ -1,2 +0,0 @@
-;;; Generated package description from /home/raphael/.emacs.d/elpa/markdown-mode-20210123.1547/markdown-mode.el -*- no-byte-compile: t -*-
-(define-package "markdown-mode" "20210123.1547" "Major mode for Markdown-formatted text" '((emacs "25.1")) :commit "779a4c637719f5a192c128ed60ecffed3ff1760c" :authors '(("Jason R. Blevins" . "jblevins@xbeta.org")) :maintainer '("Jason R. Blevins" . "jblevins@xbeta.org") :keywords '("markdown" "github flavored markdown" "itex") :url "https://jblevins.org/projects/markdown-mode/")
diff --git a/elpa/markdown-mode-20210123.1547/markdown-mode-autoloads.el b/elpa/markdown-mode-20210216.852/markdown-mode-autoloads.el
similarity index 100%
rename from elpa/markdown-mode-20210123.1547/markdown-mode-autoloads.el
rename to elpa/markdown-mode-20210216.852/markdown-mode-autoloads.el
diff --git a/elpa/markdown-mode-20210216.852/markdown-mode-pkg.el b/elpa/markdown-mode-20210216.852/markdown-mode-pkg.el
new file mode 100644
index 0000000..1d7be5e
--- /dev/null
+++ b/elpa/markdown-mode-20210216.852/markdown-mode-pkg.el
@@ -0,0 +1,2 @@
+;;; Generated package description from /home/raphael/.emacs.d/elpa/markdown-mode-20210216.852/markdown-mode.el -*- no-byte-compile: t -*-
+(define-package "markdown-mode" "20210216.852" "Major mode for Markdown-formatted text" '((emacs "25.1")) :commit "377ce39ffe69f058994ac4e98bde8cfb58661406" :authors '(("Jason R. Blevins" . "jblevins@xbeta.org")) :maintainer '("Jason R. Blevins" . "jblevins@xbeta.org") :keywords '("markdown" "github flavored markdown" "itex") :url "https://jblevins.org/projects/markdown-mode/")
diff --git a/elpa/markdown-mode-20210123.1547/markdown-mode.el b/elpa/markdown-mode-20210216.852/markdown-mode.el
similarity index 98%
rename from elpa/markdown-mode-20210123.1547/markdown-mode.el
rename to elpa/markdown-mode-20210216.852/markdown-mode.el
index 37b1b54..4073763 100644
--- a/elpa/markdown-mode-20210123.1547/markdown-mode.el
+++ b/elpa/markdown-mode-20210216.852/markdown-mode.el
@@ -7,8 +7,8 @@
;; Maintainer: Jason R. Blevins
;; Created: May 24, 2007
;; Version: 2.5-dev
-;; Package-Version: 20210123.1547
-;; Package-Commit: 779a4c637719f5a192c128ed60ecffed3ff1760c
+;; Package-Version: 20210216.852
+;; Package-Commit: 377ce39ffe69f058994ac4e98bde8cfb58661406
;; Package-Requires: ((emacs "25.1"))
;; Keywords: Markdown, GitHub Flavored Markdown, itex
;; URL: https://jblevins.org/projects/markdown-mode/
@@ -50,6 +50,8 @@
(defvar flyspell-generic-check-word-predicate)
(defvar electric-pair-pairs)
+(declare-function project-roots "project")
+
;;; Constants =================================================================
@@ -245,6 +247,22 @@ This is the default search behavior of Ikiwiki."
:safe 'booleanp
:package-version '(markdown-mode . "2.2"))
+(defcustom markdown-wiki-link-search-type nil
+ "Searching type for markdown wiki link.
+
+sub-directories: search for wiki link targets in sub directories
+parent-directories: search for wiki link targets in parent directories
+project: search for wiki link targets under project root"
+ :group 'markdown
+ :type '(set
+ (const :tag "search wiki link from subdirectories" sub-directories)
+ (const :tag "search wiki link from parent directories" parent-directories)
+ (const :tag "search wiki link under project root" project))
+ :package-version '(markdown-mode . "2.5"))
+
+(make-obsolete-variable 'markdown-wiki-link-search-subdirectories 'markdown-wiki-link-search-type "2.5")
+(make-obsolete-variable 'markdown-wiki-link-search-parent-directories 'markdown-wiki-link-search-type "2.5")
+
(defcustom markdown-wiki-link-fontify-missing nil
"When non-nil, change wiki link face according to existence of target files.
This is expensive because it requires checking for the file each time the buffer
@@ -4419,6 +4437,49 @@ at the beginning of the block."
do (progn (when lang (markdown-gfm-add-used-language lang))
(goto-char (next-single-property-change (point) prop)))))))
+(defun markdown-insert-foldable-block ()
+ "Insert details disclosure element to make content foldable.
+If a region is active, wrap this region with the disclosure
+element. More detais here 'https://developer.mozilla.org/en-US/docs/Web/HTML/Element/details'."
+ (interactive)
+ (let ((details-open-tag "")
+ (details-close-tag " ")
+ (summary-open-tag "")
+ (summary-close-tag " "))
+ (if (use-region-p)
+ (let* ((b (region-beginning))
+ (e (region-end))
+ (indent (progn (goto-char b) (current-indentation))))
+ (goto-char e)
+ ;; if we're on a blank line, don't newline, otherwise the tags
+ ;; should go on its own line
+ (unless (looking-back "\n" nil)
+ (newline))
+ (indent-to indent)
+ (insert details-close-tag)
+ (markdown-ensure-blank-line-after)
+ (goto-char b)
+ ;; if we're on a blank line, insert the quotes here, otherwise
+ ;; add a new line first
+ (unless (looking-at-p "\n")
+ (newline)
+ (forward-line -1))
+ (markdown-ensure-blank-line-before)
+ (indent-to indent)
+ (insert details-open-tag "\n")
+ (insert summary-open-tag summary-close-tag)
+ (search-backward summary-close-tag))
+ (let ((indent (current-indentation)))
+ (delete-horizontal-space :backward-only)
+ (markdown-ensure-blank-line-before)
+ (indent-to indent)
+ (insert details-open-tag "\n")
+ (insert summary-open-tag summary-close-tag "\n")
+ (insert details-close-tag)
+ (indent-to indent)
+ (markdown-ensure-blank-line-after)
+ (search-backward summary-close-tag)))))
+
;;; Footnotes =================================================================
@@ -5164,6 +5225,7 @@ Assumes match data is available for `markdown-regex-italic'."
(propertize "C = GFM code" 'face 'markdown-code-face) ", "
(propertize "pre" 'face 'markdown-pre-face) ", "
(propertize "footnote" 'face 'markdown-footnote-text-face) ", "
+ (propertize "F = foldable" 'face 'markdown-bold-face) ", "
(propertize "q = blockquote" 'face 'markdown-blockquote-face) ", "
(propertize "h & 1-6 = heading" 'face 'markdown-header-face) ", "
(propertize "- = hr" 'face 'markdown-hr-face) ", "
@@ -5197,6 +5259,7 @@ Assumes match data is available for `markdown-regex-italic'."
(define-key map (kbd "c") 'markdown-insert-code)
(define-key map (kbd "C") 'markdown-insert-gfm-code-block)
(define-key map (kbd "f") 'markdown-insert-footnote)
+ (define-key map (kbd "F") 'markdown-insert-foldable-block)
(define-key map (kbd "h") 'markdown-insert-header-dwim)
(define-key map (kbd "H") 'markdown-insert-header-setext-dwim)
(define-key map (kbd "i") 'markdown-insert-italic)
@@ -5508,6 +5571,7 @@ See also `markdown-mode-map'.")
["GFM Code Block" markdown-insert-gfm-code-block]
["Edit Code Block" markdown-edit-code-block
:enable (markdown-code-block-at-point-p)]
+ ["Foldable Block" markdown-insert-foldable-block]
"---"
["Blockquote Region" markdown-blockquote-region]
["Preformatted Region" markdown-pre-region]
@@ -7832,6 +7896,29 @@ The location of the alias component depends on the value of
(match-string-no-properties 3)
(or (match-string-no-properties 5) (match-string-no-properties 3))))
+(defun markdown--wiki-link-search-types ()
+ (let ((ret (and markdown-wiki-link-search-type
+ (cl-copy-list markdown-wiki-link-search-type))))
+ (when (and markdown-wiki-link-search-subdirectories
+ (not (memq 'sub-directories markdown-wiki-link-search-type)))
+ (push 'sub-directories ret))
+ (when (and markdown-wiki-link-search-parent-directories
+ (not (memq 'parent-directories markdown-wiki-link-search-type)))
+ (push 'parent-directories ret))
+ ret))
+
+(defun markdown--project-root ()
+ (or (cl-loop for dir in '(".git" ".hg" ".svn")
+ when (locate-dominating-file default-directory dir)
+ return it)
+ (progn
+ (require 'project)
+ (let ((project (project-current t)))
+ (with-no-warnings
+ (if (fboundp 'project-root)
+ (project-root project)
+ (car (project-roots project))))))))
+
(defun markdown-convert-wiki-link-to-filename (name)
"Generate a filename from the wiki link NAME.
Spaces in NAME are replaced with `markdown-link-space-sub-char'.
@@ -7841,35 +7928,43 @@ directory first, then in subdirectories if
`markdown-wiki-link-search-subdirectories' is non-nil, and then
in parent directories if
`markdown-wiki-link-search-parent-directories' is non-nil."
- (let* ((basename (replace-regexp-in-string
- "[[:space:]\n]" markdown-link-space-sub-char name))
- (basename (if (derived-mode-p 'gfm-mode)
- (concat (upcase (substring basename 0 1))
- (downcase (substring basename 1 nil)))
- basename))
- directory extension default candidates dir)
- (when buffer-file-name
- (setq directory (file-name-directory buffer-file-name)
- extension (file-name-extension buffer-file-name)))
- (setq default (concat basename
- (when extension (concat "." extension))))
- (cond
- ;; Look in current directory first.
- ((or (null buffer-file-name)
- (file-exists-p default))
- default)
- ;; Possibly search in subdirectories, next.
- ((and markdown-wiki-link-search-subdirectories
- (setq candidates
- (directory-files-recursively
- directory (concat "^" default "$"))))
- (car candidates))
- ;; Possibly search in parent directories as a last resort.
- ((and markdown-wiki-link-search-parent-directories
- (setq dir (locate-dominating-file directory default)))
- (concat dir default))
- ;; If nothing is found, return default in current directory.
- (t default))))
+ (save-match-data
+ ;; This function must not overwrite match data(PR #590)
+ (let* ((basename (replace-regexp-in-string
+ "[[:space:]\n]" markdown-link-space-sub-char name))
+ (basename (if (derived-mode-p 'gfm-mode)
+ (concat (upcase (substring basename 0 1))
+ (downcase (substring basename 1 nil)))
+ basename))
+ (search-types (markdown--wiki-link-search-types))
+ directory extension default candidates dir)
+ (when buffer-file-name
+ (setq directory (file-name-directory buffer-file-name)
+ extension (file-name-extension buffer-file-name)))
+ (setq default (concat basename
+ (when extension (concat "." extension))))
+ (cond
+ ;; Look in current directory first.
+ ((or (null buffer-file-name)
+ (file-exists-p default))
+ default)
+ ;; Possibly search in subdirectories, next.
+ ((and (memq 'sub-directories search-types)
+ (setq candidates
+ (directory-files-recursively
+ directory (concat "^" default "$"))))
+ (car candidates))
+ ;; Possibly search in parent directories as a last resort.
+ ((and (memq 'parent-directories search-types)
+ (setq dir (locate-dominating-file directory default)))
+ (concat dir default))
+ ((and (memq 'project search-types)
+ (setq candidates
+ (directory-files-recursively
+ (markdown--project-root) (concat "^" default "$"))))
+ (car candidates))
+ ;; If nothing is found, return default in current directory.
+ (t default)))))
(defun markdown-follow-wiki-link (name &optional other)
"Follow the wiki link NAME.
@@ -9204,15 +9299,23 @@ Create new table lines if required."
(unless (markdown-table-at-point-p)
(user-error "Not at a table"))
(markdown-table-align)
- (when (markdown-table-hline-at-point-p) (end-of-line 1))
+ (when (markdown-table-hline-at-point-p) (beginning-of-line 1))
(condition-case nil
(progn
(re-search-backward "\\(?:^\\|[^\\]\\)|" (markdown-table-begin))
+ ;; When this function is called while in the first cell in a
+ ;; table, the point will now be at the beginning of a line. In
+ ;; this case, we need to move past one additional table
+ ;; boundary, the end of the table on the previous line.
+ (when (= (point) (line-beginning-position))
+ (re-search-backward "\\(?:^\\|[^\\]\\)|" (markdown-table-begin)))
(re-search-backward "\\(?:^\\|[^\\]\\)|" (markdown-table-begin)))
(error (user-error "Cannot move to previous table cell")))
- (while (looking-at "|\\([-:]\\|[ \t]*$\\)")
- (re-search-backward "\\(?:^\\|[^\\]\\)|" (markdown-table-begin)))
- (when (looking-at "| ?") (goto-char (match-end 0))))
+ (when (looking-at "\\(?:^\\|[^\\]\\)| ?") (goto-char (match-end 0)))
+
+ ;; This may have dropped point on the hline.
+ (when (markdown-table-hline-at-point-p)
+ (markdown-table-backward-cell)))
(defun markdown-table-transpose ()
"Transpose table at point.
diff --git a/elpa/nginx-mode-1.1.9/nginx-mode-autoloads.el b/elpa/nginx-mode-1.1.9/nginx-mode-autoloads.el
new file mode 100644
index 0000000..201ced8
--- /dev/null
+++ b/elpa/nginx-mode-1.1.9/nginx-mode-autoloads.el
@@ -0,0 +1,36 @@
+;;; nginx-mode-autoloads.el --- automatically extracted autoloads
+;;
+;;; Code:
+
+(add-to-list 'load-path (directory-file-name
+ (or (file-name-directory #$) (car load-path))))
+
+
+;;;### (autoloads nil "nginx-mode" "nginx-mode.el" (0 0 0 0))
+;;; Generated autoloads from nginx-mode.el
+
+(autoload 'nginx-mode "nginx-mode" "\
+Major mode for highlighting nginx config files.
+
+The variable nginx-indent-level controls the amount of indentation.
+\\{nginx-mode-map}
+
+\(fn)" t nil)
+
+(add-to-list 'auto-mode-alist '("nginx\\.conf\\'" . nginx-mode))
+
+(add-to-list 'auto-mode-alist '("/nginx/.+\\.conf\\'" . nginx-mode))
+
+(add-to-list 'magic-fallback-mode-alist '("\\(?:.*\n\\)*\\(?:http\\|server\\|location .+\\|upstream .+\\)[ \n\11]+{" . nginx-mode))
+
+(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "nginx-mode" '("nginx-")))
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; coding: utf-8
+;; End:
+;;; nginx-mode-autoloads.el ends here
diff --git a/elpa/nginx-mode-1.1.9/nginx-mode-pkg.el b/elpa/nginx-mode-1.1.9/nginx-mode-pkg.el
new file mode 100644
index 0000000..73a4eee
--- /dev/null
+++ b/elpa/nginx-mode-1.1.9/nginx-mode-pkg.el
@@ -0,0 +1,2 @@
+;;; Generated package description from /home/raphael/.emacs.d/elpa/nginx-mode-1.1.9/nginx-mode.el -*- no-byte-compile: t -*-
+(define-package "nginx-mode" "1.1.9" "major mode for editing nginx config files" 'nil :commit "a2bab83c2eb233d57d76b236e7c141c2ccc97005" :authors '(("Andrew J Cosgriff" . "andrew@cosgriff.name")) :maintainer '("Andrew J Cosgriff" . "andrew@cosgriff.name") :keywords '("languages" "nginx"))
diff --git a/elpa/nginx-mode-1.1.9/nginx-mode.el b/elpa/nginx-mode-1.1.9/nginx-mode.el
new file mode 100644
index 0000000..c285d31
--- /dev/null
+++ b/elpa/nginx-mode-1.1.9/nginx-mode.el
@@ -0,0 +1,203 @@
+;;; nginx-mode.el --- major mode for editing nginx config files
+
+;; Copyright 2010 Andrew J Cosgriff
+
+;; Author: Andrew J Cosgriff
+;; Maintainer: Andrew J Cosgriff
+;; Created: 15 Oct 2010
+;; Version: 1.1.9
+;; Package-Version: 1.1.9
+;; Package-Commit: a2bab83c2eb233d57d76b236e7c141c2ccc97005
+;; Keywords: languages, nginx
+
+;; available from http://github.com/ajc/nginx-mode
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, or (at your option)
+;; any later version.
+;;
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program; if not, see .
+
+;;; Commentary:
+
+;; This is a quick mode for editing Nginx config files, as I didn't find
+;; anything else around that did quite this much.
+
+;; Many thanks to the authors of puppet-mode.el, from where I found a
+;; useful indentation function that I've modified to suit this situation.
+
+;; Put this file into your load-path and the following into your ~/.emacs:
+;; (require 'nginx-mode)
+
+;;; Code:
+
+
+;;;;##########################################################################
+;;;; User Options, Variables
+;;;;##########################################################################
+
+(defcustom nginx-indent-level 4
+ "*Indentation of Nginx statements."
+ :type 'integer :group 'nginx)
+
+(defcustom nginx-indent-tabs-mode nil
+ "*Indentation can insert tabs in nginx mode if this is non-nil."
+ :type 'boolean :group 'nginx)
+
+(defvar nginx-mode-syntax-table
+ (let ((table (make-syntax-table)))
+ (modify-syntax-entry ?# "< b" table)
+ (modify-syntax-entry ?\n "> b" table)
+ table)
+ "Syntax table for `nginx-mode'.")
+
+(defvar nginx-font-lock-keywords
+ (list '("^\\([ \t]+\\)?\\([A-Za-z09_]+\\)" 2 font-lock-keyword-face t)
+ ;; uncomment the next one if you want your eyes to bleed
+ ;; (it'll highlight parentheses and curly braces)
+ ;;'("\\(\{\\|\}\\|\(\\|\)\\)" . font-lock-pseudo-keyword-face)
+ '("^\\([ \t]+\\)?rewrite[ \t]+.+[ \t]+\\(permanent\\|redirect\\|break\\|last\\);$" 2 font-lock-function-name-face)
+ '("\\(\$[0-9]+\\)[^0-9]" 1 font-lock-constant-face)
+ '("\$[A-Za-z0-9_\-]+" . font-lock-variable-name-face)
+ '("[ \t]+\\(on\\|off\\);$" 1 font-lock-constant-face)
+ '("[A-Za-z0-9_\-]+\\([ \t]+[^ \t\n]+\\)?[ \t]+\\([^ \t\n]+\\)[ \t]+{" 2 font-lock-function-name-face)))
+
+
+;;;;##########################################################################
+;;;; Code
+;;;;##########################################################################
+
+(defun nginx-block-indent ()
+ "If point is in a block, return the indentation of the first line of that
+block (the line containing the opening brace). Used to set the indentation
+of the closing brace of a block."
+ (save-excursion
+ (save-match-data
+ (let ((opoint (point))
+ (apoint (search-backward "{" nil t)))
+ (when apoint
+ ;; This is a bit of a hack and doesn't allow for strings. We really
+ ;; want to parse by sexps at some point.
+ (let ((close-braces (count-matches "}" apoint opoint))
+ (open-braces 0))
+ (while (and apoint (> close-braces open-braces))
+ (setq apoint (search-backward "{" nil t))
+ (when apoint
+ (setq close-braces (count-matches "}" apoint opoint))
+ (setq open-braces (1+ open-braces)))))
+ (if apoint
+ (current-indentation)
+ nil))))))
+
+
+(defun nginx-comment-line-p ()
+ "Return non-nil iff this line is a comment."
+ (save-excursion
+ (save-match-data
+ (beginning-of-line)
+ (looking-at "^\\s-*#"))))
+
+(defun nginx-indent-line ()
+ "Indent current line as nginx code."
+ (interactive)
+ (beginning-of-line)
+ (if (bobp)
+ (indent-line-to 0) ; First line is always non-indented
+ (let ((not-indented t)
+ (block-indent (nginx-block-indent))
+ cur-indent)
+ (cond
+ ((and (looking-at "^\\s-*}\\s-*$") block-indent)
+ ;; This line contains a closing brace and we're at the inner
+ ;; block, so we should indent it matching the indentation of
+ ;; the opening brace of the block.
+ (setq cur-indent block-indent))
+ (t
+ ;; Otherwise, we did not start on a block-ending-only line.
+ (save-excursion
+ ;; Iterate backwards until we find an indentation hint
+ (while not-indented
+ (forward-line -1)
+ (cond
+ ;; Comment lines are ignored unless we're at the start of the
+ ;; buffer.
+ ((nginx-comment-line-p)
+ (if (bobp)
+ (setq not-indented nil)))
+
+ ;; Brace or paren on a line by itself will already be indented to
+ ;; the right level, so we can cheat and stop there.
+ ((looking-at "^\\s-*}\\s-*")
+ (setq cur-indent (current-indentation))
+ (setq not-indented nil))
+
+ ;; Indent by one level more than the start of our block. We lose
+ ;; if there is more than one block opened and closed on the same
+ ;; line but it's still unbalanced; hopefully people don't do that.
+ ((looking-at "^.*{[^\n}]*$")
+ (setq cur-indent (+ (current-indentation) nginx-indent-level))
+ (setq not-indented nil))
+
+ ;; Start of buffer.
+ ((bobp)
+ (setq not-indented nil)))))))
+
+ ;; We've figured out the indentation, so do it.
+ (if (and cur-indent (> cur-indent 0))
+ (indent-line-to cur-indent)
+ (indent-line-to 0)))))
+
+
+(defvar nginx-mode-map
+ (let
+ ((map (make-sparse-keymap)))
+ (define-key map "\C-j" 'newline-and-indent)
+ (define-key map "\C-m" 'newline-and-indent)
+ map)
+ "Keymap for editing nginx config files.")
+
+;;;###autoload
+(define-derived-mode nginx-mode prog-mode "Nginx"
+ "Major mode for highlighting nginx config files.
+
+The variable nginx-indent-level controls the amount of indentation.
+\\{nginx-mode-map}"
+ :syntax-table nginx-mode-syntax-table
+
+ (use-local-map nginx-mode-map)
+
+ (set (make-local-variable 'comment-start) "# ")
+ (set (make-local-variable 'comment-start-skip) "#+ *")
+ (set (make-local-variable 'comment-end) "")
+ (set (make-local-variable 'comment-auto-fill-only-comments) t)
+
+ (set (make-local-variable 'indent-line-function) 'nginx-indent-line)
+ (set (make-local-variable 'indent-tabs-mode) nginx-indent-tabs-mode)
+ (set (make-local-variable 'require-final-newline) t)
+ (set (make-local-variable 'paragraph-ignore-fill-prefix) t)
+ (set (make-local-variable 'paragraph-start) "\f\\|[ ]*$\\|#$")
+ (set (make-local-variable 'paragraph-separate) "\\([ \f]*\\|#\\)$")
+
+ (set (make-local-variable 'font-lock-defaults)
+ '(nginx-font-lock-keywords nil)))
+
+;;;###autoload
+(add-to-list 'auto-mode-alist '("nginx\\.conf\\'" . nginx-mode))
+;;;###autoload
+(add-to-list 'auto-mode-alist '("/nginx/.+\\.conf\\'" . nginx-mode))
+;;;###autoload
+(add-to-list
+ 'magic-fallback-mode-alist
+ '("\\(?:.*\n\\)*\\(?:http\\|server\\|location .+\\|upstream .+\\)[ \n\t]+{"
+ . nginx-mode))
+
+(provide 'nginx-mode)
+
+;;; nginx-mode.el ends here
diff --git a/elpa/request-20201026.2324/request-pkg.el b/elpa/request-20201026.2324/request-pkg.el
deleted file mode 100755
index 81d00bb..0000000
--- a/elpa/request-20201026.2324/request-pkg.el
+++ /dev/null
@@ -1,2 +0,0 @@
-;;; Generated package description from /data/data/com.termux/files/home/.emacs.d/elpa/request-20201026.2324/request.el -*- no-byte-compile: t -*-
-(define-package "request" "20201026.2324" "Compatible layer for URL request in Emacs" '((emacs "24.4")) :commit "0183da84cb45eb94da996cd2eab714ef0d7504cc" :authors '(("Takafumi Arakaki ")) :maintainer '("Takafumi Arakaki ") :url "https://github.com/tkf/emacs-request")
diff --git a/elpa/request-20201026.2324/request-autoloads.el b/elpa/request-20210214.37/request-autoloads.el
old mode 100755
new mode 100644
similarity index 100%
rename from elpa/request-20201026.2324/request-autoloads.el
rename to elpa/request-20210214.37/request-autoloads.el
diff --git a/elpa/request-20210214.37/request-pkg.el b/elpa/request-20210214.37/request-pkg.el
new file mode 100644
index 0000000..ad70584
--- /dev/null
+++ b/elpa/request-20210214.37/request-pkg.el
@@ -0,0 +1,2 @@
+;;; Generated package description from /home/raphael/.emacs.d/elpa/request-20210214.37/request.el -*- no-byte-compile: t -*-
+(define-package "request" "20210214.37" "Compatible layer for URL request" '((emacs "24.4")) :commit "accd430ee706f5b10fb20003b06bd8209bcdaa82" :authors '(("Takafumi Arakaki ")) :maintainer '("Takafumi Arakaki ") :url "https://github.com/tkf/emacs-request")
diff --git a/elpa/request-20201026.2324/request.el b/elpa/request-20210214.37/request.el
old mode 100755
new mode 100644
similarity index 79%
rename from elpa/request-20201026.2324/request.el
rename to elpa/request-20210214.37/request.el
index 6531cea..cbab6c8
--- a/elpa/request-20201026.2324/request.el
+++ b/elpa/request-20210214.37/request.el
@@ -1,4 +1,4 @@
-;;; request.el --- Compatible layer for URL request in Emacs -*- lexical-binding: t; -*-
+;;; request.el --- Compatible layer for URL request -*- lexical-binding: t; -*-
;; Copyright (C) 2012 Takafumi Arakaki
;; Copyright (C) 1985-1986, 1992, 1994-1995, 1999-2012
@@ -6,10 +6,10 @@
;; Author: Takafumi Arakaki
;; URL: https://github.com/tkf/emacs-request
-;; Package-Version: 20201026.2324
-;; Package-Commit: 0183da84cb45eb94da996cd2eab714ef0d7504cc
+;; Package-Version: 20210214.37
+;; Package-Commit: accd430ee706f5b10fb20003b06bd8209bcdaa82
;; Package-Requires: ((emacs "24.4"))
-;; Version: 0.3.2
+;; Version: 0.3.3
;; This file is NOT part of GNU Emacs.
@@ -25,21 +25,15 @@
;; You should have received a copy of the GNU General Public License
;; along with request.el.
-;; If not, see .
+;; If not, see .
;;; Commentary:
-;; Request.el is a HTTP request library with multiple backends. It
-;; supports url.el which is shipped with Emacs and curl command line
-;; program. User can use curl when s/he has it, as curl is more reliable
-;; than url.el. Library author can use request.el to avoid imposing
-;; external dependencies such as curl to users while giving richer
-;; experience for users who have curl.
-
-;; Following functions are adapted from GNU Emacs source code.
-;; Free Software Foundation holds the copyright of them.
-;; * `request--process-live-p'
-;; * `request--url-default-expander'
+;; Uses ``curl`` as its backend or Emacs's native ``url.el`` library if
+;; ``curl`` is not found.
+;;
+;; The default encoding for requests is ``utf-8``. Please explicitly specify
+;; ``:encoding 'binary`` for binary data.
;;; Code:
@@ -52,16 +46,14 @@
(require 'mail-utils)
(require 'autorevert)
(require 'auth-source)
+(require 'mailheader)
(defgroup request nil
"Compatible layer for URL request in Emacs."
:group 'comm
:prefix "request-")
-(defconst request-version "0.3.0")
-
-
-;;; Customize variables
+(defconst request-version "0.3.3")
(defcustom request-storage-directory
(concat (file-name-as-directory user-emacs-directory) "request")
@@ -73,10 +65,10 @@
:type 'string)
(defcustom request-curl-options nil
- "curl command options.
+ "List of curl command options.
-List of strings that will be passed to every curl invocation. You can pass
-extra options here, like setting the proxy."
+List of strings that will be passed to every curl invocation.
+You can pass extra options here, like setting the proxy."
:type '(repeat string))
(defcustom request-backend (if (executable-find request-curl)
@@ -89,14 +81,11 @@ Automatically set to `curl' if curl command is found."
(defcustom request-timeout nil
"Default request timeout in second.
-`nil' means no timeout."
+nil means no timeout."
:type '(choice (integer :tag "Request timeout seconds")
(boolean :tag "No timeout" nil)))
-(defcustom request-temp-prefix "emacs-request"
- "Prefix for temporary files created by Request."
- :type 'string
- :risky t)
+(make-obsolete-variable 'request-temp-prefix nil "0.3.3")
(defcustom request-log-level -1
"Logging level for request.
@@ -123,41 +112,12 @@ See `request-log-level'."
(const :tag "Level TRACE" trace)
(const :tag "Level BLATHER" blather)))
-
-;;; Utilities
-
-(defun request--safe-apply (function &rest arguments)
- "Apply FUNCTION with ARGUMENTS, suppressing any errors."
- (condition-case nil
- (apply #'apply function arguments)
- ((debug error))))
-
-(defun request--safe-call (function &rest arguments)
- (request--safe-apply function arguments))
-
-;; (defun request--url-no-cache (url)
-;; "Imitate `cache=false' of `jQuery.ajax'.
-;; See: http://api.jquery.com/jQuery.ajax/"
-;; ;; FIXME: parse URL before adding ?_=TIME.
-;; (concat url (format-time-string "?_=%s")))
-
(defmacro request--document-function (function docstring)
"Document FUNCTION with DOCSTRING. Use this for defstruct accessor etc."
(declare (indent defun)
(doc-string 2))
`(put ',function 'function-documentation ,docstring))
-(defun request--process-live-p (process)
- "Copied from `process-live-p' for backward compatibility (Emacs < 24).
-Adapted from lisp/subr.el.
-FSF holds the copyright of this function:
- Copyright (C) 1985-1986, 1992, 1994-1995, 1999-2012
- Free Software Foundation, Inc."
- (memq (process-status process) '(run open listen connect stop)))
-
-
-;;; Logging
-
(defconst request--log-level-def
'(;; debugging
(blather . 60) (trace . 50) (debug . 40)
@@ -167,43 +127,29 @@ FSF holds the copyright of this function:
(warn . 10) (error . 0))
"Named logging levels.")
-(defun request--log-level-as-int (level)
- (if (integerp level)
- level
- (or (cdr (assq level request--log-level-def))
- 0)))
-
(defvar request-log-buffer-name " *request-log*")
-(defun request--log-buffer ()
- (get-buffer-create request-log-buffer-name))
-
(defmacro request-log (level fmt &rest args)
+ "Main logging function at warning LEVEL in FMT with ARGS."
(declare (indent 1))
- `(let ((level (request--log-level-as-int ,level))
- (log-level (request--log-level-as-int request-log-level))
- (msg-level (request--log-level-as-int request-message-level)))
- (when (<= level (max log-level msg-level))
- (let ((msg (format "[%s] %s" ,level
- (condition-case err
- (format ,fmt ,@args)
- (error (format "
-!!! Logging error while executing:
-%S
-!!! Error:
-%S"
- ',args err))))))
- (when (<= level log-level)
- (with-current-buffer (request--log-buffer)
- (setq buffer-read-only t)
- (let ((inhibit-read-only t))
- (goto-char (point-max))
- (insert msg "\n"))))
- (when (<= level msg-level)
- (message "%s" msg))))))
-
-
-;;; HTTP specific utilities
+ `(cl-flet ((log-level-as-int
+ (level)
+ (if (integerp level)
+ level
+ (or (cdr (assq level request--log-level-def)) 0))))
+ (let ((level (log-level-as-int ,level))
+ (log-level (log-level-as-int request-log-level))
+ (msg-level (log-level-as-int request-message-level)))
+ (when (<= level (max log-level msg-level))
+ (let ((msg (format "[%s] %s" ,level (format ,fmt ,@args))))
+ (when (<= level log-level)
+ (with-current-buffer (get-buffer-create request-log-buffer-name)
+ (setq buffer-read-only t)
+ (let ((inhibit-read-only t))
+ (goto-char (point-max))
+ (insert msg "\n"))))
+ (when (<= level msg-level)
+ (message "%s" msg)))))))
(defconst request--url-unreserved-chars
'(?a ?b ?c ?d ?e ?f ?g ?h ?i ?j ?k ?l ?m ?n ?o ?p ?q ?r ?s ?t ?u ?v ?w ?x ?y ?z
@@ -215,7 +161,7 @@ This is used for making `request--urlencode-alist' RFC 3986 compliant
for older Emacs versions.")
(defun request--urlencode-alist (alist)
- ;; FIXME: make monkey patching `url-unreserved-chars' optional
+ "Hexify ALIST fields according to RFC3986."
(let ((url-unreserved-chars request--url-unreserved-chars))
(cl-loop for sep = "" then "&"
for (k . v) in alist
@@ -224,8 +170,6 @@ for older Emacs versions.")
concat "="
concat (url-hexify-string (format "%s" v)))))
-
-;;; Header parser
(defun request--parse-response-at-point ()
"Parse the first header line such as \"HTTP/1.1 200 OK\"."
@@ -234,21 +178,19 @@ for older Emacs versions.")
:code (string-to-number (match-string 2)))))
(defun request--goto-next-body (&optional noerror)
+ "Scan forward to next blank line allowing NOERROR if missing."
(re-search-forward "^\r\n" nil noerror))
-
-;;; Response object
-
(cl-defstruct request-response
"A structure holding all relevant information of a request."
status-code history data error-thrown symbol-status url
done-p settings
;; internal variables
- -buffer -raw-header -timer -backend -tempfiles)
+ -buffer -raw-header -timer -backend)
(defmacro request--document-response (function docstring)
- (declare (indent defun)
- (doc-string 2))
+ "Append to FUNCTION's DOCSTRING some more canned verbiage."
+ (declare (indent defun) (doc-string 2))
`(request--document-function ,function ,(concat docstring "
.. This is an accessor for `request-response' object.
@@ -313,8 +255,7 @@ Examples::
(request-response-header response
\"content-type\") ; => \"text/html; charset=utf-8\"
(request-response-header response
- \"unknown-field\") ; => nil
-"
+ \"unknown-field\") ; => nil"
(let ((raw-header (request-response--raw-header response)))
(when raw-header
(with-temp-buffer
@@ -324,11 +265,23 @@ Examples::
;; separated value [#rfc2616-sec4]_.
(mail-fetch-field field-name nil t)))))
;; .. [#rfc2616-sec4] RFC2616 says this is the right thing to do
-;; (see http://tools.ietf.org/html/rfc2616.html#section-4.2).
+;; (see https://tools.ietf.org/html/rfc2616.html#section-4.2).
;; Python's requests module does this too.
-
-;;; Backend dispatcher
+(defun request-response-headers (response)
+ "Return RESPONSE headers as an alist.
+I would have chosen a function name that wasn't so suggestive that
+`headers` is a member of the `request-response` struct, but
+as there's already precedent with `request-response-header', I
+hew to consistency."
+ (let ((raw-header (request-response--raw-header response)))
+ (when raw-header
+ raw-header
+ (with-temp-buffer
+ (save-excursion (insert raw-header))
+ (when (save-excursion (request--parse-response-at-point))
+ (forward-line))
+ (mail-header-extract-no-properties)))))
(defconst request--backend-alist
'((url-retrieve
@@ -358,38 +311,26 @@ let's stick to manual dispatch for now.")
(assoc-default
method
(or (assoc-default request-backend request--backend-alist)
- (error "%S is not valid `request-backend'." request-backend))))
+ (error "%S is not valid `request-backend'" request-backend))))
-
-;;; Cookie
(defun request-cookie-string (host &optional localpart secure)
- "Return cookie string (like `document.cookie').
-
+ "Lookup HOST LOCALPART SECURE in cookie jar as`document.cookie` string.
Example::
- (request-cookie-string \"127.0.0.1\" \"/\") ; => \"key=value; key2=value2\"
-"
+ (request-cookie-string \"127.0.0.1\" \"/\") ; => \"key=value; key2=value2\""
(mapconcat (lambda (nv) (concat (car nv) "=" (cdr nv)))
(request-cookie-alist host localpart secure)
"; "))
(defun request-cookie-alist (host &optional localpart secure)
- "Return cookies as an alist.
+ "Lookup HOST LOCALPART SECURE in cookie jar as alist.
Example::
- (request-cookie-alist \"127.0.0.1\" \"/\") ; => ((\"key\" . \"value\") ...)
-"
+ (request-cookie-alist \"127.0.0.1\" \"/\") ; => ((\"key\" . \"value\") ...)"
(funcall (request--choose-backend 'get-cookies) host localpart secure))
-
-;;; Main
-
-(cl-defun request-default-error-callback (url &key symbol-status
- &allow-other-keys)
- (request-log 'error
- "request-default-error-callback: %s %s" url symbol-status))
(cl-defun request (url &rest settings
&key
@@ -401,9 +342,7 @@ Example::
(sync nil)
(response (make-request-response))
&allow-other-keys)
- "Send request to URL.
-
-Request.el has a single entry point. It is `request'.
+ "Main entry requesting URL with property list SETTINGS as follow.
==================== ========================================================
Keyword argument Explanation
@@ -420,7 +359,7 @@ ERROR (function) called on error
COMPLETE (function) called on both success and error
TIMEOUT (number) timeout in second
STATUS-CODE (alist) map status code (int) to callback
-SYNC (bool) If `t', wait until request is done. Default is `nil'.
+SYNC (bool) If non-nil, wait until request is done. Default is nil.
==================== ========================================================
@@ -497,7 +436,7 @@ Example FILES argument::
support FILES in pure elisp by making furl.el_ another backend.
Contributions are welcome.
- .. _furl.el: http://code.google.com/p/furl-el/
+ .. _furl.el: https://code.google.com/p/furl-el/
* PARSER function
@@ -518,7 +457,7 @@ objects to plist instead of alist, wrap `json-read' by `lambda'
like this.::
(request
- \"http://...\"
+ \"https://...\"
:parser (lambda ()
(let ((json-object-type 'plist))
(json-read)))
@@ -541,7 +480,7 @@ relatively small value.
Due to limitation of `url-retrieve-synchronously', response slots
`request-response-error-thrown', `request-response-history' and
-`request-response-url' are unknown (always `nil') when using
+`request-response-url' are unknown (always nil) when using
synchronous request with `url-retrieve' backend.
* Note
@@ -549,15 +488,18 @@ synchronous request with `url-retrieve' backend.
API of `request' is somewhat mixture of jQuery.ajax_ (Javascript)
and requests.request_ (Python).
-.. _jQuery.ajax: http://api.jquery.com/jQuery.ajax/
-.. _requests.request: http://docs.python-requests.org
-"
+.. _jQuery.ajax: https://api.jquery.com/jQuery.ajax/
+.. _requests.request: https://docs.python-requests.org"
(declare (indent defun))
;; FIXME: support CACHE argument (if possible)
;; (unless cache
;; (setq url (request--url-no-cache url)))
(unless error
- (setq error (apply-partially #'request-default-error-callback url))
+ (setq error (cl-function
+ (lambda (&rest args &key symbol-status &allow-other-keys)
+ (request-log 'error
+ "request-default-error-callback: %s %s"
+ url symbol-status))))
(setq settings (plist-put settings :error error)))
(unless (or (stringp data)
(null data)
@@ -582,7 +524,7 @@ and requests.request_ (Python).
response)
(defun request--clean-header (response)
- "Strip off carriage returns in the header of REQUEST."
+ "Strip off carriage return in the header of RESPONSE."
(let* ((buffer (request-response--buffer response))
(backend (request-response--backend response))
;; FIXME: a workaround when `url-http-clean-headers' fails...
@@ -603,8 +545,7 @@ and requests.request_ (Python).
(replace-match "")))))))
(defun request--cut-header (response)
- "Cut the first header part in the buffer of RESPONSE and move it to
-raw-header slot."
+ "Move the header to the raw-header slot of RESPONSE object."
(let ((buffer (request-response--buffer response)))
(when (buffer-live-p buffer)
(with-current-buffer buffer
@@ -621,8 +562,7 @@ raw-header slot."
(or (file-remote-p file 'localname) file))
(defun request--parse-data (response encoding parser)
- "For buffer held by RESPONSE, first decode via user's ENCODING elective,
-then send to PARSER."
+ "In RESPONSE buffer, decode via ENCODING, then send to PARSER."
(let ((buffer (request-response--buffer response)))
(when (buffer-live-p buffer)
(with-current-buffer buffer
@@ -645,15 +585,18 @@ then send to PARSER."
status-code response
encoding
&allow-other-keys)
+ "Parse BUFFER according to PARSER.
+Delegate to callbacks SUCCESS, ERROR, and COMPLETE the STATUS-CODE of
+RESPONSE via ENCODING."
(request-log 'debug "request--callback: UNPARSED\n%s"
(when (buffer-live-p buffer)
(with-current-buffer buffer (buffer-string))))
-
- ;; Sometimes BUFFER given as the argument is different from the
- ;; buffer already set in RESPONSE. That's why it is reset here.
- ;; FIXME: Refactor how BUFFER is passed around.
+ ;; Reset RESPONSE buffer to argument BUFFER.
(setf (request-response--buffer response) buffer)
- (request-response--cancel-timer response)
+ (cl-symbol-macrolet ((timer (request-response--timer response)))
+ (when timer
+ (cancel-timer timer)
+ (setq timer nil)))
(cl-symbol-macrolet
((error-thrown (request-response-error-thrown response))
(symbol-status (request-response-symbol-status response))
@@ -693,32 +636,26 @@ then send to PARSER."
(name (if success-p "success" "error")))
(when cb
(request-log 'debug "request--callback: executing %s" name)
- (request--safe-apply cb args)))
-
+ (apply cb args)))
(let ((cb (cdr (assq (request-response-status-code response)
status-code))))
(when cb
(request-log 'debug "request--callback: executing status-code")
- (request--safe-apply cb args)))
-
+ (apply cb args)))
(when complete
(request-log 'debug "request--callback: executing complete")
- (request--safe-apply complete args)))
-
- (setq done-p t)
+ (apply complete args)))
- ;; Remove temporary files
- ;; FIXME: Make tempfile cleanup more reliable. It is possible
- ;; callback is never called.
- (request--safe-delete-files (request-response--tempfiles response))))
+ (setq done-p t)))
(cl-defun request-response--timeout-callback (response)
+ "If RESPONSE times out, ensure `request--callback' gets called."
(setf (request-response-symbol-status response) 'timeout)
(setf (request-response-error-thrown response) '(error . ("Timeout")))
(let* ((buffer (request-response--buffer response))
(proc (and (buffer-live-p buffer) (get-buffer-process buffer))))
(if proc
- ;; This will call `request--callback':
+ ;; This implicitly calls `request--callback'!
(funcall (request--choose-backend 'terminate-process) proc)
(cl-symbol-macrolet ((done-p (request-response-done-p response)))
(unless done-p
@@ -733,13 +670,6 @@ then send to PARSER."
(request-response-settings response))
(setq done-p t))))))
-(defun request-response--cancel-timer (response)
- (cl-symbol-macrolet ((timer (request-response--timer response)))
- (when timer
- (cancel-timer timer)
- (setq timer nil))))
-
-
(defun request-abort (response)
"Abort request for RESPONSE (the object returned by `request').
Note that this function invoke ERROR and COMPLETE callbacks.
@@ -752,18 +682,15 @@ associated process is exited."
(unless symbol-status ; should I use done-p here?
(setq symbol-status 'abort)
(setq done-p t)
- (when (and
- (processp process) ; process can be nil when buffer is killed
- (request--process-live-p process))
+ (when (process-live-p process)
(funcall (request--choose-backend 'terminate-process) process))))))
-
-;;; Backend: `url-retrieve'
(cl-defun request--url-retrieve-preprocess-settings
(&rest settings &key type data files headers &allow-other-keys)
+ "Augment SETTINGS with properties TYPE DATA FILES HEADERS."
(when files
- (error "`url-retrieve' backend does not support FILES."))
+ (error "`url-retrieve' backend does not support FILES"))
(when (and (equal type "POST")
data
(not (assoc-string "Content-Type" headers t)))
@@ -775,6 +702,10 @@ associated process is exited."
&key type data timeout response
&allow-other-keys
&aux headers)
+ "Internal workhorse querying URL via curl.
+SETTINGS is a property list with keys (some optional) such as GET or POST TYPE,
+DATA for posting fields, TIMEOUT in seconds, RESPONSE a mandatory struct.
+HEADERS needs to be assigned after SETTINGS is preprocessed."
(setq settings (apply #'request--url-retrieve-preprocess-settings settings))
(setq headers (plist-get settings :headers))
(let* ((url-request-extra-headers headers)
@@ -791,6 +722,9 @@ associated process is exited."
(cl-defun request--url-retrieve-callback (status &rest settings
&key response url
&allow-other-keys)
+ "Ensure `request--callback' gets called for STATUS.
+SETTINGS should include RESPONSE and URL properties which
+inform any necessary redirect or history recording logic."
(when (featurep 'url-http)
(setf (request-response-status-code response) url-http-response-status))
(let ((redirect (plist-get status :redirect)))
@@ -810,20 +744,21 @@ associated process is exited."
do (let ((r (make-request-response :-backend 'url-retrieve)))
(setf (request-response-url r) v)
(push r (request-response-history response))))
-
(cl-symbol-macrolet ((error-thrown (request-response-error-thrown response))
(status-error (plist-get status :error)))
(when status-error
(request-log 'warn "request--url-retrieve-callback: %s" status-error)
(unless error-thrown
(setq error-thrown status-error))))
-
(apply #'request--callback (current-buffer) settings))
(cl-defun request--url-retrieve-sync (url &rest settings
&key type data timeout response
&allow-other-keys
&aux headers)
+ "Internal synchronous retrieve of URL.
+SETTINGS include typical TYPE DATA TIMEOUT RESPONSE properties.
+HEADERS needs to be assigned after SETTINGS is preprocessed."
(setq settings (apply #'request--url-retrieve-preprocess-settings settings))
(setq headers (plist-get settings :headers))
(let* ((url-request-extra-headers headers)
@@ -852,13 +787,11 @@ associated process is exited."
response)
(defun request--url-retrieve-get-cookies (host localpart secure)
+ "Retrieve cookies corresponding to HOST LOCALPART SECURE."
(mapcar
(lambda (c) (cons (url-cookie-name c) (url-cookie-value c)))
(url-cookie-retrieve host localpart secure)))
-
-;;; Backend: curl
-
(defvar request--curl-cookie-jar nil
"Override what the function `request--curl-cookie-jar' returns.
Currently it is used only for testing.")
@@ -898,16 +831,17 @@ Currently it is used only for testing.")
"\\n(:num-redirects %{num_redirects} :url-effective %{url_effective})"
"\\n(:num-redirects %{num_redirects} :url-effective \"%{url_effective}\")"))
-(defun request--curl-mkdir-for-cookie-jar ()
- (ignore-errors
- (make-directory (file-name-directory (request--curl-cookie-jar)) t)))
-
(cl-defun request--curl-command
- (url &key type data headers response files* unix-socket encoding auth
+ (url &key type data headers files unix-socket auth
&allow-other-keys
&aux (cookie-jar (convert-standard-filename
(expand-file-name (request--curl-cookie-jar)))))
- "BUG: Simultaneous requests are a known cause of cookie-jar corruption."
+ "Internal command cobbler for curl to URL.
+TYPE, DATA, HEADERS, FILES, UNIX-SOCKET, AUTH are as described in `request'.
+COOKIE-JAR is the file location for the netscape cookie jar, usually
+in the request subdirectory of `user-emacs-directory'.
+
+BUG: Simultaneous requests are a known cause of cookie-jar corruption."
(append
(list request-curl
"--silent" "--location"
@@ -930,33 +864,34 @@ Currently it is used only for testing.")
request-curl-options
(when (plist-get (request--curl-capabilities) :compression) (list "--compressed"))
(when unix-socket (list "--unix-socket" unix-socket))
- (cl-loop for (name filename path mime-type) in files*
+ (cl-loop with stdin-p = data
+ for (name . item) in files
collect "--form"
- collect (format "%s=@%s;filename=%s%s" name
- (request-untrampify-filename path) filename
- (if mime-type
- (format ";type=%s" mime-type)
- "")))
+ collect
+ (apply #'format "%s=@%s;filename=%s%s"
+ (cond ((stringp item)
+ (list name item (file-name-nondirectory item) ""))
+ ((bufferp item)
+ (if stdin-p
+ (error (concat "request--curl-command: "
+ "only one buffer or data entry permitted"))
+ (setq stdin-p t))
+ (list name "-" (buffer-name item) ""))
+ ((listp item)
+ (unless (plist-get (cdr item) :file)
+ (if stdin-p
+ (error (concat "request--curl-command: "
+ "only one buffer or data entry permitted"))
+ (setq stdin-p t)))
+ (list name (or (plist-get (cdr item) :file) "-") (car item)
+ (if (plist-get item :mime-type)
+ (format ";type=%s" (plist-get item :mime-type))
+ "")))
+ (t (error (concat "request--curl-command: "
+ "%S not string, buffer, or list")
+ item)))))
(when data
- (let ((tempfile (request--make-temp-file)))
- (push tempfile (request-response--tempfiles response))
- ;; We dynamic-let the global `buffer-file-coding-system' to `no-conversion'
- ;; in case the user-configured `encoding' doesn't fly.
- ;; If we do not dynamic-let the global, `select-safe-coding-system' would
- ;; plunge us into an undesirable interactive dialogue.
- (let ((buffer-file-coding-system-orig
- (default-value 'buffer-file-coding-system))
- (select-safe-coding-system-accept-default-p
- (lambda (&rest _) t)))
- (unwind-protect
- (progn
- (setf (default-value 'buffer-file-coding-system) 'no-conversion)
- (with-temp-file tempfile
- (setq-local buffer-file-coding-system encoding)
- (insert data)))
- (setf (default-value 'buffer-file-coding-system)
- buffer-file-coding-system-orig)))
- (list "--data-binary" (concat "@" (request-untrampify-filename tempfile)))))
+ (split-string "--data-binary @-"))
(when type (if (equal "head" (downcase type))
(list "--head")
(list "--request" type)))
@@ -965,83 +900,15 @@ Currently it is used only for testing.")
collect (format "%s: %s" k v))
(list url)))
-(defun request--curl-normalize-files-1 (files get-temp-file)
- (cl-loop for (name . item) in files
- collect
- (cl-destructuring-bind
- (filename &key file buffer data mime-type)
- (cond
- ((stringp item) (list (file-name-nondirectory item) :file item))
- ((bufferp item) (list (buffer-name item) :buffer item))
- (t item))
- (unless (= (cl-loop for v in (list file buffer data) if v sum 1) 1)
- (error "Only one of :file/:buffer/:data must be given. Got: %S"
- (cons name item)))
- (cond
- (file
- (list name filename file mime-type))
- (buffer
- (let ((tf (funcall get-temp-file)))
- (with-current-buffer buffer
- (write-region (point-min) (point-max) tf nil 'silent))
- (list name filename tf mime-type)))
- (data
- (let ((tf (funcall get-temp-file)))
- (with-temp-buffer
- (erase-buffer)
- (insert data)
- (write-region (point-min) (point-max) tf nil 'silent))
- (list name filename tf mime-type)))))))
-
-
-(declare-function tramp-get-remote-tmpdir "tramp")
-(declare-function tramp-dissect-file-name "tramp")
-
-(defun request--make-temp-file ()
- "Create a temporary file."
- (if (file-remote-p default-directory)
- (let ((temporary-file-directory
- (tramp-get-remote-tmpdir (tramp-dissect-file-name default-directory))))
- (make-temp-file request-temp-prefix))
- (make-temp-file request-temp-prefix)))
-
-(defun request--curl-normalize-files (files)
- "Change FILES into a list of (NAME FILENAME PATH MIME-TYPE).
-This is to make `request--curl-command' cleaner by converting
-FILES to a homogeneous list. It returns a list (FILES* TEMPFILES)
-where FILES* is a converted FILES and TEMPFILES is a list of
-temporary file paths."
- (let (tempfiles noerror)
- (unwind-protect
- (let* ((get-temp-file (lambda ()
- (let ((tf (request--make-temp-file)))
- (push tf tempfiles)
- tf)))
- (files* (request--curl-normalize-files-1 files get-temp-file)))
- (setq noerror t)
- (list files* tempfiles))
- (unless noerror
- ;; Remove temporary files only when an error occurs
- (request--safe-delete-files tempfiles)))))
-
-(defun request--safe-delete-files (files)
- "Remove FILES but do not raise error when failed to do so."
- (mapc (lambda (f) (condition-case err
- (delete-file f)
- (error (request-log 'error
- "request--safe-delete-files: %s %s"
- f (error-message-string err)))))
- files))
-
(defun request--install-timeout (timeout response)
- "Out-of-band trigger after TIMEOUT seconds to prevent hangs."
+ "Out-of-band trigger after TIMEOUT seconds to forestall a hung RESPONSE."
(when (numberp timeout)
(setf (request-response--timer response)
(run-at-time timeout nil
#'request-response--timeout-callback response))))
(defun request--curl-occlude-secret (command)
- "Simple regex filter on anything looking like a secret."
+ "Simple regex filter on anything looking like a secret in COMMAND."
(let ((matched
(string-match (concat (regexp-quote "--user") "\\s-*\\(\\S-+\\)") command)))
(if matched
@@ -1049,9 +916,19 @@ temporary file paths."
command)))
(cl-defun request--curl (url &rest settings
- &key files timeout response encoding semaphore
+ &key data files timeout response encoding semaphore
&allow-other-keys)
- "cURL-based request backend.
+ "Internal workhorse querying URL via curl.
+
+SETTINGS is a property list with keys (some optional) such as DATA for
+posting fields, FILES containing one or more lists of the form
+ (NAME . FILENAME)
+ (NAME . BUFFER)
+ (NAME . (FILENAME :buffer BUFFER))
+ (NAME . (FILENAME :data DATA))
+with NAME and FILENAME defined by curl(1)'s overwrought `--form` switch format,
+TIMEOUT in seconds, RESPONSE a mandatory struct, ENCODING, and SEMAPHORE,
+an internal semaphore.
Redirection handling strategy
-----------------------------
@@ -1064,29 +941,57 @@ This number is used for removing extra headers and parse
location header from the last redirection header.
Sexp at the end of buffer and extra headers for redirects are
-removed from the buffer before it is shown to the parser function.
-"
- (request--curl-mkdir-for-cookie-jar)
- (let* (;; Use pipe instead of pty. Otherwise, curl process hangs.
- (process-connection-type nil)
- ;; Avoid starting program in non-existing directory.
+removed from the buffer before it is shown to the parser function."
+ (ignore-errors
+ (make-directory (file-name-directory (request--curl-cookie-jar)) t))
+ (let* (process-connection-type ;; pipe, not pty, else curl hangs
(home-directory (or (file-remote-p default-directory) "~/"))
(default-directory (expand-file-name home-directory))
(buffer (generate-new-buffer " *request curl*"))
- (command (cl-destructuring-bind
- (files* tempfiles)
- (request--curl-normalize-files files)
- (setf (request-response--tempfiles response) tempfiles)
- (apply #'request--curl-command url :files* files*
- :response response :encoding encoding settings)))
- (proc (apply #'start-process "request curl" buffer command)))
+ (command (apply #'request--curl-command url settings))
+ (proc (apply #'start-process "request curl" buffer command))
+ (file-items (mapcar #'cdr files))
+ (file-buffer (or (cl-some (lambda (item)
+ (when (bufferp item) item))
+ file-items)
+ (cl-some (lambda (item)
+ (and (listp item)
+ (plist-get (cdr item) :buffer)))
+ file-items)))
+ (file-data (cl-some (lambda (item)
+ (and (listp item)
+ (plist-get (cdr item) :data)))
+ file-items)))
(request--install-timeout timeout response)
(request-log 'debug "request--curl: %s"
- (request--curl-occlude-secret (mapconcat 'identity command " ")))
+ (request--curl-occlude-secret (mapconcat #'identity command " ")))
(setf (request-response--buffer response) buffer)
(process-put proc :request-response response)
(set-process-coding-system proc 'no-conversion 'no-conversion)
(set-process-query-on-exit-flag proc nil)
+ (when (or data file-buffer file-data)
+ ;; We dynamic-let the global `buffer-file-coding-system' to `no-conversion'
+ ;; in case the user-configured `encoding' doesn't fly.
+ ;; If we do not dynamic-let the global, `select-safe-coding-system' would
+ ;; plunge us into an undesirable interactive dialogue.
+ (let* ((buffer-file-coding-system-orig
+ (default-value 'buffer-file-coding-system))
+ (select-safe-coding-system-accept-default-p
+ (lambda (&rest _) t)))
+ (unwind-protect
+ (progn
+ (setf (default-value 'buffer-file-coding-system) 'no-conversion)
+ (with-temp-buffer
+ (setq-local buffer-file-coding-system encoding)
+ (insert (or data
+ (when file-buffer
+ (with-current-buffer file-buffer
+ (buffer-substring-no-properties (point-min) (point-max))))
+ file-data))
+ (process-send-region proc (point-min) (point-max))
+ (process-send-eof proc)))
+ (setf (default-value 'buffer-file-coding-system)
+ buffer-file-coding-system-orig))))
(let ((callback-2 (apply-partially #'request--curl-callback url)))
(if semaphore
(set-process-sentinel proc (lambda (&rest args)
@@ -1113,7 +1018,7 @@ See also `request--curl-write-out-template'."
"secure" "version" "expires")
"\\|")
"Uninterested keys in cookie.
-See \"set-cookie-av\" in http://www.ietf.org/rfc/rfc2965.txt")
+See \"set-cookie-av\" in https://www.ietf.org/rfc/rfc2965.txt")
(defun request--consume-100-continue ()
"Remove \"HTTP/* 100 Continue\" header at the point."
@@ -1135,7 +1040,8 @@ See \"set-cookie-av\" in http://www.ietf.org/rfc/rfc2965.txt")
(delete-region (point) (progn (request--goto-next-body) (point)))))
(defun request--curl-preprocess (&optional url)
- "Pre-process current buffer before showing it to user."
+ "Pre-process current buffer before showing it to user.
+Curl switches need to be adjusted if URL is a file://."
(let (history)
(cl-destructuring-bind (&key num-redirects url-effective)
(if (request-url-file-p url)
@@ -1185,6 +1091,8 @@ START-URL is the URL requested."
do (setf (request-response-url response) url)))
(defun request--curl-callback (url proc event)
+ "Ensure `request--callback' gets called after curl to URL finishes.
+See info entries on sentinels regarding PROC and EVENT."
(let* ((buffer (process-buffer proc))
(response (process-get proc :request-response))
(settings (request-response-settings response)))
@@ -1220,19 +1128,20 @@ START-URL is the URL requested."
auto-revert--buffers-by-watch-descriptor
(when (boundp 'auto-revert-notify-watch-descriptor-hash-list)
auto-revert-notify-watch-descriptor-hash-list))))
- (when desc
+ (when (and desc table)
(let ((buffers (delq (current-buffer) (gethash desc table))))
(if buffers
(puthash desc buffers table)
(remhash desc table)))
(condition-case nil ;; ignore-errors doesn't work for me, sorry
- (file-notify-rm-watch desc)
+ (file-notify-rm-watch desc)
(error))
(remove-hook 'kill-buffer-hook #'auto-revert-notify-rm-watch t)))
(setq auto-revert-notify-watch-descriptor nil
auto-revert-notify-modified-p nil))
(cl-defun request--curl-sync (url &rest settings &key response &allow-other-keys)
+ "Internal synchronous curl call to URL with SETTINGS bespeaking RESPONSE."
(let (finished)
(prog1 (apply #'request--curl url
:semaphore (lambda (&rest _) (setq finished t))
@@ -1250,7 +1159,7 @@ START-URL is the URL requested."
(cl-loop with iter = 0
until (or (>= iter maxiter) finished)
do (accept-process-output nil interval)
- unless (request--process-live-p proc)
+ unless (process-live-p proc)
do (cl-incf iter)
end
finally (when (>= iter maxiter)
@@ -1259,12 +1168,10 @@ START-URL is the URL requested."
(request-log 'error m)))))))))
(defun request--curl-get-cookies (host localpart secure)
+ "Return entry for HOST LOCALPART SECURE in cookie jar."
(request--netscape-get-cookies (request--curl-cookie-jar)
host localpart secure))
-
-;;; Netscape cookie.txt parser
-
(defun request--netscape-cookie-parse ()
"Parse Netscape/Mozilla cookie format."
(goto-char (point-min))
@@ -1292,6 +1199,7 @@ START-URL is the URL requested."
value))))
(defun request--netscape-filter-cookies (cookies host localpart secure)
+ "Filter COOKIES for entries containing HOST LOCALPART SECURE."
(cl-loop for (domain _flag path secure-1 _http-only _expiration name value) in cookies
when (and (equal domain host)
(equal path localpart)
@@ -1299,6 +1207,7 @@ START-URL is the URL requested."
collect (cons name value)))
(defun request--netscape-get-cookies (filename host localpart secure)
+ "Get cookies from FILENAME corresponding to HOST LOCALPART SECURE."
(when (file-readable-p filename)
(with-temp-buffer
(erase-buffer)
diff --git a/elpa/ssh-config-mode-20210123.1051/ssh-config-keywords.txt b/elpa/ssh-config-mode-20210217.1051/ssh-config-keywords.txt
similarity index 97%
rename from elpa/ssh-config-mode-20210123.1051/ssh-config-keywords.txt
rename to elpa/ssh-config-mode-20210217.1051/ssh-config-keywords.txt
index 5d603a3..1360ed6 100644
--- a/elpa/ssh-config-mode-20210123.1051/ssh-config-keywords.txt
+++ b/elpa/ssh-config-mode-20210217.1051/ssh-config-keywords.txt
@@ -39,8 +39,8 @@ HashKnownHosts
Host
HostKeyAlgorithms
HostKeyAlias
+HostbasedAcceptedAlgorithms
HostbasedAuthentication
-HostbasedKeyTypes
Hostname
IPQoS
IdentitiesOnly
@@ -66,6 +66,7 @@ NumberOfPasswordPrompts
PKCS11Provider
PasswordAuthentication
PermitLocalCommand
+PermitRemoteOpen
Port
PreferredAuthentications
ProxyCommand
diff --git a/elpa/ssh-config-mode-20210123.1051/ssh-config-mode-autoloads.el b/elpa/ssh-config-mode-20210217.1051/ssh-config-mode-autoloads.el
similarity index 100%
rename from elpa/ssh-config-mode-20210123.1051/ssh-config-mode-autoloads.el
rename to elpa/ssh-config-mode-20210217.1051/ssh-config-mode-autoloads.el
diff --git a/elpa/ssh-config-mode-20210123.1051/ssh-config-mode-pkg.el b/elpa/ssh-config-mode-20210217.1051/ssh-config-mode-pkg.el
similarity index 61%
rename from elpa/ssh-config-mode-20210123.1051/ssh-config-mode-pkg.el
rename to elpa/ssh-config-mode-20210217.1051/ssh-config-mode-pkg.el
index 76b1ac8..52ae2a8 100644
--- a/elpa/ssh-config-mode-20210123.1051/ssh-config-mode-pkg.el
+++ b/elpa/ssh-config-mode-20210217.1051/ssh-config-mode-pkg.el
@@ -1,4 +1,4 @@
-(define-package "ssh-config-mode" "20210123.1051" "Mode for fontification of ~/.ssh/config" 'nil :commit "3639241d0e435e622049e6e72866da6b8b201241" :authors
+(define-package "ssh-config-mode" "20210217.1051" "Mode for fontification of ~/.ssh/config" 'nil :commit "820f60af17e71898303f4f3c2576f0619528a492" :authors
'(("Harley Gorrell" . "harley@panix.com"))
:maintainer
'("Harley Gorrell" . "harley@panix.com")
diff --git a/elpa/ssh-config-mode-20210123.1051/ssh-config-mode.el b/elpa/ssh-config-mode-20210217.1051/ssh-config-mode.el
similarity index 100%
rename from elpa/ssh-config-mode-20210123.1051/ssh-config-mode.el
rename to elpa/ssh-config-mode-20210217.1051/ssh-config-mode.el