diff options
Diffstat (limited to 'configs/shared/emacs/.emacs.d/elpa/evil-20180912.957/evil-ex.el')
-rw-r--r-- | configs/shared/emacs/.emacs.d/elpa/evil-20180912.957/evil-ex.el | 1169 |
1 files changed, 0 insertions, 1169 deletions
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-20180912.957/evil-ex.el b/configs/shared/emacs/.emacs.d/elpa/evil-20180912.957/evil-ex.el deleted file mode 100644 index e7e5e5ab3b48..000000000000 --- a/configs/shared/emacs/.emacs.d/elpa/evil-20180912.957/evil-ex.el +++ /dev/null @@ -1,1169 +0,0 @@ -;;; evil-ex.el --- Ex-mode - -;; Author: Frank Fischer <frank fischer at mathematik.tu-chemnitz.de> -;; Maintainer: Vegard Øye <vegard_oye at hotmail.com> - -;; Version: 1.2.13 - -;; -;; 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: - -;; Ex is implemented as an extensible minilanguage, whose grammar -;; is stored in `evil-ex-grammar'. Ex commands are defined with -;; `evil-ex-define-cmd', which creates a binding from a string -;; to an interactive function. It is also possible to define key -;; sequences which execute a command immediately when entered: -;; such shortcuts go in `evil-ex-map'. -;; -;; To provide buffer and filename completion, as well as interactive -;; feedback, Ex defines the concept of an argument handler, specified -;; with `evil-ex-define-argument-type'. In the case of the -;; substitution command (":s/foo/bar"), the handler incrementally -;; highlights matches in the buffer as the substitution is typed. - -(require 'evil-common) -(require 'evil-states) -(require 'shell) - -;;; Code: - -(defconst evil-ex-grammar - '((expression - (count command argument #'evil-ex-call-command) - ((\? range) command argument #'evil-ex-call-command) - (line #'evil-goto-line) - (sexp #'eval-expression)) - (count - number) - (command #'evil-ex-parse-command) - (binding - "[~&*@<>=:]+\\|[[:alpha:]-]+\\|!") - (emacs-binding - "[[:alpha:]-][[:alnum:][:punct:]-]+") - (bang - (\? (! space) "!" #'$1)) - (argument - ((\? space) (\? "\\(?:.\\|\n\\)+") #'$2)) - (range - ("%" #'(evil-ex-full-range)) - (line ";" line #'(let ((tmp1 $1)) - (save-excursion - (goto-line tmp1) - (evil-ex-range tmp1 $3)))) - (line "," line #'(evil-ex-range $1 $3)) - (line #'(evil-ex-range $1 nil)) - ("`" "[-a-zA-Z_<>']" ",`" "[-a-zA-Z_<>']" - #'(evil-ex-char-marker-range $2 $4))) - (line - (base (\? offset) search (\? offset) - #'(let ((tmp (evil-ex-line $1 $2))) - (save-excursion - (goto-line tmp) - (evil-ex-line $3 $4)))) - ((\? base) offset search (\? offset) - #'(let ((tmp (evil-ex-line $1 $2))) - (save-excursion - (goto-line tmp) - (evil-ex-line $3 $4)))) - (base (\? offset) #'evil-ex-line) - ((\? base) offset #'evil-ex-line)) - (base - number - marker - search - ("\\^" #'(evil-ex-first-line)) - ("\\$" #'(evil-ex-last-line)) - ("\\." #'(evil-ex-current-line))) - (offset - (+ signed-number #'+)) - (marker - ("'" "[-a-zA-Z_<>']" #'(evil-ex-marker $2))) - (search - forward - backward - next - prev - subst) - (forward - ("/" "\\(?:[\\].\\|[^/,; ]\\)+" (! "/") - #'(evil-ex-re-fwd $2)) - ("/" "\\(?:[\\].\\|[^/]\\)+" "/" - #'(evil-ex-re-fwd $2))) - (backward - ("\\?" "\\(?:[\\].\\|[^?,; ]\\)+" (! "\\?") - #'(evil-ex-re-bwd $2)) - ("\\?" "\\(?:[\\].\\|[^?]\\)+" "\\?" - #'(evil-ex-re-bwd $2))) - (next - "\\\\/" #'(evil-ex-prev-search)) - (prev - "\\\\\\?" #'(evil-ex-prev-search)) - (subst - "\\\\&" #'(evil-ex-prev-search)) - (signed-number - (sign (\? number) #'evil-ex-signed-number)) - (sign - "\\+\\|-" #'intern) - (number - "[0-9]+" #'string-to-number) - (space - "[ ]+") - (sexp - "(.*)" #'(car-safe (read-from-string $1)))) - "Grammar for Ex. -An association list of syntactic symbols and their definitions. -The first entry is the start symbol. A symbol's definition may -reference other symbols, but the grammar cannot contain -left recursion. See `evil-parser' for a detailed explanation -of the syntax.") - -(defvar evil-ex-echo-overlay nil - "Overlay used for displaying info messages during ex.") - -(defun evil-ex-p () - "Whether Ex is currently active." - (and evil-ex-current-buffer t)) - -(evil-define-command evil-ex (&optional initial-input) - "Enter an Ex command. -The ex command line is initialized with the value of -INITIAL-INPUT. If the command is called interactively the initial -input depends on the current state. If the current state is -normal state and no count argument is given then the initial -input is empty. If a prefix count is given the initial input is -.,.+count. If the current state is visual state then the initial -input is the visual region '<,'> or `<,`>. If the value of the -global variable `evil-ex-initial-input' is non-nil, its content -is appended to the line." - :keep-visual t - :repeat abort - (interactive - (list - (let ((s (concat - (cond - ((and (evil-visual-state-p) - evil-ex-visual-char-range - (memq (evil-visual-type) '(inclusive exclusive))) - "`<,`>") - ((evil-visual-state-p) - "'<,'>") - (current-prefix-arg - (let ((arg (prefix-numeric-value current-prefix-arg))) - (cond ((< arg 0) (setq arg (1+ arg))) - ((> arg 0) (setq arg (1- arg)))) - (if (= arg 0) '(".") - (format ".,.%+d" arg))))) - evil-ex-initial-input))) - (and (> (length s) 0) s)))) - (let ((evil-ex-current-buffer (current-buffer)) - (evil-ex-previous-command (unless initial-input - (car-safe evil-ex-history))) - evil-ex-argument-handler - evil-ex-info-string - result) - (minibuffer-with-setup-hook - (if initial-input #'evil-ex-setup-and-update #'evil-ex-setup) - (setq result - (read-from-minibuffer - ":" - (or initial-input - (and evil-ex-previous-command - (propertize evil-ex-previous-command 'face 'shadow))) - evil-ex-completion-map - nil - 'evil-ex-history - evil-ex-previous-command - t))) - (evil-ex-execute result))) - -(defun evil-ex-execute (result) - "Execute RESULT as an ex command on `evil-ex-current-buffer'." - ;; empty input means repeating the previous command - (when (zerop (length result)) - (setq result evil-ex-previous-command)) - ;; parse data - (evil-ex-update nil nil nil result) - ;; execute command - (unless (zerop (length result)) - (if evil-ex-expression - (eval evil-ex-expression) - (user-error "Ex: syntax error")))) - -(defun evil-ex-delete-backward-char () - "Close the minibuffer if it is empty. -Otherwise behaves like `delete-backward-char'." - (interactive) - (call-interactively - (if (zerop (length (minibuffer-contents))) - #'abort-recursive-edit - #'delete-backward-char))) - -(defun evil-ex-abort () - "Cancel ex state when another buffer is selected." - (unless (minibufferp) - (abort-recursive-edit))) - -(defun evil-ex-setup () - "Initialize Ex minibuffer. -This function registers several hooks that are used for the -interactive actions during ex state." - (add-hook 'post-command-hook #'evil-ex-abort) - (add-hook 'after-change-functions #'evil-ex-update nil t) - (add-hook 'minibuffer-exit-hook #'evil-ex-teardown nil t) - (when evil-ex-previous-command - (add-hook 'pre-command-hook #'evil-ex-remove-default)) - (remove-hook 'minibuffer-setup-hook #'evil-ex-setup) - (with-no-warnings - (make-variable-buffer-local 'completion-at-point-functions)) - (setq completion-at-point-functions - '(evil-ex-command-completion-at-point - evil-ex-argument-completion-at-point))) -(put 'evil-ex-setup 'permanent-local-hook t) - -(defun evil-ex-setup-and-update () - "Initialize Ex minibuffer with `evil-ex-setup', then call `evil-ex-update'." - (evil-ex-setup) - (evil-ex-update)) - -(defun evil-ex-teardown () - "Deinitialize Ex minibuffer. -Clean up everything set up by `evil-ex-setup'." - (remove-hook 'post-command-hook #'evil-ex-abort) - (remove-hook 'minibuffer-exit-hook #'evil-ex-teardown t) - (remove-hook 'after-change-functions #'evil-ex-update t) - (when evil-ex-argument-handler - (let ((runner (evil-ex-argument-handler-runner - evil-ex-argument-handler))) - (when runner - (funcall runner 'stop))))) -(put 'evil-ex-teardown 'permanent-local-hook t) - -(defun evil-ex-remove-default () - "Remove the default text shown in the ex minibuffer. -When ex starts, the previous command is shown enclosed in -parenthesis. This function removes this text when the first key -is pressed." - (when (and (not (eq this-command 'exit-minibuffer)) - (/= (minibuffer-prompt-end) (point-max))) - (if (eq this-command 'evil-ex-delete-backward-char) - (setq this-command 'ignore)) - (delete-minibuffer-contents)) - (remove-hook 'pre-command-hook #'evil-ex-remove-default)) -(put 'evil-ex-remove-default 'permanent-local-hook t) - -(defun evil-ex-update (&optional beg end len string) - "Update Ex variables when the minibuffer changes. -This function is usually called from `after-change-functions' -hook. If BEG is non-nil (which is the case when called from -`after-change-functions'), then an error description is shown -in case of incomplete or unknown commands." - (let* ((prompt (minibuffer-prompt-end)) - (string (or string (buffer-substring prompt (point-max)))) - arg bang cmd count expr func handler range tree type) - (cond - ((and (eq this-command #'self-insert-command) - (commandp (setq cmd (lookup-key evil-ex-map string)))) - (setq evil-ex-expression `(call-interactively #',cmd)) - (when (minibufferp) - (exit-minibuffer))) - (t - (setq cmd nil) - ;; store the buffer position of each character - ;; as the `ex-index' text property - (dotimes (i (length string)) - (add-text-properties - i (1+ i) (list 'ex-index (+ i prompt)) string)) - (with-current-buffer evil-ex-current-buffer - (setq tree (evil-ex-parse string t) - expr (evil-ex-parse string)) - (when (eq (car-safe expr) 'evil-ex-call-command) - (setq count (eval (nth 1 expr)) - cmd (eval (nth 2 expr)) - arg (eval (nth 3 expr)) - range (cond - ((evil-range-p count) - count) - ((numberp count) - (evil-ex-range count count))) - bang (and (save-match-data (string-match ".!$" cmd)) t)))) - (setq evil-ex-tree tree - evil-ex-expression expr - evil-ex-range range - evil-ex-cmd cmd - evil-ex-bang bang - evil-ex-argument arg) - ;; test the current command - (when (and cmd (minibufferp)) - (setq func (evil-ex-completed-binding cmd t)) - (cond - ;; update argument-handler - (func - (when (setq type (evil-get-command-property - func :ex-arg)) - (setq handler (cdr-safe - (assoc type - evil-ex-argument-types)))) - (unless (eq handler evil-ex-argument-handler) - (let ((runner (and evil-ex-argument-handler - (evil-ex-argument-handler-runner - evil-ex-argument-handler)))) - (when runner (funcall runner 'stop))) - (setq evil-ex-argument-handler handler) - (let ((runner (and evil-ex-argument-handler - (evil-ex-argument-handler-runner - evil-ex-argument-handler)))) - (when runner (funcall runner 'start evil-ex-argument)))) - (let ((runner (and evil-ex-argument-handler - (evil-ex-argument-handler-runner - evil-ex-argument-handler)))) - (when runner (funcall runner 'update evil-ex-argument)))) - (beg - ;; show error message only when called from `after-change-functions' - (let ((n (length (all-completions cmd (evil-ex-completion-table))))) - (cond - ((> n 1) (evil-ex-echo "Incomplete command")) - ((= n 0) (evil-ex-echo "Unknown command"))))))))))) -(put 'evil-ex-update 'permanent-local-hook t) - -(defun evil-ex-echo (string &rest args) - "Display a message after the current Ex command." - (with-selected-window (minibuffer-window) - (with-current-buffer (window-buffer (minibuffer-window)) - (unless (or evil-no-display - (zerop (length string))) - (let ((string (format " [%s]" (apply #'format string args))) - (ov (or evil-ex-echo-overlay - (setq evil-ex-echo-overlay (make-overlay (point-min) (point-max) nil t t)))) - after-change-functions before-change-functions) - (put-text-property 0 (length string) 'face 'evil-ex-info string) - ;; The following 'trick' causes point to be shown before the - ;; message instead behind. It is shamelessly stolen from the - ;; implementation of `minibuffer-message`. - (put-text-property 0 1 'cursor t string) - (move-overlay ov (point-max) (point-max)) - (overlay-put ov 'after-string string) - (add-hook 'pre-command-hook #'evil--ex-remove-echo-overlay nil t)))))) - -(defun evil--ex-remove-echo-overlay () - "Remove echo overlay from ex minibuffer." - (when evil-ex-echo-overlay - (delete-overlay evil-ex-echo-overlay) - (setq evil-ex-echo-overlay nil)) - (remove-hook 'pre-command-hook 'evil--ex-remove-echo-overlay t)) - -(defun evil-ex-completion () - "Completes the current ex command or argument." - (interactive) - (let (after-change-functions) - (evil-ex-update) - (completion-at-point) - (remove-text-properties (minibuffer-prompt-end) (point-max) '(face nil evil)))) - -(defun evil-ex-command-completion-at-point () - (let ((context (evil-ex-syntactic-context (1- (point))))) - (when (memq 'command context) - (let ((beg (or (get-text-property 0 'ex-index evil-ex-cmd) - (point))) - (end (1+ (or (get-text-property (1- (length evil-ex-cmd)) - 'ex-index - evil-ex-cmd) - (1- (point)))))) - (list beg end (evil-ex-completion-table)))))) - -(defun evil-ex-completion-table () - (cond - ((eq evil-ex-complete-emacs-commands nil) - #'evil-ex-command-collection) - ((eq evil-ex-complete-emacs-commands 'in-turn) - (completion-table-in-turn - #'evil-ex-command-collection - #'(lambda (str pred flag) - (completion-table-with-predicate - obarray #'commandp t str pred flag)))) - (t - #'(lambda (str pred flag) - (evil-completion-table-concat - #'evil-ex-command-collection - #'(lambda (str pred flag) - (completion-table-with-predicate - obarray #'commandp t str pred flag)) - str pred flag))))) - -(defun evil-completion-table-concat (table1 table2 string pred flag) - (cond - ((eq flag nil) - (let ((result1 (try-completion string table1 pred)) - (result2 (try-completion string table2 pred))) - (cond - ((null result1) result2) - ((null result2) result1) - ((and (eq result1 t) (eq result2 t)) t) - (t result1)))) - ((eq flag t) - (delete-dups - (append (all-completions string table1 pred) - (all-completions string table2 pred)))) - ((eq flag 'lambda) - (and (or (eq t (test-completion string table1 pred)) - (eq t (test-completion string table2 pred))) - t)) - ((eq (car-safe flag) 'boundaries) - (or (completion-boundaries string table1 pred (cdr flag)) - (completion-boundaries string table2 pred (cdr flag)))) - ((eq flag 'metadata) - '(metadata (display-sort-function . evil-ex-sort-completions))))) - -(defun evil-ex-sort-completions (completions) - (sort completions - #'(lambda (str1 str2) - (let ((p1 (eq 'evil-ex-commands (get-text-property 0 'face str1))) - (p2 (eq 'evil-ex-commands (get-text-property 0 'face str2)))) - (if (equal p1 p2) - (string< str1 str2) - p1))))) - -(defun evil-ex-command-collection (cmd predicate flag) - "Called to complete a command." - (let (commands) - ;; append ! to all commands that may take a bang argument - (dolist (cmd (mapcar #'car evil-ex-commands)) - (push cmd commands) - (if (evil-ex-command-force-p cmd) - (push (concat cmd "!") commands))) - (when (eq evil-ex-complete-emacs-commands t) - (setq commands - (mapcar #'(lambda (str) (propertize str 'face 'evil-ex-commands)) - commands))) - (cond - ((eq flag nil) (try-completion cmd commands predicate)) - ((eq flag t) (all-completions cmd commands predicate)) - ((eq flag 'lambda) (test-completion cmd commands)) - ((eq (car-safe flag) 'boundaries) - `(boundaries 0 . ,(length (cdr flag))))))) - -(defun evil-ex-argument-completion-at-point () - (let ((context (evil-ex-syntactic-context (1- (point))))) - (when (memq 'argument context) - ;; if it's an autoload, load the function; this allows external - ;; packages to register autoloaded ex commands which will be - ;; loaded when ex argument completion is triggered - (let ((binding-definition (symbol-function (evil-ex-binding evil-ex-cmd)))) - (when (autoloadp binding-definition) - (autoload-do-load binding-definition))) - - (let* ((beg (or (and evil-ex-argument - (get-text-property 0 'ex-index evil-ex-argument)) - (point))) - (end (1+ (or (and evil-ex-argument - (get-text-property (1- (length evil-ex-argument)) - 'ex-index - evil-ex-argument)) - (1- (point))))) - (binding (evil-ex-completed-binding evil-ex-cmd)) - (arg-type (evil-get-command-property binding :ex-arg)) - (arg-handler (assoc arg-type evil-ex-argument-types)) - (completer (and arg-handler - (evil-ex-argument-handler-completer - (cdr arg-handler))))) - (when completer - (if (eq (car completer) 'collection) - (list beg end (cdr completer)) - (save-restriction - (narrow-to-region beg (point-max)) - (funcall (cdr completer))))))))) - -(defun evil-ex-define-cmd (cmd function) - "Binds the function FUNCTION to the command CMD." - (save-match-data - (if (string-match "^[^][]*\\(\\[\\(.*\\)\\]\\)[^][]*$" cmd) - (let ((abbrev (replace-match "" nil t cmd 1)) - (full (replace-match "\\2" nil nil cmd 1))) - (evil-add-to-alist 'evil-ex-commands full function) - (evil-add-to-alist 'evil-ex-commands abbrev full)) - (evil-add-to-alist 'evil-ex-commands cmd function)))) - -(defun evil-ex-make-argument-handler (runner completer) - (list runner completer)) - -(defun evil-ex-argument-handler-runner (arg-handler) - (car arg-handler)) - -(defun evil-ex-argument-handler-completer (arg-handler) - (cadr arg-handler)) - -(defmacro evil-ex-define-argument-type (arg-type doc &rest body) - "Defines a new handler for argument-type ARG-TYPE. -DOC is the documentation string. It is followed by a list of -keywords and function: - -:collection COLLECTION - - A collection for completion as required by `all-completions'. - -:completion-at-point FUNC - - Function to be called to initialize a potential - completion. FUNC must match the requirements as described for - the variable `completion-at-point-functions'. When FUNC is - called the minibuffer content is narrowed to exactly match the - argument. - -:runner FUNC - - Function to be called when the type of the current argument - changes or when the content of this argument changes. This - function should take one obligatory argument FLAG followed by - an optional argument ARG. FLAG is one of three symbol 'start, - 'stop or 'update. When the argument type is recognized for the - first time and this handler is started the FLAG is 'start. If - the argument type changes to something else or ex state - finished the handler FLAG is 'stop. If the content of the - argument has changed FLAG is 'update. If FLAG is either 'start - or 'update then ARG is the current value of this argument. If - FLAG is 'stop then arg is nil." - (declare (indent defun) - (debug (&define name - [&optional stringp] - [&rest [keywordp function-form]]))) - (unless (stringp doc) (push doc body)) - (let (runner completer) - (while (keywordp (car-safe body)) - (let ((key (pop body)) - (func (pop body))) - (cond - ((eq key :runner) - (setq runner func)) - ((eq key :collection) - (setq completer (cons 'collection func))) - ((eq key :completion-at-point) - (setq completer (cons 'completion-at-point func)))))) - `(eval-and-compile - (evil-add-to-alist - 'evil-ex-argument-types - ',arg-type - '(,runner ,completer))))) - -(evil-ex-define-argument-type file - "Handles a file argument." - :collection read-file-name-internal) - -(evil-ex-define-argument-type buffer - "Called to complete a buffer name argument." - :collection internal-complete-buffer) - -(declare-function shell-completion-vars "shell" ()) - -(defun evil-ex-init-shell-argument-completion (flag &optional arg) - "Prepares the current minibuffer for completion of shell commands. -This function must be called from the :runner function of some -argument handler that requires shell completion." - (when (and (eq flag 'start) - (not evil-ex-shell-argument-initialized)) - (set (make-local-variable 'evil-ex-shell-argument-initialized) t) - (cond - ;; Emacs 24 - ((fboundp 'comint-completion-at-point) - (shell-completion-vars)) - (t - (set (make-local-variable 'minibuffer-default-add-function) - 'minibuffer-default-add-shell-commands))) - (setq completion-at-point-functions - '(evil-ex-command-completion-at-point - evil-ex-argument-completion-at-point)))) - -(define-obsolete-function-alias - 'evil-ex-shell-command-completion-at-point - 'comint-completion-at-point) - -(evil-ex-define-argument-type shell - "Shell argument type, supports completion." - :completion-at-point comint-completion-at-point - :runner evil-ex-init-shell-argument-completion) - -(defun evil-ex-file-or-shell-command-completion-at-point () - (if (and (< (point-min) (point-max)) - (= (char-after (point-min)) ?!)) - (save-restriction - (narrow-to-region (1+ (point-min)) (point-max)) - (comint-completion-at-point)) - (list (point-min) (point-max) #'read-file-name-internal))) - -(evil-ex-define-argument-type file-or-shell - "File or shell argument type. -If the current argument starts with a ! the rest of the argument -is considered a shell command, otherwise a file-name. Completion -works accordingly." - :completion-at-point evil-ex-file-or-shell-command-completion-at-point - :runner evil-ex-init-shell-argument-completion) - -(defun evil-ex-binding (command &optional noerror) - "Returns the final binding of COMMAND." - (save-match-data - (let ((binding command)) - (when binding - (string-match "^\\(.+?\\)\\!?$" binding) - (setq binding (match-string 1 binding)) - (while (progn - (setq binding (cdr (assoc binding evil-ex-commands))) - (stringp binding))) - (unless binding - (setq binding (intern command))) - (if (commandp binding) - ;; check for remaps - (or (command-remapping binding) binding) - (unless noerror - (user-error "Unknown command: `%s'" command))))))) - -(defun evil-ex-completed-binding (command &optional noerror) - "Returns the final binding of the completion of COMMAND." - (let ((completion (try-completion command evil-ex-commands))) - (evil-ex-binding (if (eq completion t) command - (or completion command)) - noerror))) - -;;; TODO: extensions likes :p :~ <cfile> ... -(defun evil-ex-replace-special-filenames (file-name) - "Replace special symbols in FILE-NAME. -Replaces % by the current file-name, -Replaces # by the alternate file-name in FILE-NAME." - (let ((remote (file-remote-p file-name)) - (current-fname (buffer-file-name)) - (alternate-fname (and (other-buffer) - (buffer-file-name (other-buffer))))) - (setq file-name (or (file-remote-p file-name 'localname) file-name)) - (when current-fname - (setq current-fname (or (file-remote-p current-fname 'localname) - current-fname)) - (setq file-name - (replace-regexp-in-string "\\(^\\|[^\\\\]\\)\\(%\\)" - current-fname file-name - t t 2))) - (when alternate-fname - (setq alternate-fname (or (file-remote-p alternate-fname 'localname) - alternate-fname)) - (setq file-name - (replace-regexp-in-string "\\(^\\|[^\\\\]\\)\\(#\\)" - alternate-fname file-name - t t 2))) - (setq file-name - (replace-regexp-in-string "\\\\\\([#%]\\)" - "\\1" file-name t)) - (setq file-name (concat remote file-name))) - file-name) - -(defun evil-ex-file-arg () - "Returns the current Ex argument as a file name. -This function interprets special file names like # and %." - (unless (zerop (length evil-ex-argument)) - (evil-ex-replace-special-filenames evil-ex-argument))) - -(defun evil-ex-repeat (count) - "Repeats the last ex command." - (interactive "P") - (when count - (goto-char (point-min)) - (forward-line (1- count))) - (let ((evil-ex-current-buffer (current-buffer)) - (hist evil-ex-history)) - (while hist - (let ((evil-ex-last-cmd (pop hist))) - (when evil-ex-last-cmd - (evil-ex-update nil nil nil evil-ex-last-cmd) - (let ((binding (evil-ex-binding evil-ex-cmd))) - (unless (eq binding #'evil-ex-repeat) - (setq hist nil) - (if evil-ex-expression - (eval evil-ex-expression) - (user-error "Ex: syntax error"))))))))) - -(defun evil-ex-call-command (range command argument) - "Execute the given command COMMAND." - (let* ((count (when (numberp range) range)) - (range (when (evil-range-p range) range)) - (bang (and (save-match-data (string-match ".!$" command)) t)) - (evil-ex-point (point)) - (evil-ex-range - (or range (and count (evil-ex-range count count)))) - (evil-ex-command (evil-ex-completed-binding command)) - (evil-ex-bang (and bang t)) - (evil-ex-argument (copy-sequence argument)) - (evil-this-type (evil-type evil-ex-range)) - (current-prefix-arg count) - (prefix-arg current-prefix-arg)) - (when (stringp evil-ex-argument) - (set-text-properties - 0 (length evil-ex-argument) nil evil-ex-argument)) - (let ((buf (current-buffer))) - (unwind-protect - (cond - ((not evil-ex-range) - (setq this-command evil-ex-command) - (run-hooks 'pre-command-hook) - (call-interactively evil-ex-command) - (run-hooks 'post-command-hook)) - (t - ;; set visual selection to match the region if an explicit - ;; range has been specified - (let ((ex-range (evil-copy-range evil-ex-range)) - beg end) - (evil-expand-range ex-range) - (setq beg (evil-range-beginning ex-range) - end (evil-range-end ex-range)) - (evil-sort beg end) - (setq this-command evil-ex-command) - (run-hooks 'pre-command-hook) - (set-mark end) - (goto-char beg) - (activate-mark) - (call-interactively evil-ex-command) - (run-hooks 'post-command-hook)))) - (when (buffer-live-p buf) - (with-current-buffer buf - (deactivate-mark))))))) - -(defun evil-ex-line (base &optional offset) - "Return the line number of BASE plus OFFSET." - (+ (or base (line-number-at-pos)) - (or offset 0))) - -(defun evil-ex-first-line () - "Return the line number of the first line." - (line-number-at-pos (point-min))) - -(defun evil-ex-current-line () - "Return the line number of the current line." - (line-number-at-pos (point))) - -(defun evil-ex-last-line () - "Return the line number of the last line." - (save-excursion - (goto-char (point-max)) - (when (bolp) - (forward-line -1)) - (line-number-at-pos))) - -(defun evil-ex-range (beg-line &optional end-line) - "Returns the first and last position of the current range." - (evil-range - (evil-line-position beg-line) - (evil-line-position (or end-line beg-line) -1) - 'line - :expanded t)) - -(defun evil-ex-full-range () - "Return a range encompassing the whole buffer." - (evil-range (point-min) (point-max) 'line)) - -(defun evil-ex-marker (marker) - "Return MARKER's line number in the current buffer. -Signal an error if MARKER is in a different buffer." - (when (stringp marker) - (setq marker (aref marker 0))) - (setq marker (evil-get-marker marker)) - (if (numberp marker) - (line-number-at-pos marker) - (user-error "Ex does not support markers in other files"))) - -(defun evil-ex-char-marker-range (beg end) - (when (stringp beg) (setq beg (aref beg 0))) - (when (stringp end) (setq end (aref end 0))) - (setq beg (evil-get-marker beg) - end (evil-get-marker end)) - (if (and (numberp beg) (numberp end)) - (evil-expand-range - (evil-range beg end - (if (evil-visual-state-p) - (evil-visual-type) - 'inclusive))) - (user-error "Ex does not support markers in other files"))) - -(defun evil-ex-re-fwd (pattern) - "Search forward for PATTERN. -Returns the line number of the match." - (condition-case err - (save-match-data - (save-excursion - (set-text-properties 0 (length pattern) nil pattern) - (evil-move-end-of-line) - (and (re-search-forward pattern nil t) - (line-number-at-pos (1- (match-end 0)))))) - (invalid-regexp - (evil-ex-echo (cadr err)) - nil))) - -(defun evil-ex-re-bwd (pattern) - "Search backward for PATTERN. -Returns the line number of the match." - (condition-case err - (save-match-data - (save-excursion - (set-text-properties 0 (length pattern) nil pattern) - (evil-move-beginning-of-line) - (and (re-search-backward pattern nil t) - (line-number-at-pos (match-beginning 0))))) - (invalid-regexp - (evil-ex-echo (cadr err)) - nil))) - -(defun evil-ex-prev-search () - (error "Previous search not yet implemented")) - -(defun evil-ex-signed-number (sign &optional number) - "Return a signed number like -3 and +1. -NUMBER defaults to 1." - (funcall sign (or number 1))) - -;; function `evil-ex-eval' has been superseded by `evil-ex-parse' plus `eval' -(make-obsolete 'evil-ex-eval 'evil-ex-parse "1.2.14") - -(defun evil-ex-parse (string &optional syntax start) - "Parse STRING as an Ex expression and return an evaluation tree. -If SYNTAX is non-nil, return a syntax tree instead. -START is the start symbol, which defaults to `expression'." - (let* ((start (or start (car-safe (car-safe evil-ex-grammar)))) - (match (evil-parser - string start evil-ex-grammar t syntax))) - (car-safe match))) - -(defun evil-ex-parse-command (string) - "Parse STRING as an Ex binding." - (let ((result (evil-parser string 'binding evil-ex-grammar)) - bang command) - (when result - (setq command (car-safe result) - string (cdr-safe result)) - ;; check whether the parsed command is followed by a slash or - ;; number and the part before it is not a known ex binding - (when (and (> (length string) 0) - (string-match-p "^[/[:digit:]]" string) - (not (evil-ex-binding command t))) - ;; if this is the case, assume the slash or number and all - ;; following symbol characters form an (Emacs-)command - (setq result (evil-parser (concat command string) - 'emacs-binding - evil-ex-grammar) - command (car-safe result) - string (cdr-safe result))) - ;; parse a following "!" as bang only if - ;; the command has the property :ex-bang t - (when (evil-ex-command-force-p command) - (setq result (evil-parser string 'bang evil-ex-grammar) - bang (or (car-safe result) "") - string (cdr-safe result) - command (concat command bang))) - (cons command string)))) - -(defun evil-ex-command-force-p (command) - "Whether COMMAND accepts the bang argument." - (let ((binding (evil-ex-completed-binding command t))) - (when binding - (evil-get-command-property binding :ex-bang)))) - -(defun evil-flatten-syntax-tree (tree) - "Find all paths from the root of TREE to its leaves. -TREE is a syntax tree, i.e., all its leave nodes are strings. -The `nth' element in the result is the syntactic context -for the corresponding string index (counted from zero)." - (let* ((result nil) - (traverse nil) - (traverse - #'(lambda (tree path) - (if (stringp tree) - (dotimes (char (length tree)) - (push path result)) - (let ((path (cons (car tree) path))) - (dolist (subtree (cdr tree)) - (funcall traverse subtree path))))))) - (funcall traverse tree nil) - (nreverse result))) - -(defun evil-ex-syntactic-context (&optional pos) - "Return the syntactical context of the character at POS. -POS defaults to the current position of point." - (let* ((contexts (evil-flatten-syntax-tree evil-ex-tree)) - (length (length contexts)) - (pos (- (or pos (point)) (minibuffer-prompt-end)))) - (when (>= pos length) - (setq pos (1- length))) - (when (< pos 0) - (setq pos 0)) - (when contexts - (nth pos contexts)))) - -(defun evil-parser (string symbol grammar &optional greedy syntax) - "Parse STRING as a SYMBOL in GRAMMAR. -If GREEDY is non-nil, the whole of STRING must match. -If the parse succeeds, the return value is a cons cell -\(RESULT . TAIL), where RESULT is a parse tree and TAIL is -the remainder of STRING. Otherwise, the return value is nil. - -GRAMMAR is an association list of symbols and their definitions. -A definition is either a list of production rules, which are -tried in succession, or a #'-quoted function, which is called -to parse the input. - -A production rule can be one of the following: - - nil matches the empty string. - A regular expression matches a substring. - A symbol matches a production for that symbol. - (X Y) matches X followed by Y. - (\\? X) matches zero or one of X. - (* X) matches zero or more of X. - (+ X) matches one or more of X. - (& X) matches X, but does not consume. - (! X) matches anything but X, but does not consume. - -Thus, a simple grammar may look like: - - ((plus \"\\\\+\") ; plus <- \"+\" - (minus \"-\") ; minus <- \"-\" - (operator plus minus)) ; operator <- plus / minus - -All input-consuming rules have a value. A regular expression evaluates -to the text matched, while a list evaluates to a list of values. -The value of a list may be overridden with a semantic action, which is -specified with a #'-quoted expression at the end: - - (X Y #'foo) - -The value of this rule is the result of calling foo with the values -of X and Y as arguments. Alternatively, the function call may be -specified explicitly: - - (X Y #'(foo $1 $2)) - -Here, $1 refers to X and $2 refers to Y. $0 refers to the whole list. -Dollar expressions can also be used directly: - - (X Y #'$1) - -This matches X followed by Y, but ignores the value of Y; -the value of the list is the same as the value of X. - -If the SYNTAX argument is non-nil, then all semantic actions -are ignored, and a syntax tree is constructed instead. The -syntax tree obeys the property that all the leave nodes are -parts of the input string. Thus, by traversing the syntax tree, -one can determine how each character was parsed. - -The following symbols have reserved meanings within a grammar: -`\\?', `*', `+', `&', `!', `function', `alt', `seq' and nil." - (let ((string (or string "")) - func pair result rules tail) - (cond - ;; epsilon - ((member symbol '("" nil)) - (setq pair (cons (if syntax "" nil) string))) - ;; token - ((stringp symbol) - (save-match-data - (when (or (eq (string-match symbol string) 0) - ;; ignore leading whitespace - (and (eq (string-match "^[ \f\t\n\r\v]+" string) 0) - (eq (match-end 0) - (string-match - symbol string (match-end 0))))) - (setq result (match-string 0 string) - tail (substring string (match-end 0)) - pair (cons result tail)) - (when (and syntax pair) - (setq result (substring string 0 - (- (length string) - (length tail)))) - (setcar pair result))))) - ;; symbol - ((symbolp symbol) - (let ((context symbol)) - (setq rules (cdr-safe (assq symbol grammar))) - (setq pair (evil-parser string `(alt ,@rules) - grammar greedy syntax)) - (when (and syntax pair) - (setq result (car pair)) - (if (and (listp result) (sequencep (car result))) - (setq result `(,symbol ,@result)) - (setq result `(,symbol ,result))) - (setcar pair result)))) - ;; function - ((eq (car-safe symbol) 'function) - (setq symbol (cadr symbol) - pair (funcall symbol string)) - (when (and syntax pair) - (setq tail (or (cdr pair) "") - result (substring string 0 - (- (length string) - (length tail)))) - (setcar pair result))) - ;; list - ((listp symbol) - (setq rules symbol - symbol (car-safe rules)) - (if (memq symbol '(& ! \? * + alt seq)) - (setq rules (cdr rules)) - (setq symbol 'seq)) - (when (and (memq symbol '(+ alt seq)) - (> (length rules) 1)) - (setq func (car (last rules))) - (if (eq (car-safe func) 'function) - (setq rules (delq func (copy-sequence rules)) - func (cadr func)) - (setq func nil))) - (cond - ;; positive lookahead - ((eq symbol '&) - (when (evil-parser string rules grammar greedy syntax) - (setq pair (evil-parser string nil grammar nil syntax)))) - ;; negative lookahead - ((eq symbol '!) - (unless (evil-parser string rules grammar greedy syntax) - (setq pair (evil-parser string nil grammar nil syntax)))) - ;; zero or one - ((eq symbol '\?) - (setq rules (if (> (length rules) 1) - `(alt ,rules nil) - `(alt ,@rules nil)) - pair (evil-parser string rules grammar greedy syntax))) - ;; zero or more - ((eq symbol '*) - (setq rules `(alt (+ ,@rules) nil) - pair (evil-parser string rules grammar greedy syntax))) - ;; one or more - ((eq symbol '+) - (let (current results) - (catch 'done - (while (setq current (evil-parser - string rules grammar nil syntax)) - (setq result (car-safe current) - tail (or (cdr-safe current) "") - results (append results (if syntax result - (cdr-safe result)))) - ;; stop if stuck - (if (equal string tail) - (throw 'done nil) - (setq string tail)))) - (when results - (setq func (or func 'list) - pair (cons results tail))))) - ;; alternatives - ((eq symbol 'alt) - (catch 'done - (dolist (rule rules) - (when (setq pair (evil-parser - string rule grammar greedy syntax)) - (throw 'done pair))))) - ;; sequence - (t - (setq func (or func 'list)) - (let ((last (car-safe (last rules))) - current results rule) - (catch 'done - (while rules - (setq rule (pop rules) - current (evil-parser string rule grammar - (when greedy - (null rules)) - syntax)) - (cond - ((null current) - (setq results nil) - (throw 'done nil)) - (t - (setq result (car-safe current) - tail (cdr-safe current)) - (unless (memq (car-safe rule) '(& !)) - (if (and syntax - (or (null result) - (and (listp result) - (listp rule) - ;; splice in single-element - ;; (\? ...) expressions - (not (and (eq (car-safe rule) '\?) - (eq (length rule) 2)))))) - (setq results (append results result)) - (setq results (append results (list result))))) - (setq string (or tail "")))))) - (when results - (setq pair (cons results tail)))))) - ;; semantic action - (when (and pair func (not syntax)) - (setq result (car pair)) - (let* ((dexp - #'(lambda (obj) - (when (symbolp obj) - (let ((str (symbol-name obj))) - (save-match-data - (when (string-match "\\$\\([0-9]+\\)" str) - (string-to-number (match-string 1 str)))))))) - ;; traverse a tree for dollar expressions - (dval nil) - (dval - #'(lambda (obj) - (if (listp obj) - (mapcar dval obj) - (let ((num (funcall dexp obj))) - (if num - (if (not (listp result)) - result - (if (eq num 0) - `(list ,@result) - (nth (1- num) result))) - obj)))))) - (cond - ((null func) - (setq result nil)) - ;; lambda function - ((eq (car-safe func) 'lambda) - (if (memq symbol '(+ seq)) - (setq result `(funcall ,func ,@result)) - (setq result `(funcall ,func ,result)))) - ;; string replacement - ((or (stringp func) (stringp (car-safe func))) - (let* ((symbol (or (car-safe (cdr-safe func)) - (and (boundp 'context) context) - (car-safe (car-safe grammar)))) - (string (if (stringp func) func (car-safe func)))) - (setq result (car-safe (evil-parser string symbol grammar - greedy syntax))))) - ;; dollar expression - ((funcall dexp func) - (setq result (funcall dval func))) - ;; function call - ((listp func) - (setq result (funcall dval func))) - ;; symbol - (t - (if (memq symbol '(+ seq)) - (setq result `(,func ,@result)) - (setq result `(,func ,result)))))) - (setcar pair result)))) - ;; weed out incomplete matches - (when pair - (if (not greedy) pair - (if (null (cdr pair)) pair - ;; ignore trailing whitespace - (when (save-match-data (string-match "^[ \f\t\n\r\v]*$" (cdr pair))) - (unless syntax (setcdr pair nil)) - pair)))))) - -(provide 'evil-ex) - -;;; evil-ex.el ends here |