From 281b6995404b687b0f2ed608a2f6440de26ddbf7 Mon Sep 17 00:00:00 2001 From: Daniel Borchmann Date: Fri, 20 Dec 2019 16:43:57 +0100 Subject: [PATCH] ELPA update --- elpa/hydra-20191125.955/hydra-autoloads.el | 99 + elpa/hydra-20191125.955/hydra-examples.el | 393 ++++ elpa/hydra-20191125.955/hydra-ox.el | 127 ++ elpa/hydra-20191125.955/hydra-pkg.el | 13 + elpa/hydra-20191125.955/hydra.el | 1547 ++++++++++++++++ elpa/lv-20191214.1357/lv-autoloads.el | 22 + elpa/lv-20191214.1357/lv-pkg.el | 2 + elpa/lv-20191214.1357/lv.el | 145 ++ .../mc-cycle-cursors.el | 119 ++ .../mc-edit-lines.el | 110 ++ .../mc-hide-unmatched-lines-mode.el | 107 ++ .../mc-mark-more.el | 709 ++++++++ .../mc-mark-pop.el | 22 + .../mc-separate-operations.el | 150 ++ .../multiple-cursors-autoloads.el | 362 ++++ .../multiple-cursors-core.el | 852 +++++++++ .../multiple-cursors-pkg.el | 5 + .../multiple-cursors.el | 203 +++ .../rectangular-region-mode.el | 125 ++ elpa/use-package-20191126.2034/dir | 18 + .../use-package-autoloads.el | 228 +++ .../use-package-bind-key.el | 172 ++ .../use-package-core.el | 1593 +++++++++++++++++ .../use-package-delight.el | 91 + .../use-package-diminish.el | 80 + .../use-package-ensure.el | 214 +++ .../use-package-jump.el | 79 + .../use-package-lint.el | 84 + .../use-package-pkg.el | 13 + elpa/use-package-20191126.2034/use-package.el | 54 + .../use-package.info | 1048 +++++++++++ 31 files changed, 8786 insertions(+) create mode 100644 elpa/hydra-20191125.955/hydra-autoloads.el create mode 100644 elpa/hydra-20191125.955/hydra-examples.el create mode 100644 elpa/hydra-20191125.955/hydra-ox.el create mode 100644 elpa/hydra-20191125.955/hydra-pkg.el create mode 100644 elpa/hydra-20191125.955/hydra.el create mode 100644 elpa/lv-20191214.1357/lv-autoloads.el create mode 100644 elpa/lv-20191214.1357/lv-pkg.el create mode 100644 elpa/lv-20191214.1357/lv.el create mode 100644 elpa/multiple-cursors-20191210.1759/mc-cycle-cursors.el create mode 100644 elpa/multiple-cursors-20191210.1759/mc-edit-lines.el create mode 100644 elpa/multiple-cursors-20191210.1759/mc-hide-unmatched-lines-mode.el create mode 100644 elpa/multiple-cursors-20191210.1759/mc-mark-more.el create mode 100644 elpa/multiple-cursors-20191210.1759/mc-mark-pop.el create mode 100644 elpa/multiple-cursors-20191210.1759/mc-separate-operations.el create mode 100644 elpa/multiple-cursors-20191210.1759/multiple-cursors-autoloads.el create mode 100644 elpa/multiple-cursors-20191210.1759/multiple-cursors-core.el create mode 100644 elpa/multiple-cursors-20191210.1759/multiple-cursors-pkg.el create mode 100644 elpa/multiple-cursors-20191210.1759/multiple-cursors.el create mode 100644 elpa/multiple-cursors-20191210.1759/rectangular-region-mode.el create mode 100644 elpa/use-package-20191126.2034/dir create mode 100644 elpa/use-package-20191126.2034/use-package-autoloads.el create mode 100644 elpa/use-package-20191126.2034/use-package-bind-key.el create mode 100644 elpa/use-package-20191126.2034/use-package-core.el create mode 100644 elpa/use-package-20191126.2034/use-package-delight.el create mode 100644 elpa/use-package-20191126.2034/use-package-diminish.el create mode 100644 elpa/use-package-20191126.2034/use-package-ensure.el create mode 100644 elpa/use-package-20191126.2034/use-package-jump.el create mode 100644 elpa/use-package-20191126.2034/use-package-lint.el create mode 100644 elpa/use-package-20191126.2034/use-package-pkg.el create mode 100644 elpa/use-package-20191126.2034/use-package.el create mode 100644 elpa/use-package-20191126.2034/use-package.info diff --git a/elpa/hydra-20191125.955/hydra-autoloads.el b/elpa/hydra-20191125.955/hydra-autoloads.el new file mode 100644 index 0000000..66f654e --- /dev/null +++ b/elpa/hydra-20191125.955/hydra-autoloads.el @@ -0,0 +1,99 @@ +;;; hydra-autoloads.el --- automatically extracted autoloads +;; +;;; Code: + +(add-to-list 'load-path (directory-file-name + (or (file-name-directory #$) (car load-path)))) + + +;;;### (autoloads nil "hydra" "hydra.el" (0 0 0 0)) +;;; Generated autoloads from hydra.el + +(autoload 'defhydra "hydra" "\ +Create a Hydra - a family of functions with prefix NAME. + +NAME should be a symbol, it will be the prefix of all functions +defined here. + +BODY has the format: + + (BODY-MAP BODY-KEY &rest BODY-PLIST) + +DOCSTRING will be displayed in the echo area to identify the +Hydra. When DOCSTRING starts with a newline, special Ruby-style +substitution will be performed by `hydra--format'. + +Functions are created on basis of HEADS, each of which has the +format: + + (KEY CMD &optional HINT &rest PLIST) + +BODY-MAP is a keymap; `global-map' is used quite often. Each +function generated from HEADS will be bound in BODY-MAP to +BODY-KEY + KEY (both are strings passed to `kbd'), and will set +the transient map so that all following heads can be called +though KEY only. BODY-KEY can be an empty string. + +CMD is a callable expression: either an interactive function +name, or an interactive lambda, or a single sexp (it will be +wrapped in an interactive lambda). + +HINT is a short string that identifies its head. It will be +printed beside KEY in the echo erea if `hydra-is-helpful' is not +nil. If you don't even want the KEY to be printed, set HINT +explicitly to nil. + +The heads inherit their PLIST from BODY-PLIST and are allowed to +override some keys. The keys recognized are :exit, :bind, and :column. +:exit can be: + +- nil (default): this head will continue the Hydra state. +- t: this head will stop the Hydra state. + +:bind can be: +- nil: this head will not be bound in BODY-MAP. +- a lambda taking KEY and CMD used to bind a head. + +:column is a string that sets the column for all subsequent heads. + +It is possible to omit both BODY-MAP and BODY-KEY if you don't +want to bind anything. In that case, typically you will bind the +generated NAME/body command. This command is also the return +result of `defhydra'. + +\(fn NAME BODY &optional DOCSTRING &rest HEADS)" nil t) + +(function-put 'defhydra 'lisp-indent-function 'defun) + +(function-put 'defhydra 'doc-string-elt '3) + +(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "hydra" '("hydra-" "defhydra"))) + +;;;*** + +;;;### (autoloads nil "hydra-examples" "hydra-examples.el" (0 0 0 +;;;;;; 0)) +;;; Generated autoloads from hydra-examples.el + +(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "hydra-examples" '("hydra-" "org-agenda-cts" "whitespace-mode"))) + +;;;*** + +;;;### (autoloads nil "hydra-ox" "hydra-ox.el" (0 0 0 0)) +;;; Generated autoloads from hydra-ox.el + +(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "hydra-ox" '("hydra-ox"))) + +;;;*** + +;;;### (autoloads nil nil ("hydra-pkg.el") (0 0 0 0)) + +;;;*** + +;; Local Variables: +;; version-control: never +;; no-byte-compile: t +;; no-update-autoloads: t +;; coding: utf-8 +;; End: +;;; hydra-autoloads.el ends here diff --git a/elpa/hydra-20191125.955/hydra-examples.el b/elpa/hydra-20191125.955/hydra-examples.el new file mode 100644 index 0000000..5262ec6 --- /dev/null +++ b/elpa/hydra-20191125.955/hydra-examples.el @@ -0,0 +1,393 @@ +;;; hydra-examples.el --- Some applications for Hydra + +;; Copyright (C) 2015 Free Software Foundation, Inc. + +;; Author: Oleh Krehel + +;; This file is part of GNU Emacs. + +;; GNU Emacs 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. + +;; GNU Emacs 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 GNU Emacs. If not, see . + +;;; Commentary: +;; +;; These are the sample Hydras. +;; +;; If you want to use them plainly, set `hydra-examples-verbatim' to t +;; before requiring this file. But it's probably better to only look +;; at them and use them as templates for building your own. + +;;; Code: + +(require 'hydra) + +;;* Examples +;;** Example 1: text scale +(when (bound-and-true-p hydra-examples-verbatim) + (defhydra hydra-zoom (global-map "") + "zoom" + ("g" text-scale-increase "in") + ("l" text-scale-decrease "out"))) + +;; This example generates three commands: +;; +;; `hydra-zoom/text-scale-increase' +;; `hydra-zoom/text-scale-decrease' +;; `hydra-zoom/body' +;; +;; In addition, two of them are bound like this: +;; +;; (global-set-key (kbd " g") 'hydra-zoom/text-scale-increase) +;; (global-set-key (kbd " l") 'hydra-zoom/text-scale-decrease) +;; +;; Note that you can substitute `global-map' with e.g. `emacs-lisp-mode-map' if you need. +;; The functions generated will be the same, except the binding code will change to: +;; +;; (define-key emacs-lisp-mode-map [f2 103] +;; (function hydra-zoom/text-scale-increase)) +;; (define-key emacs-lisp-mode-map [f2 108] +;; (function hydra-zoom/text-scale-decrease)) + +;;** Example 2: move window splitter +(when (bound-and-true-p hydra-examples-verbatim) + (defhydra hydra-splitter (global-map "C-M-s") + "splitter" + ("h" hydra-move-splitter-left) + ("j" hydra-move-splitter-down) + ("k" hydra-move-splitter-up) + ("l" hydra-move-splitter-right))) + +;;** Example 3: jump to error +(when (bound-and-true-p hydra-examples-verbatim) + (defhydra hydra-error (global-map "M-g") + "goto-error" + ("h" first-error "first") + ("j" next-error "next") + ("k" previous-error "prev") + ("v" recenter-top-bottom "recenter") + ("q" nil "quit"))) + +;; This example introduces only one new thing: since the command +;; passed to the "q" head is nil, it will quit the Hydra without doing +;; anything. Heads that quit the Hydra instead of continuing are +;; referred to as having blue :color. All the other heads have red +;; :color, unless other is specified. + +;;** Example 4: toggle rarely used modes +(when (bound-and-true-p hydra-examples-verbatim) + (defvar whitespace-mode nil) + (global-set-key + (kbd "C-c C-v") + (defhydra hydra-toggle-simple (:color blue) + "toggle" + ("a" abbrev-mode "abbrev") + ("d" toggle-debug-on-error "debug") + ("f" auto-fill-mode "fill") + ("t" toggle-truncate-lines "truncate") + ("w" whitespace-mode "whitespace") + ("q" nil "cancel")))) + +;; Note that in this case, `defhydra' returns the `hydra-toggle-simple/body' +;; symbol, which is then passed to `global-set-key'. +;; +;; Another new thing is that both the keymap and the body prefix are +;; skipped. This means that `defhydra' will bind nothing - that's why +;; `global-set-key' is necessary. +;; +;; One more new thing is that you can assign a :color to the body. All +;; heads will inherit this color. The code above is very much equivalent to: +;; +;; (global-set-key (kbd "C-c C-v a") 'abbrev-mode) +;; (global-set-key (kbd "C-c C-v d") 'toggle-debug-on-error) +;; +;; The differences are: +;; +;; * You get a hint immediately after "C-c C-v" +;; * You can cancel and call a command immediately, e.g. "C-c C-v C-n" +;; is equivalent to "C-n" with Hydra approach, while it will error +;; that "C-c C-v C-n" isn't bound with the usual approach. + +;;** Example 5: mini-vi +(defun hydra-vi/pre () + (set-cursor-color "#e52b50")) + +(defun hydra-vi/post () + (set-cursor-color "#ffffff")) + +(when (bound-and-true-p hydra-examples-verbatim) + (global-set-key + (kbd "C-z") + (defhydra hydra-vi (:pre hydra-vi/pre :post hydra-vi/post :color amaranth) + "vi" + ("l" forward-char) + ("h" backward-char) + ("j" next-line) + ("k" previous-line) + ("m" set-mark-command "mark") + ("a" move-beginning-of-line "beg") + ("e" move-end-of-line "end") + ("d" delete-region "del" :color blue) + ("y" kill-ring-save "yank" :color blue) + ("q" nil "quit"))) + (hydra-set-property 'hydra-vi :verbosity 1)) + +;; This example introduces :color amaranth. It's similar to red, +;; except while you can quit red with any binding which isn't a Hydra +;; head, you can quit amaranth only with a blue head. So you can quit +;; this mode only with "d", "y", "q" or "C-g". +;; +;; Another novelty are the :pre and :post handlers. :pre will be +;; called before each command, while :post will be called when the +;; Hydra quits. In this case, they're used to override the cursor +;; color while Hydra is active. + +;;** Example 6: selective global bind +(when (bound-and-true-p hydra-examples-verbatim) + (defhydra hydra-next-error (global-map "C-x") + "next-error" + ("`" next-error "next") + ("j" next-error "next" :bind nil) + ("k" previous-error "previous" :bind nil))) + +;; This example will bind "C-x `" in `global-map', but it will not +;; bind "C-x j" and "C-x k". +;; You can still "C-x `jjk" though. + +;;** Example 7: toggle with Ruby-style docstring +(defvar whitespace-mode nil) +(defhydra hydra-toggle (:color pink) + " +_a_ abbrev-mode: %`abbrev-mode +_d_ debug-on-error: %`debug-on-error +_f_ auto-fill-mode: %`auto-fill-function +_t_ truncate-lines: %`truncate-lines +_w_ whitespace-mode: %`whitespace-mode + +" + ("a" abbrev-mode nil) + ("d" toggle-debug-on-error nil) + ("f" auto-fill-mode nil) + ("t" toggle-truncate-lines nil) + ("w" whitespace-mode nil) + ("q" nil "quit")) +;; Recommended binding: +;; (global-set-key (kbd "C-c C-v") 'hydra-toggle/body) + +;; Here, using e.g. "_a_" translates to "a" with proper face. +;; More interestingly: +;; +;; "foobar %`abbrev-mode" means roughly (format "foobar %S" abbrev-mode) +;; +;; This means that you actually see the state of the mode that you're changing. + +;;** Example 8: the whole menu for `Buffer-menu-mode' +(defhydra hydra-buffer-menu (:color pink + :hint nil) + " +^Mark^ ^Unmark^ ^Actions^ ^Search +^^^^^^^^----------------------------------------------------------------- (__) +_m_: mark _u_: unmark _x_: execute _R_: re-isearch (oo) +_s_: save _U_: unmark up _b_: bury _I_: isearch /------\\/ +_d_: delete ^ ^ _g_: refresh _O_: multi-occur / | || +_D_: delete up ^ ^ _T_: files only: % -28`Buffer-menu-files-only^^ * /\\---/\\ +_~_: modified ^ ^ ^ ^ ^^ ~~ ~~ +" + ("m" Buffer-menu-mark) + ("u" Buffer-menu-unmark) + ("U" Buffer-menu-backup-unmark) + ("d" Buffer-menu-delete) + ("D" Buffer-menu-delete-backwards) + ("s" Buffer-menu-save) + ("~" Buffer-menu-not-modified) + ("x" Buffer-menu-execute) + ("b" Buffer-menu-bury) + ("g" revert-buffer) + ("T" Buffer-menu-toggle-files-only) + ("O" Buffer-menu-multi-occur :color blue) + ("I" Buffer-menu-isearch-buffers :color blue) + ("R" Buffer-menu-isearch-buffers-regexp :color blue) + ("c" nil "cancel") + ("v" Buffer-menu-select "select" :color blue) + ("o" Buffer-menu-other-window "other-window" :color blue) + ("q" quit-window "quit" :color blue)) +;; Recommended binding: +;; (define-key Buffer-menu-mode-map "." 'hydra-buffer-menu/body) + +;;** Example 9: s-expressions in the docstring +;; You can inline s-expresssions into the docstring like this: +(defvar dired-mode-map) +(declare-function dired-mark "dired") +(when (bound-and-true-p hydra-examples-verbatim) + (require 'dired) + (defhydra hydra-marked-items (dired-mode-map "") + " +Number of marked items: %(length (dired-get-marked-files)) +" + ("m" dired-mark "mark"))) + +;; This results in the following dynamic docstring: +;; +;; (format "Number of marked items: %S\n" +;; (length (dired-get-marked-files))) +;; +;; You can use `format'-style width specs, e.g. % 10(length nil). + +;;** Example 10: apropos family +(defhydra hydra-apropos (:color blue + :hint nil) + " +_a_propos _c_ommand +_d_ocumentation _l_ibrary +_v_ariable _u_ser-option +^ ^ valu_e_" + ("a" apropos) + ("d" apropos-documentation) + ("v" apropos-variable) + ("c" apropos-command) + ("l" apropos-library) + ("u" apropos-user-option) + ("e" apropos-value)) +;; Recommended binding: +;; (global-set-key (kbd "C-c h") 'hydra-apropos/body) + +;;** Example 11: rectangle-mark-mode +(require 'rect) +(defhydra hydra-rectangle (:body-pre (rectangle-mark-mode 1) + :color pink + :post (deactivate-mark)) + " + ^_k_^ _d_elete _s_tring +_h_ _l_ _o_k _y_ank + ^_j_^ _n_ew-copy _r_eset +^^^^ _e_xchange _u_ndo +^^^^ ^ ^ _x_kill +" + ("h" rectangle-backward-char nil) + ("l" rectangle-forward-char nil) + ("k" rectangle-previous-line nil) + ("j" rectangle-next-line nil) + ("e" hydra-ex-point-mark nil) + ("n" copy-rectangle-as-kill nil) + ("d" delete-rectangle nil) + ("r" (if (region-active-p) + (deactivate-mark) + (rectangle-mark-mode 1)) nil) + ("y" yank-rectangle nil) + ("u" undo nil) + ("s" string-rectangle nil) + ("x" kill-rectangle nil) + ("o" nil nil)) + +;; Recommended binding: +;; (global-set-key (kbd "C-x SPC") 'hydra-rectangle/body) + +;;** Example 12: org-agenda-view +(defun org-agenda-cts () + (and (eq major-mode 'org-agenda-mode) + (let ((args (get-text-property + (min (1- (point-max)) (point)) + 'org-last-args))) + (nth 2 args)))) + +(defhydra hydra-org-agenda-view (:hint none) + " +_d_: ?d? day _g_: time grid=?g? _a_: arch-trees +_w_: ?w? week _[_: inactive _A_: arch-files +_t_: ?t? fortnight _f_: follow=?f? _r_: clock report=?r? +_m_: ?m? month _e_: entry text=?e? _D_: include diary=?D? +_y_: ?y? year _q_: quit _L__l__c_: log = ?l?" + ("SPC" org-agenda-reset-view) + ("d" org-agenda-day-view (if (eq 'day (org-agenda-cts)) "[x]" "[ ]")) + ("w" org-agenda-week-view (if (eq 'week (org-agenda-cts)) "[x]" "[ ]")) + ("t" org-agenda-fortnight-view (if (eq 'fortnight (org-agenda-cts)) "[x]" "[ ]")) + ("m" org-agenda-month-view (if (eq 'month (org-agenda-cts)) "[x]" "[ ]")) + ("y" org-agenda-year-view (if (eq 'year (org-agenda-cts)) "[x]" "[ ]")) + ("l" org-agenda-log-mode (format "% -3S" org-agenda-show-log)) + ("L" (org-agenda-log-mode '(4))) + ("c" (org-agenda-log-mode 'clockcheck)) + ("f" org-agenda-follow-mode (format "% -3S" org-agenda-follow-mode)) + ("a" org-agenda-archives-mode) + ("A" (org-agenda-archives-mode 'files)) + ("r" org-agenda-clockreport-mode (format "% -3S" org-agenda-clockreport-mode)) + ("e" org-agenda-entry-text-mode (format "% -3S" org-agenda-entry-text-mode)) + ("g" org-agenda-toggle-time-grid (format "% -3S" org-agenda-use-time-grid)) + ("D" org-agenda-toggle-diary (format "% -3S" org-agenda-include-diary)) + ("!" org-agenda-toggle-deadlines) + ("[" (let ((org-agenda-include-inactive-timestamps t)) + (org-agenda-check-type t 'timeline 'agenda) + (org-agenda-redo) + (message "Display now includes inactive timestamps as well"))) + ("q" (message "Abort") :exit t) + ("v" nil)) + +;; Recommended binding: +;; (define-key org-agenda-mode-map "v" 'hydra-org-agenda-view/body) + +;;** Example 13: automatic columns +(defhydra hydra-movement () + ("j" next-line "down" :column "Vertical") + ("k" previous-line "up") + ("l" forward-char "forward" :column "Horizontal") + ("h" backward-char "back")) + +;;* Helpers +(require 'windmove) + +(defun hydra-move-splitter-left (arg) + "Move window splitter left." + (interactive "p") + (if (let ((windmove-wrap-around)) + (windmove-find-other-window 'right)) + (shrink-window-horizontally arg) + (enlarge-window-horizontally arg))) + +(defun hydra-move-splitter-right (arg) + "Move window splitter right." + (interactive "p") + (if (let ((windmove-wrap-around)) + (windmove-find-other-window 'right)) + (enlarge-window-horizontally arg) + (shrink-window-horizontally arg))) + +(defun hydra-move-splitter-up (arg) + "Move window splitter up." + (interactive "p") + (if (let ((windmove-wrap-around)) + (windmove-find-other-window 'up)) + (enlarge-window arg) + (shrink-window arg))) + +(defun hydra-move-splitter-down (arg) + "Move window splitter down." + (interactive "p") + (if (let ((windmove-wrap-around)) + (windmove-find-other-window 'up)) + (shrink-window arg) + (enlarge-window arg))) + +(defvar rectangle-mark-mode) +(defun hydra-ex-point-mark () + "Exchange point and mark." + (interactive) + (if rectangle-mark-mode + (rectangle-exchange-point-and-mark) + (let ((mk (mark))) + (rectangle-mark-mode 1) + (goto-char mk)))) + +(provide 'hydra-examples) + +;; Local Variables: +;; no-byte-compile: t +;; End: +;;; hydra-examples.el ends here diff --git a/elpa/hydra-20191125.955/hydra-ox.el b/elpa/hydra-20191125.955/hydra-ox.el new file mode 100644 index 0000000..a992efc --- /dev/null +++ b/elpa/hydra-20191125.955/hydra-ox.el @@ -0,0 +1,127 @@ +;;; hydra-ox.el --- Org mode export widget implemented in Hydra + +;; Copyright (C) 2015 Free Software Foundation, Inc. + +;; Author: Oleh Krehel + +;; This file is part of GNU Emacs. + +;; GNU Emacs 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. + +;; GNU Emacs 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 GNU Emacs. If not, see . + +;;; Commentary: +;; +;; This shows how a complex dispatch menu can be built with Hydra. + +;;; Code: + +(require 'hydra) +(require 'org) +(declare-function org-html-export-as-html 'ox-html) +(declare-function org-html-export-to-html 'ox-html) +(declare-function org-latex-export-as-latex 'ox-latex) +(declare-function org-latex-export-to-latex 'ox-latex) +(declare-function org-latex-export-to-pdf 'ox-latex) +(declare-function org-ascii-export-as-ascii 'ox-ascii) +(declare-function org-ascii-export-to-ascii 'ox-ascii) + +(defhydradio hydra-ox () + (body-only "Export only the body.") + (export-scope "Export scope." [buffer subtree]) + (async-export "When non-nil, export async.") + (visible-only "When non-nil, export visible only") + (force-publishing "Toggle force publishing")) + +(defhydra hydra-ox-html (:color blue) + "ox-html" + ("H" (org-html-export-as-html + hydra-ox/async-export + (eq hydra-ox/export-scope 'subtree) + hydra-ox/visible-only + hydra-ox/body-only) + "As HTML buffer") + ("h" (org-html-export-to-html + hydra-ox/async-export + (eq hydra-ox/export-scope 'subtree) + hydra-ox/visible-only + hydra-ox/body-only) "As HTML file") + ("o" (org-open-file + (org-html-export-to-html + hydra-ox/async-export + (eq hydra-ox/export-scope 'subtree) + hydra-ox/visible-only + hydra-ox/body-only)) "As HTML file and open") + ("b" hydra-ox/body "back") + ("q" nil "quit")) + +(defhydra hydra-ox-latex (:color blue) + "ox-latex" + ("L" org-latex-export-as-latex "As LaTeX buffer") + ("l" org-latex-export-to-latex "As LaTeX file") + ("p" org-latex-export-to-pdf "As PDF file") + ("o" (org-open-file (org-latex-export-to-pdf)) "As PDF file and open") + ("b" hydra-ox/body "back") + ("q" nil "quit")) + +(defhydra hydra-ox-text (:color blue) + "ox-text" + ("A" (org-ascii-export-as-ascii + nil nil nil nil + '(:ascii-charset ascii)) + "As ASCII buffer") + + ("a" (org-ascii-export-to-ascii + nil nil nil nil + '(:ascii-charset ascii)) + "As ASCII file") + ("L" (org-ascii-export-as-ascii + nil nil nil nil + '(:ascii-charset latin1)) + "As Latin1 buffer") + ("l" (org-ascii-export-to-ascii + nil nil nil nil + '(:ascii-charset latin1)) + "As Latin1 file") + ("U" (org-ascii-export-as-ascii + nil nil nil nil + '(:ascii-charset utf-8)) + "As UTF-8 buffer") + ("u" (org-ascii-export-to-ascii + nil nil nil nil + '(:ascii-charset utf-8)) + "As UTF-8 file") + ("b" hydra-ox/body "back") + ("q" nil "quit")) + +(defhydra hydra-ox () + " +_C-b_ Body only: % -15`hydra-ox/body-only^^^ _C-v_ Visible only: %`hydra-ox/visible-only +_C-s_ Export scope: % -15`hydra-ox/export-scope _C-f_ Force publishing: %`hydra-ox/force-publishing +_C-a_ Async export: %`hydra-ox/async-export + +" + ("C-b" (hydra-ox/body-only) nil) + ("C-v" (hydra-ox/visible-only) nil) + ("C-s" (hydra-ox/export-scope) nil) + ("C-f" (hydra-ox/force-publishing) nil) + ("C-a" (hydra-ox/async-export) nil) + ("h" hydra-ox-html/body "Export to HTML" :exit t) + ("l" hydra-ox-latex/body "Export to LaTeX" :exit t) + ("t" hydra-ox-text/body "Export to Plain Text" :exit t) + ("q" nil "quit")) + +(define-key org-mode-map (kbd "C-c C-,") 'hydra-ox/body) + +(provide 'hydra-ox) + +;;; hydra-ox.el ends here diff --git a/elpa/hydra-20191125.955/hydra-pkg.el b/elpa/hydra-20191125.955/hydra-pkg.el new file mode 100644 index 0000000..a688756 --- /dev/null +++ b/elpa/hydra-20191125.955/hydra-pkg.el @@ -0,0 +1,13 @@ +(define-package "hydra" "20191125.955" "Make bindings that stick around." + '((cl-lib "0.5") + (lv "0")) + :keywords + '("bindings") + :authors + '(("Oleh Krehel" . "ohwoeowho@gmail.com")) + :maintainer + '("Oleh Krehel" . "ohwoeowho@gmail.com") + :url "https://github.com/abo-abo/hydra") +;; Local Variables: +;; no-byte-compile: t +;; End: diff --git a/elpa/hydra-20191125.955/hydra.el b/elpa/hydra-20191125.955/hydra.el new file mode 100644 index 0000000..3508532 --- /dev/null +++ b/elpa/hydra-20191125.955/hydra.el @@ -0,0 +1,1547 @@ +;;; hydra.el --- Make bindings that stick around. -*- lexical-binding: t -*- + +;; Copyright (C) 2015-2019 Free Software Foundation, Inc. + +;; Author: Oleh Krehel +;; Maintainer: Oleh Krehel +;; URL: https://github.com/abo-abo/hydra +;; Version: 0.15.0 +;; Keywords: bindings +;; Package-Requires: ((cl-lib "0.5") (lv "0")) + +;; This file is part of GNU Emacs. + +;; GNU Emacs 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. + +;; GNU Emacs 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 GNU Emacs. If not, see . + +;;; Commentary: +;; +;; This package can be used to tie related commands into a family of +;; short bindings with a common prefix - a Hydra. +;; +;; Once you summon the Hydra (through the prefixed binding), all the +;; heads can be called in succession with only a short extension. +;; The Hydra is vanquished once Hercules, any binding that isn't the +;; Hydra's head, arrives. Note that Hercules, besides vanquishing the +;; Hydra, will still serve his original purpose, calling his proper +;; command. This makes the Hydra very seamless, it's like a minor +;; mode that disables itself automagically. +;; +;; Here's an example Hydra, bound in the global map (you can use any +;; keymap in place of `global-map'): +;; +;; (defhydra hydra-zoom (global-map "") +;; "zoom" +;; ("g" text-scale-increase "in") +;; ("l" text-scale-decrease "out")) +;; +;; It allows to start a command chain either like this: +;; " gg4ll5g", or " lgllg". +;; +;; Here's another approach, when you just want a "callable keymap": +;; +;; (defhydra hydra-toggle (:color blue) +;; "toggle" +;; ("a" abbrev-mode "abbrev") +;; ("d" toggle-debug-on-error "debug") +;; ("f" auto-fill-mode "fill") +;; ("t" toggle-truncate-lines "truncate") +;; ("w" whitespace-mode "whitespace") +;; ("q" nil "cancel")) +;; +;; This binds nothing so far, but if you follow up with: +;; +;; (global-set-key (kbd "C-c C-v") 'hydra-toggle/body) +;; +;; you will have bound "C-c C-v a", "C-c C-v d" etc. +;; +;; Knowing that `defhydra' defines e.g. `hydra-toggle/body' command, +;; you can nest Hydras if you wish, with `hydra-toggle/body' possibly +;; becoming a blue head of another Hydra. +;; +;; If you want to learn all intricacies of using `defhydra' without +;; having to figure it all out from this source code, check out the +;; wiki: https://github.com/abo-abo/hydra/wiki. There's a wealth of +;; information there. Everyone is welcome to bring the existing pages +;; up to date and add new ones. +;; +;; Additionally, the file hydra-examples.el serves to demo most of the +;; functionality. + +;;; Code: +;;* Requires +(require 'cl-lib) +(require 'lv) +(require 'ring) + +(defvar hydra-curr-map nil + "The keymap of the current Hydra called.") + +(defvar hydra-curr-on-exit nil + "The on-exit predicate for the current Hydra.") + +(defvar hydra-curr-foreign-keys nil + "The current :foreign-keys behavior.") + +(defvar hydra-curr-body-fn nil + "The current hydra-.../body function.") + +(defvar hydra-deactivate nil + "If a Hydra head sets this to t, exit the Hydra. +This will be done even if the head wasn't designated for exiting.") + +(defvar hydra-amaranth-warn-message "An amaranth Hydra can only exit through a blue head" + "Amaranth Warning message. Shown when the user tries to press an unbound/non-exit key while in an amaranth head.") + +(defun hydra-set-transient-map (keymap on-exit &optional foreign-keys) + "Set KEYMAP to the highest priority. + +Call ON-EXIT when the KEYMAP is deactivated. + +FOREIGN-KEYS determines the deactivation behavior, when a command +that isn't in KEYMAP is called: + +nil: deactivate KEYMAP and run the command. +run: keep KEYMAP and run the command. +warn: keep KEYMAP and issue a warning instead of running the command." + (if hydra-deactivate + (hydra-keyboard-quit) + (setq hydra-curr-map keymap) + (setq hydra-curr-on-exit on-exit) + (setq hydra-curr-foreign-keys foreign-keys) + (add-hook 'pre-command-hook 'hydra--clearfun) + (internal-push-keymap keymap 'overriding-terminal-local-map))) + +(defun hydra--clearfun () + "Disable the current Hydra unless `this-command' is a head." + (unless (eq this-command 'hydra-pause-resume) + (when (or + (memq this-command '(handle-switch-frame + keyboard-quit)) + (null overriding-terminal-local-map) + (not (or (eq this-command + (lookup-key hydra-curr-map (this-single-command-keys))) + (cl-case hydra-curr-foreign-keys + (warn + (setq this-command 'hydra-amaranth-warn)) + (run + t) + (t nil))))) + (hydra-disable)))) + +(defvar hydra--ignore nil + "When non-nil, don't call `hydra-curr-on-exit'.") + +(defvar hydra--input-method-function nil + "Store overridden `input-method-function' here.") + +(defun hydra-disable () + "Disable the current Hydra." + (setq hydra-deactivate nil) + (remove-hook 'pre-command-hook 'hydra--clearfun) + (unless hydra--ignore + (if (fboundp 'remove-function) + (remove-function input-method-function #'hydra--imf) + (when hydra--input-method-function + (setq input-method-function hydra--input-method-function) + (setq hydra--input-method-function nil)))) + (dolist (frame (frame-list)) + (with-selected-frame frame + (when overriding-terminal-local-map + (internal-pop-keymap hydra-curr-map 'overriding-terminal-local-map)))) + (unless hydra--ignore + (when hydra-curr-on-exit + (let ((on-exit hydra-curr-on-exit)) + (setq hydra-curr-on-exit nil) + (funcall on-exit))))) + +(unless (fboundp 'internal-push-keymap) + (defun internal-push-keymap (keymap symbol) + (let ((map (symbol-value symbol))) + (unless (memq keymap map) + (unless (memq 'add-keymap-witness (symbol-value symbol)) + (setq map (make-composed-keymap nil (symbol-value symbol))) + (push 'add-keymap-witness (cdr map)) + (set symbol map)) + (push keymap (cdr map)))))) + +(unless (fboundp 'internal-pop-keymap) + (defun internal-pop-keymap (keymap symbol) + (let ((map (symbol-value symbol))) + (when (memq keymap map) + (setf (cdr map) (delq keymap (cdr map)))) + (let ((tail (cddr map))) + (and (or (null tail) (keymapp tail)) + (eq 'add-keymap-witness (nth 1 map)) + (set symbol tail)))))) + +(defun hydra-amaranth-warn () + "Issue a warning that the current input was ignored." + (interactive) + (message hydra-amaranth-warn-message)) + +;;* Customize +(defgroup hydra nil + "Make bindings that stick around." + :group 'bindings + :prefix "hydra-") + +(defcustom hydra-is-helpful t + "When t, display a hint with possible bindings in the echo area." + :type 'boolean + :group 'hydra) + +(defcustom hydra-default-hint "" + "Default :hint property to use for heads when not specified in +the body or the head." + :type 'sexp + :group 'hydra) + +(declare-function posframe-show "posframe") +(declare-function posframe-hide "posframe") +(declare-function posframe-poshandler-window-center "posframe") + +(defvar hydra-posframe-show-params + '(:internal-border-width 1 + :internal-border-color "red" + :poshandler posframe-poshandler-window-center) + "List of parameters passed to `posframe-show'.") + +(defvar hydra--posframe-timer nil + "Timer for hiding posframe hint.") + +(defun hydra-posframe-show (str) + (require 'posframe) + (when hydra--posframe-timer + (cancel-timer hydra--posframe-timer)) + (setq hydra--posframe-timer nil) + (apply #'posframe-show + " *hydra-posframe*" + :string str + hydra-posframe-show-params)) + +(defun hydra-posframe-hide () + (require 'posframe) + (unless hydra--posframe-timer + (setq hydra--posframe-timer + (run-with-idle-timer + 0 nil (lambda () + (setq hydra--posframe-timer nil) + (posframe-hide " *hydra-posframe*")))))) + +(defvar hydra-hint-display-alist + (list (list 'lv #'lv-message #'lv-delete-window) + (list 'message #'message (lambda () (message ""))) + (list 'posframe #'hydra-posframe-show #'hydra-posframe-hide)) + "Store the functions for `hydra-hint-display-type'.") + +(defcustom hydra-hint-display-type 'lv + "The utility to show hydra hint" + :type '(choice + (const message) + (const lv) + (const posframe)) + :group 'hydra) + +(defcustom hydra-verbose nil + "When non-nil, hydra will issue some non essential style warnings." + :type 'boolean) + +(defcustom hydra-key-format-spec "%s" + "Default `format'-style specifier for _a_ syntax in docstrings. +When nil, you can specify your own at each location like this: _ 5a_." + :type 'string) + +(defcustom hydra-doc-format-spec "%s" + "Default `format'-style specifier for ?a? syntax in docstrings." + :type 'string) + +(defcustom hydra-look-for-remap nil + "When non-nil, hydra binding behaves as keymap binding with [remap]. +When calling a head with a simple command, hydra will lookup for a potential +remap command according to the current active keymap and call it instead if +found" + :type 'boolean) + +(make-obsolete-variable + 'hydra-key-format-spec + "Since the docstrings are aligned by hand anyway, this isn't very useful." + "0.13.1") + +(defface hydra-face-red + '((t (:foreground "#FF0000" :bold t))) + "Red Hydra heads don't exit the Hydra. +Every other command exits the Hydra." + :group 'hydra) + +(defface hydra-face-blue + '((((class color) (background light)) + :foreground "#0000FF" :bold t) + (((class color) (background dark)) + :foreground "#8ac6f2" :bold t)) + "Blue Hydra heads exit the Hydra. +Every other command exits as well.") + +(defface hydra-face-amaranth + '((t (:foreground "#E52B50" :bold t))) + "Amaranth body has red heads and warns on intercepting non-heads. +Exitable only through a blue head.") + +(defface hydra-face-pink + '((t (:foreground "#FF6EB4" :bold t))) + "Pink body has red heads and runs intercepted non-heads. +Exitable only through a blue head.") + +(defface hydra-face-teal + '((t (:foreground "#367588" :bold t))) + "Teal body has blue heads and warns on intercepting non-heads. +Exitable only through a blue head.") + +;;* Fontification +(defun hydra-add-font-lock () + "Fontify `defhydra' statements." + (font-lock-add-keywords + 'emacs-lisp-mode + '(("(\\(defhydra\\)\\_> +\\(.*?\\)\\_>" + (1 font-lock-keyword-face) + (2 font-lock-type-face)) + ("(\\(defhydradio\\)\\_> +\\(.*?\\)\\_>" + (1 font-lock-keyword-face) + (2 font-lock-type-face))))) + +;;* Find Function +(eval-after-load 'find-func + '(defadvice find-function-search-for-symbol + (around hydra-around-find-function-search-for-symbol-advice + (symbol type library) activate) + "Navigate to hydras with `find-function-search-for-symbol'." + (prog1 ad-do-it + (when (symbolp symbol) + ;; The original function returns (cons (current-buffer) (point)) + ;; if it found the point. + (unless (cdr ad-return-value) + (with-current-buffer (find-file-noselect library) + (let ((sn (symbol-name symbol))) + (when (and (null type) + (string-match "\\`\\(hydra-[a-z-A-Z0-9]+\\)/\\(.*\\)\\'" sn) + (re-search-forward (concat "(defhydra " (match-string 1 sn)) + nil t)) + (goto-char (match-beginning 0))) + (cons (current-buffer) (point))))))))) + +;;* Universal Argument +(defvar hydra-base-map + (let ((map (make-sparse-keymap))) + (define-key map [?\C-u] 'hydra--universal-argument) + (define-key map [?-] 'hydra--negative-argument) + (define-key map [?0] 'hydra--digit-argument) + (define-key map [?1] 'hydra--digit-argument) + (define-key map [?2] 'hydra--digit-argument) + (define-key map [?3] 'hydra--digit-argument) + (define-key map [?4] 'hydra--digit-argument) + (define-key map [?5] 'hydra--digit-argument) + (define-key map [?6] 'hydra--digit-argument) + (define-key map [?7] 'hydra--digit-argument) + (define-key map [?8] 'hydra--digit-argument) + (define-key map [?9] 'hydra--digit-argument) + (define-key map [kp-0] 'hydra--digit-argument) + (define-key map [kp-1] 'hydra--digit-argument) + (define-key map [kp-2] 'hydra--digit-argument) + (define-key map [kp-3] 'hydra--digit-argument) + (define-key map [kp-4] 'hydra--digit-argument) + (define-key map [kp-5] 'hydra--digit-argument) + (define-key map [kp-6] 'hydra--digit-argument) + (define-key map [kp-7] 'hydra--digit-argument) + (define-key map [kp-8] 'hydra--digit-argument) + (define-key map [kp-9] 'hydra--digit-argument) + (define-key map [kp-subtract] 'hydra--negative-argument) + map) + "Keymap that all Hydras inherit. See `universal-argument-map'.") + +(defun hydra--universal-argument (arg) + "Forward to (`universal-argument' ARG)." + (interactive "P") + (setq prefix-arg (if (consp arg) + (list (* 4 (car arg))) + (if (eq arg '-) + (list -4) + '(4))))) + +(defun hydra--digit-argument (arg) + "Forward to (`digit-argument' ARG)." + (interactive "P") + (let* ((char (if (integerp last-command-event) + last-command-event + (get last-command-event 'ascii-character))) + (digit (- (logand char ?\177) ?0))) + (setq prefix-arg (cond ((integerp arg) + (+ (* arg 10) + (if (< arg 0) + (- digit) + digit))) + ((eq arg '-) + (if (zerop digit) + '- + (- digit))) + (t + digit))))) + +(defun hydra--negative-argument (arg) + "Forward to (`negative-argument' ARG)." + (interactive "P") + (setq prefix-arg (cond ((integerp arg) (- arg)) + ((eq arg '-) nil) + (t '-)))) + +;;* Repeat +(defvar hydra-repeat--prefix-arg nil + "Prefix arg to use with `hydra-repeat'.") + +(defvar hydra-repeat--command nil + "Command to use with `hydra-repeat'.") + +(defun hydra-repeat (&optional arg) + "Repeat last command with last prefix arg. +When ARG is non-nil, use that instead." + (interactive "p") + (if (eq arg 1) + (unless (string-match "hydra-repeat$" (symbol-name last-command)) + (setq hydra-repeat--command last-command) + (setq hydra-repeat--prefix-arg last-prefix-arg)) + (setq hydra-repeat--prefix-arg arg)) + (setq current-prefix-arg hydra-repeat--prefix-arg) + (funcall hydra-repeat--command)) + +;;* Misc internals +(defun hydra--callablep (x) + "Test if X is callable." + (or (functionp x) + (and (consp x) + (memq (car x) '(function quote))))) + +(defun hydra--make-callable (x) + "Generate a callable symbol from X. +If X is a function symbol or a lambda, return it. Otherwise, it +should be a single statement. Wrap it in an interactive lambda." + (cond ((or (symbolp x) (functionp x)) + x) + ((and (consp x) (eq (car x) 'function)) + (cadr x)) + (t + `(lambda () + (interactive) + ,x)))) + +(defun hydra-plist-get-default (plist prop default) + "Extract a value from a property list. +PLIST is a property list, which is a list of the form +\(PROP1 VALUE1 PROP2 VALUE2...). + +Return the value corresponding to PROP, or DEFAULT if PROP is not +one of the properties on the list." + (if (memq prop plist) + (plist-get plist prop) + default)) + +(defun hydra--head-property (h prop &optional default) + "Return for Hydra head H the value of property PROP. +Return DEFAULT if PROP is not in H." + (hydra-plist-get-default (cl-cdddr h) prop default)) + +(defun hydra--head-set-property (h prop value) + "In hydra Head H, set a property PROP to the value VALUE." + (cons (car h) (plist-put (cdr h) prop value))) + +(defun hydra--head-has-property (h prop) + "Return non nil if heads H has the property PROP." + (plist-member (cdr h) prop)) + +(defun hydra--body-foreign-keys (body) + "Return what BODY does with a non-head binding." + (or + (plist-get (cddr body) :foreign-keys) + (let ((color (plist-get (cddr body) :color))) + (cl-case color + ((amaranth teal) 'warn) + (pink 'run))))) + +(defun hydra--body-exit (body) + "Return the exit behavior of BODY." + (or + (plist-get (cddr body) :exit) + (let ((color (plist-get (cddr body) :color))) + (cl-case color + ((blue teal) t) + (t nil))))) + +(defun hydra--normalize-body (body) + "Put BODY in a normalized format. +Add :exit and :foreign-keys if they are not there. +Remove :color key. And sort the plist alphabetically." + (let ((plist (cddr body))) + (plist-put plist :exit (hydra--body-exit body)) + (plist-put plist :foreign-keys (hydra--body-foreign-keys body)) + (let* ((alist0 (cl-loop for (k v) on plist + by #'cddr collect (cons k v))) + (alist1 (assq-delete-all :color alist0)) + (alist2 (cl-sort alist1 #'string< + :key (lambda (x) (symbol-name (car x)))))) + (append (list (car body) (cadr body)) + (cl-mapcan (lambda (x) (list (car x) (cdr x))) alist2))))) + +(defalias 'hydra--imf #'list) + +(defun hydra-default-pre () + "Default setup that happens in each head before :pre." + (when (eq input-method-function 'key-chord-input-method) + (if (fboundp 'add-function) + (add-function :override input-method-function #'hydra--imf) + (unless hydra--input-method-function + (setq hydra--input-method-function input-method-function) + (setq input-method-function nil))))) + +(defvar hydra-timeout-timer (timer-create) + "Timer for `hydra-timeout'.") + +(defvar hydra-message-timer (timer-create) + "Timer for the hint.") + +(defvar hydra--work-around-dedicated t + "When non-nil, assume there's no bug in `pop-to-buffer'. +`pop-to-buffer' should not select a dedicated window.") + +(defun hydra-keyboard-quit () + "Quitting function similar to `keyboard-quit'." + (interactive) + (hydra-disable) + (cancel-timer hydra-timeout-timer) + (cancel-timer hydra-message-timer) + (setq hydra-curr-map nil) + (unless (and hydra--ignore + (null hydra--work-around-dedicated)) + (funcall + (nth 2 (assoc hydra-hint-display-type hydra-hint-display-alist)))) + nil) + +(defvar hydra-head-format "[%s]: " + "The formatter for each head of a plain docstring.") + +(defvar hydra-key-doc-function 'hydra-key-doc-function-default + "The function for formatting key-doc pairs.") + +(defun hydra-key-doc-function-default (key key-width doc doc-width) + (cond + ((equal key " ") (format (format "%%-%ds" (+ 3 key-width doc-width)) doc)) + ((listp doc) + `(format ,(format "%%%ds: %%%ds" key-width (- -1 doc-width)) ,key ,doc)) + (t (format (format "%%%ds: %%%ds" key-width (- -1 doc-width)) key doc)))) + +(defun hydra--to-string (x) + (if (stringp x) + x + (eval x))) + +(defun hydra--eval-and-format (x) + (let ((str (hydra--to-string (cdr x)))) + (format + (if (> (length str) 0) + (concat hydra-head-format str) + "%s") + (car x)))) + +(defun hydra--hint-heads-wocol (body heads) + "Generate a hint for the echo area. +BODY, and HEADS are parameters to `defhydra'. +Works for heads without a property :column." + (let (alist) + (dolist (h heads) + (let ((val (assoc (cadr h) alist)) + (pstr (hydra-fontify-head h body))) + (if val + (setf (cadr val) + (concat (cadr val) " " pstr)) + (push + (cons (cadr h) + (cons pstr (cl-caddr h))) + alist)))) + (let ((keys (nreverse (mapcar #'cdr alist))) + (n-cols (plist-get (cddr body) :columns)) + res) + (setq res + (if n-cols + (let ((n-rows (1+ (/ (length keys) n-cols))) + (max-key-len (apply #'max (mapcar (lambda (x) (length (car x))) keys))) + (max-doc-len (apply #'max (mapcar (lambda (x) + (length (hydra--to-string (cdr x)))) keys)))) + `(concat + "\n" + (mapconcat #'identity + (mapcar + (lambda (x) + (mapconcat + (lambda (y) + (and y + (funcall hydra-key-doc-function + (car y) + ,max-key-len + (hydra--to-string (cdr y)) + ,max-doc-len))) x "")) + ',(hydra--matrix keys n-cols n-rows)) + "\n"))) + + + `(concat + (mapconcat + #'hydra--eval-and-format + ',keys + ", ") + ,(if keys "." "")))) + (if (cl-every #'stringp + (mapcar 'cddr alist)) + (eval res) + res)))) + +(defun hydra--hint (body heads) + "Generate a hint for the echo area. +BODY, and HEADS are parameters to `defhydra'." + (let* ((sorted-heads (hydra--sort-heads (hydra--normalize-heads heads))) + (heads-w-col (cl-remove-if-not (lambda (heads) (hydra--head-property (nth 0 heads) :column)) sorted-heads)) + (heads-wo-col (cl-remove-if (lambda (heads) (hydra--head-property (nth 0 heads) :column)) sorted-heads)) + (hint-w-col (when heads-w-col + (hydra--hint-from-matrix body (hydra--generate-matrix heads-w-col)))) + (hint-wo-col (when heads-wo-col + (hydra--hint-heads-wocol body (car heads-wo-col))))) + (if (null hint-w-col) + hint-wo-col + (if (stringp hint-wo-col) + `(concat ,@hint-w-col ,hint-wo-col) + `(concat ,@hint-w-col ,@(cdr hint-wo-col)))))) + +(defvar hydra-fontify-head-function nil + "Possible replacement for `hydra-fontify-head-default'.") + +(defun hydra-fontify-head-default (head body) + "Produce a pretty string from HEAD and BODY. +HEAD's binding is returned as a string with a colored face." + (let* ((foreign-keys (hydra--body-foreign-keys body)) + (head-exit (hydra--head-property head :exit)) + (head-color + (if head-exit + (if (eq foreign-keys 'warn) + 'teal + 'blue) + (cl-case foreign-keys + (warn 'amaranth) + (run 'pink) + (t 'red))))) + (when (and (null (cadr head)) + (not head-exit)) + (hydra--complain "nil cmd can only be blue")) + (propertize + (replace-regexp-in-string "%" "%%" (car head)) + 'face + (or (hydra--head-property head :face) + (cl-case head-color + (blue 'hydra-face-blue) + (red 'hydra-face-red) + (amaranth 'hydra-face-amaranth) + (pink 'hydra-face-pink) + (teal 'hydra-face-teal) + (t (error "Unknown color for %S" head))))))) + +(defun hydra-fontify-head-greyscale (head _body) + "Produce a pretty string from HEAD and BODY. +HEAD's binding is returned as a string wrapped with [] or {}." + (format + (if (hydra--head-property head :exit) + "[%s]" + "{%s}") (car head))) + +(defun hydra-fontify-head (head body) + "Produce a pretty string from HEAD and BODY." + (funcall (or hydra-fontify-head-function 'hydra-fontify-head-default) + head body)) + +(defun hydra--strip-align-markers (str) + "Remove ^ from STR, unless they're escaped: \\^." + (let ((start 0)) + (while (setq start (string-match "\\\\?\\^" str start)) + (if (eq (- (match-end 0) (match-beginning 0)) 2) + (progn + (setq str (replace-match "^" nil nil str)) + (cl-incf start)) + (setq str (replace-match "" nil nil str)))) + str)) + +(defvar hydra-docstring-keys-translate-alist + '(("↑" . "") + ("↓" . "") + ("→" . "") + ("←" . "") + ("⌫" . "DEL") + ("⌦" . "") + ("⏎" . "RET"))) + +(defconst hydra-width-spec-regex " ?-?[0-9]*?" + "Regex for the width spec in keys and %` quoted sexps.") + +(defvar hydra-key-regex "\\[\\|]\\|[-\\[:alnum:] ~.,;:/|?<>={}*+#%@!&^↑↓←→⌫⌦⏎'`()\"$]+?" + "Regex for the key quoted in the docstring.") + +(defun hydra--format (_name body docstring heads) + "Generate a `format' statement from STR. +\"%`...\" expressions are extracted into \"%S\". +_NAME, BODY, DOCSTRING and HEADS are parameters of `defhydra'. +The expressions can be auto-expanded according to NAME." + (unless (memq 'elisp--witness--lisp (mapcar #'cadr heads)) + (setq docstring (hydra--strip-align-markers docstring)) + (setq docstring (replace-regexp-in-string "___" "_β_" docstring)) + (let ((rest (if (eq (plist-get (cddr body) :hint) 'none) + "" + (hydra--hint body heads))) + (start 0) + (inner-regex (format "\\(%s\\)\\(%s\\)" hydra-width-spec-regex hydra-key-regex)) + varlist + offset) + (while (setq start + (string-match + (format + "\\(?:%%\\( ?-?[0-9]*s?\\)\\(`[a-z-A-Z/0-9]+\\|(\\)\\)\\|\\(?:_%s_\\)\\|\\(?:[?]%s[?]\\)" + inner-regex + inner-regex) + docstring start)) + (cond ((eq ?? (aref (match-string 0 docstring) 0)) + (let* ((key (match-string 6 docstring)) + (head (assoc key heads))) + (if head + (progn + (push (nth 2 head) varlist) + (setq docstring + (replace-match + (or + hydra-doc-format-spec + (concat "%" (match-string 3 docstring) "s")) + t nil docstring))) + (setq start (match-end 0)) + (warn "Unrecognized key: ?%s?" key)))) + ((eq ?_ (aref (match-string 0 docstring) 0)) + (let* ((key (match-string 4 docstring)) + (key (if (equal key "β") "_" key)) + normal-key + (head (or (assoc key heads) + (when (setq normal-key + (cdr (assoc + key hydra-docstring-keys-translate-alist))) + (assoc normal-key heads))))) + (if head + (progn + (push (hydra-fontify-head (if normal-key + (cons key (cdr head)) + head) + body) + varlist) + (let ((replacement + (or + hydra-key-format-spec + (concat "%" (match-string 3 docstring) "s")))) + (setq docstring + (replace-match replacement t nil docstring)) + (setq start (+ start (length replacement))))) + (setq start (match-end 0)) + (warn "Unrecognized key: _%s_" key)))) + + (t + (let* ((varp (if (eq ?` (aref (match-string 2 docstring) 0)) 1 0)) + (spec (match-string 1 docstring)) + (lspec (length spec))) + (setq offset + (with-temp-buffer + (insert (substring docstring (+ 1 start varp + (length spec)))) + (goto-char (point-min)) + (push (read (current-buffer)) varlist) + (- (point) (point-min)))) + (when (or (zerop lspec) + (/= (aref spec (1- (length spec))) ?s)) + (setq spec (concat spec "S"))) + (setq docstring + (concat + (substring docstring 0 start) + "%" spec + (substring docstring (+ start offset 1 lspec varp)))))))) + (hydra--format-1 docstring rest varlist)))) + +(defun hydra--format-1 (docstring rest varlist) + (cond + ((string= docstring "") + rest) + ((listp rest) + (unless (string-match-p "[:\n]" docstring) + (setq docstring (concat docstring ":\n"))) + (unless (or (string-match-p "\n\\'" docstring) + (equal (cadr rest) "\n")) + (setq docstring (concat docstring "\n"))) + `(concat (format ,(replace-regexp-in-string "\\`\n" "" docstring) ,@(nreverse varlist)) + ,@(cdr rest))) + ((eq ?\n (aref docstring 0)) + `(format ,(concat (substring docstring 1) rest) ,@(nreverse varlist))) + (t + (let ((r `(replace-regexp-in-string + " +$" "" + (concat ,docstring + ,(cond ((string-match-p "\\`\n" rest) + ":") + ((string-match-p "\n" rest) + ":\n") + (t + ": ")) + (replace-regexp-in-string + "\\(%\\)" "\\1\\1" ,rest))))) + (if (stringp rest) + `(format ,(eval r)) + `(format ,r)))))) + +(defun hydra--complain (format-string &rest args) + "Forward to (`message' FORMAT-STRING ARGS) unless `hydra-verbose' is nil." + (if hydra-verbose + (apply #'error format-string args) + (apply #'message format-string args))) + +(defun hydra--doc (body-key body-name heads) + "Generate a part of Hydra docstring. +BODY-KEY is the body key binding. +BODY-NAME is the symbol that identifies the Hydra. +HEADS is a list of heads." + (format + "The heads for the associated hydra are:\n\n%s\n\n%s%s." + (mapconcat + (lambda (x) + (format "\"%s\": `%S'" (car x) (cadr x))) + heads ",\n") + (format "The body can be accessed via `%S'" body-name) + (if body-key + (format ", which is bound to \"%s\"" body-key) + ""))) + +(defun hydra--call-interactively-remap-maybe (cmd) + "`call-interactively' the given CMD or its remapped equivalent. +Only when `hydra-look-for-remap' is non nil." + (let ((remapped-cmd (if hydra-look-for-remap + (command-remapping `,cmd) + nil))) + (if remapped-cmd + (call-interactively `,remapped-cmd) + (call-interactively `,cmd)))) + +(defun hydra--call-interactively (cmd name) + "Generate a `call-interactively' statement for CMD. +Set `this-command' to NAME." + (if (and (symbolp name) + (not (memq name '(nil body)))) + `(progn + (setq this-command ',name) + (hydra--call-interactively-remap-maybe #',cmd)) + `(hydra--call-interactively-remap-maybe #',cmd))) + +(defun hydra--make-defun (name body doc head + keymap body-pre body-before-exit + &optional body-after-exit) + "Make a defun wrapper, using NAME, BODY, DOC, HEAD, and KEYMAP. +NAME and BODY are the arguments to `defhydra'. +DOC was generated with `hydra--doc'. +HEAD is one of the HEADS passed to `defhydra'. +BODY-PRE is added to the start of the wrapper. +BODY-BEFORE-EXIT will be called before the hydra quits. +BODY-AFTER-EXIT is added to the end of the wrapper." + (let ((cmd-name (hydra--head-name head name)) + (cmd (when (car head) + (hydra--make-callable + (cadr head)))) + (doc (if (car head) + (format "Call the head `%S' in the \"%s\" hydra.\n\n%s" + (cadr head) name doc) + (format "Call the body in the \"%s\" hydra.\n\n%s" + name doc))) + (hint (intern (format "%S/hint" name))) + (body-foreign-keys (hydra--body-foreign-keys body)) + (body-timeout (plist-get body :timeout)) + (body-idle (plist-get body :idle))) + `(defun ,cmd-name () + ,doc + (interactive) + (require 'hydra) + (hydra-default-pre) + ,@(when body-pre (list body-pre)) + ,@(if (hydra--head-property head :exit) + `((hydra-keyboard-quit) + (setq hydra-curr-body-fn ',(intern (format "%S/body" name))) + ,@(if body-after-exit + `((unwind-protect + ,(when cmd + (hydra--call-interactively cmd (cadr head))) + ,body-after-exit)) + (when cmd + `(,(hydra--call-interactively cmd (cadr head)))))) + (delq + nil + `((let ((hydra--ignore ,(not (eq (cadr head) 'body)))) + (hydra-keyboard-quit) + (setq hydra-curr-body-fn ',(intern (format "%S/body" name)))) + ,(when cmd + `(condition-case err + ,(hydra--call-interactively cmd (cadr head)) + ((quit error) + (message (error-message-string err))))) + ,(if (and body-idle (eq (cadr head) 'body)) + `(hydra-idle-message ,body-idle ,hint ',name) + `(hydra-show-hint ,hint ',name)) + (hydra-set-transient-map + ,keymap + (lambda () (hydra-keyboard-quit) ,body-before-exit) + ,(when body-foreign-keys + (list 'quote body-foreign-keys))) + ,body-after-exit + ,(when body-timeout + `(hydra-timeout ,body-timeout)))))))) + +(defvar hydra-props-alist nil) + +(defun hydra-set-property (name key val) + "Set hydra property. +NAME is the symbolic name of the hydra. +KEY and VAL are forwarded to `plist-put'." + (let ((entry (assoc name hydra-props-alist)) + plist) + (when (null entry) + (add-to-list 'hydra-props-alist (list name)) + (setq entry (assoc name hydra-props-alist))) + (setq plist (cdr entry)) + (setcdr entry (plist-put plist key val)))) + +(defun hydra-get-property (name key) + "Get hydra property. +NAME is the symbolic name of the hydra. +KEY is forwarded to `plist-get'." + (let ((entry (assoc name hydra-props-alist))) + (when entry + (plist-get (cdr entry) key)))) + +(defun hydra-show-hint (hint caller) + (let ((verbosity (plist-get (cdr (assoc caller hydra-props-alist)) + :verbosity))) + (cond ((eq verbosity 0)) + ((eq verbosity 1) + (message (eval hint))) + (t + (when hydra-is-helpful + (funcall + (nth 1 (assoc hydra-hint-display-type hydra-hint-display-alist)) + (eval hint))))))) + +(defmacro hydra--make-funcall (sym) + "Transform SYM into a `funcall' to call it." + `(when (and ,sym (symbolp ,sym)) + (setq ,sym `(funcall #',,sym)))) + +(defun hydra--head-name (h name) + "Return the symbol for head H of hydra with NAME." + (let ((str (format "%S/%s" name + (cond ((symbolp (cadr h)) + (cadr h)) + ((and (consp (cadr h)) + (eq (cl-caadr h) 'function)) + (cadr (cadr h))) + (t + (concat "lambda-" (car h))))))) + (when (and (hydra--head-property h :exit) + (not (memq (cadr h) '(body nil)))) + (setq str (concat str "-and-exit"))) + (intern str))) + +(defun hydra--delete-duplicates (heads) + "Return HEADS without entries that have the same CMD part. +In duplicate HEADS, :cmd-name is modified to whatever they duplicate." + (let ((ali '(((hydra-repeat . nil) . hydra-repeat))) + res entry) + (dolist (h heads) + (if (setq entry (assoc (cons (cadr h) + (hydra--head-property h :exit)) + ali)) + (setf (cl-cdddr h) (plist-put (cl-cdddr h) :cmd-name (cdr entry))) + (push (cons (cons (cadr h) + (hydra--head-property h :exit)) + (plist-get (cl-cdddr h) :cmd-name)) + ali) + (push h res))) + (nreverse res))) + +(defun hydra--pad (lst n) + "Pad LST with nil until length N." + (let ((len (length lst))) + (if (= len n) + lst + (append lst (make-list (- n len) nil))))) + +(defmacro hydra-multipop (lst n) + "Return LST's first N elements while removing them." + `(if (<= (length ,lst) ,n) + (prog1 ,lst + (setq ,lst nil)) + (prog1 ,lst + (setcdr + (nthcdr (1- ,n) (prog1 ,lst (setq ,lst (nthcdr ,n ,lst)))) + nil)))) + +(defun hydra--matrix (lst rows cols) + "Create a matrix from elements of LST. +The matrix size is ROWS times COLS." + (let ((ls (copy-sequence lst)) + res) + (dotimes (_c cols) + (push (hydra--pad (hydra-multipop ls rows) rows) res)) + (nreverse res))) + +(defun hydra--cell (fstr names) + "Format a rectangular cell based on FSTR and NAMES. +FSTR is a format-style string with two string inputs: one for the +doc and one for the symbol name. +NAMES is a list of variables." + (let ((len (cl-reduce + (lambda (acc it) (max (length (symbol-name it)) acc)) + names + :initial-value 0))) + (mapconcat + (lambda (sym) + (if sym + (format fstr + (documentation-property sym 'variable-documentation) + (let ((name (symbol-name sym))) + (concat name (make-string (- len (length name)) ?^))) + sym) + "")) + names + "\n"))) + +(defun hydra--vconcat (strs &optional joiner) + "Glue STRS vertically. They must be the same height. +JOINER is a function similar to `concat'." + (setq joiner (or joiner #'concat)) + (mapconcat + (lambda (s) + (if (string-match " +$" s) + (replace-match "" nil nil s) + s)) + (apply #'cl-mapcar joiner + (mapcar + (lambda (s) (split-string s "\n")) + strs)) + "\n")) + +(defvar hydra-cell-format "% -20s %% -8`%s" + "The default format for docstring cells.") + +(defun hydra--table (names rows cols &optional cell-formats) + "Format a `format'-style table from variables in NAMES. +The size of the table is ROWS times COLS. +CELL-FORMATS are `format' strings for each column. +If CELL-FORMATS is a string, it's used for all columns. +If CELL-FORMATS is nil, `hydra-cell-format' is used for all columns." + (setq cell-formats + (cond ((null cell-formats) + (make-list cols hydra-cell-format)) + ((stringp cell-formats) + (make-list cols cell-formats)) + (t + cell-formats))) + (hydra--vconcat + (cl-mapcar + #'hydra--cell + cell-formats + (hydra--matrix names rows cols)) + (lambda (&rest x) + (mapconcat #'identity x " ")))) + +(defun hydra-reset-radios (names) + "Set variables NAMES to their defaults. +NAMES should be defined by `defhydradio' or similar." + (dolist (n names) + (set n (aref (get n 'range) 0)))) + +;; Following functions deal with automatic docstring table generation from :column head property +(defun hydra--normalize-heads (heads) + "Ensure each head from HEADS have a property :column. +Set it to the same value as preceding head or nil if no previous value +was defined." + (let ((current-col nil)) + (mapcar (lambda (head) + (if (hydra--head-has-property head :column) + (setq current-col (hydra--head-property head :column))) + (hydra--head-set-property head :column current-col)) + heads))) + +(defun hydra--sort-heads (normalized-heads) + "Return a list of heads with non-nil doc grouped by column property. +Each head of NORMALIZED-HEADS must have a column property." + (let* ((heads-wo-nil-doc (cl-remove-if-not (lambda (head) (nth 2 head)) normalized-heads)) + (columns-list (delete-dups (mapcar (lambda (head) (hydra--head-property head :column)) + normalized-heads))) + (get-col-index-fun (lambda (head) (cl-position (hydra--head-property head :column) + columns-list + :test 'equal))) + (heads-sorted (cl-sort heads-wo-nil-doc (lambda (it other) + (< (funcall get-col-index-fun it) + (funcall get-col-index-fun other)))))) + ;; this operation partition the sorted head list into lists of heads with same column property + (cl-loop for head in heads-sorted + for column-name = (hydra--head-property head :column) + with prev-column-name = (hydra--head-property (nth 0 heads-sorted) :column) + unless (equal prev-column-name column-name) collect heads-one-column into heads-all-columns + and do (setq heads-one-column nil) + collect head into heads-one-column + do (setq prev-column-name column-name) + finally return (append heads-all-columns (list heads-one-column))))) + +(defun hydra--pad-heads (heads-groups padding-head) + "Return a copy of HEADS-GROUPS padded where applicable with PADDING-HEAD." + (cl-loop for heads-group in heads-groups + for this-head-group-length = (length heads-group) + with head-group-max-length = (apply #'max (mapcar (lambda (heads) (length heads)) heads-groups)) + if (<= this-head-group-length head-group-max-length) + collect (append heads-group (make-list (- head-group-max-length this-head-group-length) padding-head)) + into balanced-heads-groups + else collect heads-group into balanced-heads-groups + finally return balanced-heads-groups)) + +(defun hydra--generate-matrix (heads-groups) + "Return a copy of HEADS-GROUPS decorated with table formatting information. +Details of modification: +2 virtual heads acting as table header were added to each heads-group. +Each head is decorated with 2 new properties max-doc-len and max-key-len +representing the maximum dimension of their owning group. + Every heads-group have equal length by adding padding heads where applicable." + (when heads-groups + (let ((res nil)) + (dolist (heads-group (hydra--pad-heads heads-groups '(" " nil " " :exit t))) + (let* ((column-name (hydra--head-property (nth 0 heads-group) :column)) + (max-key-len (apply #'max (mapcar (lambda (x) (length (car x))) heads-group))) + (max-doc-len (apply #'max + (length column-name) + (mapcar (lambda (x) (length (hydra--to-string (nth 2 x)))) heads-group))) + (header-virtual-head `(" " nil ,column-name :column ,column-name :exit t)) + (separator-virtual-head `(" " nil ,(make-string (+ 2 max-doc-len max-key-len) ?-) :column ,column-name :exit t)) + (decorated-heads (copy-tree (apply 'list header-virtual-head separator-virtual-head heads-group)))) + (push (mapcar (lambda (it) + (hydra--head-set-property it :max-key-len max-key-len) + (hydra--head-set-property it :max-doc-len max-doc-len)) + decorated-heads) res))) + (nreverse res)))) + +(defun hydra-interpose (x lst) + "Insert X in between each element of LST." + (let (res y) + (while (setq y (pop lst)) + (push y res) + (push x res)) + (nreverse (cdr res)))) + +(defun hydra--hint-row (heads body) + (let ((lst (hydra-interpose + "| " + (mapcar (lambda (head) + (funcall hydra-key-doc-function + (hydra-fontify-head head body) + (let ((n (hydra--head-property head :max-key-len))) + (+ n (cl-count ?% (car head)))) + (nth 2 head) ;; doc + (hydra--head-property head :max-doc-len))) + heads)))) + (when (stringp (car (last lst))) + (let ((len (length lst)) + (new-last (replace-regexp-in-string "\s+$" "" (car (last lst))))) + (when (= 0 (length (setf (nth (- len 1) lst) new-last))) + (setf (nth (- len 2) lst) "|")))) + lst)) + + +(defun hydra--hint-from-matrix (body heads-matrix) + "Generate a formatted table-style docstring according to BODY and HEADS-MATRIX. +HEADS-MATRIX is expected to be a list of heads with following features: +Each heads must have the same length +Each head must have a property max-key-len and max-doc-len." + (when heads-matrix + (let ((lines (hydra--hint-from-matrix-1 body heads-matrix))) + `(,@(apply #'append (hydra-interpose '("\n") lines)) + "\n")))) + +(defun hydra--hint-from-matrix-1 (body heads-matrix) + (let* ((first-heads-col (nth 0 heads-matrix)) + (last-row-index (- (length first-heads-col) 1)) + (lines nil)) + (dolist (row-index (number-sequence 0 last-row-index)) + (let ((heads-in-row (mapcar + (lambda (heads) (nth row-index heads)) + heads-matrix))) + (push (hydra--hint-row heads-in-row body) + lines))) + (nreverse lines))) + +(defun hydra-idle-message (secs hint name) + "In SECS seconds display HINT." + (cancel-timer hydra-message-timer) + (setq hydra-message-timer (timer-create)) + (timer-set-time hydra-message-timer + (timer-relative-time (current-time) secs)) + (timer-set-function + hydra-message-timer + (lambda () + (hydra-show-hint hint name) + (cancel-timer hydra-message-timer))) + (timer-activate hydra-message-timer)) + +(defun hydra-timeout (secs &optional function) + "In SECS seconds call FUNCTION, then function `hydra-keyboard-quit'. +Cancel the previous `hydra-timeout'." + (cancel-timer hydra-timeout-timer) + (setq hydra-timeout-timer (timer-create)) + (timer-set-time hydra-timeout-timer + (timer-relative-time (current-time) secs)) + (timer-set-function + hydra-timeout-timer + `(lambda () + ,(when function + `(funcall ,function)) + (hydra-keyboard-quit))) + (timer-activate hydra-timeout-timer)) + +;;* Macros +;;;###autoload +(defmacro defhydra (name body &optional docstring &rest heads) + "Create a Hydra - a family of functions with prefix NAME. + +NAME should be a symbol, it will be the prefix of all functions +defined here. + +BODY has the format: + + (BODY-MAP BODY-KEY &rest BODY-PLIST) + +DOCSTRING will be displayed in the echo area to identify the +Hydra. When DOCSTRING starts with a newline, special Ruby-style +substitution will be performed by `hydra--format'. + +Functions are created on basis of HEADS, each of which has the +format: + + (KEY CMD &optional HINT &rest PLIST) + +BODY-MAP is a keymap; `global-map' is used quite often. Each +function generated from HEADS will be bound in BODY-MAP to +BODY-KEY + KEY (both are strings passed to `kbd'), and will set +the transient map so that all following heads can be called +though KEY only. BODY-KEY can be an empty string. + +CMD is a callable expression: either an interactive function +name, or an interactive lambda, or a single sexp (it will be +wrapped in an interactive lambda). + +HINT is a short string that identifies its head. It will be +printed beside KEY in the echo erea if `hydra-is-helpful' is not +nil. If you don't even want the KEY to be printed, set HINT +explicitly to nil. + +The heads inherit their PLIST from BODY-PLIST and are allowed to +override some keys. The keys recognized are :exit, :bind, and :column. +:exit can be: + +- nil (default): this head will continue the Hydra state. +- t: this head will stop the Hydra state. + +:bind can be: +- nil: this head will not be bound in BODY-MAP. +- a lambda taking KEY and CMD used to bind a head. + +:column is a string that sets the column for all subsequent heads. + +It is possible to omit both BODY-MAP and BODY-KEY if you don't +want to bind anything. In that case, typically you will bind the +generated NAME/body command. This command is also the return +result of `defhydra'." + (declare (indent defun) (doc-string 3)) + (setq heads (copy-tree heads)) + (cond ((stringp docstring)) + ((and (consp docstring) + (memq (car docstring) '(hydra--table concat format))) + (setq docstring (concat "\n" (eval docstring)))) + (t + (setq heads (cons docstring heads)) + (setq docstring ""))) + (when (keywordp (car body)) + (setq body (cons nil (cons nil body)))) + (setq body (hydra--normalize-body body)) + (condition-case-unless-debug err + (let* ((keymap-name (intern (format "%S/keymap" name))) + (body-name (intern (format "%S/body" name))) + (body-key (cadr body)) + (body-plist (cddr body)) + (base-map (or (eval (plist-get body-plist :base-map)) + hydra-base-map)) + (keymap (copy-keymap base-map)) + (body-map (or (car body) + (plist-get body-plist :bind))) + (body-pre (plist-get body-plist :pre)) + (body-body-pre (plist-get body-plist :body-pre)) + (body-before-exit (or (plist-get body-plist :post) + (plist-get body-plist :before-exit))) + (body-after-exit (plist-get body-plist :after-exit)) + (body-inherit (plist-get body-plist :inherit)) + (body-foreign-keys (hydra--body-foreign-keys body)) + (body-exit (hydra--body-exit body))) + (dolist (base body-inherit) + (setq heads (append heads (copy-sequence (eval base))))) + (dolist (h heads) + (let ((len (length h))) + (cond ((< len 2) + (error "Each head should have at least two items: %S" h)) + ((= len 2) + (setcdr (cdr h) + (list + (hydra-plist-get-default + body-plist :hint hydra-default-hint))) + (setcdr (nthcdr 2 h) (list :exit body-exit))) + (t + (let ((hint (cl-caddr h))) + (unless (or (null hint) + (stringp hint) + (consp hint)) + (let ((inherited-hint + (hydra-plist-get-default + body-plist :hint hydra-default-hint))) + (setcdr (cdr h) (cons + (if (eq 'none inherited-hint) + nil + inherited-hint) + (cddr h)))))) + (let ((hint-and-plist (cddr h))) + (if (null (cdr hint-and-plist)) + (setcdr hint-and-plist (list :exit body-exit)) + (let* ((plist (cl-cdddr h)) + (h-color (plist-get plist :color))) + (if h-color + (progn + (plist-put plist :exit + (cl-case h-color + ((blue teal) t) + (t nil))) + (cl-remf (cl-cdddr h) :color)) + (let ((h-exit (hydra-plist-get-default plist :exit 'default))) + (plist-put plist :exit + (if (eq h-exit 'default) + body-exit + h-exit)))))))))) + (plist-put (cl-cdddr h) :cmd-name (hydra--head-name h name)) + (when (null (cadr h)) (plist-put (cl-cdddr h) :exit t))) + (let ((doc (hydra--doc body-key body-name heads)) + (heads-nodup (hydra--delete-duplicates heads))) + (mapc + (lambda (x) + (define-key keymap (kbd (car x)) + (plist-get (cl-cdddr x) :cmd-name))) + heads) + (hydra--make-funcall body-pre) + (hydra--make-funcall body-body-pre) + (hydra--make-funcall body-before-exit) + (hydra--make-funcall body-after-exit) + (when (memq body-foreign-keys '(run warn)) + (unless (cl-some + (lambda (h) + (hydra--head-property h :exit)) + heads) + (error + "An %S Hydra must have at least one blue head in order to exit" + body-foreign-keys))) + `(progn + (set (defvar ,(intern (format "%S/params" name)) + nil + ,(format "Params of %S." name)) + ',body) + (set (defvar ,(intern (format "%S/docstring" name)) + nil + ,(format "Docstring of %S." name)) + ,docstring) + (set (defvar ,(intern (format "%S/heads" name)) + nil + ,(format "Heads for %S." name)) + ',(mapcar (lambda (h) + (let ((j (copy-sequence h))) + (cl-remf (cl-cdddr j) :cmd-name) + j)) + heads)) + ;; create keymap + (set (defvar ,keymap-name + nil + ,(format "Keymap for %S." name)) + ',keymap) + ;; declare heads + (set + (defvar ,(intern (format "%S/hint" name)) nil + ,(format "Dynamic hint for %S." name)) + ',(hydra--format name body docstring heads)) + ;; create defuns + ,@(mapcar + (lambda (head) + (hydra--make-defun name body doc head keymap-name + body-pre + body-before-exit + body-after-exit)) + heads-nodup) + ;; free up keymap prefix + ,@(unless (or (null body-key) + (null body-map) + (hydra--callablep body-map)) + `((unless (keymapp (lookup-key ,body-map (kbd ,body-key))) + (define-key ,body-map (kbd ,body-key) nil)))) + ;; bind keys + ,@(delq nil + (mapcar + (lambda (head) + (let ((name (hydra--head-property head :cmd-name))) + (when (and (cadr head) + (or body-key body-map)) + (let ((bind (hydra--head-property head :bind body-map)) + (final-key + (if body-key + (vconcat (kbd body-key) (kbd (car head))) + (kbd (car head))))) + (cond ((null bind) nil) + ((hydra--callablep bind) + `(funcall ,bind ,final-key (function ,name))) + ((and (symbolp bind) + (if (boundp bind) + (keymapp (symbol-value bind)) + t)) + `(define-key ,bind ,final-key (quote ,name))) + (t + (error "Invalid :bind property `%S' for head %S" bind head))))))) + heads)) + ,(hydra--make-defun + name body doc '(nil body) + keymap-name + (or body-body-pre body-pre) body-before-exit + '(setq prefix-arg current-prefix-arg))))) + (error + (hydra--complain "Error in defhydra %S: %s" name (cdr err)) + nil))) + +(defmacro defhydra+ (name body &optional docstring &rest heads) + "Redefine an existing hydra by adding new heads. +Arguments are same as of `defhydra'." + (declare (indent defun) (doc-string 3)) + (unless (stringp docstring) + (setq heads + (cons docstring heads)) + (setq docstring nil)) + `(defhydra ,name ,(or body (hydra--prop name "/params")) + ,(or docstring (hydra--prop name "/docstring")) + ,@(cl-delete-duplicates + (append (hydra--prop name "/heads") heads) + :key #'car + :test #'equal))) + +(defun hydra--prop (name prop-name) + (symbol-value (intern (concat (symbol-name name) prop-name)))) + +(defmacro defhydradio (name _body &rest heads) + "Create radios with prefix NAME. +_BODY specifies the options; there are none currently. +HEADS have the format: + + (TOGGLE-NAME &optional VALUE DOC) + +TOGGLE-NAME will be used along with NAME to generate a variable +name and a function that cycles it with the same name. VALUE +should be an array. The first element of VALUE will be used to +inialize the variable. +VALUE defaults to [nil t]. +DOC defaults to TOGGLE-NAME split and capitalized." + (declare (indent defun)) + `(progn + ,@(apply #'append + (mapcar (lambda (h) + (hydra--radio name h)) + heads)) + (defvar ,(intern (format "%S/names" name)) + ',(mapcar (lambda (h) (intern (format "%S/%S" name (car h)))) + heads)))) + +(defun hydra--radio (parent head) + "Generate a hydradio with PARENT from HEAD." + (let* ((name (car head)) + (full-name (intern (format "%S/%S" parent name))) + (doc (cadr head)) + (val (or (cl-caddr head) [nil t]))) + `((defvar ,full-name ,(hydra--quote-maybe (aref val 0)) ,doc) + (put ',full-name 'range ,val) + (defun ,full-name () + (hydra--cycle-radio ',full-name))))) + +(defun hydra--quote-maybe (x) + "Quote X if it's a symbol." + (cond ((null x) + nil) + ((symbolp x) + (list 'quote x)) + (t + x))) + +(defun hydra--cycle-radio (sym) + "Set SYM to the next value in its range." + (let* ((val (symbol-value sym)) + (range (get sym 'range)) + (i 0) + (l (length range))) + (setq i (catch 'done + (while (< i l) + (if (equal (aref range i) val) + (throw 'done (1+ i)) + (cl-incf i))) + (error "Val not in range for %S" sym))) + (set sym + (aref range + (if (>= i l) + 0 + i))))) + +(defvar hydra-pause-ring (make-ring 10) + "Ring for paused hydras.") + +(defun hydra-pause-resume () + "Quit the current hydra and save it to the stack. +If there's no active hydra, pop one from the stack and call its body. +If the stack is empty, call the last hydra's body." + (interactive) + (cond (hydra-curr-map + (ring-insert hydra-pause-ring hydra-curr-body-fn) + (hydra-keyboard-quit)) + ((zerop (ring-length hydra-pause-ring)) + (funcall hydra-curr-body-fn)) + (t + (funcall (ring-remove hydra-pause-ring 0))))) + +;; Local Variables: +;; outline-regexp: ";;\\([;*]+ [^\s\t\n]\\|###autoload\\)\\|(" +;; indent-tabs-mode: nil +;; End: + +(provide 'hydra) + +;;; hydra.el ends here diff --git a/elpa/lv-20191214.1357/lv-autoloads.el b/elpa/lv-20191214.1357/lv-autoloads.el new file mode 100644 index 0000000..61b1079 --- /dev/null +++ b/elpa/lv-20191214.1357/lv-autoloads.el @@ -0,0 +1,22 @@ +;;; lv-autoloads.el --- automatically extracted autoloads +;; +;;; Code: + +(add-to-list 'load-path (directory-file-name + (or (file-name-directory #$) (car load-path)))) + + +;;;### (autoloads nil "lv" "lv.el" (0 0 0 0)) +;;; Generated autoloads from lv.el + +(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "lv" '("lv-"))) + +;;;*** + +;; Local Variables: +;; version-control: never +;; no-byte-compile: t +;; no-update-autoloads: t +;; coding: utf-8 +;; End: +;;; lv-autoloads.el ends here diff --git a/elpa/lv-20191214.1357/lv-pkg.el b/elpa/lv-20191214.1357/lv-pkg.el new file mode 100644 index 0000000..3d746c6 --- /dev/null +++ b/elpa/lv-20191214.1357/lv-pkg.el @@ -0,0 +1,2 @@ +;;; -*- no-byte-compile: t -*- +(define-package "lv" "20191214.1357" "Other echo area" 'nil :commit "9db28034d7d61bfeff89899633b958f22befc53d" :authors '(("Oleh Krehel")) :maintainer '("Oleh Krehel")) diff --git a/elpa/lv-20191214.1357/lv.el b/elpa/lv-20191214.1357/lv.el new file mode 100644 index 0000000..879fd61 --- /dev/null +++ b/elpa/lv-20191214.1357/lv.el @@ -0,0 +1,145 @@ +;;; lv.el --- Other echo area +;; Package-Version: 20191214.1357 + +;; Copyright (C) 2015 Free Software Foundation, Inc. + +;; Author: Oleh Krehel + +;; This file is part of GNU Emacs. + +;; GNU Emacs 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. + +;; GNU Emacs 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 GNU Emacs. If not, see . + +;;; Commentary: +;; +;; This package provides `lv-message' intended to be used in place of +;; `message' when semi-permanent hints are needed, in order to not +;; interfere with Echo Area. +;; +;; "Я тихо-тихо пiдглядаю, +;; І тiшуся собi, як бачу то, +;; Шо страшить i не пiдпускає, +;; А iншi п’ють тебе, як воду пiсок." +;; -- Андрій Кузьменко, L.V. + +;;; Code: + +(defgroup lv nil + "The other echo area." + :group 'minibuffer + :group 'hydra) + +(defcustom lv-use-separator nil + "Whether to draw a line between the LV window and the Echo Area." + :group 'lv + :type 'boolean) + +(defcustom lv-use-padding nil + "Whether to use horizontal padding in the LV window." + :group 'lv + :type 'boolean) + +(defface lv-separator + '((((class color) (background light)) :background "grey80") + (((class color) (background dark)) :background "grey30")) + "Face used to draw line between the lv window and the echo area. +This is only used if option `lv-use-separator' is non-nil. +Only the background color is significant." + :group 'lv) + +(defvar lv-wnd nil + "Holds the current LV window.") + +(defvar display-line-numbers) +(defvar display-fill-column-indicator) +(defvar tab-line-format) + +(defvar lv-window-hook nil + "Hook to run by `lv-window' when a new window is created.") + +(defun lv-window () + "Ensure that LV window is live and return it." + (if (window-live-p lv-wnd) + lv-wnd + (let ((ori (selected-window)) + buf) + (prog1 (setq lv-wnd + (select-window + (let ((ignore-window-parameters t)) + (split-window + (frame-root-window) -1 'below)))) + (if (setq buf (get-buffer " *LV*")) + (switch-to-buffer buf) + (switch-to-buffer " *LV*") + (set-window-hscroll lv-wnd 0) + (setq window-size-fixed t) + (setq mode-line-format nil) + (setq header-line-format nil) + (setq tab-line-format nil) + (setq cursor-type nil) + (setq display-line-numbers nil) + (setq display-fill-column-indicator nil) + (set-window-dedicated-p lv-wnd t) + (set-window-parameter lv-wnd 'no-other-window t) + (run-hooks 'lv-window-hook)) + (select-window ori))))) + +(defvar golden-ratio-mode) + +(defvar lv-force-update nil + "When non-nil, `lv-message' will refresh even for the same string.") + +(defun lv--pad-to-center (str width) + "Pad STR with spaces on the left to be centered to WIDTH." + (let* ((strs (split-string str "\n")) + (padding (make-string + (/ (- width (length (car strs))) 2) + ?\ ))) + (mapconcat (lambda (s) (concat padding s)) strs "\n"))) + +(defun lv-message (format-string &rest args) + "Set LV window contents to (`format' FORMAT-STRING ARGS)." + (let* ((str (apply #'format format-string args)) + (n-lines (cl-count ?\n str)) + deactivate-mark + golden-ratio-mode) + (with-selected-window (lv-window) + (when lv-use-padding + (setq str (lv--pad-to-center str (window-width)))) + (unless (and (string= (buffer-string) str) + (null lv-force-update)) + (delete-region (point-min) (point-max)) + (insert str) + (when (and (window-system) lv-use-separator) + (unless (looking-back "\n" nil) + (insert "\n")) + (insert + (propertize "__" 'face 'lv-separator 'display '(space :height (1))) + (propertize "\n" 'face 'lv-separator 'line-height t))) + (set (make-local-variable 'window-min-height) n-lines) + (setq truncate-lines (> n-lines 1)) + (let ((window-resize-pixelwise t) + (window-size-fixed nil)) + (fit-window-to-buffer nil nil 1))) + (goto-char (point-min))))) + +(defun lv-delete-window () + "Delete LV window and kill its buffer." + (when (window-live-p lv-wnd) + (let ((buf (window-buffer lv-wnd))) + (delete-window lv-wnd) + (kill-buffer buf)))) + +(provide 'lv) + +;;; lv.el ends here diff --git a/elpa/multiple-cursors-20191210.1759/mc-cycle-cursors.el b/elpa/multiple-cursors-20191210.1759/mc-cycle-cursors.el new file mode 100644 index 0000000..85af352 --- /dev/null +++ b/elpa/multiple-cursors-20191210.1759/mc-cycle-cursors.el @@ -0,0 +1,119 @@ +;;; mc-cycle-cursors.el + +;; Copyright (C) 2012-2016 Magnar Sveen + +;; Author: Magnar Sveen +;; Keywords: editing cursors + +;; 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 scrolls the buffer to center each cursor in turn. +;; Scroll down with C-v, scroll up with M-v +;; This is nice when you have cursors that's outside of your view. + +;;; Code: + +(require 'multiple-cursors-core) + +(defun mc/next-fake-cursor-after-point () + (let ((pos (point)) + (next-pos (1+ (point-max))) + next) + (mc/for-each-fake-cursor + (let ((cursor-pos (overlay-get cursor 'point))) + (when (and (< pos cursor-pos) + (< cursor-pos next-pos)) + (setq next-pos cursor-pos) + (setq next cursor)))) + next)) + +(defun mc/prev-fake-cursor-before-point () + (let ((pos (point)) + (prev-pos (1- (point-min))) + prev) + (mc/for-each-fake-cursor + (let ((cursor-pos (overlay-get cursor 'point))) + (when (and (> pos cursor-pos) + (> cursor-pos prev-pos)) + (setq prev-pos cursor-pos) + (setq prev cursor)))) + prev)) + +(defcustom mc/cycle-looping-behaviour 'continue + "What to do if asked to cycle beyond the last cursor or before the first cursor." + :type '(radio (const :tag "Loop around to beginning/end of document." continue) + (const :tag "Warn and then loop around." warn) + (const :tag "Signal an error." error) + (const :tag "Don't loop." stop)) + :group 'multiple-cursors) + +(defun mc/handle-loop-condition (error-message) + (cl-ecase mc/cycle-looping-behaviour + (error (error error-message)) + (warn (message error-message)) + (continue 'continue) + (stop 'stop))) + +(defun mc/first-fake-cursor-after (point) + "Very similar to mc/furthest-cursor-before-point, but ignores (mark) and (point)." + (let* ((cursors (mc/all-fake-cursors)) + (cursors-after-point (cl-remove-if (lambda (cursor) + (< (mc/cursor-beg cursor) point)) + cursors)) + (cursors-in-order (cl-sort cursors-after-point '< :key 'mc/cursor-beg))) + (car cursors-in-order))) + +(defun mc/last-fake-cursor-before (point) + "Very similar to mc/furthest-cursor-before-point, but ignores (mark) and (point)." + (let* ((cursors (mc/all-fake-cursors)) + (cursors-before-point (cl-remove-if (lambda (cursor) + (> (mc/cursor-end cursor) point)) + cursors)) + (cursors-in-order (cl-sort cursors-before-point '> :key 'mc/cursor-end))) + (car cursors-in-order))) + +(cl-defun mc/cycle (next-cursor fallback-cursor loop-message) + (when (null next-cursor) + (when (eql 'stop (mc/handle-loop-condition loop-message)) + (return-from mc/cycle nil)) + (setf next-cursor fallback-cursor)) + (mc/create-fake-cursor-at-point) + (mc/pop-state-from-overlay next-cursor) + (recenter)) + +(defun mc/cycle-forward () + (interactive) + (mc/cycle (mc/next-fake-cursor-after-point) + (mc/first-fake-cursor-after (point-min)) + "We're already at the last cursor.")) + +(defun mc/cycle-backward () + (interactive) + (mc/cycle (mc/prev-fake-cursor-before-point) + (mc/last-fake-cursor-before (point-max)) + "We're already at the last cursor")) + +(define-key mc/keymap (kbd "C-v") 'mc/cycle-forward) +(define-key mc/keymap (kbd "M-v") 'mc/cycle-backward) + +(provide 'mc-cycle-cursors) + + +;; Local Variables: +;; coding: utf-8 +;; End: + +;;; mc-cycle-cursors.el ends here diff --git a/elpa/multiple-cursors-20191210.1759/mc-edit-lines.el b/elpa/multiple-cursors-20191210.1759/mc-edit-lines.el new file mode 100644 index 0000000..55772af --- /dev/null +++ b/elpa/multiple-cursors-20191210.1759/mc-edit-lines.el @@ -0,0 +1,110 @@ +;;; mc-edit-lines.el + +;; Copyright (C) 2012-2016 Magnar Sveen + +;; Author: Magnar Sveen +;; Keywords: editing cursors + +;; 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 file contains functions to add multiple cursors to consecutive lines +;; given an active region. + +;; Please see multiple-cursors.el for more commentary. + +;;; Code: + +(require 'multiple-cursors-core) + +(defcustom mc/edit-lines-empty-lines nil + "What should be done by `mc/edit-lines' when a line is not long enough." + :type '(radio (const :tag "Pad the line with spaces." pad) + (const :tag "Ignore the line." ignore) + (const :tag "Signal an error." error) + (const :tag "Nothing. Cursor is at end of line." nil)) + :group 'multiple-cursors) + +;;;###autoload +(defun mc/edit-lines (&optional arg) + "Add one cursor to each line of the active region. +Starts from mark and moves in straight down or up towards the +line point is on. + +What is done with lines which are not long enough is governed by +`mc/edit-lines-empty-lines'. The prefix argument ARG can be used +to override this. If ARG is a symbol (when called from Lisp), +that symbol is used instead of `mc/edit-lines-empty-lines'. +Otherwise, if ARG negative, short lines will be ignored. Any +other non-nil value will cause short lines to be padded." + (interactive "P") + (when (not (and mark-active (/= (point) (mark)))) + (error "Mark a set of lines first")) + (mc/remove-fake-cursors) + (let* ((col (current-column)) + (point-line (mc/line-number-at-pos)) + (mark-line (progn (exchange-point-and-mark) (mc/line-number-at-pos))) + (direction (if (< point-line mark-line) :up :down)) + (style (cond + ;; called from lisp + ((and arg (symbolp arg)) + arg) + ;; negative argument + ((< (prefix-numeric-value arg) 0) + 'ignore) + (arg 'pad) + (t mc/edit-lines-empty-lines)))) + (deactivate-mark) + (when (and (eq direction :up) (bolp)) + (previous-logical-line 1 nil) + (move-to-column col)) + ;; Add the cursors + (while (not (eq (mc/line-number-at-pos) point-line)) + ;; Pad the line + (when (eq style 'pad) + (while (< (current-column) col) + (insert " "))) + ;; Error + (when (and (eq style 'error) + (not (equal col (current-column)))) + (error "Short line encountered in `mc/edit-lines'")) + ;; create the cursor + (unless (and (eq style 'ignore) + (not (equal col (current-column)))) + (mc/create-fake-cursor-at-point)) + ;; proceed to next + (if (eq direction :up) + (previous-logical-line 1 nil) + (next-logical-line 1 nil)) + (move-to-column col)) + (multiple-cursors-mode))) + +;;;###autoload +(defun mc/edit-ends-of-lines () + "Add one cursor to the end of each line in the active region." + (interactive) + (mc/edit-lines) + (mc/execute-command-for-all-cursors 'end-of-line)) + +;;;###autoload +(defun mc/edit-beginnings-of-lines () + "Add one cursor to the beginning of each line in the active region." + (interactive) + (mc/edit-lines) + (mc/execute-command-for-all-cursors 'beginning-of-line)) + +(provide 'mc-edit-lines) + +;;; mc-edit-lines.el ends here diff --git a/elpa/multiple-cursors-20191210.1759/mc-hide-unmatched-lines-mode.el b/elpa/multiple-cursors-20191210.1759/mc-hide-unmatched-lines-mode.el new file mode 100644 index 0000000..0167dbc --- /dev/null +++ b/elpa/multiple-cursors-20191210.1759/mc-hide-unmatched-lines-mode.el @@ -0,0 +1,107 @@ +;;; mc-hide-unmatched-lines.el + +;; Copyright (C) 2014 Aleksey Fedotov + +;; Author: Aleksey Fedotov +;; Keywords: editing cursors + +;; 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 minor mode when enabled hides all lines where no cursors (and +;; also hum/lines-to-expand below and above) To make use of this mode +;; press "C-'" while multiple-cursor-mode is active. You can still +;; edit lines while you are in mc-hide-unmatched-lines mode. To leave +;; this mode press "" or "C-g" +;; + +;;; Code: + +(require 'multiple-cursors-core) +(require 'mc-mark-more) + +(defvar hum/hide-unmatched-lines-mode-map (make-sparse-keymap) + "Keymap for hide unmatched lines is mainly for rebinding C-g") + +(define-key hum/hide-unmatched-lines-mode-map (kbd "C-g") 'hum/keyboard-quit) +(define-key hum/hide-unmatched-lines-mode-map (kbd "") 'hum/keyboard-quit) + +(defun hum/keyboard-quit () + "Leave hide-unmatched-lines mode" + (interactive) + (mc-hide-unmatched-lines-mode 0)) + +;; used only in in multiple-cursors-mode-disabled-hook +(defun hum/disable-hum-mode () + (mc-hide-unmatched-lines-mode 0)) + +;;;###autoload +(define-minor-mode mc-hide-unmatched-lines-mode + "Minor mode when enabled hides all lines where no cursors (and +also hum/lines-to-expand below and above) To make use of this +mode press \"C-'\" while multiple-cursor-mode is active. You can +still edit lines while you are in mc-hide-unmatched-lines +mode. To leave this mode press or \"C-g\"" + nil " hu" + hum/hide-unmatched-lines-mode-map + (if mc-hide-unmatched-lines-mode + ;;just in case if mc mode will be disabled while hide-unmatched-lines is active + (progn + (hum/hide-unmatched-lines) + (add-hook 'multiple-cursors-mode-disabled-hook 'hum/disable-hum-mode t t)) + (progn + (hum/unhide-unmatched-lines) + (remove-hook 'multiple-cursors-mode-disabled-hook 'hum/disable-hum-mode)))) + +(defconst hum/invisible-overlay-name 'hum/invisible-overlay-name) + +(defcustom hum/lines-to-expand 2 + "How many lines below and above cursor to show" + :type '(integer) + :group 'multiple-cursors) + +(defcustom hum/placeholder "..." + "Placeholder which will be placed instead of hidden text" + :type '(string) + :group 'multiple-cursors) + +(defun hum/add-invisible-overlay (begin end) + (let ((overlay (make-overlay begin + end + (current-buffer) + t + nil + ))) + (overlay-put overlay hum/invisible-overlay-name t) + (overlay-put overlay 'invisible t) + (overlay-put overlay 'intangible t) + (overlay-put overlay 'evaporate t) + (overlay-put overlay 'after-string hum/placeholder))) + +(defun hum/hide-unmatched-lines () + (let ((begin (point-min))) + (mc/for-each-cursor-ordered + (save-excursion + (goto-char (mc/cursor-beg cursor)) + (if (< begin (line-beginning-position (- hum/lines-to-expand))) + (hum/add-invisible-overlay begin (line-end-position (- hum/lines-to-expand)))) + (setq begin (line-beginning-position (+ 2 hum/lines-to-expand))))) + (hum/add-invisible-overlay begin (point-max)))) + +(defun hum/unhide-unmatched-lines () + (remove-overlays nil nil hum/invisible-overlay-name t)) + +(provide 'mc-hide-unmatched-lines-mode) +(define-key mc/keymap (kbd "C-'") 'mc-hide-unmatched-lines-mode) diff --git a/elpa/multiple-cursors-20191210.1759/mc-mark-more.el b/elpa/multiple-cursors-20191210.1759/mc-mark-more.el new file mode 100644 index 0000000..2e63130 --- /dev/null +++ b/elpa/multiple-cursors-20191210.1759/mc-mark-more.el @@ -0,0 +1,709 @@ +;;; mc-mark-more.el + +;; Copyright (C) 2012-2016 Magnar Sveen + +;; Author: Magnar Sveen +;; Keywords: editing cursors + +;; 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 file contains functions to mark more parts of the buffer. +;; See ./features/mark-more.feature for examples. + +;; Please see multiple-cursors.el for more commentary. + +;;; Code: + +(require 'multiple-cursors-core) +(require 'thingatpt) + +(defun mc/cursor-end (cursor) + (if (overlay-get cursor 'mark-active) + (max (overlay-get cursor 'point) + (overlay-get cursor 'mark)) + (overlay-get cursor 'point))) + +(defun mc/cursor-beg (cursor) + (if (overlay-get cursor 'mark-active) + (min (overlay-get cursor 'point) + (overlay-get cursor 'mark)) + (overlay-get cursor 'point))) + +(defun mc/furthest-region-end () + (let ((end (max (mark) (point)))) + (mc/for-each-fake-cursor + (setq end (max end (mc/cursor-end cursor)))) + end)) + +(defun mc/first-region-start () + (let ((beg (min (mark) (point)))) + (mc/for-each-fake-cursor + (setq beg (min beg (mc/cursor-beg cursor)))) + beg)) + +(defun mc/furthest-cursor-before-point () + (let ((beg (if mark-active (min (mark) (point)) (point))) + furthest) + (mc/for-each-fake-cursor + (when (< (mc/cursor-beg cursor) beg) + (setq beg (mc/cursor-beg cursor)) + (setq furthest cursor))) + furthest)) + +(defun mc/furthest-cursor-after-point () + (let ((end (if mark-active (max (mark) (point)) (point))) + furthest) + (mc/for-each-fake-cursor + (when (> (mc/cursor-end cursor) end) + (setq end (mc/cursor-end cursor)) + (setq furthest cursor))) + furthest)) + +(defun mc/fake-cursor-at-point (&optional point) + "Return the fake cursor with its point right at POINT (defaults +to (point)), or nil." + (setq point (or point (point))) + (let ((cursors (mc/all-fake-cursors)) + (c nil)) + (catch 'found + (while (setq c (pop cursors)) + (when (eq (marker-position (overlay-get c 'point)) + point) + (throw 'found c)))))) + +(defun mc/region-strings () + (let ((strings (list (buffer-substring-no-properties (point) (mark))))) + (mc/for-each-fake-cursor + (add-to-list 'strings (buffer-substring-no-properties + (mc/cursor-beg cursor) + (mc/cursor-end cursor)))) + strings)) + +(defvar mc/enclose-search-term nil + "How should mc/mark-more-* search for more matches? + +Match everything: nil +Match only whole words: 'words +Match only whole symbols: 'symbols + +Use like case-fold-search, don't recommend setting it globally.") + +(defun mc/mark-more-like-this (skip-last direction) + (let ((case-fold-search nil) + (re (regexp-opt (mc/region-strings) mc/enclose-search-term)) + (point-out-of-order (cl-ecase direction + (forwards (< (point) (mark))) + (backwards (not (< (point) (mark)))))) + (furthest-cursor (cl-ecase direction + (forwards (mc/furthest-cursor-after-point)) + (backwards (mc/furthest-cursor-before-point)))) + (start-char (cl-ecase direction + (forwards (mc/furthest-region-end)) + (backwards (mc/first-region-start)))) + (search-function (cl-ecase direction + (forwards 'search-forward-regexp) + (backwards 'search-backward-regexp))) + (match-point-getter (cl-ecase direction + (forwards 'match-beginning) + (backwards 'match-end)))) + (if (and skip-last (not furthest-cursor)) + (error "No cursors to be skipped") + (mc/save-excursion + (goto-char start-char) + (when skip-last + (mc/remove-fake-cursor furthest-cursor)) + (if (funcall search-function re nil t) + (progn + (push-mark (funcall match-point-getter 0)) + (when point-out-of-order + (exchange-point-and-mark)) + (mc/create-fake-cursor-at-point)) + (user-error "no more matches found.")))))) + +;;;###autoload +(defun mc/mark-next-like-this (arg) + "Find and mark the next part of the buffer matching the currently active region +If no region is active add a cursor on the next line +With negative ARG, delete the last one instead. +With zero ARG, skip the last one and mark next." + (interactive "p") + (if (< arg 0) + (let ((cursor (mc/furthest-cursor-after-point))) + (if cursor + (mc/remove-fake-cursor cursor) + (error "No cursors to be unmarked"))) + (if (region-active-p) + (mc/mark-more-like-this (= arg 0) 'forwards) + (mc/mark-lines arg 'forwards))) + (mc/maybe-multiple-cursors-mode)) + +;;;###autoload +(defun mc/mark-next-like-this-word (arg) + "Find and mark the next part of the buffer matching the currently active region +If no region is active, mark the word at the point and find the next match +With negative ARG, delete the last one instead. +With zero ARG, skip the last one and mark next." + (interactive "p") + (if (< arg 0) + (let ((cursor (mc/furthest-cursor-after-point))) + (if cursor + (mc/remove-fake-cursor cursor) + (error "No cursors to be unmarked"))) + (if (region-active-p) + (mc/mark-more-like-this (= arg 0) 'forwards) + (mc--select-thing-at-point 'word) + (mc/mark-more-like-this (= arg 0) 'forwards))) + (mc/maybe-multiple-cursors-mode)) + +(defun mc/mark-next-like-this-symbol (arg) + "Find and mark the next part of the buffer matching the currently active region +If no region is active, mark the symbol at the point and find the next match +With negative ARG, delete the last one instead. +With zero ARG, skip the last one and mark next." + (interactive "p") + (if (< arg 0) + (let ((cursor (mc/furthest-cursor-after-point))) + (if cursor + (mc/remove-fake-cursor cursor) + (error "No cursors to be unmarked"))) + (if (region-active-p) + (mc/mark-more-like-this (= arg 0) 'forwards) + (mc--select-thing-at-point 'symbol) + (mc/mark-more-like-this (= arg 0) 'forwards))) + (mc/maybe-multiple-cursors-mode)) + + +;;;###autoload +(defun mc/mark-next-word-like-this (arg) + "Find and mark the next word of the buffer matching the currently active region +The matching region must be a whole word to be a match +If no region is active, mark the symbol at the point and find the next match +With negative ARG, delete the last one instead. +With zero ARG, skip the last one and mark next." + (interactive "p") + (let ((mc/enclose-search-term 'words)) + (mc/mark-next-like-this arg))) + +;;;###autoload +(defun mc/mark-next-symbol-like-this (arg) + "Find and mark the next symbol of the buffer matching the currently active region +The matching region must be a whole symbol to be a match +If no region is active, mark the symbol at the point and find the next match +With negative ARG, delete the last one instead. +With zero ARG, skip the last one and mark next." + (interactive "p") + (let ((mc/enclose-search-term 'symbols)) + (mc/mark-next-like-this arg))) + +;;;###autoload +(defun mc/mark-previous-like-this (arg) + "Find and mark the previous part of the buffer matching the currently active region +If no region is active add a cursor on the previous line +With negative ARG, delete the last one instead. +With zero ARG, skip the last one and mark next." + (interactive "p") + (if (< arg 0) + (let ((cursor (mc/furthest-cursor-before-point))) + (if cursor + (mc/remove-fake-cursor cursor) + (error "No cursors to be unmarked"))) + (if (region-active-p) + (mc/mark-more-like-this (= arg 0) 'backwards) + (mc/mark-lines arg 'backwards))) + (mc/maybe-multiple-cursors-mode)) + +;;;###autoload +(defun mc/mark-previous-like-this-word (arg) + "Find and mark the previous part of the buffer matching the currently active region +If no region is active, mark the word at the point and find the previous match +With negative ARG, delete the last one instead. +With zero ARG, skip the last one and mark previous." + (interactive "p") + (if (< arg 0) + (let ((cursor (mc/furthest-cursor-after-point))) + (if cursor + (mc/remove-fake-cursor cursor) + (error "No cursors to be unmarked"))) + (if (region-active-p) + (mc/mark-more-like-this (= arg 0) 'backwards) + (mc--select-thing-at-point 'word) + (mc/mark-more-like-this (= arg 0) 'backwards))) + (mc/maybe-multiple-cursors-mode)) + +(defun mc/mark-previous-like-this-symbol (arg) + "Find and mark the previous part of the buffer matching the currently active region +If no region is active, mark the symbol at the point and find the previous match +With negative ARG, delete the last one instead. +With zero ARG, skip the last one and mark previous." + (interactive "p") + (if (< arg 0) + (let ((cursor (mc/furthest-cursor-after-point))) + (if cursor + (mc/remove-fake-cursor cursor) + (error "No cursors to be unmarked"))) + (if (region-active-p) + (mc/mark-more-like-this (= arg 0) 'backwards) + (mc--select-thing-at-point 'symbol) + (mc/mark-more-like-this (= arg 0) 'backwards))) + (mc/maybe-multiple-cursors-mode)) + + +;;;###autoload +(defun mc/mark-previous-word-like-this (arg) + "Find and mark the previous part of the buffer matching the currently active region +The matching region must be a whole word to be a match +If no region is active add a cursor on the previous line +With negative ARG, delete the last one instead. +With zero ARG, skip the last one and mark next." + (interactive "p") + (let ((mc/enclose-search-term 'words)) + (mc/mark-previous-like-this arg))) + +;;;###autoload +(defun mc/mark-previous-symbol-like-this (arg) + "Find and mark the previous part of the buffer matching the currently active region +The matching region must be a whole symbol to be a match +If no region is active add a cursor on the previous line +With negative ARG, delete the last one instead. +With zero ARG, skip the last one and mark next." + (interactive "p") + (let ((mc/enclose-search-term 'symbols)) + (mc/mark-previous-like-this arg))) + +(defun mc/mark-lines (num-lines direction) + (dotimes (i (if (= num-lines 0) 1 num-lines)) + (mc/save-excursion + (let ((furthest-cursor (cl-ecase direction + (forwards (mc/furthest-cursor-after-point)) + (backwards (mc/furthest-cursor-before-point))))) + (when (overlayp furthest-cursor) + (goto-char (overlay-get furthest-cursor 'point)) + (when (= num-lines 0) + (mc/remove-fake-cursor furthest-cursor)))) + (cl-ecase direction + (forwards (next-logical-line 1 nil)) + (backwards (previous-logical-line 1 nil))) + (mc/create-fake-cursor-at-point)))) + +;;;###autoload +(defun mc/mark-next-lines (arg) + (interactive "p") + (mc/mark-lines arg 'forwards) + (mc/maybe-multiple-cursors-mode)) + +;;;###autoload +(defun mc/mark-previous-lines (arg) + (interactive "p") + (mc/mark-lines arg 'backwards) + (mc/maybe-multiple-cursors-mode)) + +;;;###autoload +(defun mc/unmark-next-like-this () + "Deselect next part of the buffer matching the currently active region." + (interactive) + (mc/mark-next-like-this -1)) + +;;;###autoload +(defun mc/unmark-previous-like-this () + "Deselect prev part of the buffer matching the currently active region." + (interactive) + (mc/mark-previous-like-this -1)) + +;;;###autoload +(defun mc/skip-to-next-like-this () + "Skip the current one and select the next part of the buffer matching the currently active region." + (interactive) + (mc/mark-next-like-this 0)) + +;;;###autoload +(defun mc/skip-to-previous-like-this () + "Skip the current one and select the prev part of the buffer matching the currently active region." + (interactive) + (mc/mark-previous-like-this 0)) + +;;;###autoload +(defun mc/mark-all-like-this () + "Find and mark all the parts of the buffer matching the currently active region" + (interactive) + (unless (region-active-p) + (error "Mark a region to match first.")) + (mc/remove-fake-cursors) + (let ((master (point)) + (case-fold-search nil) + (point-first (< (point) (mark))) + (re (regexp-opt (mc/region-strings) mc/enclose-search-term))) + (mc/save-excursion + (goto-char 0) + (while (search-forward-regexp re nil t) + (push-mark (match-beginning 0)) + (when point-first (exchange-point-and-mark)) + (unless (= master (point)) + (mc/create-fake-cursor-at-point)) + (when point-first (exchange-point-and-mark))))) + (if (> (mc/num-cursors) 1) + (multiple-cursors-mode 1) + (multiple-cursors-mode 0))) + +(defun mc--select-thing-at-point (thing) + (let ((bound (bounds-of-thing-at-point thing))) + (when bound + (set-mark (car bound)) + (goto-char (cdr bound)) + bound))) + +(defun mc--select-thing-at-point-or-bark (thing) + (unless (or (region-active-p) (mc--select-thing-at-point thing)) + (error "Mark a region or set cursor on a %s." thing))) + +;;;###autoload +(defun mc/mark-all-words-like-this () + (interactive) + (mc--select-thing-at-point-or-bark 'word) + (let ((mc/enclose-search-term 'words)) + (mc/mark-all-like-this))) + +;;;###autoload +(defun mc/mark-all-symbols-like-this () + (interactive) + (mc--select-thing-at-point-or-bark 'symbol) + (let ((mc/enclose-search-term 'symbols)) + (mc/mark-all-like-this))) + +;;;###autoload +(defun mc/mark-all-in-region (beg end &optional search) + "Find and mark all the parts in the region matching the given search" + (interactive "r") + (let ((search (or search (read-from-minibuffer "Mark all in region: "))) + (case-fold-search nil)) + (if (string= search "") + (message "Mark aborted") + (progn + (mc/remove-fake-cursors) + (goto-char beg) + (while (search-forward search end t) + (push-mark (match-beginning 0)) + (mc/create-fake-cursor-at-point)) + (let ((first (mc/furthest-cursor-before-point))) + (if (not first) + (error "Search failed for %S" search) + (mc/pop-state-from-overlay first))) + (if (> (mc/num-cursors) 1) + (multiple-cursors-mode 1) + (multiple-cursors-mode 0)))))) + +;;;###autoload +(defun mc/mark-all-in-region-regexp (beg end) + "Find and mark all the parts in the region matching the given regexp." + (interactive "r") + (let ((search (read-regexp "Mark regexp in region: ")) + (case-fold-search nil)) + (if (string= search "") + (message "Mark aborted") + (progn + (mc/remove-fake-cursors) + (goto-char beg) + (let ((lastmatch)) + (while (and (< (point) end) ; can happen because of (forward-char) + (search-forward-regexp search end t)) + (push-mark (match-beginning 0)) + (mc/create-fake-cursor-at-point) + (setq lastmatch (point)) + (when (= (point) (match-beginning 0)) + (forward-char))) + (unless lastmatch + (error "Search failed for %S" search))) + (goto-char (match-end 0)) + (if (< (mc/num-cursors) 3) + (multiple-cursors-mode 0) + (mc/pop-state-from-overlay (mc/furthest-cursor-before-point)) + (multiple-cursors-mode 1)))))) + +(when (not (fboundp 'set-temporary-overlay-map)) + ;; Backport this function from newer emacs versions + (defun set-temporary-overlay-map (map &optional keep-pred) + "Set a new keymap that will only exist for a short period of time. +The new keymap to use must be given in the MAP variable. When to +remove the keymap depends on user input and KEEP-PRED: + +- if KEEP-PRED is nil (the default), the keymap disappears as + soon as any key is pressed, whether or not the key is in MAP; + +- if KEEP-PRED is t, the keymap disappears as soon as a key *not* + in MAP is pressed; + +- otherwise, KEEP-PRED must be a 0-arguments predicate that will + decide if the keymap should be removed (if predicate returns + nil) or kept (otherwise). The predicate will be called after + each key sequence." + + (let* ((clearfunsym (make-symbol "clear-temporary-overlay-map")) + (overlaysym (make-symbol "t")) + (alist (list (cons overlaysym map))) + (clearfun + `(lambda () + (unless ,(cond ((null keep-pred) nil) + ((eq t keep-pred) + `(eq this-command + (lookup-key ',map + (this-command-keys-vector)))) + (t `(funcall ',keep-pred))) + (remove-hook 'pre-command-hook ',clearfunsym) + (setq emulation-mode-map-alists + (delq ',alist emulation-mode-map-alists)))))) + (set overlaysym overlaysym) + (fset clearfunsym clearfun) + (add-hook 'pre-command-hook clearfunsym) + + (push alist emulation-mode-map-alists)))) + +;;;###autoload +(defun mc/mark-more-like-this-extended () + "Like mark-more-like-this, but then lets you adjust with arrows key. +The adjustments work like this: + + Mark previous like this and set direction to 'up + Mark next like this and set direction to 'down + +If direction is 'up: + + Skip past the cursor furthest up + Remove the cursor furthest up + +If direction is 'down: + + Remove the cursor furthest down + Skip past the cursor furthest down + +The bindings for these commands can be changed. See `mc/mark-more-like-this-extended-keymap'." + (interactive) + (mc/mmlte--down) + (set-temporary-overlay-map mc/mark-more-like-this-extended-keymap t)) + +(defvar mc/mark-more-like-this-extended-direction nil + "When using mc/mark-more-like-this-extended are we working on the next or previous cursors?") + +(make-variable-buffer-local 'mc/mark-more-like-this-extended) + +(defun mc/mmlte--message () + (if (eq mc/mark-more-like-this-extended-direction 'up) + (message " to mark previous, to skip, to remove, to mark next") + (message " to mark next, to skip, to remove, to mark previous"))) + +(defun mc/mmlte--up () + (interactive) + (mc/mark-previous-like-this 1) + (setq mc/mark-more-like-this-extended-direction 'up) + (mc/mmlte--message)) + +(defun mc/mmlte--down () + (interactive) + (mc/mark-next-like-this 1) + (setq mc/mark-more-like-this-extended-direction 'down) + (mc/mmlte--message)) + +(defun mc/mmlte--left () + (interactive) + (if (eq mc/mark-more-like-this-extended-direction 'down) + (mc/unmark-next-like-this) + (mc/skip-to-previous-like-this)) + (mc/mmlte--message)) + +(defun mc/mmlte--right () + (interactive) + (if (eq mc/mark-more-like-this-extended-direction 'up) + (mc/unmark-previous-like-this) + (mc/skip-to-next-like-this)) + (mc/mmlte--message)) + +(defvar mc/mark-more-like-this-extended-keymap (make-sparse-keymap)) + +(define-key mc/mark-more-like-this-extended-keymap (kbd "") 'mc/mmlte--up) +(define-key mc/mark-more-like-this-extended-keymap (kbd "") 'mc/mmlte--down) +(define-key mc/mark-more-like-this-extended-keymap (kbd "") 'mc/mmlte--left) +(define-key mc/mark-more-like-this-extended-keymap (kbd "") 'mc/mmlte--right) + +(defvar mc--restrict-mark-all-to-symbols nil) + +;;;###autoload +(defun mc/mark-all-like-this-dwim (arg) + "Tries to guess what you want to mark all of. +Can be pressed multiple times to increase selection. + +With prefix, it behaves the same as original `mc/mark-all-like-this'" + (interactive "P") + (if arg + (mc/mark-all-like-this) + (if (and (not (use-region-p)) + (derived-mode-p 'sgml-mode) + (mc--on-tag-name-p)) + (mc/mark-sgml-tag-pair) + (let ((before (mc/num-cursors))) + (unless (eq last-command 'mc/mark-all-like-this-dwim) + (setq mc--restrict-mark-all-to-symbols nil)) + (unless (use-region-p) + (mc--mark-symbol-at-point) + (setq mc--restrict-mark-all-to-symbols t)) + (if mc--restrict-mark-all-to-symbols + (mc/mark-all-symbols-like-this-in-defun) + (mc/mark-all-like-this-in-defun)) + (when (<= (mc/num-cursors) before) + (if mc--restrict-mark-all-to-symbols + (mc/mark-all-symbols-like-this) + (mc/mark-all-like-this))) + (when (<= (mc/num-cursors) before) + (mc/mark-all-like-this)))))) + +;;;###autoload +(defun mc/mark-all-dwim (arg) + "Tries even harder to guess what you want to mark all of. + +If the region is active and spans multiple lines, it will behave +as if `mc/mark-all-in-region'. With the prefix ARG, it will call +`mc/edit-lines' instead. + +If the region is inactive or on a single line, it will behave like +`mc/mark-all-like-this-dwim'." + (interactive "P") + (if (and (use-region-p) + (not (> (mc/num-cursors) 1)) + (not (= (mc/line-number-at-pos (region-beginning)) + (mc/line-number-at-pos (region-end))))) + (if arg + (call-interactively 'mc/edit-lines) + (call-interactively 'mc/mark-all-in-region)) + (progn + (setq this-command 'mc/mark-all-like-this-dwim) + (mc/mark-all-like-this-dwim arg)))) + +(defun mc--in-defun () + (bounds-of-thing-at-point 'defun)) + +;;;###autoload +(defun mc/mark-all-like-this-in-defun () + "Mark all like this in defun." + (interactive) + (if (mc--in-defun) + (save-restriction + (widen) + (narrow-to-defun) + (mc/mark-all-like-this)) + (mc/mark-all-like-this))) + +;;;###autoload +(defun mc/mark-all-words-like-this-in-defun () + "Mark all words like this in defun." + (interactive) + (mc--select-thing-at-point-or-bark 'word) + (if (mc--in-defun) + (save-restriction + (widen) + (narrow-to-defun) + (mc/mark-all-words-like-this)) + (mc/mark-all-words-like-this))) + +;;;###autoload +(defun mc/mark-all-symbols-like-this-in-defun () + "Mark all symbols like this in defun." + (interactive) + (mc--select-thing-at-point-or-bark 'symbol) + (if (mc--in-defun) + (save-restriction + (widen) + (narrow-to-defun) + (mc/mark-all-symbols-like-this)) + (mc/mark-all-symbols-like-this))) + +(defun mc--mark-symbol-at-point () + "Select the symbol under cursor" + (interactive) + (when (not (use-region-p)) + (let ((b (bounds-of-thing-at-point 'symbol))) + (goto-char (car b)) + (set-mark (cdr b))))) + +(defun mc--get-nice-sgml-context () + (car + (last + (progn + (when (looking-at "<") (forward-char 1)) + (when (looking-back ">") (forward-char -1)) + (sgml-get-context))))) + +(defun mc--on-tag-name-p () + (let* ((context (save-excursion (mc--get-nice-sgml-context))) + (tag-name-len (length (aref context 4))) + (beg (aref context 2)) + (end (+ beg tag-name-len (if (eq 'open (aref context 1)) 1 3)))) + (and context + (>= (point) beg) + (<= (point) end)))) + +;;;###autoload +(defun mc/toggle-cursor-on-click (event) + "Add a cursor where you click, or remove a fake cursor that is +already there." + (interactive "e") + (mouse-minibuffer-check event) + ;; Use event-end in case called from mouse-drag-region. + ;; If EVENT is a click, event-end and event-start give same value. + (let ((position (event-end event))) + (if (not (windowp (posn-window position))) + (error "Position not in text area of window")) + (select-window (posn-window position)) + (let ((pt (posn-point position))) + (if (numberp pt) + ;; is there a fake cursor with the actual *point* right where we are? + (let ((existing (mc/fake-cursor-at-point pt))) + (if existing + (mc/remove-fake-cursor existing) + (save-excursion + (goto-char pt) + (mc/create-fake-cursor-at-point)))))) + (mc/maybe-multiple-cursors-mode))) + +;;;###autoload +(defalias 'mc/add-cursor-on-click 'mc/toggle-cursor-on-click) + +;;;###autoload +(defun mc/mark-sgml-tag-pair () + "Mark the tag we're in and its pair for renaming." + (interactive) + (when (not (mc--inside-tag-p)) + (error "Place point inside tag to rename.")) + (let ((context (mc--get-nice-sgml-context))) + (if (looking-at " +;; Keywords: editing cursors + +;; 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 file contains functions that work differently on each cursor, +;; instead of treating all of them the same. + +;; Please see multiple-cursors.el for more commentary. + +;;; Code: + +(require 'multiple-cursors-core) + +(defcustom mc/insert-numbers-default 0 + "The default number at which to start counting for +`mc/insert-numbers'" + :type 'integer + :group 'multiple-cursors) + +(defvar mc--insert-numbers-number 0) + +;;;###autoload +(defun mc/insert-numbers (arg) + "Insert increasing numbers for each cursor, starting at +`mc/insert-numbers-default' or ARG." + (interactive "P") + (setq mc--insert-numbers-number (or (and arg (prefix-numeric-value arg)) + mc/insert-numbers-default)) + (mc/for-each-cursor-ordered + (mc/execute-command-for-fake-cursor 'mc--insert-number-and-increase cursor))) + +(defun mc--insert-number-and-increase () + (interactive) + (insert (number-to-string mc--insert-numbers-number)) + (setq mc--insert-numbers-number (1+ mc--insert-numbers-number))) + +(defun mc--ordered-region-strings () + (let (strings) + (save-excursion + (mc/for-each-cursor-ordered + (setq strings (cons (buffer-substring-no-properties + (mc/cursor-beg cursor) + (mc/cursor-end cursor)) strings)))) + (nreverse strings))) + +(defvar mc--insert-letters-number 0) + +;;;###autoload +(defun mc/insert-letters (arg) + "Insert increasing letters for each cursor, starting at 0 or ARG. + Where letter[0]=a letter[2]=c letter[26]=aa" + (interactive "P") + (setq mc--insert-letters-number (or (and arg (prefix-numeric-value arg)) + 0)) + (mc/for-each-cursor-ordered + (mc/execute-command-for-fake-cursor 'mc--insert-letter-and-increase cursor))) + +(defun mc--number-to-letters (number) + (let ((letter + (char-to-string + (+ (mod number 26) ?a))) + (number2 (/ number 26))) + (if (> number2 0) + (concat (mc--number-to-letters (- number2 1)) letter) + letter))) + +(defun mc--insert-letter-and-increase () + (interactive) + (insert (mc--number-to-letters mc--insert-letters-number)) + (setq mc--insert-letters-number (1+ mc--insert-letters-number))) + +(defvar mc--strings-to-replace nil) + +(defun mc--replace-region-strings-1 () + (interactive) + (delete-region (region-beginning) (region-end)) + (save-excursion (insert (car mc--strings-to-replace))) + (setq mc--strings-to-replace (cdr mc--strings-to-replace))) + +(defun mc--replace-region-strings () + (mc/for-each-cursor-ordered + (mc/execute-command-for-fake-cursor 'mc--replace-region-strings-1 cursor))) + +;;;###autoload +(defun mc/reverse-regions () + (interactive) + (if (not multiple-cursors-mode) + (progn + (mc/mark-next-lines 1) + (mc/reverse-regions) + (multiple-cursors-mode 0)) + (unless (use-region-p) + (mc/execute-command-for-all-cursors 'mark-sexp)) + (setq mc--strings-to-replace (nreverse (mc--ordered-region-strings))) + (mc--replace-region-strings))) + +;;;###autoload +(defun mc/sort-regions () + (interactive) + (unless (use-region-p) + (mc/execute-command-for-all-cursors 'mark-sexp)) + (setq mc--strings-to-replace (sort (mc--ordered-region-strings) 'string<)) + (mc--replace-region-strings)) + + +;;;###autoload +(defun mc/vertical-align (character) + "Aligns all cursors vertically with a given CHARACTER to the one with the +highest column number (the rightest). +Might not behave as intended if more than one cursors are on the same line." + (interactive "c") + (let ((rightest-column (current-column))) + (mc/execute-command-for-all-cursors + (lambda () "get the rightest cursor" + (interactive) + (setq rightest-column (max (current-column) rightest-column)) + )) + (mc/execute-command-for-all-cursors + (lambda () + (interactive) + (let ((missing-spaces (- rightest-column (current-column)))) + (save-excursion (insert (make-string missing-spaces character))) + (forward-char missing-spaces)))))) + +;;;###autoload +(defun mc/vertical-align-with-space () + "Aligns all cursors with whitespace like `mc/vertical-align' does" + (interactive) + (mc/vertical-align 32)) + +(provide 'mc-separate-operations) +;;; mc-separate-operations.el ends here diff --git a/elpa/multiple-cursors-20191210.1759/multiple-cursors-autoloads.el b/elpa/multiple-cursors-20191210.1759/multiple-cursors-autoloads.el new file mode 100644 index 0000000..1ddb851 --- /dev/null +++ b/elpa/multiple-cursors-20191210.1759/multiple-cursors-autoloads.el @@ -0,0 +1,362 @@ +;;; multiple-cursors-autoloads.el --- automatically extracted autoloads +;; +;;; Code: + +(add-to-list 'load-path (directory-file-name + (or (file-name-directory #$) (car load-path)))) + + +;;;### (autoloads nil "mc-cycle-cursors" "mc-cycle-cursors.el" (0 +;;;;;; 0 0 0)) +;;; Generated autoloads from mc-cycle-cursors.el + +(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "mc-cycle-cursors" '("mc/"))) + +;;;*** + +;;;### (autoloads nil "mc-edit-lines" "mc-edit-lines.el" (0 0 0 0)) +;;; Generated autoloads from mc-edit-lines.el + +(autoload 'mc/edit-lines "mc-edit-lines" "\ +Add one cursor to each line of the active region. +Starts from mark and moves in straight down or up towards the +line point is on. + +What is done with lines which are not long enough is governed by +`mc/edit-lines-empty-lines'. The prefix argument ARG can be used +to override this. If ARG is a symbol (when called from Lisp), +that symbol is used instead of `mc/edit-lines-empty-lines'. +Otherwise, if ARG negative, short lines will be ignored. Any +other non-nil value will cause short lines to be padded. + +\(fn &optional ARG)" t nil) + +(autoload 'mc/edit-ends-of-lines "mc-edit-lines" "\ +Add one cursor to the end of each line in the active region. + +\(fn)" t nil) + +(autoload 'mc/edit-beginnings-of-lines "mc-edit-lines" "\ +Add one cursor to the beginning of each line in the active region. + +\(fn)" t nil) + +(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "mc-edit-lines" '("mc/edit-lines-empty-lines"))) + +;;;*** + +;;;### (autoloads nil "mc-hide-unmatched-lines-mode" "mc-hide-unmatched-lines-mode.el" +;;;;;; (0 0 0 0)) +;;; Generated autoloads from mc-hide-unmatched-lines-mode.el + +(autoload 'mc-hide-unmatched-lines-mode "mc-hide-unmatched-lines-mode" "\ +Minor mode when enabled hides all lines where no cursors (and +also hum/lines-to-expand below and above) To make use of this +mode press \"C-'\" while multiple-cursor-mode is active. You can +still edit lines while you are in mc-hide-unmatched-lines +mode. To leave this mode press or \"C-g\" + +\(fn &optional ARG)" t nil) + +(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "mc-hide-unmatched-lines-mode" '("hum/"))) + +;;;*** + +;;;### (autoloads nil "mc-mark-more" "mc-mark-more.el" (0 0 0 0)) +;;; Generated autoloads from mc-mark-more.el + +(autoload 'mc/mark-next-like-this "mc-mark-more" "\ +Find and mark the next part of the buffer matching the currently active region +If no region is active add a cursor on the next line +With negative ARG, delete the last one instead. +With zero ARG, skip the last one and mark next. + +\(fn ARG)" t nil) + +(autoload 'mc/mark-next-like-this-word "mc-mark-more" "\ +Find and mark the next part of the buffer matching the currently active region +If no region is active, mark the word at the point and find the next match +With negative ARG, delete the last one instead. +With zero ARG, skip the last one and mark next. + +\(fn ARG)" t nil) + +(autoload 'mc/mark-next-word-like-this "mc-mark-more" "\ +Find and mark the next word of the buffer matching the currently active region +The matching region must be a whole word to be a match +If no region is active, mark the symbol at the point and find the next match +With negative ARG, delete the last one instead. +With zero ARG, skip the last one and mark next. + +\(fn ARG)" t nil) + +(autoload 'mc/mark-next-symbol-like-this "mc-mark-more" "\ +Find and mark the next symbol of the buffer matching the currently active region +The matching region must be a whole symbol to be a match +If no region is active, mark the symbol at the point and find the next match +With negative ARG, delete the last one instead. +With zero ARG, skip the last one and mark next. + +\(fn ARG)" t nil) + +(autoload 'mc/mark-previous-like-this "mc-mark-more" "\ +Find and mark the previous part of the buffer matching the currently active region +If no region is active add a cursor on the previous line +With negative ARG, delete the last one instead. +With zero ARG, skip the last one and mark next. + +\(fn ARG)" t nil) + +(autoload 'mc/mark-previous-like-this-word "mc-mark-more" "\ +Find and mark the previous part of the buffer matching the currently active region +If no region is active, mark the word at the point and find the previous match +With negative ARG, delete the last one instead. +With zero ARG, skip the last one and mark previous. + +\(fn ARG)" t nil) + +(autoload 'mc/mark-previous-word-like-this "mc-mark-more" "\ +Find and mark the previous part of the buffer matching the currently active region +The matching region must be a whole word to be a match +If no region is active add a cursor on the previous line +With negative ARG, delete the last one instead. +With zero ARG, skip the last one and mark next. + +\(fn ARG)" t nil) + +(autoload 'mc/mark-previous-symbol-like-this "mc-mark-more" "\ +Find and mark the previous part of the buffer matching the currently active region +The matching region must be a whole symbol to be a match +If no region is active add a cursor on the previous line +With negative ARG, delete the last one instead. +With zero ARG, skip the last one and mark next. + +\(fn ARG)" t nil) + +(autoload 'mc/mark-next-lines "mc-mark-more" "\ + + +\(fn ARG)" t nil) + +(autoload 'mc/mark-previous-lines "mc-mark-more" "\ + + +\(fn ARG)" t nil) + +(autoload 'mc/unmark-next-like-this "mc-mark-more" "\ +Deselect next part of the buffer matching the currently active region. + +\(fn)" t nil) + +(autoload 'mc/unmark-previous-like-this "mc-mark-more" "\ +Deselect prev part of the buffer matching the currently active region. + +\(fn)" t nil) + +(autoload 'mc/skip-to-next-like-this "mc-mark-more" "\ +Skip the current one and select the next part of the buffer matching the currently active region. + +\(fn)" t nil) + +(autoload 'mc/skip-to-previous-like-this "mc-mark-more" "\ +Skip the current one and select the prev part of the buffer matching the currently active region. + +\(fn)" t nil) + +(autoload 'mc/mark-all-like-this "mc-mark-more" "\ +Find and mark all the parts of the buffer matching the currently active region + +\(fn)" t nil) + +(autoload 'mc/mark-all-words-like-this "mc-mark-more" "\ + + +\(fn)" t nil) + +(autoload 'mc/mark-all-symbols-like-this "mc-mark-more" "\ + + +\(fn)" t nil) + +(autoload 'mc/mark-all-in-region "mc-mark-more" "\ +Find and mark all the parts in the region matching the given search + +\(fn BEG END &optional SEARCH)" t nil) + +(autoload 'mc/mark-all-in-region-regexp "mc-mark-more" "\ +Find and mark all the parts in the region matching the given regexp. + +\(fn BEG END)" t nil) + +(autoload 'mc/mark-more-like-this-extended "mc-mark-more" "\ +Like mark-more-like-this, but then lets you adjust with arrows key. +The adjustments work like this: + + Mark previous like this and set direction to 'up + Mark next like this and set direction to 'down + +If direction is 'up: + + Skip past the cursor furthest up + Remove the cursor furthest up + +If direction is 'down: + + Remove the cursor furthest down + Skip past the cursor furthest down + +The bindings for these commands can be changed. See `mc/mark-more-like-this-extended-keymap'. + +\(fn)" t nil) + +(autoload 'mc/mark-all-like-this-dwim "mc-mark-more" "\ +Tries to guess what you want to mark all of. +Can be pressed multiple times to increase selection. + +With prefix, it behaves the same as original `mc/mark-all-like-this' + +\(fn ARG)" t nil) + +(autoload 'mc/mark-all-dwim "mc-mark-more" "\ +Tries even harder to guess what you want to mark all of. + +If the region is active and spans multiple lines, it will behave +as if `mc/mark-all-in-region'. With the prefix ARG, it will call +`mc/edit-lines' instead. + +If the region is inactive or on a single line, it will behave like +`mc/mark-all-like-this-dwim'. + +\(fn ARG)" t nil) + +(autoload 'mc/mark-all-like-this-in-defun "mc-mark-more" "\ +Mark all like this in defun. + +\(fn)" t nil) + +(autoload 'mc/mark-all-words-like-this-in-defun "mc-mark-more" "\ +Mark all words like this in defun. + +\(fn)" t nil) + +(autoload 'mc/mark-all-symbols-like-this-in-defun "mc-mark-more" "\ +Mark all symbols like this in defun. + +\(fn)" t nil) + +(autoload 'mc/toggle-cursor-on-click "mc-mark-more" "\ +Add a cursor where you click, or remove a fake cursor that is +already there. + +\(fn EVENT)" t nil) + +(defalias 'mc/add-cursor-on-click 'mc/toggle-cursor-on-click) + +(autoload 'mc/mark-sgml-tag-pair "mc-mark-more" "\ +Mark the tag we're in and its pair for renaming. + +\(fn)" t nil) + +(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "mc-mark-more" '("mc/" "mc--"))) + +;;;*** + +;;;### (autoloads nil "mc-mark-pop" "mc-mark-pop.el" (0 0 0 0)) +;;; Generated autoloads from mc-mark-pop.el + +(autoload 'mc/mark-pop "mc-mark-pop" "\ +Add a cursor at the current point, pop off mark ring and jump +to the popped mark. + +\(fn)" t nil) + +;;;*** + +;;;### (autoloads nil "mc-separate-operations" "mc-separate-operations.el" +;;;;;; (0 0 0 0)) +;;; Generated autoloads from mc-separate-operations.el + +(autoload 'mc/insert-numbers "mc-separate-operations" "\ +Insert increasing numbers for each cursor, starting at +`mc/insert-numbers-default' or ARG. + +\(fn ARG)" t nil) + +(autoload 'mc/insert-letters "mc-separate-operations" "\ +Insert increasing letters for each cursor, starting at 0 or ARG. + Where letter[0]=a letter[2]=c letter[26]=aa + +\(fn ARG)" t nil) + +(autoload 'mc/reverse-regions "mc-separate-operations" "\ + + +\(fn)" t nil) + +(autoload 'mc/sort-regions "mc-separate-operations" "\ + + +\(fn)" t nil) + +(autoload 'mc/vertical-align "mc-separate-operations" "\ +Aligns all cursors vertically with a given CHARACTER to the one with the +highest column number (the rightest). +Might not behave as intended if more than one cursors are on the same line. + +\(fn CHARACTER)" t nil) + +(autoload 'mc/vertical-align-with-space "mc-separate-operations" "\ +Aligns all cursors with whitespace like `mc/vertical-align' does + +\(fn)" t nil) + +(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "mc-separate-operations" '("mc/insert-numbers-default" "mc--"))) + +;;;*** + +;;;### (autoloads nil "multiple-cursors-core" "multiple-cursors-core.el" +;;;;;; (0 0 0 0)) +;;; Generated autoloads from multiple-cursors-core.el + +(autoload 'multiple-cursors-mode "multiple-cursors-core" "\ +Mode while multiple cursors are active. + +\(fn &optional ARG)" t nil) + +(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "multiple-cursors-core" '("multiple-cursors-mode" "unsupported-cmd" "deactivate-cursor-after-undo" "activate-cursor-for-undo"))) + +;;;*** + +;;;### (autoloads nil "rectangular-region-mode" "rectangular-region-mode.el" +;;;;;; (0 0 0 0)) +;;; Generated autoloads from rectangular-region-mode.el + +(autoload 'set-rectangular-region-anchor "rectangular-region-mode" "\ +Anchors the rectangular region at point. + +Think of this one as `set-mark' except you're marking a rectangular region. It is +an exceedingly quick way of adding multiple cursors to multiple lines. + +\(fn)" t nil) + +(autoload 'rectangular-region-mode "rectangular-region-mode" "\ +A mode for creating a rectangular region to edit + +\(fn &optional ARG)" t nil) + +(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "rectangular-region-mode" '("rectangular-region-mode" "rrm/"))) + +;;;*** + +;;;### (autoloads nil nil ("multiple-cursors-pkg.el" "multiple-cursors.el") +;;;;;; (0 0 0 0)) + +;;;*** + +;; Local Variables: +;; version-control: never +;; no-byte-compile: t +;; no-update-autoloads: t +;; coding: utf-8 +;; End: +;;; multiple-cursors-autoloads.el ends here diff --git a/elpa/multiple-cursors-20191210.1759/multiple-cursors-core.el b/elpa/multiple-cursors-20191210.1759/multiple-cursors-core.el new file mode 100644 index 0000000..5d8cb8a --- /dev/null +++ b/elpa/multiple-cursors-20191210.1759/multiple-cursors-core.el @@ -0,0 +1,852 @@ +;;; multiple-cursors-core.el --- An experiment in multiple cursors for emacs. + +;; Copyright (C) 2012-2016 Magnar Sveen + +;; Author: Magnar Sveen +;; Keywords: editing cursors + +;; 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 file contains the core functionality of multiple-cursors. +;; Please see multiple-cursors.el for more commentary. + +;;; Code: + +(require 'cl-lib) +(require 'rect) + +(defvar mc--read-char) + +(defface mc/cursor-face + '((t (:inverse-video t))) + "The face used for fake cursors" + :group 'multiple-cursors) + +(defface mc/cursor-bar-face + `((t (:height 1 :background ,(face-attribute 'cursor :background)))) + "The face used for fake cursors if the cursor-type is bar" + :group 'multiple-cursors) + +(defface mc/region-face + '((t :inherit region)) + "The face used for fake regions" + :group 'multiple-cursors) + +(defmacro mc/add-fake-cursor-to-undo-list (&rest forms) + "Make sure point is in the right place when undoing" + (let ((uc (make-symbol "undo-cleaner"))) + `(let ((,uc (cons 'apply (cons 'deactivate-cursor-after-undo (list id))))) + (setq buffer-undo-list (cons ,uc buffer-undo-list)) + ,@forms + (if (eq ,uc (car buffer-undo-list)) ;; if nothing has been added to the undo-list + (setq buffer-undo-list (cdr buffer-undo-list)) ;; then pop the cleaner right off again + (setq buffer-undo-list ;; otherwise add a function to activate this cursor + (cons (cons 'apply (cons 'activate-cursor-for-undo (list id))) buffer-undo-list)))))) + +(defun mc/all-fake-cursors (&optional start end) + (cl-remove-if-not 'mc/fake-cursor-p + (overlays-in (or start (point-min)) + (or end (point-max))))) + +(defmacro mc/for-each-fake-cursor (&rest forms) + "Runs the body for each fake cursor, bound to the name cursor" + `(mapc #'(lambda (cursor) ,@forms) + (mc/all-fake-cursors))) + +(defmacro mc/save-excursion (&rest forms) + "Saves and restores all the state that multiple-cursors cares about." + (let ((cs (make-symbol "current-state"))) + `(let ((,cs (mc/store-current-state-in-overlay + (make-overlay (point) (point) nil nil t)))) + (overlay-put ,cs 'type 'original-cursor) + (save-excursion ,@forms) + (mc/pop-state-from-overlay ,cs)))) + +(defun mc--compare-by-overlay-start (o1 o2) + (< (overlay-start o1) (overlay-start o2))) + +(defmacro mc/for-each-cursor-ordered (&rest forms) + "Runs the body for each cursor, fake and real, bound to the name cursor" + (let ((rci (make-symbol "real-cursor-id"))) + `(let ((,rci (overlay-get (mc/create-fake-cursor-at-point) 'mc-id))) + (mapc #'(lambda (cursor) + (when (mc/fake-cursor-p cursor) + ,@forms)) + (sort (overlays-in (point-min) (point-max)) 'mc--compare-by-overlay-start)) + (mc/pop-state-from-overlay (mc/cursor-with-id ,rci))))) + +(defmacro mc/save-window-scroll (&rest forms) + "Saves and restores the window scroll position" + (let ((p (make-symbol "p")) + (s (make-symbol "start")) + (h (make-symbol "hscroll"))) + `(let ((,p (set-marker (make-marker) (point))) + (,s (set-marker (make-marker) (window-start))) + (,h (window-hscroll))) + ,@forms + (goto-char ,p) + (set-window-start nil ,s t) + (set-window-hscroll nil ,h) + (set-marker ,p nil) + (set-marker ,s nil)))) + +(defun mc/cursor-is-bar () + "Return non-nil if the cursor is a bar." + (or (eq cursor-type 'bar) + (and (listp cursor-type) + (eq (car cursor-type) 'bar)))) + +(defun mc/line-number-at-pos (&optional pos absolute) + "Faster implementation of `line-number-at-pos'." + (if pos + (save-excursion + (if absolute + (save-restriction + (widen) + (goto-char pos) + (string-to-number (format-mode-line "%l"))) + (goto-char pos) + (string-to-number (format-mode-line "%l")))) + (string-to-number (format-mode-line "%l")))) + +(defun mc/make-cursor-overlay-at-eol (pos) + "Create overlay to look like cursor at end of line." + (let ((overlay (make-overlay pos pos nil nil nil))) + (if (mc/cursor-is-bar) + (overlay-put overlay 'before-string (propertize "|" 'face 'mc/cursor-bar-face)) + (overlay-put overlay 'after-string (propertize " " 'face 'mc/cursor-face))) + overlay)) + +(defun mc/make-cursor-overlay-inline (pos) + "Create overlay to look like cursor inside text." + (let ((overlay (make-overlay pos (1+ pos) nil nil nil))) + (if (mc/cursor-is-bar) + (overlay-put overlay 'before-string (propertize "|" 'face 'mc/cursor-bar-face)) + (overlay-put overlay 'face 'mc/cursor-face)) + overlay)) + +(defun mc/make-cursor-overlay-at-point () + "Create overlay to look like cursor. +Special case for end of line, because overlay over a newline +highlights the entire width of the window." + (if (eolp) + (mc/make-cursor-overlay-at-eol (point)) + (mc/make-cursor-overlay-inline (point)))) + +(defun mc/make-region-overlay-between-point-and-mark () + "Create overlay to look like active region." + (let ((overlay (make-overlay (mark) (point) nil nil t))) + (overlay-put overlay 'face 'mc/region-face) + (overlay-put overlay 'type 'additional-region) + overlay)) + +(defvar mc/cursor-specific-vars '(transient-mark-mode + kill-ring + kill-ring-yank-pointer + mark-ring + mark-active + yank-undo-function + autopair-action + autopair-wrap-action + temporary-goal-column + er/history + dabbrev--abbrev-char-regexp + dabbrev--check-other-buffers + dabbrev--friend-buffer-list + dabbrev--last-abbrev-location + dabbrev--last-abbreviation + dabbrev--last-buffer + dabbrev--last-buffer-found + dabbrev--last-direction + dabbrev--last-expansion + dabbrev--last-expansion-location + dabbrev--last-table) + "A list of vars that need to be tracked on a per-cursor basis.") + +(defun mc/store-current-state-in-overlay (o) + "Store relevant info about point and mark in the given overlay." + (overlay-put o 'point (set-marker (make-marker) (point))) + (overlay-put o 'mark (set-marker (make-marker) + (let ((mark-even-if-inactive t)) + (mark)))) + (dolist (var mc/cursor-specific-vars) + (when (boundp var) (overlay-put o var (symbol-value var)))) + o) + +(defun mc/restore-state-from-overlay (o) + "Restore point and mark from stored info in the given overlay." + (goto-char (overlay-get o 'point)) + (set-marker (mark-marker) (overlay-get o 'mark)) + (dolist (var mc/cursor-specific-vars) + (when (boundp var) (set var (overlay-get o var))))) + +(defun mc/remove-fake-cursor (o) + "Delete overlay with state, including dependent overlays and markers." + (set-marker (overlay-get o 'point) nil) + (set-marker (overlay-get o 'mark) nil) + (mc/delete-region-overlay o) + (delete-overlay o)) + +(defun mc/pop-state-from-overlay (o) + "Restore the state stored in given overlay and then remove the overlay." + (mc/restore-state-from-overlay o) + (mc/remove-fake-cursor o)) + +(defun mc/delete-region-overlay (o) + "Remove the dependent region overlay for a given cursor overlay." + (ignore-errors + (delete-overlay (overlay-get o 'region-overlay)))) + +(defvar mc--current-cursor-id 0 + "Var to store increasing id of fake cursors, used to keep track of them for undo.") + +(defun mc/create-cursor-id () + "Returns a unique cursor id" + (cl-incf mc--current-cursor-id)) + +(defvar mc--max-cursors-original nil + "This variable maintains the original maximum number of cursors. +When `mc/create-fake-cursor-at-point' is called and +`mc/max-cursors' is overridden, this value serves as a backup so +that `mc/max-cursors' can take on a new value. When +`mc/remove-fake-cursors' is called, the values are reset.") + +(defcustom mc/max-cursors nil + "Safety ceiling for the number of active cursors. +If your emacs slows down or freezes when using too many cursors, +customize this value appropriately. + +Cursors will be added until this value is reached, at which point +you can either temporarily override the value or abort the +operation entirely. + +If this value is nil, there is no ceiling." + :type '(integer) + :group 'multiple-cursors) + +(defun mc/create-fake-cursor-at-point (&optional id) + "Add a fake cursor and possibly a fake active region overlay based on point and mark. +Saves the current state in the overlay to be restored later." + (unless mc--max-cursors-original + (setq mc--max-cursors-original mc/max-cursors)) + (when mc/max-cursors + (unless (< (mc/num-cursors) mc/max-cursors) + (if (yes-or-no-p (format "%d active cursors. Continue? " (mc/num-cursors))) + (setq mc/max-cursors (read-number "Enter a new, temporary maximum: ")) + (mc/remove-fake-cursors) + (error "Aborted: too many cursors")))) + (let ((overlay (mc/make-cursor-overlay-at-point))) + (overlay-put overlay 'mc-id (or id (mc/create-cursor-id))) + (overlay-put overlay 'type 'fake-cursor) + (overlay-put overlay 'priority 100) + (mc/store-current-state-in-overlay overlay) + (when (use-region-p) + (overlay-put overlay 'region-overlay + (mc/make-region-overlay-between-point-and-mark))) + overlay)) + +(defun mc/execute-command (cmd) + "Run command, simulating the parts of the command loop that makes sense for fake cursors." + (setq this-command cmd) + (run-hooks 'pre-command-hook) + (unless (eq this-command 'ignore) + (call-interactively cmd)) + (run-hooks 'post-command-hook) + (when deactivate-mark (deactivate-mark))) + +(defvar mc--executing-command-for-fake-cursor nil) + +(defun mc/execute-command-for-fake-cursor (cmd cursor) + (let ((mc--executing-command-for-fake-cursor t) + (id (overlay-get cursor 'mc-id)) + (annoying-arrows-mode nil) + (smooth-scroll-margin 0)) + (mc/add-fake-cursor-to-undo-list + (mc/pop-state-from-overlay cursor) + (ignore-errors + (mc/execute-command cmd) + (mc/create-fake-cursor-at-point id))))) + +(defun mc/execute-command-for-all-fake-cursors (cmd) + "Calls CMD interactively for each cursor. +It works by moving point to the fake cursor, setting +up the proper environment, and then removing the cursor. +After executing the command, it sets up a new fake +cursor with updated info." + (mc/save-excursion + (mc/save-window-scroll + (mc/for-each-fake-cursor + (save-excursion + (mc/execute-command-for-fake-cursor cmd cursor))))) + (mc--reset-read-prompts)) + +(defun mc/execute-command-for-all-cursors (cmd) + "Calls CMD interactively for the real cursor and all fakes." + (call-interactively cmd) + (mc/execute-command-for-all-fake-cursors cmd)) + +;; Intercept some reading commands so you won't have to +;; answer them for every single cursor + +(defvar mc--read-char nil) +(defvar multiple-cursors-mode nil) +(defadvice read-char (around mc-support activate) + (if (not multiple-cursors-mode) + ad-do-it + (unless mc--read-char + (setq mc--read-char ad-do-it)) + (setq ad-return-value mc--read-char))) + +(defvar mc--read-quoted-char nil) +(defadvice read-quoted-char (around mc-support activate) + (if (not multiple-cursors-mode) + ad-do-it + (unless mc--read-quoted-char + (setq mc--read-quoted-char ad-do-it)) + (setq ad-return-value mc--read-quoted-char))) + +(defun mc--reset-read-prompts () + (setq mc--read-char nil) + (setq mc--read-quoted-char nil)) + +(mc--reset-read-prompts) + +(defun mc/fake-cursor-p (o) + "Predicate to check if an overlay is a fake cursor" + (eq (overlay-get o 'type) 'fake-cursor)) + +(defun mc/cursor-with-id (id) + "Find the first cursor with the given id, or nil" + (cl-find-if #'(lambda (o) (and (mc/fake-cursor-p o) + (= id (overlay-get o 'mc-id)))) + (overlays-in (point-min) (point-max)))) + +(defvar mc--stored-state-for-undo nil + "Variable to keep the state of the real cursor while undoing a fake one") + +(defun activate-cursor-for-undo (id) + "Called when undoing to temporarily activate the fake cursor which action is being undone." + (let ((cursor (mc/cursor-with-id id))) + (when cursor + (setq mc--stored-state-for-undo (mc/store-current-state-in-overlay + (make-overlay (point) (point) nil nil t))) + (mc/pop-state-from-overlay cursor)))) + +(defun deactivate-cursor-after-undo (id) + "Called when undoing to reinstate the real cursor after undoing a fake one." + (when mc--stored-state-for-undo + (mc/create-fake-cursor-at-point id) + (mc/pop-state-from-overlay mc--stored-state-for-undo) + (setq mc--stored-state-for-undo nil))) + +(defcustom mc/always-run-for-all nil + "Disables whitelisting and always executes commands for every fake cursor." + :type '(boolean) + :group 'multiple-cursors) + +(defcustom mc/always-repeat-command nil + "Disables confirmation for `mc/repeat-command' command." + :type '(boolean) + :group 'multiple-cursors) + +(defun mc/prompt-for-inclusion-in-whitelist (original-command) + "Asks the user, then adds the command either to the once-list or the all-list." + (let ((all-p (y-or-n-p (format "Do %S for all cursors?" original-command)))) + (if all-p + (add-to-list 'mc/cmds-to-run-for-all original-command) + (add-to-list 'mc/cmds-to-run-once original-command)) + (mc/save-lists) + all-p)) + +(defun mc/num-cursors () + "The number of cursors (real and fake) in the buffer." + (1+ (cl-count-if 'mc/fake-cursor-p + (overlays-in (point-min) (point-max))))) + +(defvar mc--this-command nil + "Used to store the original command being run.") +(make-variable-buffer-local 'mc--this-command) + +(defun mc/make-a-note-of-the-command-being-run () + "Used with pre-command-hook to store the original command being run. +Since that cannot be reliably determined in the post-command-hook. + +Specifically, this-original-command isn't always right, because it could have +been remapped. And certain modes (cua comes to mind) will change their +remapping based on state. So a command that changes the state will afterwards +not be recognized through the command-remapping lookup." + (unless mc--executing-command-for-fake-cursor + (let ((cmd (or (command-remapping this-original-command) + this-original-command))) + (setq mc--this-command (and (not (eq cmd 'god-mode-self-insert)) + cmd))))) + +(defun mc/execute-this-command-for-all-cursors () + "Wrap around `mc/execute-this-command-for-all-cursors-1' to protect hook." + (condition-case error + (mc/execute-this-command-for-all-cursors-1) + (error + (message "[mc] problem in `mc/execute-this-command-for-all-cursors': %s" + (error-message-string error))))) + +;; execute-kbd-macro should never be run for fake cursors. The real cursor will +;; execute the keyboard macro, resulting in new commands in the command loop, +;; and the fake cursors can pick up on those instead. +(defadvice execute-kbd-macro (around skip-fake-cursors activate) + (unless mc--executing-command-for-fake-cursor + ad-do-it)) + +(defun mc/execute-this-command-for-all-cursors-1 () + "Used with post-command-hook to execute supported commands for all cursors. + +It uses two lists of commands to know what to do: the run-once +list and the run-for-all list. If a command is in neither of these lists, +it will prompt for the proper action and then save that preference. + +Some commands are so unsupported that they are even prevented for +the original cursor, to inform about the lack of support." + (unless mc--executing-command-for-fake-cursor + + (if (eq 1 (mc/num-cursors)) ;; no fake cursors? disable mc-mode + (multiple-cursors-mode 0) + (when this-original-command + (let ((original-command (or mc--this-command + (command-remapping this-original-command) + this-original-command))) + + ;; skip keyboard macros, since they will generate actual commands that are + ;; also run in the command loop - we'll handle those later instead. + (when (functionp original-command) + + ;; if it's a lambda, we can't know if it's supported or not + ;; - so go ahead and assume it's ok, because we're just optimistic like that + (if (or (not (symbolp original-command)) + ;; lambda registered by smartrep + (string-prefix-p "(" (symbol-name original-command))) + (mc/execute-command-for-all-fake-cursors original-command) + + ;; smartrep `intern's commands into own obarray to help + ;; `describe-bindings'. So, let's re-`intern' here to + ;; make the command comparable by `eq'. + (setq original-command (intern (symbol-name original-command))) + + ;; otherwise it's a symbol, and we can be more thorough + (if (get original-command 'mc--unsupported) + (message "%S is not supported with multiple cursors%s" + original-command + (get original-command 'mc--unsupported)) + + ;; lazy-load the user's list file + (mc/load-lists) + + (when (and original-command + (not (memq original-command mc--default-cmds-to-run-once)) + (not (memq original-command mc/cmds-to-run-once)) + (or mc/always-run-for-all + (memq original-command mc--default-cmds-to-run-for-all) + (memq original-command mc/cmds-to-run-for-all) + (mc/prompt-for-inclusion-in-whitelist original-command))) + (mc/execute-command-for-all-fake-cursors original-command)))))))))) + +(defun mc/remove-fake-cursors () + "Remove all fake cursors. +Do not use to conclude editing with multiple cursors. For that +you should disable multiple-cursors-mode." + (mc/for-each-fake-cursor + (mc/remove-fake-cursor cursor)) + (when mc--max-cursors-original + (setq mc/max-cursors mc--max-cursors-original)) + (setq mc--max-cursors-original nil)) + +(defun mc/keyboard-quit () + "Deactivate mark if there are any active, otherwise exit multiple-cursors-mode." + (interactive) + (if (not (use-region-p)) + (multiple-cursors-mode 0) + (deactivate-mark))) + +(defun mc/repeat-command () + "Run last command from `command-history' for every fake cursor." + (interactive) + (when (or mc/always-repeat-command + (y-or-n-p (format "[mc] repeat complex command: %s? " (caar command-history)))) + (mc/execute-command-for-all-fake-cursors + (lambda () (interactive) + (cl-letf (((symbol-function 'read-from-minibuffer) + (lambda (p &optional i k r h d m) (read i)))) + (repeat-complex-command 0)))))) + +(defvar mc/keymap nil + "Keymap while multiple cursors are active. +Main goal of the keymap is to rebind C-g and to conclude +multiple cursors editing.") +(unless mc/keymap + (setq mc/keymap (make-sparse-keymap)) + (define-key mc/keymap (kbd "C-g") 'mc/keyboard-quit) + (define-key mc/keymap (kbd "") 'multiple-cursors-mode) + (define-key mc/keymap (kbd "C-:") 'mc/repeat-command) + (when (fboundp 'phi-search) + (define-key mc/keymap (kbd "C-s") 'phi-search)) + (when (fboundp 'phi-search-backward) + (define-key mc/keymap (kbd "C-r") 'phi-search-backward))) + +(defun mc--all-equal (list) + "Are all the items in LIST equal?" + (let ((first (car list)) + (all-equal t)) + (while (and all-equal list) + (setq all-equal (equal first (car list))) + (setq list (cdr list))) + all-equal)) + +(defun mc--kill-ring-entries () + "Return the latest kill-ring entry for each cursor. +The entries are returned in the order they are found in the buffer." + (let (entries) + (mc/for-each-cursor-ordered + (setq entries (cons (car (overlay-get cursor 'kill-ring)) entries))) + (reverse entries))) + +(defun mc--maybe-set-killed-rectangle () + "Add the latest kill-ring entry for each cursor to killed-rectangle. +So you can paste it in later with `yank-rectangle'." + (let ((entries (let (mc/max-cursors) (mc--kill-ring-entries)))) + (unless (mc--all-equal entries) + (setq killed-rectangle entries)))) + +(defvar mc/unsupported-minor-modes '(company-mode auto-complete-mode flyspell-mode jedi-mode) + "List of minor-modes that does not play well with multiple-cursors. +They are temporarily disabled when multiple-cursors are active.") + +(defvar mc/temporarily-disabled-minor-modes nil + "The list of temporarily disabled minor-modes.") +(make-variable-buffer-local 'mc/temporarily-disabled-minor-modes) + +(defun mc/temporarily-disable-minor-mode (mode) + "If MODE is available and turned on, remember that and turn it off." + (when (and (boundp mode) (eval mode)) + (add-to-list 'mc/temporarily-disabled-minor-modes mode) + (funcall mode -1))) + +(defun mc/temporarily-disable-unsupported-minor-modes () + (mapc 'mc/temporarily-disable-minor-mode mc/unsupported-minor-modes)) + +(defun mc/enable-minor-mode (mode) + (funcall mode 1)) + +(defun mc/enable-temporarily-disabled-minor-modes () + (mapc 'mc/enable-minor-mode mc/temporarily-disabled-minor-modes) + (setq mc/temporarily-disabled-minor-modes nil)) + +(defcustom mc/mode-line + `(" mc:" (:eval (format ,(propertize "%d" 'face 'font-lock-warning-face) + (mc/num-cursors)))) + "What to display in the mode line while multiple-cursors-mode is active." + :group 'multiple-cursors) +(put 'mc/mode-line 'risky-local-variable t) + +;;;###autoload +(define-minor-mode multiple-cursors-mode + "Mode while multiple cursors are active." + nil mc/mode-line mc/keymap + (if multiple-cursors-mode + (progn + (mc/temporarily-disable-unsupported-minor-modes) + (add-hook 'pre-command-hook 'mc/make-a-note-of-the-command-being-run nil t) + (add-hook 'post-command-hook 'mc/execute-this-command-for-all-cursors t t) + (run-hooks 'multiple-cursors-mode-enabled-hook)) + (remove-hook 'post-command-hook 'mc/execute-this-command-for-all-cursors t) + (remove-hook 'pre-command-hook 'mc/make-a-note-of-the-command-being-run t) + (setq mc--this-command nil) + (mc--maybe-set-killed-rectangle) + (mc/remove-fake-cursors) + (mc/enable-temporarily-disabled-minor-modes) + (run-hooks 'multiple-cursors-mode-disabled-hook))) + +(add-hook 'after-revert-hook #'(lambda () (multiple-cursors-mode 0))) + +(defun mc/maybe-multiple-cursors-mode () + "Enable multiple-cursors-mode if there is more than one currently active cursor." + (if (> (mc/num-cursors) 1) + (multiple-cursors-mode 1) + (multiple-cursors-mode 0))) + +(defmacro unsupported-cmd (cmd msg) + "Adds command to list of unsupported commands and prevents it +from being executed if in multiple-cursors-mode." + `(progn + (put (quote ,cmd) 'mc--unsupported ,msg) + (defadvice ,cmd (around unsupported-advice activate) + "command isn't supported with multiple cursors" + (unless (and multiple-cursors-mode (called-interactively-p 'any)) + ad-do-it)))) + +;; Commands that does not work with multiple-cursors +(unsupported-cmd isearch-forward ". Feel free to add a compatible version.") +(unsupported-cmd isearch-backward ". Feel free to add a compatible version.") + +;; Make sure pastes from other programs are added to all kill-rings when yanking +(defadvice current-kill (before interprogram-paste-for-all-cursors + (n &optional do-not-move) activate) + (let ((interprogram-paste (and (= n 0) + interprogram-paste-function + (funcall interprogram-paste-function)))) + (when interprogram-paste + ;; Add interprogram-paste to normal kill ring, just + ;; like current-kill usually does for itself. + ;; We have to do the work for it though, since the funcall only returns + ;; something once. It is not a pure function. + (let ((interprogram-cut-function nil)) + (if (listp interprogram-paste) + (mapc 'kill-new (nreverse interprogram-paste)) + (kill-new interprogram-paste)) + ;; And then add interprogram-paste to the kill-rings + ;; of all the other cursors too. + (mc/for-each-fake-cursor + (let ((kill-ring (overlay-get cursor 'kill-ring)) + (kill-ring-yank-pointer (overlay-get cursor 'kill-ring-yank-pointer))) + (if (listp interprogram-paste) + (mapc 'kill-new (nreverse interprogram-paste)) + (kill-new interprogram-paste)) + (overlay-put cursor 'kill-ring kill-ring) + (overlay-put cursor 'kill-ring-yank-pointer kill-ring-yank-pointer))))))) + +(defcustom mc/list-file (locate-user-emacs-file ".mc-lists.el") + "The position of the file that keeps track of your preferences +for running commands with multiple cursors." + :type 'file + :group 'multiple-cursors) + +(defvar mc--list-file-loaded nil + "Whether the list file has already been loaded.") + +(defun mc/load-lists () + "Loads preferences for running commands with multiple cursors from `mc/list-file'" + (unless mc--list-file-loaded + (load mc/list-file 'noerror 'nomessage) + (setq mc--list-file-loaded t))) + +(defun mc/dump-list (list-symbol) + "Insert (setq 'LIST-SYMBOL LIST-VALUE) to current buffer." + (cl-symbol-macrolet ((value (symbol-value list-symbol))) + (insert "(setq " (symbol-name list-symbol) "\n" + " '(") + (newline-and-indent) + (set list-symbol + (sort value (lambda (x y) (string-lessp (symbol-name x) + (symbol-name y))))) + (mapc #'(lambda (cmd) (insert (format "%S" cmd)) (newline-and-indent)) + value) + (insert "))") + (newline))) + +(defun mc/save-lists () + "Saves preferences for running commands with multiple cursors to `mc/list-file'" + (with-temp-file mc/list-file + (emacs-lisp-mode) + (insert ";; This file is automatically generated by the multiple-cursors extension.") + (newline) + (insert ";; It keeps track of your preferences for running commands with multiple cursors.") + (newline) + (newline) + (mc/dump-list 'mc/cmds-to-run-for-all) + (newline) + (mc/dump-list 'mc/cmds-to-run-once))) + +(defvar mc/cmds-to-run-once nil + "Commands to run only once in multiple-cursors-mode.") + +(defvar mc--default-cmds-to-run-once nil + "Default set of commands to run only once in multiple-cursors-mode.") + +(setq mc--default-cmds-to-run-once '(mc/edit-lines + mc/edit-ends-of-lines + mc/edit-beginnings-of-lines + mc/mark-next-like-this + mc/mark-next-like-this-word + mc/mark-next-like-this-symbol + mc/mark-next-word-like-this + mc/mark-next-symbol-like-this + mc/mark-previous-like-this + mc/mark-previous-like-this-word + mc/mark-previous-like-this-symbol + mc/mark-previous-word-like-this + mc/mark-previous-symbol-like-this + mc/mark-all-like-this + mc/mark-all-words-like-this + mc/mark-all-symbols-like-this + mc/mark-more-like-this-extended + mc/mark-all-like-this-in-defun + mc/mark-all-words-like-this-in-defun + mc/mark-all-symbols-like-this-in-defun + mc/mark-all-like-this-dwim + mc/mark-all-dwim + mc/mark-sgml-tag-pair + mc/insert-numbers + mc/insert-letters + mc/sort-regions + mc/reverse-regions + mc/cycle-forward + mc/cycle-backward + mc/add-cursor-on-click + mc/mark-pop + mc/add-cursors-to-all-matches + mc/mmlte--left + mc/mmlte--right + mc/mmlte--up + mc/mmlte--down + mc/unmark-next-like-this + mc/unmark-previous-like-this + mc/skip-to-next-like-this + mc/skip-to-previous-like-this + rrm/switch-to-multiple-cursors + mc-hide-unmatched-lines-mode + mc/repeat-command + hum/keyboard-quit + hum/unhide-invisible-overlays + save-buffer + ido-exit-minibuffer + ivy-done + exit-minibuffer + minibuffer-complete-and-exit + execute-extended-command + eval-expression + undo + redo + undo-tree-undo + undo-tree-redo + universal-argument + universal-argument-more + universal-argument-other-key + negative-argument + digit-argument + top-level + recenter-top-bottom + describe-mode + describe-key-1 + describe-function + describe-bindings + describe-prefix-bindings + view-echo-area-messages + other-window + kill-buffer-and-window + split-window-right + split-window-below + delete-other-windows + toggle-window-split + mwheel-scroll + scroll-up-command + scroll-down-command + mouse-set-point + mouse-drag-region + quit-window + toggle-read-only + windmove-left + windmove-right + windmove-up + windmove-down + repeat-complex-command)) + +(defvar mc--default-cmds-to-run-for-all nil + "Default set of commands that should be mirrored by all cursors") + +(setq mc--default-cmds-to-run-for-all '(mc/keyboard-quit + self-insert-command + quoted-insert + previous-line + next-line + newline + newline-and-indent + open-line + delete-blank-lines + transpose-chars + transpose-lines + transpose-paragraphs + transpose-regions + join-line + right-char + right-word + forward-char + forward-word + left-char + left-word + backward-char + backward-word + forward-paragraph + backward-paragraph + upcase-word + downcase-word + capitalize-word + forward-list + backward-list + hippie-expand + hippie-expand-lines + yank + yank-pop + append-next-kill + kill-word + kill-line + kill-whole-line + backward-kill-word + backward-delete-char-untabify + delete-char delete-forward-char + delete-backward-char + py-electric-backspace + c-electric-backspace + org-delete-backward-char + cperl-electric-backspace + python-indent-dedent-line-backspace + paredit-backward-delete + autopair-backspace + just-one-space + zap-to-char + end-of-line + set-mark-command + exchange-point-and-mark + cua-set-mark + cua-replace-region + cua-delete-region + move-end-of-line + beginning-of-line + move-beginning-of-line + kill-ring-save + back-to-indentation + subword-forward + subword-backward + subword-mark + subword-kill + subword-backward-kill + subword-transpose + subword-capitalize + subword-upcase + subword-downcase + er/expand-region + er/contract-region + smart-forward + smart-backward + smart-up + smart-down)) + +(defvar mc/cmds-to-run-for-all nil + "Commands to run for all cursors in multiple-cursors-mode") + +(provide 'multiple-cursors-core) + +;; Local Variables: +;; coding: utf-8 +;; End: + +;;; multiple-cursors-core.el ends here diff --git a/elpa/multiple-cursors-20191210.1759/multiple-cursors-pkg.el b/elpa/multiple-cursors-20191210.1759/multiple-cursors-pkg.el new file mode 100644 index 0000000..ceb4014 --- /dev/null +++ b/elpa/multiple-cursors-20191210.1759/multiple-cursors-pkg.el @@ -0,0 +1,5 @@ +(define-package "multiple-cursors" "20191210.1759" "Multiple cursors for Emacs." + '((cl-lib "0.5"))) +;; Local Variables: +;; no-byte-compile: t +;; End: diff --git a/elpa/multiple-cursors-20191210.1759/multiple-cursors.el b/elpa/multiple-cursors-20191210.1759/multiple-cursors.el new file mode 100644 index 0000000..e78bab3 --- /dev/null +++ b/elpa/multiple-cursors-20191210.1759/multiple-cursors.el @@ -0,0 +1,203 @@ +;;; multiple-cursors.el --- Multiple cursors for emacs. + +;; Copyright (C) 2012-2016 Magnar Sveen + +;; Author: Magnar Sveen +;; Version: 1.4.0 +;; Keywords: editing cursors + +;; 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: + +;; Multiple cursors for Emacs. This is some pretty crazy functionality, so yes, +;; there are kinks. Don't be afraid though, I've been using it since 2011 with +;; great success and much merriment. + +;; ## Basic usage + +;; Start out with: + +;; (require 'multiple-cursors) + +;; Then you have to set up your keybindings - multiple-cursors doesn't presume to +;; know how you'd like them laid out. Here are some examples: + +;; When you have an active region that spans multiple lines, the following will +;; add a cursor to each line: + +;; (global-set-key (kbd "C-S-c C-S-c") 'mc/edit-lines) + +;; When you want to add multiple cursors not based on continuous lines, but based on +;; keywords in the buffer, use: + +;; (global-set-key (kbd "C->") 'mc/mark-next-like-this) +;; (global-set-key (kbd "C-<") 'mc/mark-previous-like-this) +;; (global-set-key (kbd "C-c C-<") 'mc/mark-all-like-this) + +;; First mark the word, then add more cursors. + +;; To get out of multiple-cursors-mode, press `` or `C-g`. The latter will +;; first disable multiple regions before disabling multiple cursors. If you want to +;; insert a newline in multiple-cursors-mode, use `C-j`. + +;; ## Video + +;; You can [watch an intro to multiple-cursors at Emacs Rocks](http://emacsrocks.com/e13.html). + +;; ## Command overview + +;; ### Mark one more occurrence + +;; - `mc/mark-next-like-this`: Adds a cursor and region at the next part of the buffer forwards that matches the current region. +;; - `mc/mark-next-like-this-word`: Adds a cursor and region at the next part of the buffer forwards that matches the current region, if no region is selected it selects the word at the point. +;; - `mc/mark-next-like-this-symbol`: Adds a cursor and region at the next part of the buffer forwards that matches the current region, if no region is selected it selects the symbol at the point. +;; - `mc/mark-next-word-like-this`: Like `mc/mark-next-like-this` but only for whole words. +;; - `mc/mark-next-symbol-like-this`: Like `mc/mark-next-like-this` but only for whole symbols. +;; - `mc/mark-previous-like-this`: Adds a cursor and region at the next part of the buffer backwards that matches the current region. +;; - `mc/mark-previous-word-like-this`: Like `mc/mark-previous-like-this` but only for whole words. +;; - `mc/mark-previous-symbol-like-this`: Like `mc/mark-previous-like-this` but only for whole symbols. +;; - `mc/mark-more-like-this-extended`: Use arrow keys to quickly mark/skip next/previous occurrences. +;; - `mc/add-cursor-on-click`: Bind to a mouse event to add cursors by clicking. See tips-section. + +;; ### Mark many occurrences + +;; - `mc/mark-all-like-this`: Marks all parts of the buffer that matches the current region. +;; - `mc/mark-all-words-like-this`: Like `mc/mark-all-like-this` but only for whole words. +;; - `mc/mark-all-symbols-like-this`: Like `mc/mark-all-like-this` but only for whole symbols. +;; - `mc/mark-all-in-region`: Prompts for a string to match in the region, adding cursors to all of them. +;; - `mc/mark-all-like-this-in-defun`: Marks all parts of the current defun that matches the current region. +;; - `mc/mark-all-words-like-this-in-defun`: Like `mc/mark-all-like-this-in-defun` but only for whole words. +;; - `mc/mark-all-symbols-like-this-in-defun`: Like `mc/mark-all-like-this-in-defun` but only for whole symbols. +;; - `mc/mark-all-like-this-dwim`: Tries to be smart about marking everything you want. Can be pressed multiple times. + +;; ### Special + +;; - `set-rectangular-region-anchor`: Think of this one as `set-mark` except you're marking a rectangular region. +;; - `mc/mark-sgml-tag-pair`: Mark the current opening and closing tag. +;; - `mc/insert-numbers`: Insert increasing numbers for each cursor, top to bottom. +;; - `mc/insert-letters`: Insert increasing letters for each cursor, top to bottom. +;; - `mc/sort-regions`: Sort the marked regions alphabetically. +;; - `mc/reverse-regions`: Reverse the order of the marked regions. + +;; ## Tips and tricks + +;; - To get out of multiple-cursors-mode, press `` or `C-g`. The latter will +;; first disable multiple regions before disabling multiple cursors. If you want to +;; insert a newline in multiple-cursors-mode, use `C-j`. +;; +;; - Sometimes you end up with cursors outside of your view. You can +;; scroll the screen to center on each cursor with `C-v` and `M-v`. +;; +;; - Try pressing `mc/mark-next-like-this` with no region selected. It will just add a cursor +;; on the next line. +;; +;; - Try pressing `mc/mark-next-like-this-word` or +;; `mc/mark-next-like-this-symbol` with no region selected. It will +;; mark the symbol and add a cursor at the next occurrence +;; +;; - Try pressing `mc/mark-all-like-this-dwim` on a tagname in html-mode. +;; +;; - Notice that the number of cursors active can be seen in the modeline. +;; +;; - If you get out of multiple-cursors-mode and yank - it will yank only +;; from the kill-ring of main cursor. To yank from the kill-rings of +;; every cursor use yank-rectangle, normally found at C-x r y. +;; +;; - You can use `mc/reverse-regions` with nothing selected and just one cursor. +;; It will then flip the sexp at point and the one below it. +;; +;; - If you would like to keep the global bindings clean, and get custom keybindings +;; when the region is active, you can try [region-bindings-mode](https://github.com/fgallina/region-bindings-mode). +;; +;; BTW, I highly recommend adding `mc/mark-next-like-this` to a key binding that's +;; right next to the key for `er/expand-region`. + +;; ### Binding mouse events + +;; To override a mouse event, you will likely have to also unbind the +;; `down-mouse` part of the event. Like this: +;; +;; (global-unset-key (kbd "M-")) +;; (global-set-key (kbd "M-") 'mc/add-cursor-on-click) +;; +;; Or you can do like me and find an unused, but less convenient, binding: +;; +;; (global-set-key (kbd "C-S-") 'mc/add-cursor-on-click) + +;; ## Unknown commands + +;; Multiple-cursors uses two lists of commands to know what to do: the run-once list +;; and the run-for-all list. It comes with a set of defaults, but it would be beyond silly +;; to try and include all the known Emacs commands. + +;; So that's why multiple-cursors occasionally asks what to do about a command. It will +;; then remember your choice by saving it in `~/.emacs.d/.mc-lists.el`. You can change +;; the location with: + +;; (setq mc/list-file "/my/preferred/file") + +;; ## Known limitations + +;; * isearch-forward and isearch-backward aren't supported with multiple cursors. +;; You should feel free to add a simplified version that can work with it. +;; * Commands run with `M-x` won't be repeated for all cursors. +;; * All key bindings that refer to lambdas are always run for all cursors. If you +;; need to limit it, you will have to give it a name. +;; * Redo might screw with your cursors. Undo works very well. + +;; ## Contribute + +;; Yes, please do. There's a suite of tests, so remember to add tests for your +;; specific feature, or I might break it later. + +;; You'll find the repo at: + +;; https://github.com/magnars/multiple-cursors.el + +;; To fetch the test dependencies: + +;; $ cd /path/to/multiple-cursors +;; $ git submodule update --init + +;; Run the tests with: + +;; $ ./util/ecukes/ecukes --graphical + +;; ## Contributors + +;; * [Takafumi Arakaki](https://github.com/tkf) made .mc-lists.el diff friendly +;; * [Marco Baringer](https://github.com/segv) contributed looping to mc/cycle and adding cursors without region for mark-more. +;; * [Ivan Andrus](https://github.com/gvol) added showing number of cursors in mode-line +;; * [Fuco](https://github.com/Fuco1) added the first version of `mc/mark-all-like-this-dwim` + +;; Thanks! + +;;; Code: + +(defgroup multiple-cursors nil + "Multiple cursors for emacs." + :group 'editing) + +(require 'mc-edit-lines) +(require 'mc-cycle-cursors) +(require 'mc-mark-more) +(require 'mc-mark-pop) +(require 'rectangular-region-mode) +(require 'mc-separate-operations) +(require 'mc-hide-unmatched-lines-mode) + +(provide 'multiple-cursors) + +;;; multiple-cursors.el ends here diff --git a/elpa/multiple-cursors-20191210.1759/rectangular-region-mode.el b/elpa/multiple-cursors-20191210.1759/rectangular-region-mode.el new file mode 100644 index 0000000..d8051cc --- /dev/null +++ b/elpa/multiple-cursors-20191210.1759/rectangular-region-mode.el @@ -0,0 +1,125 @@ +;;; rectangular-region-mode.el + +;; Copyright (C) 2012-2016 Magnar Sveen + +;; Author: Magnar Sveen +;; Keywords: editing cursors + +;; 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: + +;; (global-set-key (kbd "H-SPC") 'set-rectangular-region-anchor) + +;; Think of this one as `set-mark` except you're marking a rectangular region. It is +;; an exceedingly quick way of adding multiple cursors to multiple lines. + +;;; Code: + +(require 'multiple-cursors-core) + +(defvar rrm/anchor (make-marker) + "The position in the buffer that anchors the rectangular region.") + +(defvar rectangular-region-mode-map (make-sparse-keymap) + "Keymap for rectangular region is mainly for rebinding C-g") + +(define-key rectangular-region-mode-map (kbd "C-g") 'rrm/keyboard-quit) +(define-key rectangular-region-mode-map (kbd "") 'rrm/switch-to-multiple-cursors) + +(defvar rectangular-region-mode nil) + +(defun rrm/keyboard-quit () + "Exit rectangular-region-mode." + (interactive) + (rectangular-region-mode 0) + (rrm/remove-rectangular-region-overlays) + (deactivate-mark)) + +;; Bind this to a key (for instance H-SPC) to start rectangular-region-mode +;;;###autoload +(defun set-rectangular-region-anchor () + "Anchors the rectangular region at point. + +Think of this one as `set-mark' except you're marking a rectangular region. It is +an exceedingly quick way of adding multiple cursors to multiple lines." + (interactive) + (set-marker rrm/anchor (point)) + (push-mark (point)) + (rectangular-region-mode 1)) + +(defun rrm/remove-rectangular-region-overlays () + "Remove all rectangular-region overlays." + (mc/remove-fake-cursors) + (mapc #'(lambda (o) + (when (eq (overlay-get o 'type) 'additional-region) + (delete-overlay o))) + (overlays-in (point-min) (point-max)))) + +(defun rrm/repaint () + "Start from the anchor and draw a rectangle between it and point." + (if (not rectangular-region-mode) + (remove-hook 'post-command-hook 'rrm/repaint t) + ;; else + (rrm/remove-rectangular-region-overlays) + (let* ((annoying-arrows-mode nil) + (point-column (current-column)) + (point-line (mc/line-number-at-pos)) + (anchor-column (save-excursion (goto-char rrm/anchor) (current-column))) + (anchor-line (save-excursion (goto-char rrm/anchor) (mc/line-number-at-pos))) + (left-column (if (< point-column anchor-column) point-column anchor-column)) + (right-column (if (> point-column anchor-column) point-column anchor-column)) + (navigation-step (if (< point-line anchor-line) 1 -1))) + (move-to-column anchor-column) + (set-mark (point)) + (move-to-column point-column) + (mc/save-excursion + (while (not (= anchor-line (mc/line-number-at-pos))) + (forward-line navigation-step) + (move-to-column anchor-column) + (when (= anchor-column (current-column)) + (set-mark (point)) + (move-to-column point-column) + (when (= point-column (current-column)) + (mc/create-fake-cursor-at-point)))))))) + +(defun rrm/switch-to-multiple-cursors (&rest forms) + "Switch from rectangular-region-mode to multiple-cursors-mode." + (interactive) + (rectangular-region-mode 0) + (multiple-cursors-mode 1)) + +(defadvice er/expand-region (before switch-from-rrm-to-mc activate) + (when rectangular-region-mode + (rrm/switch-to-multiple-cursors))) + +(defadvice kill-ring-save (before switch-from-rrm-to-mc activate) + (when rectangular-region-mode + (rrm/switch-to-multiple-cursors))) + +;;;###autoload +(define-minor-mode rectangular-region-mode + "A mode for creating a rectangular region to edit" + nil " rr" rectangular-region-mode-map + (if rectangular-region-mode + (progn + (add-hook 'after-change-functions 'rrm/switch-to-multiple-cursors t t) + (add-hook 'post-command-hook 'rrm/repaint t t)) + (remove-hook 'after-change-functions 'rrm/switch-to-multiple-cursors t) + (remove-hook 'post-command-hook 'rrm/repaint t) + (set-marker rrm/anchor nil))) + +(provide 'rectangular-region-mode) + +;;; rectangular-region-mode.el ends here diff --git a/elpa/use-package-20191126.2034/dir b/elpa/use-package-20191126.2034/dir new file mode 100644 index 0000000..651b05d --- /dev/null +++ b/elpa/use-package-20191126.2034/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 +* use-package: (use-package). Declarative package configuration for Emacs. diff --git a/elpa/use-package-20191126.2034/use-package-autoloads.el b/elpa/use-package-20191126.2034/use-package-autoloads.el new file mode 100644 index 0000000..a374fcc --- /dev/null +++ b/elpa/use-package-20191126.2034/use-package-autoloads.el @@ -0,0 +1,228 @@ +;;; use-package-autoloads.el --- automatically extracted autoloads +;; +;;; Code: + +(add-to-list 'load-path (directory-file-name + (or (file-name-directory #$) (car load-path)))) + + +;;;### (autoloads nil "use-package-bind-key" "use-package-bind-key.el" +;;;;;; (0 0 0 0)) +;;; Generated autoloads from use-package-bind-key.el + +(autoload 'use-package-autoload-keymap "use-package-bind-key" "\ +Loads PACKAGE and then binds the key sequence used to invoke +this function to KEYMAP-SYMBOL. It then simulates pressing the +same key sequence a again, so that the next key pressed is routed +to the newly loaded keymap. + +This function supports use-package's :bind-keymap keyword. It +works by binding the given key sequence to an invocation of this +function for a particular keymap. The keymap is expected to be +defined by the package. In this way, loading the package is +deferred until the prefix key sequence is pressed. + +\(fn KEYMAP-SYMBOL PACKAGE OVERRIDE)" nil nil) + +(autoload 'use-package-normalize-binder "use-package-bind-key" "\ + + +\(fn NAME KEYWORD ARGS)" nil nil) + +(defalias 'use-package-normalize/:bind 'use-package-normalize-binder) + +(defalias 'use-package-normalize/:bind* 'use-package-normalize-binder) + +(defalias 'use-package-autoloads/:bind 'use-package-autoloads-mode) + +(defalias 'use-package-autoloads/:bind* 'use-package-autoloads-mode) + +(autoload 'use-package-handler/:bind "use-package-bind-key" "\ + + +\(fn NAME KEYWORD ARGS REST STATE &optional BIND-MACRO)" nil nil) + +(defalias 'use-package-normalize/:bind-keymap 'use-package-normalize-binder) + +(defalias 'use-package-normalize/:bind-keymap* 'use-package-normalize-binder) + +(autoload 'use-package-handler/:bind-keymap "use-package-bind-key" "\ + + +\(fn NAME KEYWORD ARGS REST STATE &optional OVERRIDE)" nil nil) + +(autoload 'use-package-handler/:bind-keymap* "use-package-bind-key" "\ + + +\(fn NAME KEYWORD ARG REST STATE)" nil nil) + +(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "use-package-bind-key" '("use-package-handler/:bind*"))) + +;;;*** + +;;;### (autoloads nil "use-package-core" "use-package-core.el" (0 +;;;;;; 0 0 0)) +;;; Generated autoloads from use-package-core.el + +(autoload 'use-package "use-package-core" "\ +Declare an Emacs package by specifying a group of configuration options. + +For full documentation, please see the README file that came with +this file. Usage: + + (use-package package-name + [:keyword [option]]...) + +:init Code to run before PACKAGE-NAME has been loaded. +:config Code to run after PACKAGE-NAME has been loaded. Note that + if loading is deferred for any reason, this code does not + execute until the lazy load has occurred. +:preface Code to be run before everything except `:disabled'; this + can be used to define functions for use in `:if', or that + should be seen by the byte-compiler. + +:mode Form to be added to `auto-mode-alist'. +:magic Form to be added to `magic-mode-alist'. +:magic-fallback Form to be added to `magic-fallback-mode-alist'. +:interpreter Form to be added to `interpreter-mode-alist'. + +:commands Define autoloads for commands that will be defined by the + package. This is useful if the package is being lazily + loaded, and you wish to conditionally call functions in your + `:init' block that are defined in the package. +:hook Specify hook(s) to attach this package to. + +:bind Bind keys, and define autoloads for the bound commands. +:bind* Bind keys, and define autoloads for the bound commands, + *overriding all minor mode bindings*. +:bind-keymap Bind a key prefix to an auto-loaded keymap defined in the + package. This is like `:bind', but for keymaps. +:bind-keymap* Like `:bind-keymap', but overrides all minor mode bindings + +:defer Defer loading of a package -- this is implied when using + `:commands', `:bind', `:bind*', `:mode', `:magic', `:hook', + `:magic-fallback', or `:interpreter'. This can be an integer, + to force loading after N seconds of idle time, if the package + has not already been loaded. +:after Defer loading of a package until after any of the named + features are loaded. +:demand Prevent deferred loading in all cases. + +:if EXPR Initialize and load only if EXPR evaluates to a non-nil value. +:disabled The package is ignored completely if this keyword is present. +:defines Declare certain variables to silence the byte-compiler. +:functions Declare certain functions to silence the byte-compiler. +:load-path Add to the `load-path' before attempting to load the package. +:diminish Support for diminish.el (if installed). +:delight Support for delight.el (if installed). +:custom Call `customize-set-variable' with each variable definition. +:custom-face Call `customize-set-faces' with each face definition. +:ensure Loads the package using package.el if necessary. +:pin Pin the package to an archive. + +\(fn NAME &rest ARGS)" nil t) + +(function-put 'use-package 'lisp-indent-function '1) + +(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "use-package-core" '("use-package-"))) + +;;;*** + +;;;### (autoloads nil "use-package-delight" "use-package-delight.el" +;;;;;; (0 0 0 0)) +;;; Generated autoloads from use-package-delight.el + +(autoload 'use-package-normalize/:delight "use-package-delight" "\ +Normalize arguments to delight. + +\(fn NAME KEYWORD ARGS)" nil nil) + +(autoload 'use-package-handler/:delight "use-package-delight" "\ + + +\(fn NAME KEYWORD ARGS REST STATE)" nil nil) + +(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "use-package-delight" '("use-package-normalize-delight"))) + +;;;*** + +;;;### (autoloads nil "use-package-diminish" "use-package-diminish.el" +;;;;;; (0 0 0 0)) +;;; Generated autoloads from use-package-diminish.el + +(autoload 'use-package-normalize/:diminish "use-package-diminish" "\ + + +\(fn NAME KEYWORD ARGS)" nil nil) + +(autoload 'use-package-handler/:diminish "use-package-diminish" "\ + + +\(fn NAME KEYWORD ARG REST STATE)" nil nil) + +(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "use-package-diminish" '("use-package-normalize-diminish"))) + +;;;*** + +;;;### (autoloads nil "use-package-ensure" "use-package-ensure.el" +;;;;;; (0 0 0 0)) +;;; Generated autoloads from use-package-ensure.el + +(autoload 'use-package-normalize/:ensure "use-package-ensure" "\ + + +\(fn NAME KEYWORD ARGS)" nil nil) + +(autoload 'use-package-handler/:ensure "use-package-ensure" "\ + + +\(fn NAME KEYWORD ENSURE REST STATE)" nil nil) + +(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "use-package-ensure" '("use-package-"))) + +;;;*** + +;;;### (autoloads nil "use-package-jump" "use-package-jump.el" (0 +;;;;;; 0 0 0)) +;;; Generated autoloads from use-package-jump.el + +(autoload 'use-package-jump-to-package-form "use-package-jump" "\ +Attempt to find and jump to the `use-package' form that loaded +PACKAGE. This will only find the form if that form actually +required PACKAGE. If PACKAGE was previously required then this +function will jump to the file that originally required PACKAGE +instead. + +\(fn PACKAGE)" t nil) + +(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "use-package-jump" '("use-package-find-require"))) + +;;;*** + +;;;### (autoloads nil "use-package-lint" "use-package-lint.el" (0 +;;;;;; 0 0 0)) +;;; Generated autoloads from use-package-lint.el + +(autoload 'use-package-lint "use-package-lint" "\ +Check for errors in use-package declarations. +For example, if the module's `:if' condition is met, but even +with the specified `:load-path' the module cannot be found. + +\(fn)" t nil) + +(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "use-package-lint" '("use-package-lint-declaration"))) + +;;;*** + +;;;### (autoloads nil nil ("use-package-pkg.el" "use-package.el") +;;;;;; (0 0 0 0)) + +;;;*** + +;; Local Variables: +;; version-control: never +;; no-byte-compile: t +;; no-update-autoloads: t +;; coding: utf-8 +;; End: +;;; use-package-autoloads.el ends here diff --git a/elpa/use-package-20191126.2034/use-package-bind-key.el b/elpa/use-package-20191126.2034/use-package-bind-key.el new file mode 100644 index 0000000..e476b06 --- /dev/null +++ b/elpa/use-package-20191126.2034/use-package-bind-key.el @@ -0,0 +1,172 @@ +;;; use-package-bind-key.el --- Support for the :bind/:bind-keymap keywords -*- lexical-binding: t; -*- + +;; Copyright (C) 2012-2017 John Wiegley + +;; Author: John Wiegley +;; Maintainer: John Wiegley +;; Created: 17 Jun 2012 +;; Modified: 4 Dec 2017 +;; Version: 1.0 +;; Package-Requires: ((emacs "24.3") (use-package "2.4") (bind-key "2.4")) +;; Keywords: dotemacs startup speed config package +;; URL: https://github.com/jwiegley/use-package + +;; 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, 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 GNU Emacs; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. + +;;; Commentary: + +;; Provides support for the :bind, :bind*, :bind-keymap and :bind-keymap* +;; keywords. Note that these are currently still baked into +;; `use-package-keywords' and `use-package-deferring-keywords', although this +;; is harmless if they are never used. + +;;; Code: + +(require 'use-package-core) +(require 'bind-key) + +;;;###autoload +(defun use-package-autoload-keymap (keymap-symbol package override) + "Loads PACKAGE and then binds the key sequence used to invoke +this function to KEYMAP-SYMBOL. It then simulates pressing the +same key sequence a again, so that the next key pressed is routed +to the newly loaded keymap. + +This function supports use-package's :bind-keymap keyword. It +works by binding the given key sequence to an invocation of this +function for a particular keymap. The keymap is expected to be +defined by the package. In this way, loading the package is +deferred until the prefix key sequence is pressed." + (if (not (require package nil t)) + (use-package-error (format "Cannot load package.el: %s" package)) + (if (and (boundp keymap-symbol) + (keymapp (symbol-value keymap-symbol))) + (let* ((kv (this-command-keys-vector)) + (key (key-description kv)) + (keymap (symbol-value keymap-symbol))) + (if override + (bind-key* key keymap) + (bind-key key keymap)) + (setq unread-command-events + (mapcar (lambda (ev) (cons t ev)) + (listify-key-sequence kv)))) + (use-package-error + (format "package.el %s failed to define keymap %s" + package keymap-symbol))))) + +;;;###autoload +(defun use-package-normalize-binder (name keyword args) + (let ((arg args) + args*) + (while arg + (let ((x (car arg))) + (cond + ;; (KEY . COMMAND) + ((and (consp x) + (or (stringp (car x)) + (vectorp (car x))) + (or (use-package-recognize-function (cdr x) t #'stringp))) + (setq args* (nconc args* (list x))) + (setq arg (cdr arg))) + ;; KEYWORD + ;; :map KEYMAP + ;; :prefix-docstring STRING + ;; :prefix-map SYMBOL + ;; :prefix STRING + ;; :filter SEXP + ;; :menu-name STRING + ;; :package SYMBOL + ((or (and (eq x :map) (symbolp (cadr arg))) + (and (eq x :prefix) (stringp (cadr arg))) + (and (eq x :prefix-map) (symbolp (cadr arg))) + (and (eq x :prefix-docstring) (stringp (cadr arg))) + (eq x :filter) + (and (eq x :menu-name) (stringp (cadr arg))) + (and (eq x :package) (symbolp (cadr arg)))) + (setq args* (nconc args* (list x (cadr arg)))) + (setq arg (cddr arg))) + ((listp x) + (setq args* + (nconc args* (use-package-normalize-binder name keyword x))) + (setq arg (cdr arg))) + (t + ;; Error! + (use-package-error + (concat (symbol-name name) + " wants arguments acceptable to the `bind-keys' macro," + " or a list of such values")))))) + args*)) + +;;;; :bind, :bind* + +;;;###autoload +(defalias 'use-package-normalize/:bind 'use-package-normalize-binder) +;;;###autoload +(defalias 'use-package-normalize/:bind* 'use-package-normalize-binder) + +;; jww (2017-12-07): This is too simplistic. It will fail to determine +;; autoloads in this situation: +;; (use-package foo +;; :bind (:map foo-map (("C-a" . func)))) +;;;###autoload +(defalias 'use-package-autoloads/:bind 'use-package-autoloads-mode) +;;;###autoload +(defalias 'use-package-autoloads/:bind* 'use-package-autoloads-mode) + +;;;###autoload +(defun use-package-handler/:bind + (name _keyword args rest state &optional bind-macro) + (use-package-concat + (use-package-process-keywords name rest state) + `(,@(mapcar + #'(lambda (xs) + `(,(if bind-macro bind-macro 'bind-keys) + :package ,name ,@(use-package-normalize-commands xs))) + (use-package-split-list-at-keys :break args))))) + +(defun use-package-handler/:bind* (name keyword arg rest state) + (use-package-handler/:bind name keyword arg rest state 'bind-keys*)) + +;;;; :bind-keymap, :bind-keymap* + +;;;###autoload +(defalias 'use-package-normalize/:bind-keymap 'use-package-normalize-binder) +;;;###autoload +(defalias 'use-package-normalize/:bind-keymap* 'use-package-normalize-binder) + +;;;###autoload +(defun use-package-handler/:bind-keymap + (name _keyword args rest state &optional override) + (use-package-concat + (use-package-process-keywords name rest state) + (mapcar + #'(lambda (binding) + `(,(if override 'bind-key* 'bind-key) + ,(car binding) + #'(lambda () + (interactive) + (use-package-autoload-keymap + ',(cdr binding) ',(use-package-as-symbol name) + ,override)))) + args))) + +;;;###autoload +(defun use-package-handler/:bind-keymap* (name keyword arg rest state) + (use-package-handler/:bind-keymap name keyword arg rest state t)) + +(provide 'use-package-bind-key) + +;;; use-package-bind-key.el ends here diff --git a/elpa/use-package-20191126.2034/use-package-core.el b/elpa/use-package-20191126.2034/use-package-core.el new file mode 100644 index 0000000..83b9b29 --- /dev/null +++ b/elpa/use-package-20191126.2034/use-package-core.el @@ -0,0 +1,1593 @@ +;;; use-package-core.el --- A configuration macro for simplifying your .emacs -*- lexical-binding: t; -*- + +;; Copyright (C) 2012-2017 John Wiegley + +;; Author: John Wiegley +;; Maintainer: John Wiegley +;; Created: 17 Jun 2012 +;; Modified: 29 Nov 2017 +;; Version: 2.4 +;; Package-Requires: ((emacs "24.3")) +;; Keywords: dotemacs startup speed config package +;; URL: https://github.com/jwiegley/use-package + +;; 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, 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 GNU Emacs; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. + +;;; Commentary: + +;; The `use-package' declaration macro allows you to isolate package +;; configuration in your ".emacs" in a way that is performance-oriented and, +;; well, just tidy. I created it because I have over 80 packages that I use +;; in Emacs, and things were getting difficult to manage. Yet with this +;; utility my total load time is just under 1 second, with no loss of +;; functionality! +;; +;; Please see README.md from the same repository for documentation. + +;;; Code: + +(require 'bytecomp) +(require 'cl-lib) +(require 'tabulated-list) + +(if (and (eq emacs-major-version 24) (eq emacs-minor-version 3)) + (defsubst hash-table-keys (hash-table) + "Return a list of keys in HASH-TABLE." + (cl-loop for k being the hash-keys of hash-table collect k)) + (eval-when-compile (require 'subr-x))) + +(eval-when-compile + (require 'regexp-opt)) + +(defgroup use-package nil + "A use-package declaration for simplifying your `.emacs'." + :group 'startup) + +(defconst use-package-version "2.4" + "This version of use-package.") + +(defcustom use-package-keywords + '(:disabled + :load-path + :requires + :defines + :functions + :preface + :if :when :unless + :no-require + :catch + :after + :custom + :custom-face + :bind + :bind* + :bind-keymap + :bind-keymap* + :interpreter + :mode + :magic + :magic-fallback + :hook + ;; Any other keyword that also declares commands to be autoloaded (such as + ;; :bind) must appear before this keyword. + :commands + :init + :defer + :demand + :load + ;; This must occur almost last; the only forms which should appear after + ;; are those that must happen directly after the config forms. + :config) + "The set of valid keywords, in the order they are processed in. +The order of this list is *very important*, so it is only +advisable to insert new keywords, never to delete or reorder +them. Further, attention should be paid to the NEWS.md if the +default order ever changes, as they may have subtle effects on +the semantics of use-package declarations and may necessitate +changing where you had inserted a new keyword earlier. + +Note that `:disabled' is special in this list, as it causes +nothing at all to happen, even if the rest of the use-package +declaration is incorrect." + :type '(repeat symbol) + :group 'use-package) + +(defcustom use-package-deferring-keywords + '(:bind-keymap + :bind-keymap* + :commands) + "Unless `:demand' is used, keywords in this list imply deferred loading. +The reason keywords like `:hook' are not in this list is that +they only imply deferred loading if they reference actual +function symbols that can be autoloaded from the module; whereas +the default keywords provided here always defer loading unless +otherwise requested." + :type '(repeat symbol) + :group 'use-package) + +(defcustom use-package-ignore-unknown-keywords nil + "If non-nil, issue warning instead of error when unknown +keyword is encountered. The unknown keyword and its associated +arguments will be ignored in the `use-package' expansion." + :type 'boolean + :group 'use-package) + +(defcustom use-package-verbose nil + "Whether to report about loading and configuration details. +If you customize this, then you should require the `use-package' +feature in files that use `use-package', even if these files only +contain compiled expansions of the macros. If you don't do so, +then the expanded macros do their job silently." + :type '(choice (const :tag "Quiet, without catching errors" errors) + (const :tag "Quiet" nil) + (const :tag "Verbose" t) + (const :tag "Debug" debug)) + :group 'use-package) + +(defcustom use-package-check-before-init nil + "If non-nil, check that package exists before executing its `:init' block. +This check is performed by calling `locate-library'." + :type 'boolean + :group 'use-package) + +(defcustom use-package-always-defer nil + "If non-nil, assume `:defer t' unless `:demand' is used. +See also `use-package-defaults', which uses this value." + :type 'boolean + :group 'use-package) + +(defcustom use-package-always-demand nil + "If non-nil, assume `:demand t' unless `:defer' is used. +See also `use-package-defaults', which uses this value." + :type 'boolean + :group 'use-package) + +(defcustom use-package-defaults + '(;; this '(t) has special meaning; see `use-package-handler/:config' + (:config '(t) t) + (:init nil t) + (:catch t (lambda (name args) + (not use-package-expand-minimally))) + (:defer use-package-always-defer + (lambda (name args) + (and use-package-always-defer + (not (plist-member args :defer)) + (not (plist-member args :demand))))) + (:demand use-package-always-demand + (lambda (name args) + (and use-package-always-demand + (not (plist-member args :defer)) + (not (plist-member args :demand)))))) + "Default values for specified `use-package' keywords. +Each entry in the alist is a list of three elements: +The first element is the `use-package' keyword. + +The second is a form that can be evaluated to get the default +value. It can also be a function that will receive the name of +the use-package declaration and the keyword plist given to +`use-package', in normalized form. The value it returns should +also be in normalized form (which is sometimes *not* what one +would normally write in a `use-package' declaration, so use +caution). + +The third element is a form that can be evaluated to determine +whether or not to assign a default value; if it evaluates to nil, +then the default value is not assigned even if the keyword is not +present in the `use-package' form. This third element may also be +a function, in which case it receives the name of the package (as +a symbol) and a list of keywords (in normalized form). It should +return nil or non-nil depending on whether defaulting should be +attempted." + :type `(repeat + (list (choice :tag "Keyword" + ,@(mapcar #'(lambda (k) (list 'const k)) + use-package-keywords)) + (choice :tag "Default value" sexp function) + (choice :tag "Enable if non-nil" sexp function))) + :group 'use-package) + +(defcustom use-package-merge-key-alist + '((:if . (lambda (new old) `(and ,new ,old))) + (:after . (lambda (new old) `(:all ,new ,old))) + (:defer . (lambda (new old) old)) + (:bind . (lambda (new old) (append new (list :break) old)))) + "Alist of keys and the functions used to merge multiple values. +For example, if the following form is provided: + + (use-package foo :if pred1 :if pred2) + +Then based on the above defaults, the merged result will be: + + (use-package foo :if (and pred1 pred2)) + +This is done so that, at the stage of invoking handlers, each +handler is called only once." + :type `(repeat + (cons (choice :tag "Keyword" + ,@(mapcar #'(lambda (k) (list 'const k)) + use-package-keywords) + (const :tag "Any" t)) + function)) + :group 'use-package) + +(defcustom use-package-hook-name-suffix "-hook" + "Text append to the name of hooks mentioned by :hook. +Set to nil if you don't want this to happen; it's only a +convenience." + :type '(choice string (const :tag "No suffix" nil)) + :group 'use-package) + +(defcustom use-package-minimum-reported-time 0.1 + "Minimal load time that will be reported. +Note that `use-package-verbose' has to be set to a non-nil value +for anything to be reported at all." + :type 'number + :group 'use-package) + +(defcustom use-package-inject-hooks nil + "If non-nil, add hooks to the `:init' and `:config' sections. +In particular, for a given package `foo', the following hooks +become available: + + `use-package--foo--pre-init-hook' + `use-package--foo--post-init-hook' + `use-package--foo--pre-config-hook' + `use-package--foo--post-config-hook' + +This way, you can add to these hooks before evaluation of a +`use-package` declaration, and exercise some control over what +happens. + +NOTE: These hooks are run even if the user does not specify an +`:init' or `:config' block, and they will happen at the regular +time when initialization and configuration would have been +performed. + +NOTE: If the `pre-init' hook return a nil value, that block's +user-supplied configuration is not evaluated, so be certain to +return t if you only wish to add behavior to what the user had +specified." + :type 'boolean + :group 'use-package) + +(defcustom use-package-expand-minimally nil + "If non-nil, make the expanded code as minimal as possible. +This disables: + + - Printing to the *Messages* buffer of slowly-evaluating forms + - Capturing of load errors (normally redisplayed as warnings) + - Conditional loading of packages (load failures become errors) + +The main advantage to this variable is that, if you know your +configuration works, it will make the byte-compiled file as +minimal as possible. It can also help with reading macro-expanded +definitions, to understand the main intent of what's happening." + :type 'boolean + :group 'use-package) + +(defcustom use-package-form-regexp-eval + `(concat ,(eval-when-compile + (concat "^\\s-*(" + (regexp-opt '("use-package" "require") t) + "\\s-+\\(")) + (or (bound-and-true-p lisp-mode-symbol-regexp) + "\\(?:\\sw\\|\\s_\\|\\\\.\\)+") "\\)") + "Sexp providing regexp for finding use-package forms in user files. +This is used by `use-package-jump-to-package-form' and +`use-package-enable-imenu-support'." + :type 'sexp + :group 'use-package) + +(defcustom use-package-enable-imenu-support nil + "If non-nil, cause imenu to see `use-package' declarations. +This is done by adjusting `lisp-imenu-generic-expression' to +include support for finding `use-package' and `require' forms. + +Must be set before loading use-package." + :type 'boolean + :set + #'(lambda (_sym value) + (eval-after-load 'lisp-mode + (if value + `(add-to-list 'lisp-imenu-generic-expression + (list "Packages" ,use-package-form-regexp-eval 2)) + `(setq lisp-imenu-generic-expression + (remove (list "Packages" ,use-package-form-regexp-eval 2) + lisp-imenu-generic-expression))))) + :group 'use-package) + +(defconst use-package-font-lock-keywords + '(("(\\(use-package\\)\\_>[ \t']*\\(\\(?:\\sw\\|\\s_\\)+\\)?" + (1 font-lock-keyword-face) + (2 font-lock-constant-face nil t)))) + +(font-lock-add-keywords 'emacs-lisp-mode use-package-font-lock-keywords) + +(defcustom use-package-compute-statistics nil + "If non-nil, compute statistics concerned use-package declarations. +View the statistical report using `use-package-report'. Note that +if this option is enabled, you must require `use-package' in your +user init file at loadup time, or you will see errors concerning +undefined variables." + :type 'boolean + :group 'use-package) + +(defvar use-package-statistics (make-hash-table)) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Utility functions +;; + +(defsubst use-package-error (msg) + "Report MSG as an error, so the user knows it came from this package." + (error "use-package: %s" msg)) + +(defsubst use-package-concat (&rest elems) + "Delete all empty lists from ELEMS (nil or (list nil)), and append them." + (apply #'append (delete nil (delete (list nil) elems)))) + +(defsubst use-package-non-nil-symbolp (sym) + (and sym (symbolp sym))) + +(defsubst use-package-as-symbol (string-or-symbol) + "If STRING-OR-SYMBOL is already a symbol, return it. Otherwise +convert it to a symbol and return that." + (if (symbolp string-or-symbol) string-or-symbol + (intern string-or-symbol))) + +(defsubst use-package-as-string (string-or-symbol) + "If STRING-OR-SYMBOL is already a string, return it. Otherwise +convert it to a string and return that." + (if (stringp string-or-symbol) string-or-symbol + (symbol-name string-or-symbol))) + +(defsubst use-package-regex-p (re) + "Return t if RE is some regexp-like thing." + (or (and (listp re) (eq (car re) 'rx)) + (stringp re))) + +(defun use-package-normalize-regex (re) + "Given some regexp-like thing in RE, resolve to a regular expression." + (cond + ((and (listp re) (eq (car re) 'rx)) (eval re)) + ((stringp re) re) + (t (error "Not recognized as regular expression: %s" re)))) + +(defsubst use-package-is-pair (x car-pred cdr-pred) + "Return non-nil if X is a cons satisfying the given predicates. +CAR-PRED and CDR-PRED are applied to X's `car' and `cdr', +respectively." + (and (consp x) + (funcall car-pred (car x)) + (funcall cdr-pred (cdr x)))) + +(defun use-package-as-mode (string-or-symbol) + "If STRING-OR-SYMBOL ends in `-mode' (or its name does), return +it as a symbol. Otherwise, return it as a symbol with `-mode' +appended." + (let ((string (use-package-as-string string-or-symbol))) + (intern (if (string-match "-mode\\'" string) + string + (concat string "-mode"))))) + +(defsubst use-package-load-name (name &optional noerror) + "Return a form which will load or require NAME. +It does the right thing no matter if NAME is a string or symbol. +Argument NOERROR means to indicate load failures as a warning." + (if (stringp name) + `(load ,name ,noerror) + `(require ',name nil ,noerror))) + +(defun use-package-hook-injector (name-string keyword body) + "Wrap pre/post hook injections around the given BODY for KEYWORD. +The BODY is a list of forms, so `((foo))' if only `foo' is being called." + (if (not use-package-inject-hooks) + body + (let ((keyword-name (substring (format "%s" keyword) 1))) + `((when (run-hook-with-args-until-failure + ',(intern (concat "use-package--" name-string + "--pre-" keyword-name "-hook"))) + ,@body + (run-hooks + ',(intern (concat "use-package--" name-string + "--post-" keyword-name "-hook")))))))) + +(defun use-package-with-elapsed-timer (text body) + "BODY is a list of forms, so `((foo))' if only `foo' is being called." + (declare (indent 1)) + (if use-package-expand-minimally + body + (let ((nowvar (make-symbol "now"))) + (if (bound-and-true-p use-package-verbose) + `((let ((,nowvar (current-time))) + (message "%s..." ,text) + (prog1 + ,(macroexp-progn body) + (let ((elapsed + (float-time (time-subtract (current-time) ,nowvar)))) + (if (> elapsed ,use-package-minimum-reported-time) + (message "%s...done (%.3fs)" ,text elapsed) + (message "%s...done" ,text)))))) + body)))) + +(put 'use-package-with-elapsed-timer 'lisp-indent-function 1) + +(defun use-package-require (name &optional no-require body) + (if use-package-expand-minimally + (use-package-concat + (unless no-require + (list (use-package-load-name name))) + body) + (if no-require + body + (use-package-with-elapsed-timer + (format "Loading package %s" name) + `((if (not ,(use-package-load-name name t)) + (display-warning 'use-package + (format "Cannot load %s" ',name) + :error) + ,@body)))))) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Property lists +;; + +(defun use-package-plist-delete (plist property) + "Delete PROPERTY from PLIST. +This is in contrast to merely setting it to 0." + (let (p) + (while plist + (if (not (eq property (car plist))) + (setq p (plist-put p (car plist) (nth 1 plist)))) + (setq plist (cddr plist))) + p)) + +(defun use-package-plist-delete-first (plist property) + "Delete PROPERTY from PLIST. +This is in contrast to merely setting it to 0." + (let (p) + (while plist + (if (eq property (car plist)) + (setq p (nconc p (cddr plist)) + plist nil) + (setq p (nconc p (list (car plist) (cadr plist))) + plist (cddr plist)))) + p)) + +(defsubst use-package-plist-maybe-put (plist property value) + "Add a VALUE for PROPERTY to PLIST, if it does not already exist." + (if (plist-member plist property) + plist + (plist-put plist property value))) + +(defsubst use-package-plist-cons (plist property value) + "Cons VALUE onto the head of the list at PROPERTY in PLIST." + (plist-put plist property (cons value (plist-get plist property)))) + +(defsubst use-package-plist-append (plist property value) + "Append VALUE onto the front of the list at PROPERTY in PLIST." + (plist-put plist property (append value (plist-get plist property)))) + +(defun use-package-split-list (pred xs) + (let ((ys (list nil)) (zs (list nil)) flip) + (cl-dolist (x xs) + (if flip + (nconc zs (list x)) + (if (funcall pred x) + (progn + (setq flip t) + (nconc zs (list x))) + (nconc ys (list x))))) + (cons (cdr ys) (cdr zs)))) + +(defun use-package-split-list-at-keys (key lst) + (and lst + (let ((xs (use-package-split-list (apply-partially #'eq key) lst))) + (cons (car xs) (use-package-split-list-at-keys key (cddr xs)))))) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Keywords +;; + +(defun use-package-keyword-index (keyword) + (cl-loop named outer + with index = 0 + for k in use-package-keywords do + (if (eq k keyword) + (cl-return-from outer index)) + (cl-incf index))) + +(defun use-package-normalize-plist (name input &optional plist merge-function) + "Given a pseudo-plist, normalize it to a regular plist. +The normalized key/value pairs from input are added to PLIST, +extending any keys already present." + (if (null input) + plist + (let* ((keyword (car input)) + (xs (use-package-split-list #'keywordp (cdr input))) + (args (car xs)) + (tail (cdr xs)) + (normalizer + (intern-soft (concat "use-package-normalize/" + (symbol-name keyword)))) + (arg (and (functionp normalizer) + (funcall normalizer name keyword args))) + (error-string (format "Unrecognized keyword: %s" keyword))) + (if (memq keyword use-package-keywords) + (progn + (setq plist (use-package-normalize-plist + name tail plist merge-function)) + (plist-put plist keyword + (if (plist-member plist keyword) + (funcall merge-function keyword arg + (plist-get plist keyword)) + arg))) + (if use-package-ignore-unknown-keywords + (progn + (display-warning 'use-package error-string) + (use-package-normalize-plist + name tail plist merge-function)) + (use-package-error error-string)))))) + +(defun use-package-unalias-keywords (_name args) + (setq args (cl-nsubstitute :if :when args)) + (let (temp) + (while (setq temp (plist-get args :unless)) + (setq args (use-package-plist-delete-first args :unless) + args (append args `(:if (not ,temp)))))) + args) + +(defun use-package-merge-keys (key new old) + (let ((merger (assq key use-package-merge-key-alist))) + (if merger + (funcall (cdr merger) new old) + (append new old)))) + +(defun use-package-sort-keywords (plist) + (let (plist-grouped) + (while plist + (push (cons (car plist) (cadr plist)) + plist-grouped) + (setq plist (cddr plist))) + (let (result) + (cl-dolist + (x + (nreverse + (sort plist-grouped + #'(lambda (l r) (< (use-package-keyword-index (car l)) + (use-package-keyword-index (car r))))))) + (setq result (cons (car x) (cons (cdr x) result)))) + result))) + +(defun use-package-normalize-keywords (name args) + (let* ((name-symbol (if (stringp name) (intern name) name)) + (name-string (symbol-name name-symbol))) + + ;; The function `elisp--local-variables' inserts this unbound variable into + ;; macro forms to determine the locally bound variables for + ;; `elisp-completion-at-point'. It ends up throwing a lot of errors since it + ;; can occupy the position of a keyword (or look like a second argument to a + ;; keyword that takes one). Deleting it when it's at the top level should be + ;; harmless since there should be no locally bound variables to discover + ;; here anyway. + (setq args (delq 'elisp--witness--lisp args)) + + ;; Reduce the set of keywords down to its most fundamental expression. + (setq args (use-package-unalias-keywords name-symbol args)) + + ;; Normalize keyword values, coalescing multiple occurrences. + (setq args (use-package-normalize-plist name-symbol args nil + #'use-package-merge-keys)) + + ;; Add default values for keywords not specified, when applicable. + (cl-dolist (spec use-package-defaults) + (when (let ((func (nth 2 spec))) + (if (and func (functionp func)) + (funcall func name args) + (eval func))) + (setq args (use-package-plist-maybe-put + args (nth 0 spec) + (let ((func (nth 1 spec))) + (if (and func (functionp func)) + (funcall func name args) + (eval func))))))) + + ;; Determine any autoloads implied by the keywords used. + (let ((iargs args) + commands) + (while iargs + (when (keywordp (car iargs)) + (let ((autoloads + (intern-soft (concat "use-package-autoloads/" + (symbol-name (car iargs)))))) + (when (functionp autoloads) + (setq commands + ;; jww (2017-12-07): Right now we just ignored the type of + ;; the autoload being requested, and assume they are all + ;; `command'. + (append (mapcar + #'car + (funcall autoloads name-symbol (car iargs) + (cadr iargs))) + commands))))) + (setq iargs (cddr iargs))) + (when commands + (setq args + ;; Like `use-package-plist-append', but removing duplicates. + (plist-put args :commands + (delete-dups + (append commands (plist-get args :commands))))))) + + ;; If byte-compiling, pre-load the package so all its symbols are in + ;; scope. This is done by prepending statements to the :preface. + (when (bound-and-true-p byte-compile-current-file) + (setq args + (use-package-plist-append + args :preface + (use-package-concat + (mapcar #'(lambda (var) `(defvar ,var)) + (plist-get args :defines)) + (mapcar #'(lambda (fn) `(declare-function ,fn ,name-string)) + (plist-get args :functions)) + `((eval-when-compile + (with-demoted-errors + ,(format "Cannot load %s: %%S" name-string) + ,(when (eq use-package-verbose 'debug) + `(message ,(format "Compiling package %s" name-string))) + ,(unless (plist-get args :no-require) + `(unless (featurep ',name-symbol) + (load ,name-string nil t)))))))))) + + ;; Certain keywords imply :defer, if :demand was not specified. + (when (and (not (plist-member args :demand)) + (not (plist-member args :defer)) + (not (or (equal '(t) (plist-get args :load)) + (equal (list (use-package-as-string name)) + (mapcar #'use-package-as-string + (plist-get args :load))))) + (cl-some #'identity + (mapcar (apply-partially #'plist-member args) + use-package-deferring-keywords))) + (setq args (append args '(:defer t)))) + + ;; The :load keyword overrides :no-require + (when (and (plist-member args :load) + (plist-member args :no-require)) + (setq args (use-package-plist-delete args :no-require))) + + ;; If at this point no :load, :defer or :no-require has been seen, then + ;; :load the package itself. + (when (and (not (plist-member args :load)) + (not (plist-member args :defer)) + (not (plist-member args :no-require))) + (setq args (append args `(:load (,name))))) + + ;; Sort the list of keywords based on the order of `use-package-keywords'. + (use-package-sort-keywords args))) + +(defun use-package-process-keywords (name plist &optional state) + "Process the next keyword in the free-form property list PLIST. +The values in the PLIST have each been normalized by the function +use-package-normalize/KEYWORD (minus the colon). + +STATE is a property list that the function may modify and/or +query. This is useful if a package defines multiple keywords and +wishes them to have some kind of stateful interaction. + +Unless the KEYWORD being processed intends to ignore remaining +keywords, it must call this function recursively, passing in the +plist with its keyword and argument removed, and passing in the +next value for the STATE." + (declare (indent 1)) + (unless (null plist) + (let* ((keyword (car plist)) + (arg (cadr plist)) + (rest (cddr plist))) + (unless (keywordp keyword) + (use-package-error (format "%s is not a keyword" keyword))) + (let* ((handler (concat "use-package-handler/" (symbol-name keyword))) + (handler-sym (intern handler))) + (if (functionp handler-sym) + (funcall handler-sym name keyword arg rest state) + (use-package-error + (format "Keyword handler not defined: %s" handler))))))) + +(put 'use-package-process-keywords 'lisp-indent-function 'defun) + +(defun use-package-list-insert (elem xs &optional anchor after test) + "Insert ELEM into the list XS. +If ANCHOR is also a keyword, place the new KEYWORD before that +one. +If AFTER is non-nil, insert KEYWORD either at the end of the +keywords list, or after the ANCHOR if one has been provided. +If TEST is non-nil, it is the test used to compare ELEM to list +elements. The default is `eq'. +The modified list is returned. The original list is not modified." + (let (result) + (dolist (k xs) + (if (funcall (or test #'eq) k anchor) + (if after + (setq result (cons k result) + result (cons elem result)) + (setq result (cons elem result) + result (cons k result))) + (setq result (cons k result)))) + (if anchor + (nreverse result) + (if after + (nreverse (cons elem result)) + (cons elem (nreverse result)))))) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Argument Processing +;; + +(defun use-package-only-one (label args f) + "Call F on the first member of ARGS if it has exactly one element." + (declare (indent 1)) + (cond + ((and (listp args) (listp (cdr args)) + (= (length args) 1)) + (funcall f label (car args))) + (t + (use-package-error + (concat label " wants exactly one argument"))))) + +(put 'use-package-only-one 'lisp-indent-function 'defun) + +(defun use-package-as-one (label args f &optional allow-empty) + "Call F on the first element of ARGS if it has one element, or all of ARGS. +If ALLOW-EMPTY is non-nil, it's OK for ARGS to be an empty list." + (declare (indent 1)) + (if (if args + (and (listp args) (listp (cdr args))) + allow-empty) + (if (= (length args) 1) + (funcall f label (car args)) + (funcall f label args)) + (use-package-error + (concat label " wants a non-empty list")))) + +(put 'use-package-as-one 'lisp-indent-function 'defun) + +(defun use-package-memoize (f arg) + "Ensure the macro-expansion of F applied to ARG evaluates ARG +no more than once." + (let ((loaded (cl-gentemp "use-package--loaded")) + (result (cl-gentemp "use-package--result")) + (next (cl-gentemp "use-package--next"))) + `((defvar ,loaded nil) + (defvar ,result nil) + (defvar ,next #'(lambda () (if ,loaded ,result + (setq ,loaded t ,result ,arg)))) + ,@(funcall f `((funcall ,next)))))) + +(defsubst use-package-normalize-value (_label arg) + "Normalize the Lisp value given by ARG. +The argument LABEL is ignored." + (cond ((null arg) nil) + ((eq t arg) t) + ((use-package-non-nil-symbolp arg) + `(symbol-value ',arg)) + ((functionp arg) + `(funcall #',arg)) + (t arg))) + +(defun use-package-normalize-symbols (label arg &optional recursed) + "Normalize a list of symbols." + (cond + ((use-package-non-nil-symbolp arg) + (list arg)) + ((and (not recursed) (listp arg) (listp (cdr arg))) + (mapcar #'(lambda (x) (car (use-package-normalize-symbols label x t))) arg)) + (t + (use-package-error + (concat label " wants a symbol, or list of symbols"))))) + +(defun use-package-normalize-symlist (_name keyword args) + (use-package-as-one (symbol-name keyword) args + #'use-package-normalize-symbols)) + +(defun use-package-normalize-recursive-symbols (label arg) + "Normalize a list of symbols." + (cond + ((use-package-non-nil-symbolp arg) + arg) + ((and (listp arg) (listp (cdr arg))) + (mapcar #'(lambda (x) (use-package-normalize-recursive-symbols label x)) + arg)) + (t + (use-package-error + (concat label " wants a symbol, or nested list of symbols"))))) + +(defun use-package-normalize-recursive-symlist (_name keyword args) + (use-package-as-one (symbol-name keyword) args + #'use-package-normalize-recursive-symbols)) + +(defun use-package-normalize-paths (label arg &optional recursed) + "Normalize a list of filesystem paths." + (cond + ((and arg (or (use-package-non-nil-symbolp arg) (functionp arg))) + (let ((value (use-package-normalize-value label arg))) + (use-package-normalize-paths label (eval value)))) + ((stringp arg) + (let ((path (if (file-name-absolute-p arg) + arg + (expand-file-name arg user-emacs-directory)))) + (list path))) + ((and (not recursed) (listp arg) (listp (cdr arg))) + (mapcar #'(lambda (x) + (car (use-package-normalize-paths label x t))) arg)) + (t + (use-package-error + (concat label " wants a directory path, or list of paths"))))) + +(defun use-package-normalize-predicate (_name keyword args) + (if (null args) + t + (use-package-only-one (symbol-name keyword) args + #'use-package-normalize-value))) + +(defun use-package-normalize-form (label args) + "Given a list of forms, return it wrapped in `progn'." + (unless (listp (car args)) + (use-package-error (concat label " wants a sexp or list of sexps"))) + (mapcar #'(lambda (form) + (if (and (consp form) + (memq (car form) + '(use-package bind-key bind-key* + unbind-key bind-keys bind-keys*))) + (macroexpand form) + form)) args)) + +(defun use-package-normalize-forms (_name keyword args) + (use-package-normalize-form (symbol-name keyword) args)) + +(defun use-package-normalize-pairs + (key-pred val-pred name label arg &optional recursed) + "Normalize a list of pairs. +KEY-PRED and VAL-PRED are predicates recognizing valid keys and +values, respectively. +If RECURSED is non-nil, recurse into sublists." + (cond + ((funcall key-pred arg) + (list (cons arg (use-package-as-symbol name)))) + ((use-package-is-pair arg key-pred val-pred) + (list arg)) + ((and (not recursed) (listp arg) (listp (cdr arg))) + (let (last-item) + (mapcar + #'(lambda (x) + (prog1 + (let ((ret (use-package-normalize-pairs + key-pred val-pred name label x t))) + (if (and (listp ret) + (not (keywordp last-item))) + (car ret) + ret)) + (setq last-item x))) arg))) + (t arg))) + +(defun use-package-recognize-function (v &optional binding additional-pred) + "A predicate that recognizes functional constructions: + nil + sym + 'sym + (quote sym) + #'sym + (function sym) + (lambda () ...) + '(lambda () ...) + (quote (lambda () ...)) + #'(lambda () ...) + (function (lambda () ...))" + (or (if binding + (symbolp v) + (use-package-non-nil-symbolp v)) + (and (listp v) + (memq (car v) '(quote function)) + (use-package-non-nil-symbolp (cadr v))) + (if binding (commandp v) (functionp v)) + (and additional-pred + (funcall additional-pred v)))) + +(defun use-package-normalize-function (v) + "Reduce functional constructions to one of two normal forms: + sym + #'(lambda () ...)" + (cond ((symbolp v) v) + ((and (listp v) + (memq (car v) '(quote function)) + (use-package-non-nil-symbolp (cadr v))) + (cadr v)) + ((and (consp v) + (eq 'lambda (car v))) + v) + ((and (listp v) + (memq (car v) '(quote function)) + (eq 'lambda (car (cadr v)))) + (cadr v)) + (t v))) + +(defun use-package-normalize-commands (args) + "Map over ARGS of the form ((_ . F) ...), normalizing functional F's." + (mapcar #'(lambda (x) + (if (consp x) + (cons (car x) (use-package-normalize-function (cdr x))) + x)) + args)) + +(defun use-package-normalize-mode (name keyword args) + "Normalize arguments for keywords which add regexp/mode pairs to an alist." + (use-package-as-one (symbol-name keyword) args + (apply-partially #'use-package-normalize-pairs + #'use-package-regex-p + #'use-package-recognize-function + name))) + +(defun use-package-autoloads-mode (_name _keyword args) + (mapcar + #'(lambda (x) (cons (cdr x) 'command)) + (cl-remove-if-not #'(lambda (x) + (and (consp x) + (use-package-non-nil-symbolp (cdr x)))) + args))) + +(defun use-package-handle-mode (name alist args rest state) + "Handle keywords which add regexp/mode pairs to an alist." + (use-package-concat + (use-package-process-keywords name rest state) + (mapcar + #'(lambda (thing) + `(add-to-list + ',alist + ',(cons (use-package-normalize-regex (car thing)) + (cdr thing)))) + (use-package-normalize-commands args)))) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Statistics +;; + +(defun use-package-reset-statistics () + (interactive) + (setq use-package-statistics (make-hash-table))) + +(defun use-package-statistics-status (package) + "Return loading configuration status of PACKAGE statistics." + (cond ((gethash :config package) "Configured") + ((gethash :init package) "Initialized") + ((gethash :preface package) "Prefaced") + ((gethash :use-package package) "Declared"))) + +(defun use-package-statistics-last-event (package) + "Return the date when PACKAGE's status last changed. +The date is returned as a string." + (format-time-string "%Y-%m-%d %a %H:%M" + (or (gethash :config package) + (gethash :init package) + (gethash :preface package) + (gethash :use-package package)))) + +(defun use-package-statistics-time (package) + "Return the time is took for PACKAGE to load." + (+ (float-time (gethash :config-secs package '(0 0 0 0))) + (float-time (gethash :init-secs package '(0 0 0 0))) + (float-time (gethash :preface-secs package '(0 0 0 0))) + (float-time (gethash :use-package-secs package '(0 0 0 0))))) + +(defun use-package-statistics-convert (package) + "Return information about PACKAGE. + +The information is formatted in a way suitable for +`use-package-statistics-mode'." + (let ((statistics (gethash package use-package-statistics))) + (list + package + (vector + (symbol-name package) + (use-package-statistics-status statistics) + (use-package-statistics-last-event statistics) + (format "%.2f" (use-package-statistics-time statistics)))))) + +(defun use-package-report () + "Show current statistics gathered about use-package declarations. +In the table that's generated, the status field has the following +meaning: + Configured :config has been processed (the package is loaded!) + Initialized :init has been processed (load status unknown) + Prefaced :preface has been processed + Declared the use-package declaration was seen" + (interactive) + (with-current-buffer (get-buffer-create "*use-package statistics*") + (setq tabulated-list-entries + (mapcar #'use-package-statistics-convert + (hash-table-keys use-package-statistics))) + (use-package-statistics-mode) + (tabulated-list-print) + (display-buffer (current-buffer)))) + +(define-derived-mode use-package-statistics-mode tabulated-list-mode + "use-package statistics" + "Show current statistics gathered about use-package declarations." + (setq tabulated-list-format + ;; The sum of column width is 80 characters: + #[("Package" 25 t) + ("Status" 13 t) + ("Last Event" 23 t) + ("Time" 10 t)]) + (tabulated-list-init-header)) + +(defun use-package-statistics-gather (keyword name after) + (let* ((hash (gethash name use-package-statistics + (make-hash-table))) + (before (and after (gethash keyword hash (current-time))))) + (puthash keyword (current-time) hash) + (when after + (puthash (intern (concat (symbol-name keyword) "-secs")) + (time-subtract (current-time) before) hash)) + (puthash name hash use-package-statistics))) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Handlers +;; + +;;;; :disabled + +;; Don't alias this to `ignore', as that will cause the resulting +;; function to be interactive. +(defun use-package-normalize/:disabled (_name _keyword _arg) + "Do nothing, return nil.") + +(defun use-package-handler/:disabled (name _keyword _arg rest state) + (use-package-process-keywords name rest state)) + +;;;; :if, :when and :unless + +(defun use-package-normalize-test (_name keyword args) + (use-package-only-one (symbol-name keyword) args + #'use-package-normalize-value)) + +(defalias 'use-package-normalize/:if 'use-package-normalize-test) + +(defun use-package-handler/:if (name _keyword pred rest state) + (let ((body (use-package-process-keywords name rest state))) + `((when ,pred ,@body)))) + +(defalias 'use-package-normalize/:when 'use-package-normalize-test) + +(defalias 'use-package-handler/:when 'use-package-handler/:if) + +(defalias 'use-package-normalize/:unless 'use-package-normalize-test) + +(defun use-package-handler/:unless (name _keyword pred rest state) + (let ((body (use-package-process-keywords name rest state))) + `((unless ,pred ,@body)))) + +;;;; :requires + +(defalias 'use-package-normalize/:requires 'use-package-normalize-symlist) + +(defun use-package-handler/:requires (name _keyword requires rest state) + (let ((body (use-package-process-keywords name rest state))) + (if (null requires) + body + `((when ,(if (> (length requires) 1) + `(not (member nil (mapcar #'featurep ',requires))) + `(featurep ',(car requires))) + ,@body))))) + +;;;; :load-path + +(defun use-package-normalize/:load-path (_name keyword args) + (use-package-as-one (symbol-name keyword) args + #'use-package-normalize-paths)) + +(defun use-package-handler/:load-path (name _keyword arg rest state) + (let ((body (use-package-process-keywords name rest state))) + (use-package-concat + (mapcar #'(lambda (path) + `(eval-and-compile (add-to-list 'load-path ,path))) + arg) + body))) + +;;;; :no-require + +(defalias 'use-package-normalize/:no-require 'use-package-normalize-predicate) + +(defun use-package-handler/:no-require (name _keyword _arg rest state) + (use-package-process-keywords name rest state)) + +;;;; :defines + +(defalias 'use-package-normalize/:defines 'use-package-normalize-symlist) + +(defun use-package-handler/:defines (name _keyword _arg rest state) + (use-package-process-keywords name rest state)) + +;;;; :functions + +(defalias 'use-package-normalize/:functions 'use-package-normalize-symlist) + +(defun use-package-handler/:functions (name _keyword _arg rest state) + (use-package-process-keywords name rest state)) + +;;;; :preface + +(defalias 'use-package-normalize/:preface 'use-package-normalize-forms) + +(defun use-package-handler/:preface (name _keyword arg rest state) + (let ((body (use-package-process-keywords name rest state))) + (use-package-concat + (when use-package-compute-statistics + `((use-package-statistics-gather :preface ',name nil))) + (when arg + `((eval-and-compile ,@arg))) + body + (when use-package-compute-statistics + `((use-package-statistics-gather :preface ',name t)))))) + +;;;; :catch + +(defvar use-package--form) +(defvar use-package--hush-function #'(lambda (_keyword body) body)) + +(defsubst use-package-hush (context keyword body) + `((condition-case-unless-debug err + ,(macroexp-progn body) + (error (funcall ,context ,keyword err))))) + +(defun use-package-normalize/:catch (_name keyword args) + (if (null args) + t + (use-package-only-one (symbol-name keyword) args + use-package--hush-function))) + +(defun use-package-handler/:catch (name keyword arg rest state) + (let* ((context (cl-gentemp "use-package--warning"))) + (cond + ((not arg) + (use-package-process-keywords name rest state)) + ((eq arg t) + `((defvar ,context + #'(lambda (keyword err) + (let ((msg (format "%s/%s: %s" ',name keyword + (error-message-string err)))) + ,@(when (eq use-package-verbose 'debug) + `((with-current-buffer + (get-buffer-create "*use-package*") + (goto-char (point-max)) + (insert "-----\n" msg ,use-package--form) + (emacs-lisp-mode)) + (setq msg + (concat msg + " (see the *use-package* buffer)")))) + (display-warning 'use-package msg :error)))) + ,@(let ((use-package--hush-function + (apply-partially #'use-package-hush context))) + (funcall use-package--hush-function keyword + (use-package-process-keywords name rest state))))) + ((functionp arg) + `((defvar ,context ,arg) + ,@(let ((use-package--hush-function + (apply-partially #'use-package-hush context))) + (funcall use-package--hush-function keyword + (use-package-process-keywords name rest state))))) + (t + (use-package-error "The :catch keyword expects 't' or a function"))))) + +;;;; :interpreter + +(defalias 'use-package-normalize/:interpreter 'use-package-normalize-mode) +(defalias 'use-package-autoloads/:interpreter 'use-package-autoloads-mode) + +(defun use-package-handler/:interpreter (name _keyword arg rest state) + (use-package-handle-mode name 'interpreter-mode-alist arg rest state)) + +;;;; :mode + +(defalias 'use-package-normalize/:mode 'use-package-normalize-mode) +(defalias 'use-package-autoloads/:mode 'use-package-autoloads-mode) + +(defun use-package-handler/:mode (name _keyword arg rest state) + (use-package-handle-mode name 'auto-mode-alist arg rest state)) + +;;;; :magic + +(defalias 'use-package-normalize/:magic 'use-package-normalize-mode) +(defalias 'use-package-autoloads/:magic 'use-package-autoloads-mode) + +(defun use-package-handler/:magic (name _keyword arg rest state) + (use-package-handle-mode name 'magic-mode-alist arg rest state)) + +;;;; :magic-fallback + +(defalias 'use-package-normalize/:magic-fallback 'use-package-normalize-mode) +(defalias 'use-package-autoloads/:magic-fallback 'use-package-autoloads-mode) + +(defun use-package-handler/:magic-fallback (name _keyword arg rest state) + (use-package-handle-mode name 'magic-fallback-mode-alist arg rest state)) + +;;;; :hook + +(defun use-package-normalize/:hook (name keyword args) + (use-package-as-one (symbol-name keyword) args + #'(lambda (label arg) + (unless (or (use-package-non-nil-symbolp arg) (consp arg)) + (use-package-error + (concat label " a or ( . )" + " or list of these"))) + (use-package-normalize-pairs + #'(lambda (k) + (or (use-package-non-nil-symbolp k) + (and k (let ((every t)) + (while (and every k) + (if (and (consp k) + (use-package-non-nil-symbolp (car k))) + (setq k (cdr k)) + (setq every nil))) + every)))) + #'use-package-recognize-function + name label arg)))) + +(defalias 'use-package-autoloads/:hook 'use-package-autoloads-mode) + +(defun use-package-handler/:hook (name _keyword args rest state) + "Generate use-package custom keyword code." + (use-package-concat + (use-package-process-keywords name rest state) + (cl-mapcan + #'(lambda (def) + (let ((syms (car def)) + (fun (cdr def))) + (when fun + (mapcar + #'(lambda (sym) + `(add-hook + (quote ,(intern + (concat (symbol-name sym) + use-package-hook-name-suffix))) + (function ,fun))) + (if (use-package-non-nil-symbolp syms) (list syms) syms))))) + (use-package-normalize-commands args)))) + +;;;; :commands + +(defalias 'use-package-normalize/:commands 'use-package-normalize-symlist) + +(defun use-package-handler/:commands (name _keyword arg rest state) + (use-package-concat + ;; Since we deferring load, establish any necessary autoloads, and also + ;; keep the byte-compiler happy. + (let ((name-string (use-package-as-string name))) + (cl-mapcan + #'(lambda (command) + (when (symbolp command) + (append + (unless (plist-get state :demand) + `((unless (fboundp ',command) + (autoload #',command ,name-string nil t)))) + (when (bound-and-true-p byte-compile-current-file) + `((eval-when-compile + (declare-function ,command ,name-string))))))) + (delete-dups arg))) + (use-package-process-keywords name rest state))) + +;;;; :defer + +(defalias 'use-package-normalize/:defer 'use-package-normalize-predicate) + +(defun use-package-handler/:defer (name _keyword arg rest state) + (let ((body (use-package-process-keywords name rest state))) + (use-package-concat + ;; Load the package after a set amount of idle time, if the argument to + ;; `:defer' was a number. + (when (numberp arg) + `((run-with-idle-timer ,arg nil #'require + ',(use-package-as-symbol name) nil t))) + (if (or (not arg) (null body)) + body + `((eval-after-load ',name ',(macroexp-progn body))))))) + +;;;; :after + +(defun use-package-normalize/:after (name keyword args) + (setq args (use-package-normalize-recursive-symlist name keyword args)) + (if (consp args) + args + (list args))) + +(defun use-package-after-count-uses (features*) + "Count the number of time the body would appear in the result." + (cond ((use-package-non-nil-symbolp features*) + 1) + ((and (consp features*) + (memq (car features*) '(:or :any))) + (let ((num 0)) + (cl-dolist (next (cdr features*)) + (setq num (+ num (use-package-after-count-uses next)))) + num)) + ((and (consp features*) + (memq (car features*) '(:and :all))) + (apply #'max (mapcar #'use-package-after-count-uses + (cdr features*)))) + ((listp features*) + (use-package-after-count-uses (cons :all features*))))) + +(defun use-package-require-after-load (features* body) + "Generate `eval-after-load' statements to represents FEATURES*. +FEATURES* is a list containing keywords `:and' and `:all', where +no keyword implies `:all'." + (cond + ((use-package-non-nil-symbolp features*) + `((eval-after-load ',features* ',(macroexp-progn body)))) + ((and (consp features*) + (memq (car features*) '(:or :any))) + (cl-mapcan #'(lambda (x) (use-package-require-after-load x body)) + (cdr features*))) + ((and (consp features*) + (memq (car features*) '(:and :all))) + (cl-dolist (next (cdr features*)) + (setq body (use-package-require-after-load next body))) + body) + ((listp features*) + (use-package-require-after-load (cons :all features*) body)))) + +(defun use-package-handler/:after (name _keyword arg rest state) + (let ((body (use-package-process-keywords name rest state)) + (uses (use-package-after-count-uses arg))) + (if (or (null uses) (null body)) + body + (if (<= uses 1) + (use-package-require-after-load arg body) + (use-package-memoize + (apply-partially #'use-package-require-after-load arg) + (macroexp-progn body)))))) + +;;;; :demand + +(defalias 'use-package-normalize/:demand 'use-package-normalize-predicate) + +(defun use-package-handler/:demand (name _keyword _arg rest state) + (use-package-process-keywords name rest state)) + +;;;; :custom + +(defun use-package-normalize/:custom (_name keyword args) + "Normalize use-package custom keyword." + (use-package-as-one (symbol-name keyword) args + #'(lambda (label arg) + (unless (listp arg) + (use-package-error + (concat label " a ( [comment])" + " or list of these"))) + (if (use-package-non-nil-symbolp (car arg)) + (list arg) + arg)))) + +(defun use-package-handler/:custom (name _keyword args rest state) + "Generate use-package custom keyword code." + (use-package-concat + (mapcar + #'(lambda (def) + (let ((variable (nth 0 def)) + (value (nth 1 def)) + (comment (nth 2 def))) + (unless (and comment (stringp comment)) + (setq comment (format "Customized with use-package %s" name))) + `(customize-set-variable (quote ,variable) ,value ,comment))) + args) + (use-package-process-keywords name rest state))) + +;;;; :custom-face + +(defun use-package-normalize/:custom-face (name-symbol _keyword arg) + "Normalize use-package custom-face keyword." + (let ((error-msg + (format "%s wants a ( ) or list of these" + name-symbol))) + (unless (listp arg) + (use-package-error error-msg)) + (cl-dolist (def arg arg) + (unless (listp def) + (use-package-error error-msg)) + (let ((face (nth 0 def)) + (spec (nth 1 def))) + (when (or (not face) + (not spec) + (> (length def) 2)) + (use-package-error error-msg)))))) + +(defun use-package-handler/:custom-face (name _keyword args rest state) + "Generate use-package custom-face keyword code." + (use-package-concat + (mapcar #'(lambda (def) `(custom-set-faces (backquote ,def))) args) + (use-package-process-keywords name rest state))) + +;;;; :init + +(defalias 'use-package-normalize/:init 'use-package-normalize-forms) + +(defun use-package-handler/:init (name _keyword arg rest state) + (use-package-concat + (when use-package-compute-statistics + `((use-package-statistics-gather :init ',name nil))) + (let ((init-body + (use-package-hook-injector (use-package-as-string name) + :init arg))) + (when init-body + (funcall use-package--hush-function :init + (if use-package-check-before-init + `((when (locate-library ,(use-package-as-string name)) + ,@init-body)) + init-body)))) + (use-package-process-keywords name rest state) + (when use-package-compute-statistics + `((use-package-statistics-gather :init ',name t))))) + +;;;; :load + +(defun use-package-normalize/:load (name keyword args) + (setq args (use-package-normalize-recursive-symlist name keyword args)) + (if (consp args) + args + (list args))) + +(defun use-package-handler/:load (name _keyword arg rest state) + (let ((body (use-package-process-keywords name rest state))) + (cl-dolist (pkg arg) + (setq body (use-package-require (if (eq t pkg) name pkg) nil body))) + body)) + +;;;; :config + +(defalias 'use-package-normalize/:config 'use-package-normalize-forms) + +(defun use-package-handler/:config (name _keyword arg rest state) + (let* ((body (use-package-process-keywords name rest state)) + (name-symbol (use-package-as-symbol name))) + (use-package-concat + (when use-package-compute-statistics + `((use-package-statistics-gather :config ',name nil))) + (if (or (null arg) (equal arg '(t))) + body + (use-package-with-elapsed-timer + (format "Configuring package %s" name-symbol) + (funcall use-package--hush-function :config + (use-package-concat + (use-package-hook-injector + (symbol-name name-symbol) :config arg) + body + (list t))))) + (when use-package-compute-statistics + `((use-package-statistics-gather :config ',name t)))))) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; The main macro +;; + +(defmacro use-package-core (name args) + `(let* ((args* (use-package-normalize-keywords ,name ,args)) + (use-package--form + (if (eq use-package-verbose 'debug) + (concat "\n\n" + (pp-to-string `(use-package ,name ,@,args)) + "\n -->\n\n" + (pp-to-string `(use-package ,name ,@args*)) + "\n ==>\n\n" + (pp-to-string + (macroexp-progn + (let ((use-package-verbose 'errors) + (use-package-expand-minimally t)) + (use-package-process-keywords name args* + (and (plist-get args* :demand) + (list :demand t))))))) + ""))) + (use-package-process-keywords name args* + (and (plist-get args* :demand) + (list :demand t))))) + +;;;###autoload +(defmacro use-package (name &rest args) + "Declare an Emacs package by specifying a group of configuration options. + +For full documentation, please see the README file that came with +this file. Usage: + + (use-package package-name + [:keyword [option]]...) + +:init Code to run before PACKAGE-NAME has been loaded. +:config Code to run after PACKAGE-NAME has been loaded. Note that + if loading is deferred for any reason, this code does not + execute until the lazy load has occurred. +:preface Code to be run before everything except `:disabled'; this + can be used to define functions for use in `:if', or that + should be seen by the byte-compiler. + +:mode Form to be added to `auto-mode-alist'. +:magic Form to be added to `magic-mode-alist'. +:magic-fallback Form to be added to `magic-fallback-mode-alist'. +:interpreter Form to be added to `interpreter-mode-alist'. + +:commands Define autoloads for commands that will be defined by the + package. This is useful if the package is being lazily + loaded, and you wish to conditionally call functions in your + `:init' block that are defined in the package. +:hook Specify hook(s) to attach this package to. + +:bind Bind keys, and define autoloads for the bound commands. +:bind* Bind keys, and define autoloads for the bound commands, + *overriding all minor mode bindings*. +:bind-keymap Bind a key prefix to an auto-loaded keymap defined in the + package. This is like `:bind', but for keymaps. +:bind-keymap* Like `:bind-keymap', but overrides all minor mode bindings + +:defer Defer loading of a package -- this is implied when using + `:commands', `:bind', `:bind*', `:mode', `:magic', `:hook', + `:magic-fallback', or `:interpreter'. This can be an integer, + to force loading after N seconds of idle time, if the package + has not already been loaded. +:after Defer loading of a package until after any of the named + features are loaded. +:demand Prevent deferred loading in all cases. + +:if EXPR Initialize and load only if EXPR evaluates to a non-nil value. +:disabled The package is ignored completely if this keyword is present. +:defines Declare certain variables to silence the byte-compiler. +:functions Declare certain functions to silence the byte-compiler. +:load-path Add to the `load-path' before attempting to load the package. +:diminish Support for diminish.el (if installed). +:delight Support for delight.el (if installed). +:custom Call `customize-set-variable' with each variable definition. +:custom-face Call `customize-set-faces' with each face definition. +:ensure Loads the package using package.el if necessary. +:pin Pin the package to an archive." + (declare (indent 1)) + (unless (memq :disabled args) + (macroexp-progn + (use-package-concat + (when use-package-compute-statistics + `((use-package-statistics-gather :use-package ',name nil))) + (if (eq use-package-verbose 'errors) + (use-package-core name args) + (condition-case-unless-debug err + (use-package-core name args) + (error + (ignore + (display-warning + 'use-package + (format "Failed to parse package %s: %s" + name (error-message-string err)) :error))))) + (when use-package-compute-statistics + `((use-package-statistics-gather :use-package ',name t))))))) + +(put 'use-package 'lisp-indent-function 'defun) + +(provide 'use-package-core) + +;; Local Variables: +;; indent-tabs-mode: nil +;; End: + +;;; use-package-core.el ends here diff --git a/elpa/use-package-20191126.2034/use-package-delight.el b/elpa/use-package-20191126.2034/use-package-delight.el new file mode 100644 index 0000000..85d5c7c --- /dev/null +++ b/elpa/use-package-20191126.2034/use-package-delight.el @@ -0,0 +1,91 @@ +;;; use-package-delight.el --- Support for the :delight keyword -*- lexical-binding: t; -*- + +;; Copyright (C) 2012-2017 John Wiegley + +;; Author: John Wiegley +;; Maintainer: John Wiegley +;; Created: 17 Jun 2012 +;; Modified: 3 Dec 2017 +;; Version: 1.0 +;; Package-Requires: ((emacs "24.3") (use-package "2.4")) +;; Keywords: dotemacs startup speed config package +;; URL: https://github.com/jwiegley/use-package + +;; 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, 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 GNU Emacs; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. + +;;; Commentary: + +;; Provides support for the :delight keyword, which is made available by +;; default by requiring `use-package'. + +;;; Code: + +(require 'use-package-core) + +(defun use-package-normalize-delight (name args) + "Normalize ARGS for a single call to `delight'." + (when (eq :eval (car args)) + ;; Handle likely common mistake. + (use-package-error ":delight mode line constructs must be quoted")) + (cond ((and (= (length args) 1) + (use-package-non-nil-symbolp (car args))) + `(,(nth 0 args) nil ,name)) + ((= (length args) 2) + `(,(nth 0 args) ,(nth 1 args) ,name)) + ((= (length args) 3) + args) + (t + (use-package-error + ":delight expects `delight' arguments or a list of them")))) + +;;;###autoload +(defun use-package-normalize/:delight (name _keyword args) + "Normalize arguments to delight." + (cond ((null args) + `((,(use-package-as-mode name) nil ,name))) + ((and (= (length args) 1) + (use-package-non-nil-symbolp (car args))) + `((,(car args) nil ,name))) + ((and (= (length args) 1) + (stringp (car args))) + `((,(use-package-as-mode name) ,(car args) ,name))) + ((and (= (length args) 1) + (listp (car args)) + (eq 'quote (caar args))) + `((,(use-package-as-mode name) ,@(cdar args) ,name))) + ((and (= (length args) 2) + (listp (nth 1 args)) + (eq 'quote (car (nth 1 args)))) + `((,(car args) ,@(cdr (nth 1 args)) ,name))) + (t (mapcar + (apply-partially #'use-package-normalize-delight name) + (if (use-package-non-nil-symbolp (car args)) + (list args) + args))))) + +;;;###autoload +(defun use-package-handler/:delight (name _keyword args rest state) + (let ((body (use-package-process-keywords name rest state))) + (use-package-concat + body + `((if (fboundp 'delight) + (delight '(,@args))))))) + +(add-to-list 'use-package-keywords :delight t) + +(provide 'use-package-delight) + +;;; use-package-delight.el ends here diff --git a/elpa/use-package-20191126.2034/use-package-diminish.el b/elpa/use-package-20191126.2034/use-package-diminish.el new file mode 100644 index 0000000..1f3895f --- /dev/null +++ b/elpa/use-package-20191126.2034/use-package-diminish.el @@ -0,0 +1,80 @@ +;;; use-package-diminish.el --- Support for the :diminish keyword -*- lexical-binding: t; -*- + +;; Copyright (C) 2012-2017 John Wiegley + +;; Author: John Wiegley +;; Maintainer: John Wiegley +;; Created: 17 Jun 2012 +;; Modified: 3 Dec 2017 +;; Version: 1.0 +;; Package-Requires: ((emacs "24.3") (use-package "2.4")) +;; Keywords: dotemacs startup speed config package +;; URL: https://github.com/jwiegley/use-package + +;; 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, 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 GNU Emacs; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. + +;;; Commentary: + +;; Provides support for the :diminish keyword, which is made available by +;; default by requiring `use-package'. + +;;; Code: + +(require 'use-package-core) + +(defun use-package-normalize-diminish (name label arg &optional recursed) + "Normalize the arguments to diminish down to a list of one of two forms: + SYMBOL + (SYMBOL . STRING)" + (cond + ((not arg) + (list (use-package-as-mode name))) + ((use-package-non-nil-symbolp arg) + (list arg)) + ((stringp arg) + (list (cons (use-package-as-mode name) arg))) + ((and (consp arg) (stringp (cdr arg))) + (list arg)) + ((and (not recursed) (listp arg) (listp (cdr arg))) + (mapcar #'(lambda (x) (car (use-package-normalize-diminish + name label x t))) arg)) + (t + (use-package-error + (concat label " wants a string, symbol, " + "(symbol . string) or list of these"))))) + +;;;###autoload +(defun use-package-normalize/:diminish (name keyword args) + (use-package-as-one (symbol-name keyword) args + (apply-partially #'use-package-normalize-diminish name) t)) + +;;;###autoload +(defun use-package-handler/:diminish (name _keyword arg rest state) + (let ((body (use-package-process-keywords name rest state))) + (use-package-concat + (mapcar #'(lambda (var) + `(if (fboundp 'diminish) + ,(if (consp var) + `(diminish ',(car var) ,(cdr var)) + `(diminish ',var)))) + arg) + body))) + +(add-to-list 'use-package-keywords :diminish t) + +(provide 'use-package-diminish) + +;;; use-package-diminish.el ends here diff --git a/elpa/use-package-20191126.2034/use-package-ensure.el b/elpa/use-package-20191126.2034/use-package-ensure.el new file mode 100644 index 0000000..50005a9 --- /dev/null +++ b/elpa/use-package-20191126.2034/use-package-ensure.el @@ -0,0 +1,214 @@ +;;; use-package-ensure.el --- Support for the :ensure and :pin keywords -*- lexical-binding: t; -*- + +;; Copyright (C) 2012-2017 John Wiegley + +;; Author: John Wiegley +;; Maintainer: John Wiegley +;; Created: 17 Jun 2012 +;; Modified: 3 Dec 2017 +;; Version: 1.0 +;; Package-Requires: ((emacs "24.3") (use-package "2.4")) +;; Keywords: dotemacs startup speed config package +;; URL: https://github.com/jwiegley/use-package + +;; 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, 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 GNU Emacs; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. + +;;; Commentary: + +;; Provides support for the :ensure and :pin keywords, which is made available +;; by default by requiring `use-package'. + +;;; Code: + +(require 'cl-lib) +(require 'use-package-core) + +(defgroup use-package-ensure nil + "Support for :ensure and :pin keywords in use-package declarations." + :group 'use-package) + +(eval-when-compile + (declare-function package-installed-p "package") + (declare-function package-read-all-archive-contents "package" ())) + +(defcustom use-package-always-ensure nil + "Treat every package as though it had specified using `:ensure SEXP'. +See also `use-package-defaults', which uses this value." + :type 'sexp + :group 'use-package-ensure) + +(defcustom use-package-always-pin nil + "Treat every package as though it had specified using `:pin SYM'. +See also `use-package-defaults', which uses this value." + :type 'symbol + :group 'use-package-ensure) + +(defcustom use-package-ensure-function 'use-package-ensure-elpa + "Function that ensures a package is installed. +This function is called with three arguments: the name of the +package declared in the `use-package' form; the arguments passed +to all `:ensure' keywords (always a list, even if only one); and +the current `state' plist created by previous handlers. + +Note that this function is called whenever `:ensure' is provided, +even if it is nil. It is up to the function to decide on the +semantics of the various values for `:ensure'. + +This function should return non-nil if the package is installed. + +The default value uses package.el to install the package." + :type '(choice (const :tag "package.el" use-package-ensure-elpa) + (function :tag "Custom")) + :group 'use-package-ensure) + +;;;; :pin + +(defun use-package-normalize/:pin (_name keyword args) + (use-package-only-one (symbol-name keyword) args + #'(lambda (_label arg) + (cond + ((stringp arg) arg) + ((use-package-non-nil-symbolp arg) (symbol-name arg)) + (t + (use-package-error + ":pin wants an archive name (a string)")))))) + +(eval-when-compile + (defvar package-pinned-packages) + (defvar package-archives)) + +(defun use-package-archive-exists-p (archive) + "Check if a given ARCHIVE is enabled. + +ARCHIVE can be a string or a symbol or 'manual to indicate a +manually updated package." + (if (member archive '(manual "manual")) + 't + (let ((valid nil)) + (dolist (pa package-archives) + (when (member archive (list (car pa) (intern (car pa)))) + (setq valid 't))) + valid))) + +(defun use-package-pin-package (package archive) + "Pin PACKAGE to ARCHIVE." + (unless (boundp 'package-pinned-packages) + (setq package-pinned-packages ())) + (let ((archive-symbol (if (symbolp archive) archive (intern archive))) + (archive-name (if (stringp archive) archive (symbol-name archive)))) + (if (use-package-archive-exists-p archive-symbol) + (add-to-list 'package-pinned-packages (cons package archive-name)) + (error "Archive '%s' requested for package '%s' is not available." + archive-name package)) + (unless (bound-and-true-p package--initialized) + (package-initialize t)))) + +(defun use-package-handler/:pin (name _keyword archive-name rest state) + (let ((body (use-package-process-keywords name rest state)) + (pin-form (if archive-name + `(use-package-pin-package ',(use-package-as-symbol name) + ,archive-name)))) + ;; Pinning should occur just before ensuring + ;; See `use-package-handler/:ensure'. + (if (bound-and-true-p byte-compile-current-file) + (eval pin-form) ; Eval when byte-compiling, + (push pin-form body)) ; or else wait until runtime. + body)) + +;;;; :ensure + +(defvar package-archive-contents) + +;;;###autoload +(defun use-package-normalize/:ensure (_name keyword args) + (if (null args) + (list t) + (use-package-only-one (symbol-name keyword) args + #'(lambda (_label arg) + (cond + ((symbolp arg) + (list arg)) + ((and (listp arg) (= 3 (length arg)) + (symbolp (nth 0 arg)) + (eq :pin (nth 1 arg)) + (or (stringp (nth 2 arg)) + (symbolp (nth 2 arg)))) + (list (cons (nth 0 arg) (nth 2 arg)))) + (t + (use-package-error + (concat ":ensure wants an optional package name " + "(an unquoted symbol name), or ( :pin )")))))))) + +(defun use-package-ensure-elpa (name args _state &optional _no-refresh) + (dolist (ensure args) + (let ((package + (or (and (eq ensure t) (use-package-as-symbol name)) + ensure))) + (when package + (require 'package) + (when (consp package) + (use-package-pin-package (car package) (cdr package)) + (setq package (car package))) + (unless (package-installed-p package) + (condition-case-unless-debug err + (progn + (when (assoc package (bound-and-true-p + package-pinned-packages)) + (package-read-all-archive-contents)) + (if (assoc package package-archive-contents) + (package-install package) + (package-refresh-contents) + (when (assoc package (bound-and-true-p + package-pinned-packages)) + (package-read-all-archive-contents)) + (package-install package)) + t) + (error + (display-warning 'use-package + (format "Failed to install %s: %s" + name (error-message-string err)) + :error)))))))) + +;;;###autoload +(defun use-package-handler/:ensure (name _keyword ensure rest state) + (let* ((body (use-package-process-keywords name rest state))) + ;; We want to avoid installing packages when the `use-package' macro is + ;; being macro-expanded by elisp completion (see `lisp--local-variables'), + ;; but still install packages when byte-compiling, to avoid requiring + ;; `package' at runtime. + (if (bound-and-true-p byte-compile-current-file) + ;; Eval when byte-compiling, + (funcall use-package-ensure-function name ensure state) + ;; or else wait until runtime. + (push `(,use-package-ensure-function ',name ',ensure ',state) + body)) + body)) + +(add-to-list 'use-package-defaults + '(:ensure (list use-package-always-ensure) + (lambda (name args) + (and use-package-always-ensure + (not (plist-member args :load-path))))) t) + +(add-to-list 'use-package-defaults + '(:pin use-package-always-pin use-package-always-pin) t) + +(add-to-list 'use-package-keywords :ensure) +(add-to-list 'use-package-keywords :pin) + +(provide 'use-package-ensure) + +;;; use-package-ensure.el ends here diff --git a/elpa/use-package-20191126.2034/use-package-jump.el b/elpa/use-package-20191126.2034/use-package-jump.el new file mode 100644 index 0000000..4044ad1 --- /dev/null +++ b/elpa/use-package-20191126.2034/use-package-jump.el @@ -0,0 +1,79 @@ +;;; use-package-jump.el --- Attempt to jump to a use-package declaration -*- lexical-binding: t; -*- + +;; Copyright (C) 2012-2017 John Wiegley + +;; Author: John Wiegley +;; Maintainer: John Wiegley +;; Created: 17 Jun 2012 +;; Modified: 3 Dec 2017 +;; Version: 1.0 +;; Package-Requires: ((emacs "24.3") (use-package "2.4")) +;; Keywords: dotemacs startup speed config package +;; URL: https://github.com/jwiegley/use-package + +;; 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, 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 GNU Emacs; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. + +;;; Commentary: + +;; Provides the command `M-x use-package-jump-to-package-form', however it +;; only works if the package being jumped to was required during +;; initialization. If it was delay-loaded, it will not work. Improvements are +;; needed. + +;;; Code: + +(require 'use-package-core) + +(defun use-package-find-require (package) + "Find file that required PACKAGE by searching `load-history'. +Returns an absolute file path or nil if none is found." + (catch 'suspect + (dolist (filespec load-history) + (dolist (entry (cdr filespec)) + (when (equal entry (cons 'require package)) + (throw 'suspect (car filespec))))))) + +;;;###autoload +(defun use-package-jump-to-package-form (package) + "Attempt to find and jump to the `use-package' form that loaded +PACKAGE. This will only find the form if that form actually +required PACKAGE. If PACKAGE was previously required then this +function will jump to the file that originally required PACKAGE +instead." + (interactive (list (completing-read "Package: " features))) + (let* ((package (if (stringp package) (intern package) package)) + (requiring-file (use-package-find-require package)) + file location) + (if (null requiring-file) + (user-error "Can't find file requiring file; may have been autoloaded") + (setq file (if (string= (file-name-extension requiring-file) "elc") + (concat (file-name-sans-extension requiring-file) ".el") + requiring-file)) + (when (file-exists-p file) + (find-file-other-window file) + (save-excursion + (goto-char (point-min)) + (setq location + (re-search-forward + (format (eval use-package-form-regexp-eval) package) nil t))) + (if (null location) + (message "No use-package form found.") + (goto-char location) + (beginning-of-line)))))) + +(provide 'use-package-jump) + +;;; use-package-jump.el ends here diff --git a/elpa/use-package-20191126.2034/use-package-lint.el b/elpa/use-package-20191126.2034/use-package-lint.el new file mode 100644 index 0000000..c6e7c3c --- /dev/null +++ b/elpa/use-package-20191126.2034/use-package-lint.el @@ -0,0 +1,84 @@ +;;; use-package-lint.el --- Attempt to find errors in use-package declarations -*- lexical-binding: t; -*- + +;; Copyright (C) 2012-2017 John Wiegley + +;; Author: John Wiegley +;; Maintainer: John Wiegley +;; Created: 17 Jun 2012 +;; Modified: 3 Dec 2017 +;; Version: 1.0 +;; Package-Requires: ((emacs "24.3") (use-package "2.4")) +;; Keywords: dotemacs startup speed config package +;; URL: https://github.com/jwiegley/use-package + +;; 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, 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 GNU Emacs; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. + +;;; Commentary: + +;; Provides the command `M-x use-package-lint'. + +;;; Code: + +(require 'cl-lib) +(require 'use-package-core) + +(defun use-package-lint-declaration (name plist) + (dolist (path (plist-get plist :load-path)) + (unless (file-exists-p path) + (display-warning + 'use-package + (format "%s :load-path does not exist: %s" + name path) :error))) + + (unless (or (plist-member plist :disabled) + (plist-get plist :no-require) + (locate-library (use-package-as-string name) nil + (plist-get plist :load-path))) + (display-warning + 'use-package + (format "%s module cannot be located" name) :error)) + + ;; (dolist (command (plist-get plist :commands)) + ;; (unless (string= (find-lisp-object-file-name command nil) + ;; (locate-library (use-package-as-string name) nil + ;; (plist-get plist :load-path))) + ;; (display-warning + ;; 'use-package + ;; (format "%s :command is from different path: %s" + ;; name (symbol-name command)) :error))) + ) + +;;;###autoload +(defun use-package-lint () + "Check for errors in use-package declarations. +For example, if the module's `:if' condition is met, but even +with the specified `:load-path' the module cannot be found." + (interactive) + (save-excursion + (goto-char (point-min)) + (let ((re (eval use-package-form-regexp-eval))) + (while (re-search-forward re nil t) + (goto-char (match-beginning 0)) + (let ((decl (read (current-buffer)))) + (when (eq (car decl) 'use-package) + (use-package-lint-declaration + (use-package-as-string (cadr decl)) + (use-package-normalize-keywords + (cadr decl) (cddr decl))))))))) + +(provide 'use-package-lint) + +;;; use-package-lint.el ends here diff --git a/elpa/use-package-20191126.2034/use-package-pkg.el b/elpa/use-package-20191126.2034/use-package-pkg.el new file mode 100644 index 0000000..3e5195f --- /dev/null +++ b/elpa/use-package-20191126.2034/use-package-pkg.el @@ -0,0 +1,13 @@ +(define-package "use-package" "20191126.2034" "A configuration macro for simplifying your .emacs" + '((emacs "24.3") + (bind-key "2.4")) + :keywords + '("dotemacs" "startup" "speed" "config" "package") + :authors + '(("John Wiegley" . "johnw@newartisans.com")) + :maintainer + '("John Wiegley" . "johnw@newartisans.com") + :url "https://github.com/jwiegley/use-package") +;; Local Variables: +;; no-byte-compile: t +;; End: diff --git a/elpa/use-package-20191126.2034/use-package.el b/elpa/use-package-20191126.2034/use-package.el new file mode 100644 index 0000000..1a8fff8 --- /dev/null +++ b/elpa/use-package-20191126.2034/use-package.el @@ -0,0 +1,54 @@ +;;; use-package.el --- A configuration macro for simplifying your .emacs -*- lexical-binding: t; -*- + +;; Copyright (C) 2012-2017 John Wiegley + +;; Author: John Wiegley +;; Maintainer: John Wiegley +;; Created: 17 Jun 2012 +;; Modified: 29 Nov 2017 +;; Version: 2.4 +;; Package-Requires: ((emacs "24.3") (bind-key "2.4")) +;; Keywords: dotemacs startup speed config package +;; URL: https://github.com/jwiegley/use-package + +;; 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, 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 GNU Emacs; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. + +;;; Commentary: + +;; The `use-package' declaration macro allows you to isolate package +;; configuration in your ".emacs" in a way that is performance-oriented and, +;; well, just tidy. I created it because I have over 80 packages that I use +;; in Emacs, and things were getting difficult to manage. Yet with this +;; utility my total load time is just under 1 second, with no loss of +;; functionality! +;; +;; Please see README.md from the same repository for documentation. + +;;; Code: + +(require 'use-package-core) + +(require 'use-package-bind-key) +(require 'use-package-diminish) +(require 'use-package-delight) +(require 'use-package-ensure) + +(declare-function use-package-jump-to-package-form "use-package-jump") +(autoload #'use-package-jump-to-package-form "use-package-jump" nil t) + +(provide 'use-package) + +;;; use-package.el ends here diff --git a/elpa/use-package-20191126.2034/use-package.info b/elpa/use-package-20191126.2034/use-package.info new file mode 100644 index 0000000..9e6a1d8 --- /dev/null +++ b/elpa/use-package-20191126.2034/use-package.info @@ -0,0 +1,1048 @@ +This is use-package.info, produced by makeinfo version 6.5 from +use-package.texi. + + Copyright (C) 2012-2017 John Wiegley + + You can redistribute this document 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 document 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. +INFO-DIR-SECTION Emacs +START-INFO-DIR-ENTRY +* use-package: (use-package). Declarative package configuration for Emacs. +END-INFO-DIR-ENTRY + + +File: use-package.info, Node: Top, Next: Introduction, Up: (dir) + +use-package User Manual +*********************** + +use-package is... + + Copyright (C) 2012-2017 John Wiegley + + You can redistribute this document 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 document 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. + +* Menu: + +* Introduction:: +* Installation:: +* Getting Started:: +* Keywords:: +* FAQ:: +* Debugging Tools:: +* Command Index:: +* Function Index:: +* Variable Index:: + +— The Detailed Node Listing — + + +Installation + +* Installing from an Elpa Archive:: +* Installing from the Git Repository:: +* Post-Installation Tasks:: + + + + +Keywords + +* ‘:after’: after. +* ‘:bind-keymap’, ‘:bind-keymap*’: bind-keymap bind-keymap*. +* ‘:bind’, ‘:bind*’: bind bind*. +* ‘:commands’: commands. +* ‘:preface’, ‘:init’, ‘:config’: preface init config. +* ‘:custom’: custom. +* ‘:custom-face’: custom-face. +* ‘:defer’, ‘:demand’: defer demand. +* ‘:defines’, ‘:functions’: defines functions. +* ‘:diminish’, ‘:delight’: diminish delight. +* ‘:disabled’: disabled. +* ‘:ensure’, ‘:pin’: ensure pin. +* ‘:hook’: hook. +* ‘:if’, ‘:when’, ‘:unless’: if when unless. +* ‘:load-path’: load-path. +* ‘:mode’, ‘:interpreter’: mode interpreter. +* ‘:magic’, ‘:magic-fallback’: magic magic-fallback. +* ‘:no-require’: no-require. +* ‘:requires’: requires. + + + +‘:bind’, ‘:bind*’ + +* Binding to local keymaps:: + +FAQ + +* FAQ - How to ...?:: +* FAQ - Issues and Errors:: + +FAQ - How to ...? + +* This is a question:: + + +FAQ - Issues and Errors + +* This is an issues:: + + +File: use-package.info, Node: Introduction, Next: Installation, Prev: Top, Up: Top + +1 Introduction +************** + +The ‘use-package’ macro allows you to isolate package configuration in +your ‘.emacs’ file in a way that is both performance-oriented and, well, +tidy. I created it because I have over 400 packages that I use in +Emacs, and things were getting difficult to manage. Yet with this +utility my total load time is around 2 seconds, with no loss of +functionality! + + +File: use-package.info, Node: Installation, Next: Getting Started, Prev: Introduction, Up: Top + +2 Installation +************** + +use-package can be installed using Emacs’ package manager or manually +from its development repository. + +* Menu: + +* Installing from an Elpa Archive:: +* Installing from the Git Repository:: +* Post-Installation Tasks:: + + +File: use-package.info, Node: Installing from an Elpa Archive, Next: Installing from the Git Repository, Up: Installation + +2.1 Installing from an Elpa Archive +=================================== + +use-package is available from Melpa and Melpa-Stable. If you haven’t +used Emacs’ package manager before, then it is high time you familiarize +yourself with it by reading the documentation in the Emacs manual, see +*note (emacs)Packages::. Then add one of the archives to +‘package-archives’: + + • To use Melpa: + + (require 'package) + (add-to-list 'package-archives + '("melpa" . "https://melpa.org/packages/") t) + + • To use Melpa-Stable: + + (require 'package) + (add-to-list 'package-archives + '("melpa-stable" . "https://stable.melpa.org/packages/") t) + + Once you have added your preferred archive, you need to update the +local package list using: + + M-x package-refresh-contents RET + + Once you have done that, you can install use-package and its +dependencies using: + + M-x package-install RET use-package RET + + Now see *note Post-Installation Tasks::. + + +File: use-package.info, Node: Installing from the Git Repository, Next: Post-Installation Tasks, Prev: Installing from an Elpa Archive, Up: Installation + +2.2 Installing from the Git Repository +====================================== + +First, use Git to clone the use-package repository: + + $ git clone https://github.com/jwiegley/use-package.git ~/.emacs.d/site-lisp/use-package + $ cd ~/.emacs.d/site-lisp/use-package + + Then compile the libraries and generate the info manuals: + + $ make + + You may need to create ‘/path/to/use-package/config.mk’ with the +following content before running ‘make’: + + LOAD_PATH = -L /path/to/use-package + + Finally add this to your init file: + + (add-to-list 'load-path "~/.emacs.d/site-lisp/use-package") + (require 'use-package) + + (with-eval-after-load 'info + (info-initialize) + (add-to-list 'Info-directory-list + "~/.emacs.d/site-lisp/use-package/")) + + Note that elements of ‘load-path’ should not end with a slash, while +those of ‘Info-directory-list’ should. + + Instead of running use-package directly from the repository by adding +it to the ‘load-path’, you might want to instead install it in some +other directory using ‘sudo make install’ and setting ‘load-path’ +accordingly. + + To update use-package use: + + $ git pull + $ make + + At times it might be necessary to run ‘make clean all’ instead. + + To view all available targets use ‘make help’. + + Now see *note Post-Installation Tasks::. + + +File: use-package.info, Node: Post-Installation Tasks, Prev: Installing from the Git Repository, Up: Installation + +2.3 Post-Installation Tasks +=========================== + +After installing use-package you should verify that you are indeed using +the use-package release you think you are using. It’s best to restart +Emacs before doing so, to make sure you are not using an outdated value +for ‘load-path’. + + C-h v use-package-version RET + + should display something like + + use-package-version’s value is "2.4" + + If you are completely new to use-package then see *note Getting +Started::. + + If you run into problems, then please see the *note FAQ::. Also see +the *note Debugging Tools::. + + +File: use-package.info, Node: Getting Started, Next: Keywords, Prev: Installation, Up: Top + +3 Getting Started +***************** + +TODO. For now, see ‘README.md’. + + +File: use-package.info, Node: Keywords, Next: FAQ, Prev: Getting Started, Up: Top + +4 Keywords +********** + +* Menu: + +* ‘:after’: after. +* ‘:bind-keymap’, ‘:bind-keymap*’: bind-keymap bind-keymap*. +* ‘:bind’, ‘:bind*’: bind bind*. +* ‘:commands’: commands. +* ‘:preface’, ‘:init’, ‘:config’: preface init config. +* ‘:custom’: custom. +* ‘:custom-face’: custom-face. +* ‘:defer’, ‘:demand’: defer demand. +* ‘:defines’, ‘:functions’: defines functions. +* ‘:diminish’, ‘:delight’: diminish delight. +* ‘:disabled’: disabled. +* ‘:ensure’, ‘:pin’: ensure pin. +* ‘:hook’: hook. +* ‘:if’, ‘:when’, ‘:unless’: if when unless. +* ‘:load-path’: load-path. +* ‘:mode’, ‘:interpreter’: mode interpreter. +* ‘:magic’, ‘:magic-fallback’: magic magic-fallback. +* ‘:no-require’: no-require. +* ‘:requires’: requires. + + +File: use-package.info, Node: after, Next: bind-keymap bind-keymap*, Up: Keywords + +4.1 ‘:after’ +============ + +Sometimes it only makes sense to configure a package after another has +been loaded, because certain variables or functions are not in scope +until that time. This can achieved using an ‘:after’ keyword that +allows a fairly rich description of the exact conditions when loading +should occur. Here is an example: + + (use-package hydra + :load-path "site-lisp/hydra") + + (use-package ivy + :load-path "site-lisp/swiper") + + (use-package ivy-hydra + :after (ivy hydra)) + + In this case, because all of these packages are demand-loaded in the +order they occur, the use of ‘:after’ is not strictly necessary. By +using it, however, the above code becomes order-independent, without an +implicit depedence on the nature of your init file. + + By default, ‘:after (foo bar)’ is the same as ‘:after (:all foo +bar)’, meaning that loading of the given package will not happen until +both ‘foo’ and ‘bar’ have been loaded. Here are some of the other +possibilities: + + :after (foo bar) + :after (:all foo bar) + :after (:any foo bar) + :after (:all (:any foo bar) (:any baz quux)) + :after (:any (:all foo bar) (:all baz quux)) + + When you nest selectors, such as ‘(:any (:all foo bar) (:all baz +quux))’, it means that the package will be loaded when either both ‘foo’ +and ‘bar’ have been loaded, or both ‘baz’ and ‘quux’ have been loaded. + + +File: use-package.info, Node: bind-keymap bind-keymap*, Next: bind bind*, Prev: after, Up: Keywords + +4.2 ‘:bind-keymap’, ‘:bind-keymap*’ +=================================== + +Normally ‘:bind’ expects that commands are functions that will be +autoloaded from the given package. However, this does not work if one +of those commands is actually a keymap, since keymaps are not functions, +and cannot be autoloaded using Emacs’ ‘autoload’ mechanism. + + To handle this case, ‘use-package’ offers a special, limited variant +of ‘:bind’ called ‘:bind-keymap’. The only difference is that the +"commands" bound to by ‘:bind-keymap’ must be keymaps defined in the +package, rather than command functions. This is handled behind the +scenes by generating custom code that loads the package containing the +keymap, and then re-executes your keypress after the first load, to +reinterpret that keypress as a prefix key. + + For example: + + (use-package projectile + :bind-keymap + ("C-c p" . projectile-command-map) + + +File: use-package.info, Node: bind bind*, Next: commands, Prev: bind-keymap bind-keymap*, Up: Keywords + +4.3 ‘:bind’, ‘:bind*’ +===================== + +Another common thing to do when loading a module is to bind a key to +primary commands within that module: + + (use-package ace-jump-mode + :bind ("C-." . ace-jump-mode)) + + This does two things: first, it creates an autoload for the +‘ace-jump-mode’ command and defers loading of ‘ace-jump-mode’ until you +actually use it. Second, it binds the key ‘C-.’ to that command. After +loading, you can use ‘M-x describe-personal-keybindings’ to see all such +keybindings you’ve set throughout your ‘.emacs’ file. + + A more literal way to do the exact same thing is: + + (use-package ace-jump-mode + :commands ace-jump-mode + :init + (bind-key "C-." 'ace-jump-mode)) + + When you use the ‘:commands’ keyword, it creates autoloads for those +commands and defers loading of the module until they are used. Since +the ‘:init’ form is always run—even if ‘ace-jump-mode’ might not be on +your system—remember to restrict ‘:init’ code to only what would succeed +either way. + + The ‘:bind’ keyword takes either a cons or a list of conses: + + (use-package hi-lock + :bind (("M-o l" . highlight-lines-matching-regexp) + ("M-o r" . highlight-regexp) + ("M-o w" . highlight-phrase))) + + The ‘:commands’ keyword likewise takes either a symbol or a list of +symbols. + + NOTE: Special keys like ‘tab’ or ‘F1’-‘Fn’ can be written in square +brackets, i.e. ‘[tab]’ instead of ‘"tab"’. The syntax for the +keybindings is similar to the "kbd" syntax: see the Emacs Manual +(https://www.gnu.org/software/emacs/manual/html_node/emacs/Init-Rebinding.html) +for more information. + + Examples: + + (use-package helm + :bind (("M-x" . helm-M-x) + ("M-" . helm-find-files) + ([f10] . helm-buffers-list) + ([S-f10] . helm-recentf))) + +* Menu: + +* Binding to local keymaps:: + + +File: use-package.info, Node: Binding to local keymaps, Up: bind bind* + +4.3.1 Binding to local keymaps +------------------------------ + +Slightly different from binding a key to a keymap, is binding a key +*within* a local keymap that only exists after the package is loaded. +‘use-package’ supports this with a ‘:map’ modifier, taking the local +keymap to bind to: + + (use-package helm + :bind (:map helm-command-map + ("C-c h" . helm-execute-persistent-action))) + + The effect of this statement is to wait until ‘helm’ has loaded, and +then to bind the key ‘C-c h’ to ‘helm-execute-persistent-action’ within +Helm’s local keymap, ‘helm-mode-map’. + + Multiple uses of ‘:map’ may be specified. Any binding occurring +before the first use of ‘:map’ are applied to the global keymap: + + (use-package term + :bind (("C-c t" . term) + :map term-mode-map + ("M-p" . term-send-up) + ("M-n" . term-send-down) + :map term-raw-map + ("M-o" . other-window) + ("M-p" . term-send-up) + ("M-n" . term-send-down))) + + +File: use-package.info, Node: commands, Next: preface init config, Prev: bind bind*, Up: Keywords + +4.4 ‘:commands’ +=============== + + +File: use-package.info, Node: preface init config, Next: custom, Prev: commands, Up: Keywords + +4.5 ‘:preface’, ‘:init’, ‘:config’ +================================== + +Here is the simplest ‘use-package’ declaration: + + ;; This is only needed once, near the top of the file + (eval-when-compile + ;; Following line is not needed if use-package.el is in ~/.emacs.d + (add-to-list 'load-path "") + (require 'use-package)) + + (use-package foo) + + This loads in the package ‘foo’, but only if ‘foo’ is available on +your system. If not, a warning is logged to the ‘*Messages*’ buffer. +If it succeeds, a message about ‘"Loading foo"’ is logged, along with +the time it took to load, if it took over 0.1 seconds. + + Use the ‘:init’ keyword to execute code before a package is loaded. +It accepts one or more forms, up until the next keyword: + + (use-package foo + :init + (setq foo-variable t)) + + Similarly, ‘:config’ can be used to execute code after a package is +loaded. In cases where loading is done lazily (see more about +autoloading below), this execution is deferred until after the autoload +occurs: + + (use-package foo + :init + (setq foo-variable t) + :config + (foo-mode 1)) + + As you might expect, you can use ‘:init’ and ‘:config’ together: + + (use-package color-moccur + :commands (isearch-moccur isearch-all) + :bind (("M-s O" . moccur) + :map isearch-mode-map + ("M-o" . isearch-moccur) + ("M-O" . isearch-moccur-all)) + :init + (setq isearch-lazy-highlight t) + :config + (use-package moccur-edit)) + + In this case, I want to autoload the commands ‘isearch-moccur’ and +‘isearch-all’ from ‘color-moccur.el’, and bind keys both at the global +level and within the ‘isearch-mode-map’ (see next section). When the +package is actually loaded (by using one of these commands), +‘moccur-edit’ is also loaded, to allow editing of the ‘moccur’ buffer. + + +File: use-package.info, Node: custom, Next: custom-face, Prev: preface init config, Up: Keywords + +4.6 ‘:custom’ +============= + +The ‘:custom’ keyword allows customization of package custom variables. + + (use-package comint + :custom + (comint-buffer-maximum-size 20000 "Increase comint buffer size.") + (comint-prompt-read-only t "Make the prompt read only.")) + + The documentation string is not mandatory. + + +File: use-package.info, Node: custom-face, Next: defer demand, Prev: custom, Up: Keywords + +4.7 ‘:custom-face’ +================== + +The ‘:custom-face’ keyword allows customization of package custom faces. + + (use-package eruby-mode + :custom-face + (eruby-standard-face ((t (:slant italic))))) + + +File: use-package.info, Node: defer demand, Next: defines functions, Prev: custom-face, Up: Keywords + +4.8 ‘:defer’, ‘:demand’ +======================= + +In almost all cases you don’t need to manually specify ‘:defer t’. This +is implied whenever ‘:bind’ or ‘:mode’ or ‘:interpreter’ is used. +Typically, you only need to specify ‘:defer’ if you know for a fact that +some other package will do something to cause your package to load at +the appropriate time, and thus you would like to defer loading even +though use-package isn’t creating any autoloads for you. + + You can override package deferral with the ‘:demand’ keyword. Thus, +even if you use ‘:bind’, using ‘:demand’ will force loading to occur +immediately and not establish an autoload for the bound key. + + +File: use-package.info, Node: defines functions, Next: diminish delight, Prev: defer demand, Up: Keywords + +4.9 ‘:defines’, ‘:functions’ +============================ + +Another feature of ‘use-package’ is that it always loads every file that +it can when ‘.emacs’ is being byte-compiled. This helps to silence +spurious warnings about unknown variables and functions. + + However, there are times when this is just not enough. For those +times, use the ‘:defines’ and ‘:functions’ keywords to introduce dummy +variable and function declarations solely for the sake of the +byte-compiler: + + (use-package texinfo + :defines texinfo-section-list + :commands texinfo-mode + :init + (add-to-list 'auto-mode-alist '("\\.texi$" . texinfo-mode))) + + If you need to silence a missing function warning, you can use +‘:functions’: + + (use-package ruby-mode + :mode "\\.rb\\'" + :interpreter "ruby" + :functions inf-ruby-keys + :config + (defun my-ruby-mode-hook () + (require 'inf-ruby) + (inf-ruby-keys)) + + (add-hook 'ruby-mode-hook 'my-ruby-mode-hook)) + + +File: use-package.info, Node: diminish delight, Next: disabled, Prev: defines functions, Up: Keywords + +4.10 ‘:diminish’, ‘:delight’ +============================ + +‘use-package’ also provides built-in support for the diminish and +delight utilities—if you have them installed. Their purpose is to +remove or change minor mode strings in your mode-line. + + diminish (https://github.com/myrjola/diminish.el) is invoked with the +‘:diminish’ keyword, which is passed either a minor mode symbol, a cons +of the symbol and its replacement string, or just a replacement string, +in which case the minor mode symbol is guessed to be the package name +with "-mode" appended at the end: + + (use-package abbrev + :diminish abbrev-mode + :config + (if (file-exists-p abbrev-file-name) + (quietly-read-abbrev-file))) + + delight (https://elpa.gnu.org/packages/delight.html) is invoked with +the ‘:delight’ keyword, which is passed a minor mode symbol, a +replacement string or quoted mode-line data +(https://www.gnu.org/software/emacs/manual/html_node/elisp/Mode-Line-Data.html) +(in which case the minor mode symbol is guessed to be the package name +with "-mode" appended at the end), both of these, or several lists of +both. If no arguments are provided, the default mode name is hidden +completely. + + ;; Don't show anything for rainbow-mode. + (use-package rainbow-mode + :delight) + + ;; Don't show anything for auto-revert-mode, which doesn't match + ;; its package name. + (use-package autorevert + :delight auto-revert-mode) + + ;; Remove the mode name for projectile-mode, but show the project name. + (use-package projectile + :delight '(:eval (concat " " (projectile-project-name)))) + + ;; Completely hide visual-line-mode and change auto-fill-mode to " AF". + (use-package emacs + :delight + (auto-fill-function " AF") + (visual-line-mode)) + + +File: use-package.info, Node: disabled, Next: ensure pin, Prev: diminish delight, Up: Keywords + +4.11 ‘:disabled’ +================ + +The ‘:disabled’ keyword can turn off a module you’re having difficulties +with, or stop loading something you’re not using at the present time: + + (use-package ess-site + :disabled + :commands R) + + When byte-compiling your ‘.emacs’ file, disabled declarations are +omitted from the output entirely, to accelerate startup times. + + +File: use-package.info, Node: ensure pin, Next: hook, Prev: disabled, Up: Keywords + +4.12 ‘:ensure’, ‘:pin’ +====================== + +You can use ‘use-package’ to load packages from ELPA with ‘package.el’. +This is particularly useful if you share your ‘.emacs’ among several +machines; the relevant packages are downloaded automatically once +declared in your ‘.emacs’. The ‘:ensure’ keyword causes the package(s) +to be installed automatically if not already present on your system (set +‘(setq use-package-always-ensure t)’ if you wish this behavior to be +global for all packages): + + (use-package magit + :ensure t) + + If you need to install a different package from the one named by +‘use-package’, you can specify it like this: + + (use-package tex + :ensure auctex) + + Lastly, when running on Emacs 24.4 or later, use-package can pin a +package to a specific archive, allowing you to mix and match packages +from different archives. The primary use-case for this is preferring +packages from the ‘melpa-stable’ and ‘gnu’ archives, but using specific +packages from ‘melpa’ when you need to track newer versions than what is +available in the ‘stable’ archives is also a valid use-case. + + By default ‘package.el’ prefers ‘melpa’ over ‘melpa-stable’ due to +the versioning ‘(> evil-20141208.623 evil-1.0.9)’, so even if you are +tracking only a single package from ‘melpa’, you will need to tag all +the non-‘melpa’ packages with the appropriate archive. If this really +annoys you, then you can set ‘use-package-always-pin’ to set a default. + + If you want to manually keep a package updated and ignore upstream +updates, you can pin it to ‘manual’, which as long as there is no +repository by that name, will Just Work(tm). + + ‘use-package’ throws an error if you try to pin a package to an +archive that has not been configured using ‘package-archives’ (apart +from the magic ‘manual’ archive mentioned above): + + Archive 'foo' requested for package 'bar' is not available. + + Example: + + (use-package company + :ensure t + :pin melpa-stable) + + (use-package evil + :ensure t) + ;; no :pin needed, as package.el will choose the version in melpa + + (use-package adaptive-wrap + :ensure t + ;; as this package is available only in the gnu archive, this is + ;; technically not needed, but it helps to highlight where it + ;; comes from + :pin gnu) + + (use-package org + :ensure t + ;; ignore org-mode from upstream and use a manually installed version + :pin manual) + + *NOTE*: the ‘:pin’ argument has no effect on emacs versions < 24.4. + + +File: use-package.info, Node: hook, Next: if when unless, Prev: ensure pin, Up: Keywords + +4.13 ‘:hook’ +============ + +The ‘:hook’ keyword allows adding functions onto hooks, here only the +basename of the hook is required. Thus, all of the following are +equivalent: + + (use-package ace-jump-mode + :hook prog-mode) + + (use-package ace-jump-mode + :hook (prog-mode . ace-jump-mode)) + + (use-package ace-jump-mode + :commands ace-jump-mode + :init + (add-hook 'prog-mode-hook #'ace-jump-mode)) + + And likewise, when multiple hooks should be applied, the following +are also equivalent: + + (use-package ace-jump-mode + :hook (prog-mode text-mode)) + + (use-package ace-jump-mode + :hook ((prog-mode text-mode) . ace-jump-mode)) + + (use-package ace-jump-mode + :hook ((prog-mode . ace-jump-mode) + (text-mode . ace-jump-mode))) + + (use-package ace-jump-mode + :commands ace-jump-mode + :init + (add-hook 'prog-mode-hook #'ace-jump-mode) + (add-hook 'text-mode-hook #'ace-jump-mode)) + + The use of ‘:hook’, as with ‘:bind’, ‘:mode’, ‘:interpreter’, etc., +causes the functions being hooked to implicitly be read as ‘:commands’ +(meaning they will establish interactive ‘autoload’ definitions for that +module, if not already defined as functions), and so ‘:defer t’ is also +implied by ‘:hook’. + + +File: use-package.info, Node: if when unless, Next: load-path, Prev: hook, Up: Keywords + +4.14 ‘:if’, ‘:when’, ‘:unless’ +============================== + +You can use the ‘:if’ keyword to predicate the loading and +initialization of modules. + + For example, I only want ‘edit-server’ running for my main, graphical +Emacs, not for other Emacsen I may start at the command line: + + (use-package edit-server + :if window-system + :init + (add-hook 'after-init-hook 'server-start t) + (add-hook 'after-init-hook 'edit-server-start t)) + + In another example, we can load things conditional on the operating +system: + + (use-package exec-path-from-shell + :if (memq window-system '(mac ns)) + :ensure t + :config + (exec-path-from-shell-initialize)) + + Note that ‘:when’ is provided as an alias for ‘:if’, and ‘:unless +foo’ means the same thing as ‘:if (not foo)’. + + +File: use-package.info, Node: load-path, Next: mode interpreter, Prev: if when unless, Up: Keywords + +4.15 ‘:load-path’ +================= + +If your package needs a directory added to the ‘load-path’ in order to +load, use ‘:load-path’. This takes a symbol, a function, a string or a +list of strings. If the path is relative, it is expanded within +‘user-emacs-directory’: + + (use-package ess-site + :load-path "site-lisp/ess/lisp/" + :commands R) + + Note that when using a symbol or a function to provide a dynamically +generated list of paths, you must inform the byte-compiler of this +definition so the value is available at byte-compilation time. This is +done by using the special form ‘eval-and-compile’ (as opposed to +‘eval-when-compile’). Further, this value is fixed at whatever was +determined during compilation, to avoid looking up the same information +again on each startup: + + (eval-and-compile + (defun ess-site-load-path () + (shell-command "find ~ -path ess/lisp"))) + + (use-package ess-site + :load-path (lambda () (list (ess-site-load-path))) + :commands R) + + +File: use-package.info, Node: mode interpreter, Next: magic magic-fallback, Prev: load-path, Up: Keywords + +4.16 ‘:mode’, ‘:interpreter’ +============================ + +Similar to ‘:bind’, you can use ‘:mode’ and ‘:interpreter’ to establish +a deferred binding within the ‘auto-mode-alist’ and +‘interpreter-mode-alist’ variables. The specifier to either keyword can +be a cons cell, a list of cons cells, or a string or regexp: + + (use-package ruby-mode + :mode "\\.rb\\'" + :interpreter "ruby") + + ;; The package is "python" but the mode is "python-mode": + (use-package python + :mode ("\\.py\\'" . python-mode) + :interpreter ("python" . python-mode)) + + If you aren’t using ‘:commands’, ‘:bind’, ‘:bind*’, ‘:bind-keymap’, +‘:bind-keymap*’, ‘:mode’, or ‘:interpreter’ (all of which imply +‘:defer’; see the docstring for ‘use-package’ for a brief description of +each), you can still defer loading with the ‘:defer’ keyword: + + (use-package ace-jump-mode + :defer t + :init + (autoload 'ace-jump-mode "ace-jump-mode" nil t) + (bind-key "C-." 'ace-jump-mode)) + + This does exactly the same thing as the following: + + (use-package ace-jump-mode + :bind ("C-." . ace-jump-mode)) + + +File: use-package.info, Node: magic magic-fallback, Next: no-require, Prev: mode interpreter, Up: Keywords + +4.17 ‘:magic’, ‘:magic-fallback’ +================================ + +Similar to ‘:mode‘ and ‘:interpreter‘, you can also use ‘:magic‘ and +‘:magic-fallback‘ to cause certain function to be run if the beginning +of a file matches a given regular expression. The difference between +the two is that ‘:magic-fallback‘ has a lower priority than ‘:mode‘. +For example: + + “‘ elisp (use-package pdf-tools :load-path "site-lisp/pdf-tools/lisp" +:magic ("%PDF" . pdf-view-mode) :config (pdf-tools-install)) “‘ + + This registers an autoloaded command for ‘pdf-view-mode‘, defers +loading of ‘pdf-tools‘, and runs ‘pdf-view-mode‘ if the beginning of a +buffer matches the string ‘"%PDF"‘. + + +File: use-package.info, Node: no-require, Next: requires, Prev: magic magic-fallback, Up: Keywords + +4.18 ‘:no-require’ +================== + +Normally, ‘use-package’ will load each package at compile time before +compiling the configuration, to ensure that any necessary symbols are in +scope to satisfy the byte-compiler. At times this can cause problems, +since a package may have special loading requirements, and all that you +want to use ‘use-package’ for is to add a configuration to the +‘eval-after-load’ hook. In such cases, use the ‘:no-require’ keyword: + + (use-package foo + :no-require t + :config + (message "This is evaluated when `foo' is loaded")) + + +File: use-package.info, Node: requires, Prev: no-require, Up: Keywords + +4.19 ‘:requires’ +================ + +While the ‘:after’ keyword delays loading until the dependencies are +loaded, the somewhat simpler ‘:requires’ keyword simply never loads the +package if the dependencies are not available at the time the +‘use-package’ declaration is encountered. By "available" in this +context it means that ‘foo’ is available of ‘(featurep 'foo)’ evaluates +to a non-nil value. For example: + + (use-package abbrev + :requires foo) + + This is the same as: + + (use-package abbrev + :if (featurep 'foo)) + + As a convenience, a list of such packages may be specified: + + (use-package abbrev + :requires (foo bar baz)) + + For more complex logic, such as that supported by ‘:after’, simply +use ‘:if’ and the appropriate Lisp expression. + + +File: use-package.info, Node: FAQ, Next: Debugging Tools, Prev: Keywords, Up: Top + +Appendix A FAQ +************** + +The next two nodes lists frequently asked questions. + + Please also use the *note Debugging Tools::. + +* Menu: + +* FAQ - How to ...?:: +* FAQ - Issues and Errors:: + + +File: use-package.info, Node: FAQ - How to ...?, Next: FAQ - Issues and Errors, Up: FAQ + +A.1 FAQ - How to ...? +===================== + +* Menu: + +* This is a question:: + + +File: use-package.info, Node: This is a question, Up: FAQ - How to ...? + +A.1.1 This is a question +------------------------ + +This is an answer. + + +File: use-package.info, Node: FAQ - Issues and Errors, Prev: FAQ - How to ...?, Up: FAQ + +A.2 FAQ - Issues and Errors +=========================== + +* Menu: + +* This is an issues:: + + +File: use-package.info, Node: This is an issues, Up: FAQ - Issues and Errors + +A.2.1 This is an issues +----------------------- + +This is a description. + + +File: use-package.info, Node: Debugging Tools, Next: Command Index, Prev: FAQ, Up: Top + +B Debugging Tools +***************** + +TODO + + Please also see the *note FAQ::. + + +File: use-package.info, Node: Command Index, Next: Function Index, Prev: Debugging Tools, Up: Top + +Appendix C Command Index +************************ + + +File: use-package.info, Node: Function Index, Next: Variable Index, Prev: Command Index, Up: Top + +Appendix D Function Index +************************* + + +File: use-package.info, Node: Variable Index, Prev: Function Index, Up: Top + +Appendix E Variable Index +************************* + + + +Tag Table: +Node: Top784 +Node: Introduction2819 +Node: Installation3306 +Node: Installing from an Elpa Archive3658 +Node: Installing from the Git Repository4773 +Node: Post-Installation Tasks6309 +Node: Getting Started7022 +Node: Keywords7194 +Node: after8113 +Node: bind-keymap bind-keymap*9645 +Node: bind bind*10698 +Node: Binding to local keymaps12738 +Node: commands13829 +Node: preface init config13971 +Node: custom16049 +Node: custom-face16489 +Node: defer demand16809 +Node: defines functions17621 +Node: diminish delight18766 +Node: disabled20709 +Node: ensure pin21204 +Node: hook23934 +Node: if when unless25352 +Node: load-path26298 +Node: mode interpreter27444 +Node: magic magic-fallback28755 +Node: no-require29600 +Node: requires30304 +Node: FAQ31191 +Node: FAQ - How to ...?31474 +Node: This is a question31646 +Node: FAQ - Issues and Errors31794 +Node: This is an issues31977 +Node: Debugging Tools32132 +Node: Command Index32306 +Node: Function Index32462 +Node: Variable Index32619 + +End Tag Table + + +Local Variables: +coding: utf-8 +End: