[ELPA] Some more packages
parent
60905453ef
commit
4daeaba40c
@ -0,0 +1,2 @@
|
||||
;;; -*- no-byte-compile: t -*-
|
||||
(define-package "dash" "20170810.137" "A modern list library for Emacs" 'nil :commit "0df0ff1a65d54377381e50c08d88b247db44c3dd" :keywords '("lists"))
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,2 @@
|
||||
;;; -*- no-byte-compile: t -*-
|
||||
(define-package "exec-path-from-shell" "20170508.4" "Get environment variables such as $PATH from the shell" 'nil :commit "5e355fbc50913d1ffe48bf86df0bcecd8b369ffb" :url "https://github.com/purcell/exec-path-from-shell" :keywords '("environment"))
|
@ -0,0 +1,270 @@
|
||||
;;; exec-path-from-shell.el --- Get environment variables such as $PATH from the shell
|
||||
|
||||
;; Copyright (C) 2012-2014 Steve Purcell
|
||||
|
||||
;; Author: Steve Purcell <steve@sanityinc.com>
|
||||
;; Keywords: environment
|
||||
;; URL: https://github.com/purcell/exec-path-from-shell
|
||||
;; Package-Version: 20170508.4
|
||||
;; Package-X-Original-Version: 0
|
||||
|
||||
;; This file is not part of GNU Emacs.
|
||||
|
||||
;; This file is free software: you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
|
||||
;; This file 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 file. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
;; On OS X (and perhaps elsewhere) the $PATH environment variable and
|
||||
;; `exec-path' used by a windowed Emacs instance will usually be the
|
||||
;; system-wide default path, rather than that seen in a terminal
|
||||
;; window.
|
||||
|
||||
;; This library allows the user to set Emacs' `exec-path' and $PATH
|
||||
;; from the shell path, so that `shell-command', `compile' and the
|
||||
;; like work as expected.
|
||||
|
||||
;; It also allows other environment variables to be retrieved from the
|
||||
;; shell, so that Emacs will see the same values you get in a terminal.
|
||||
|
||||
;; If you use a non-POSIX-standard shell like "tcsh" or "fish", your
|
||||
;; shell will be asked to execute "sh" as a subshell in order to print
|
||||
;; out the variables in a format which can be reliably parsed. "sh"
|
||||
;; must be a POSIX-compliant shell in this case.
|
||||
|
||||
;; Note that shell variables which have not been exported as
|
||||
;; environment variables (e.g. using the "export" keyword) may not be
|
||||
;; visible to `exec-path-from-shell'.
|
||||
|
||||
;; Installation:
|
||||
|
||||
;; ELPA packages are available on Marmalade and MELPA. Alternatively,
|
||||
;; place this file on a directory in your `load-path', and explicitly
|
||||
;; require it.
|
||||
|
||||
;; Usage:
|
||||
;;
|
||||
;; (require 'exec-path-from-shell) ;; if not using the ELPA package
|
||||
;; (exec-path-from-shell-initialize)
|
||||
;;
|
||||
;; Customize `exec-path-from-shell-variables' to modify the list of
|
||||
;; variables imported.
|
||||
;;
|
||||
;; If you use your Emacs config on other platforms, you can instead
|
||||
;; make initialization conditional as follows:
|
||||
;;
|
||||
;; (when (memq window-system '(mac ns))
|
||||
;; (exec-path-from-shell-initialize))
|
||||
;;
|
||||
;; Alternatively, you can use `exec-path-from-shell-copy-envs' or
|
||||
;; `exec-path-from-shell-copy-env' directly, e.g.
|
||||
;;
|
||||
;; (exec-path-from-shell-copy-env "PYTHONPATH")
|
||||
|
||||
;;; Code:
|
||||
|
||||
(defgroup exec-path-from-shell nil
|
||||
"Make Emacs use shell-defined values for $PATH etc."
|
||||
:prefix "exec-path-from-shell-"
|
||||
:group 'environment)
|
||||
|
||||
(defcustom exec-path-from-shell-variables
|
||||
'("PATH" "MANPATH")
|
||||
"List of environment variables which are copied from the shell."
|
||||
:type '(repeat (string :tag "Environment variable"))
|
||||
:group 'exec-path-from-shell)
|
||||
|
||||
(defcustom exec-path-from-shell-check-startup-files t
|
||||
"If non-nil, warn if variables are being set in the wrong shell startup files.
|
||||
Environment variables should be set in .profile or .zshenv rather than
|
||||
.bashrc or .zshrc."
|
||||
:type 'boolean
|
||||
:group 'exec-path-from-shell)
|
||||
|
||||
(defcustom exec-path-from-shell-shell-name nil
|
||||
"If non-nil, use this shell executable.
|
||||
Otherwise, use either `shell-file-name' (if set), or the value of
|
||||
the SHELL environment variable."
|
||||
:type '(choice
|
||||
(file :tag "Shell executable")
|
||||
(const :tag "Use `shell-file-name' or $SHELL" nil))
|
||||
:group 'exec-path-from-shell)
|
||||
|
||||
(defvar exec-path-from-shell-debug nil
|
||||
"Display debug info when non-nil.")
|
||||
|
||||
(defun exec-path-from-shell--double-quote (s)
|
||||
"Double-quote S, escaping any double-quotes already contained in it."
|
||||
(concat "\"" (replace-regexp-in-string "\"" "\\\\\"" s) "\""))
|
||||
|
||||
(defun exec-path-from-shell--shell ()
|
||||
"Return the shell to use.
|
||||
See documentation for `exec-path-from-shell-shell-name'."
|
||||
(or
|
||||
exec-path-from-shell-shell-name
|
||||
shell-file-name
|
||||
(getenv "SHELL")
|
||||
(error "SHELL environment variable is unset")))
|
||||
|
||||
(defcustom exec-path-from-shell-arguments
|
||||
(if (string-match-p "t?csh$" (exec-path-from-shell--shell))
|
||||
(list "-d")
|
||||
(list "-l" "-i"))
|
||||
"Additional arguments to pass to the shell.
|
||||
|
||||
The default value denotes an interactive login shell."
|
||||
:type '(repeat (string :tag "Shell argument"))
|
||||
:group 'exec-path-from-shell)
|
||||
|
||||
(defun exec-path-from-shell--debug (msg &rest args)
|
||||
"Print MSG and ARGS like `message', but only if debug output is enabled."
|
||||
(when exec-path-from-shell-debug
|
||||
(apply 'message msg args)))
|
||||
|
||||
(defun exec-path-from-shell--standard-shell-p (shell)
|
||||
"Return non-nil iff the shell supports the standard ${VAR-default} syntax."
|
||||
(not (string-match "\\(fish\\|t?csh\\)$" shell)))
|
||||
|
||||
(defun exec-path-from-shell-printf (str &optional args)
|
||||
"Return the result of printing STR in the user's shell.
|
||||
|
||||
Executes the shell as interactive login shell.
|
||||
|
||||
STR is inserted literally in a single-quoted argument to printf,
|
||||
and may therefore contain backslashed escape sequences understood
|
||||
by printf.
|
||||
|
||||
ARGS is an optional list of args which will be inserted by printf
|
||||
in place of any % placeholders in STR. ARGS are not automatically
|
||||
shell-escaped, so they may contain $ etc."
|
||||
(let* ((printf-bin (or (executable-find "printf") "printf"))
|
||||
(printf-command
|
||||
(concat printf-bin
|
||||
" '__RESULT\\000" str "\\000__RESULT' "
|
||||
(mapconcat #'exec-path-from-shell--double-quote args " ")))
|
||||
(shell (exec-path-from-shell--shell))
|
||||
(shell-args (append exec-path-from-shell-arguments
|
||||
(list "-c"
|
||||
(if (exec-path-from-shell--standard-shell-p shell)
|
||||
printf-command
|
||||
(concat "sh -c " (shell-quote-argument printf-command)))))))
|
||||
(with-temp-buffer
|
||||
(exec-path-from-shell--debug "Invoking shell %s with args %S" shell shell-args)
|
||||
(let ((exit-code (apply #'call-process shell nil t nil shell-args)))
|
||||
(exec-path-from-shell--debug "Shell printed: %S" (buffer-string))
|
||||
(unless (zerop exit-code)
|
||||
(error "Non-zero exit code from shell %s invoked with args %S. Output was:\n%S"
|
||||
shell shell-args (buffer-string))))
|
||||
(goto-char (point-min))
|
||||
(if (re-search-forward "__RESULT\0\\(.*\\)\0__RESULT" nil t)
|
||||
(match-string 1)
|
||||
(error "Expected printf output from shell, but got: %S" (buffer-string))))))
|
||||
|
||||
(defun exec-path-from-shell-getenvs (names)
|
||||
"Get the environment variables with NAMES from the user's shell.
|
||||
|
||||
Execute the shell according to `exec-path-from-shell-arguments'.
|
||||
The result is a list of (NAME . VALUE) pairs."
|
||||
(let* ((random-default (md5 (format "%s%s%s" (emacs-pid) (random) (current-time))))
|
||||
(dollar-names (mapcar (lambda (n) (format "${%s-%s}" n random-default)) names))
|
||||
(values (split-string (exec-path-from-shell-printf
|
||||
(mapconcat #'identity (make-list (length names) "%s") "\\000")
|
||||
dollar-names) "\0")))
|
||||
(let (result)
|
||||
(while names
|
||||
(prog1
|
||||
(let ((value (car values)))
|
||||
(push (cons (car names)
|
||||
(unless (string-equal random-default value)
|
||||
value))
|
||||
result))
|
||||
(setq values (cdr values)
|
||||
names (cdr names))))
|
||||
result)))
|
||||
|
||||
(defun exec-path-from-shell-getenv (name)
|
||||
"Get the environment variable NAME from the user's shell.
|
||||
|
||||
Execute the shell as interactive login shell, have it output the
|
||||
variable of NAME and return this output as string."
|
||||
(cdr (assoc name (exec-path-from-shell-getenvs (list name)))))
|
||||
|
||||
(defun exec-path-from-shell-setenv (name value)
|
||||
"Set the value of environment var NAME to VALUE.
|
||||
Additionally, if NAME is \"PATH\" then also set corresponding
|
||||
variables such as `exec-path'."
|
||||
(setenv name value)
|
||||
(when (string-equal "PATH" name)
|
||||
(setq eshell-path-env value
|
||||
exec-path (append (parse-colon-path value) (list exec-directory)))))
|
||||
|
||||
;;;###autoload
|
||||
(defun exec-path-from-shell-copy-envs (names)
|
||||
"Set the environment variables with NAMES from the user's shell.
|
||||
|
||||
As a special case, if the variable is $PATH, then `exec-path' and
|
||||
`eshell-path-env' are also set appropriately. The result is an alist,
|
||||
as described by `exec-path-from-shell-getenvs'."
|
||||
(let ((pairs (exec-path-from-shell-getenvs names)))
|
||||
(when exec-path-from-shell-check-startup-files
|
||||
(exec-path-from-shell--maybe-warn-about-startup-files pairs))
|
||||
(mapc (lambda (pair)
|
||||
(exec-path-from-shell-setenv (car pair) (cdr pair)))
|
||||
pairs)))
|
||||
|
||||
(defun exec-path-from-shell--maybe-warn-about-startup-files (pairs)
|
||||
"Warn the user if the value of PAIRS seems to depend on interactive shell startup files."
|
||||
(let ((without-minus-i (remove "-i" exec-path-from-shell-arguments)))
|
||||
;; If the user is using "-i", we warn them if it is necessary.
|
||||
(unless (eq exec-path-from-shell-arguments without-minus-i)
|
||||
(let* ((exec-path-from-shell-arguments without-minus-i)
|
||||
(alt-pairs (exec-path-from-shell-getenvs (mapcar 'car pairs)))
|
||||
different)
|
||||
(dolist (pair pairs)
|
||||
(unless (equal pair (assoc (car pair) alt-pairs))
|
||||
(push (car pair) different)))
|
||||
(when different
|
||||
(message "You appear to be setting environment variables %S in your .bashrc or .zshrc: those files are only read by interactive shells, so you should instead set environment variables in startup files like .profile, .bash_profile or .zshenv. Refer to your shell's man page for more info. Customize `exec-path-from-shell-arguments' to remove \"-i\" when done, or disable `exec-path-from-shell-check-startup-files' to disable this message." different))))))
|
||||
|
||||
;;;###autoload
|
||||
(defun exec-path-from-shell-copy-env (name)
|
||||
"Set the environment variable $NAME from the user's shell.
|
||||
|
||||
As a special case, if the variable is $PATH, then `exec-path' and
|
||||
`eshell-path-env' are also set appropriately. Return the value
|
||||
of the environment variable."
|
||||
(interactive "sCopy value of which environment variable from shell? ")
|
||||
(cdar (exec-path-from-shell-copy-envs (list name))))
|
||||
|
||||
;;;###autoload
|
||||
(defun exec-path-from-shell-initialize ()
|
||||
"Initialize environment from the user's shell.
|
||||
|
||||
The values of all the environment variables named in
|
||||
`exec-path-from-shell-variables' are set from the corresponding
|
||||
values used in the user's shell."
|
||||
(interactive)
|
||||
(exec-path-from-shell-copy-envs exec-path-from-shell-variables))
|
||||
|
||||
|
||||
(provide 'exec-path-from-shell)
|
||||
|
||||
;; Local Variables:
|
||||
;; coding: utf-8
|
||||
;; indent-tabs-mode: nil
|
||||
;; mangle-whitespace: t
|
||||
;; require-final-newline: t
|
||||
;; checkdoc-minor-mode: t
|
||||
;; End:
|
||||
|
||||
;;; exec-path-from-shell.el ends here
|
@ -0,0 +1,386 @@
|
||||
;;; 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
;;; 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 "<f2>")
|
||||
"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 "<f2> g") 'hydra-zoom/text-scale-increase)
|
||||
;; (global-set-key (kbd "<f2> 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
|
||||
^^^^ ^ ^ _p_aste
|
||||
"
|
||||
("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)
|
||||
("p" 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)
|
||||
|
||||
;;* 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
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
;;; 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
|
@ -0,0 +1,7 @@
|
||||
(define-package "hydra" "20170813.1058" "Make bindings that stick around."
|
||||
'((cl-lib "0.5"))
|
||||
:url "https://github.com/abo-abo/hydra" :keywords
|
||||
'("bindings"))
|
||||
;; Local Variables:
|
||||
;; no-byte-compile: t
|
||||
;; End:
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,119 @@
|
||||
;;; mc-cycle-cursors.el
|
||||
|
||||
;; Copyright (C) 2012-2016 Magnar Sveen
|
||||
|
||||
;; Author: Magnar Sveen <magnars@gmail.com>
|
||||
;; 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
;;; 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
|
@ -0,0 +1,110 @@
|
||||
;;; mc-edit-lines.el
|
||||
|
||||
;; Copyright (C) 2012-2016 Magnar Sveen
|
||||
|
||||
;; Author: Magnar Sveen <magnars@gmail.com>
|
||||
;; 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
;;; 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 (line-number-at-pos))
|
||||
(mark-line (progn (exchange-point-and-mark) (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 (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
|
@ -0,0 +1,107 @@
|
||||
;;; mc-hide-unmatched-lines.el
|
||||
|
||||
;; Copyright (C) 2014 Aleksey Fedotov
|
||||
|
||||
;; Author: Aleksey Fedotov <lexa@cfotr.com>
|
||||
;; 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
;;; 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 "<return>" 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 "<return>") '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 <return> 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 insted of hiden 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)
|
@ -0,0 +1,709 @@
|
||||
;;; mc-mark-more.el
|
||||
|
||||
;; Copyright (C) 2012-2016 Magnar Sveen
|
||||
|
||||
;; Author: Magnar Sveen <magnars@gmail.com>
|
||||
;; 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
;;; 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-sta |