aboutsummaryrefslogtreecommitdiff
path: root/.config/emacs/lisp/evil/evil-command-window.el
diff options
context:
space:
mode:
Diffstat (limited to '.config/emacs/lisp/evil/evil-command-window.el')
-rw-r--r--.config/emacs/lisp/evil/evil-command-window.el191
1 files changed, 191 insertions, 0 deletions
diff --git a/.config/emacs/lisp/evil/evil-command-window.el b/.config/emacs/lisp/evil/evil-command-window.el
new file mode 100644
index 0000000..ef22be0
--- /dev/null
+++ b/.config/emacs/lisp/evil/evil-command-window.el
@@ -0,0 +1,191 @@
+;;; evil-command-window.el --- Evil command-line window -*- lexical-binding: t -*-
+;; Author: Emanuel Evans <emanuel.evans at gmail.com>
+;; Maintainer: Vegard Øye <vegard_oye at hotmail.com>
+
+;; Version: 1.15.0
+
+;;
+;; This file is NOT part of GNU Emacs.
+
+;;; License:
+
+;; This file is part of Evil.
+;;
+;; Evil 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.
+;;
+;; Evil 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 Evil. If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; This provides an implementation of the Vim command-line window for
+;; editing and repeating past Ex commands and searches.
+
+;;; Code:
+
+(require 'evil-vars)
+(require 'evil-common)
+(require 'evil-ex)
+(require 'evil-search)
+
+(defvar evil-search-module)
+
+(defvar evil-command-window-current-buffer nil
+ "The buffer from which the command-line window was called.")
+
+(defvar evil-command-window-execute-fn nil
+ "The command to execute when exiting the command-line window.")
+
+(defvar evil--command-window-prompt nil
+ "The key for the command that opened the command-line window (:, /, or ?).")
+
+(define-derived-mode evil-command-window-mode fundamental-mode "Evil-cmd"
+ "Major mode for the Evil command-line window."
+ (add-hook 'after-change-functions #'evil--command-window-draw-prefix nil t)
+ (auto-fill-mode 0))
+
+(defun evil-command-window (history prompt execute-fn)
+ "Open a command-line window for HISTORY with PROMPT and EXECUTE-FN.
+HISTORY should be a list of commands. PROMPT should be the
+command-line prompt (one of \":\", \"/\" or \"?\"). EXECUTE-FN should
+be a unary function to execute on the result that the user selects.
+
+If called interactively, edit this minibuffer argument."
+ (interactive
+ (list (cons (minibuffer-contents) (minibuffer-history-value))
+ (or (minibuffer-prompt) (user-error "Minibuffer is inactive"))
+ #'evil--command-window-minibuffer-execute))
+ (when (derived-mode-p 'evil-command-window-mode)
+ (user-error "Command-line window is already open"))
+ (when (evil-ex-p) (evil-ex-teardown))
+ (let ((previous-buffer (current-buffer))
+ (buffer (get-buffer-create "*Command Line*")))
+ (with-current-buffer buffer
+ (erase-buffer)
+ (evil-command-window-mode)
+ (setq-local evil-command-window-current-buffer previous-buffer)
+ (setq-local evil-command-window-execute-fn execute-fn)
+ (setq-local evil--command-window-prompt prompt)
+ (evil--command-window-insert-commands history))
+
+ (let* ((action
+ `((display-buffer-reuse-window display-buffer-at-bottom)
+ ,@(unless (zerop evil-command-window-height)
+ `((window-height body-lines . ,evil-command-window-height)
+ (preserve-size nil . t)))
+ (dedicated . t)))
+ (window (display-buffer buffer action))
+ (delete-window-fun
+ (lambda (window)
+ (set-window-parameter window 'delete-window nil)
+ (delete-window window)
+ (switch-to-minibuffer))))
+ (when (minibufferp)
+ (set-window-parameter window 'delete-window delete-window-fun))
+ (select-window window)))
+ (goto-char (point-max))
+ (unless (bobp) (backward-char) (evil-adjust-cursor)))
+
+(defun evil--command-window-draw-prefix (beg end _old-len)
+ "Display `evil--command-window-prompt' as a prefix of the changed lines."
+ (let ((prefix (propertize evil--command-window-prompt
+ 'font-lock-face 'minibuffer-prompt)))
+ (put-text-property beg end 'line-prefix prefix)))
+
+(defun evil--command-window-insert-commands (history)
+ "Insert the commands in HISTORY."
+ (let ((inhibit-modification-hooks t))
+ (dolist (cmd (reverse history)) (insert cmd "\n"))
+ (evil--command-window-draw-prefix (point-min) (point-max) nil)))
+
+(defun evil-command-window-execute ()
+ "Execute the command on the current line in the appropriate buffer.
+The local variable `evil-command-window-execute-fn' determines which
+function to execute."
+ (interactive)
+ (let ((result (buffer-substring-no-properties
+ (line-beginning-position) (line-end-position)))
+ (original-buffer evil-command-window-current-buffer)
+ (execute-fn evil-command-window-execute-fn))
+ (let ((ignore-window-parameters t))
+ (ignore-errors (kill-buffer-and-window)))
+ (unless (buffer-live-p original-buffer)
+ (user-error "Originating buffer is no longer active"))
+ (let ((window (get-buffer-window original-buffer)))
+ (when window (select-window window)))
+ (with-current-buffer original-buffer (funcall execute-fn result))))
+
+(defun evil--command-window-minibuffer-execute (result)
+ "Terminate this minibuffer argument with RESULT."
+ (delete-minibuffer-contents)
+ (insert result)
+ (exit-minibuffer))
+
+(defun evil-command-window-ex (&optional current-command)
+ "Open a command-line window for editing and executing Ex commands.
+If CURRENT-COMMAND is present, it will be inserted under the cursor as
+the current command to be edited."
+ (interactive)
+ (evil-command-window (cons (or current-command "") evil-ex-history)
+ ":"
+ #'evil-command-window-ex-execute))
+
+(define-obsolete-function-alias
+ 'evil-ex-command-window #'evil-command-window "1.15.0"
+ "Start command window with Ex history and current minibuffer content.")
+
+(define-obsolete-function-alias
+ 'evil-ex-search-command-window #'evil-command-window "1.15.0"
+ "Start command window with search history and current minibuffer content.")
+
+(defun evil-command-window-ex-execute (result)
+ "Execute RESULT as an Ex command."
+ (unless (string-match-p "\\`[ \t\n\r]*\\'" result)
+ (unless (equal result (car evil-ex-history))
+ (push result evil-ex-history))
+ (evil-ex-execute result)))
+
+(defun evil--command-window-search (forward)
+ "Open a command-line window for searches."
+ (evil-command-window
+ (cons "" (cond ((eq evil-search-module 'evil-search)
+ evil-ex-search-history)
+ (forward evil-search-forward-history)
+ (t evil-search-backward-history)))
+ (evil-search-prompt forward)
+ (lambda (result) (evil-command-window-search-execute result forward))))
+
+(defun evil-command-window-search-forward ()
+ "Open a command-line window for forward searches."
+ (interactive)
+ (evil--command-window-search t))
+
+(defun evil-command-window-search-backward ()
+ "Open a command-line window for backward searches."
+ (interactive)
+ (evil--command-window-search nil))
+
+(defun evil-command-window-search-execute (result forward)
+ "Search for RESULT using FORWARD to determine direction."
+ (unless (string= result "")
+ (if (eq evil-search-module 'evil-search)
+ (progn
+ (setq evil-ex-search-pattern (evil-ex-make-search-pattern result)
+ evil-ex-search-direction (if forward 'forward 'backward))
+ (unless (equal result (car evil-ex-search-history))
+ (push result evil-ex-search-history))
+ (evil-ex-search))
+ (evil-push-search-history result forward)
+ (evil-search result forward evil-regexp-search))))
+
+(provide 'evil-command-window)
+
+;;; evil-command-window.el ends here