Fix #2832: filename modifiers replaced with empty strings
This commit is contained in:
parent
077b6f00d4
commit
50ff934ff2
5 changed files with 65 additions and 66 deletions
|
@ -7,7 +7,7 @@
|
||||||
(call-interactively #'doom/escape)))
|
(call-interactively #'doom/escape)))
|
||||||
|
|
||||||
;;;###autoload
|
;;;###autoload
|
||||||
(defun +evil-resolve-vim-path-a (file-name)
|
(defun +evil-replace-filename-modifiers-a (file-name)
|
||||||
"Take a path and resolve any vim-like filename modifiers in it. This adds
|
"Take a path and resolve any vim-like filename modifiers in it. This adds
|
||||||
support for most vim file modifiers, as well as:
|
support for most vim file modifiers, as well as:
|
||||||
|
|
||||||
|
@ -15,66 +15,65 @@ support for most vim file modifiers, as well as:
|
||||||
|
|
||||||
See http://vimdoc.sourceforge.net/htmldoc/cmdline.html#filename-modifiers for
|
See http://vimdoc.sourceforge.net/htmldoc/cmdline.html#filename-modifiers for
|
||||||
more information on modifiers."
|
more information on modifiers."
|
||||||
(let (case-fold-search)
|
(let ((origin-buffer (current-buffer))
|
||||||
|
case-fold-search)
|
||||||
(with-temp-buffer
|
(with-temp-buffer
|
||||||
(save-excursion (insert file-name))
|
(let ((buffer-file-name (buffer-file-name origin-buffer)))
|
||||||
(while (re-search-forward "\\(^\\|[^\\\\]\\)\\(\\([%#]\\)\\(:\\([PphtreS~.]\\|g?s\\)\\)*\\)" nil t)
|
(save-excursion (insert file-name))
|
||||||
(catch 'continue
|
(while (re-search-forward "\\(^\\|[^\\\\]\\)\\(\\([%#]\\)\\(:\\([PphtreS~.]\\|g?s\\)\\)*\\)" nil t)
|
||||||
(unless buffer-file-name
|
(if (null buffer-file-name)
|
||||||
(replace-match (match-string 1) t t nil 2)
|
(replace-match (match-string 1) t t nil 2)
|
||||||
(throw 'continue t))
|
(let ((beg (match-beginning 2))
|
||||||
(let ((beg (match-beginning 2))
|
(end (match-end 3))
|
||||||
(end (match-end 3))
|
(path (pcase (match-string 3)
|
||||||
(path (pcase (match-string 3)
|
("%" (file-relative-name buffer-file-name default-directory))
|
||||||
("%" (file-relative-name buffer-file-name))
|
("#" (and (other-buffer origin-buffer)
|
||||||
("#" (and (other-buffer)
|
(buffer-file-name (other-buffer origin-buffer)))))))
|
||||||
(buffer-file-name (other-buffer)))))))
|
(save-match-data
|
||||||
(save-match-data
|
(goto-char beg)
|
||||||
(goto-char beg)
|
(while (re-search-forward ":\\([PphtreS~.]\\|g?s\\)" (+ (point) 3) t)
|
||||||
(while (re-search-forward ":\\([PphtreS~.]\\|g?s\\)" (+ (point) 3) t)
|
(let* ((modifier (match-string 1))
|
||||||
(let* ((modifier (match-string 1))
|
(global (string-prefix-p "gs" modifier)))
|
||||||
(global (string-prefix-p "gs" modifier)))
|
(when global
|
||||||
(when global
|
(setq modifier (substring modifier 1)))
|
||||||
(setq modifier (substring modifier 1)))
|
(setq end (match-end 1)
|
||||||
(setq end (match-end 1)
|
path
|
||||||
path
|
(pcase (and path (substring modifier 0 1))
|
||||||
(or (when path
|
(`nil "")
|
||||||
(pcase (substring modifier 0 1)
|
("p" (expand-file-name path))
|
||||||
("p" (expand-file-name path))
|
("~" (concat "~/" (file-relative-name path "~")))
|
||||||
("~" (concat "~/" (file-relative-name path "~")))
|
("." (file-relative-name path))
|
||||||
("." (file-relative-name path default-directory))
|
("t" (file-name-nondirectory (directory-file-name path)))
|
||||||
("t" (file-name-nondirectory (directory-file-name path)))
|
("r" (file-name-sans-extension path))
|
||||||
("r" (file-name-sans-extension path))
|
("e" (file-name-extension path))
|
||||||
("e" (file-name-extension path))
|
("S" (shell-quote-argument path))
|
||||||
("S" (shell-quote-argument path))
|
("h"
|
||||||
("h"
|
(let ((parent (file-name-directory (expand-file-name path))))
|
||||||
(let ((parent (file-name-directory (expand-file-name path))))
|
(unless (file-equal-p path parent)
|
||||||
(unless (file-equal-p path parent)
|
(if (file-name-absolute-p path)
|
||||||
(if (file-name-absolute-p path)
|
(directory-file-name parent)
|
||||||
(directory-file-name parent)
|
(file-relative-name parent)))))
|
||||||
(file-relative-name parent)))))
|
("s"
|
||||||
("s"
|
(if (featurep 'evil)
|
||||||
(if (featurep 'evil)
|
(when-let (args (evil-delimited-arguments (substring modifier 1) 2))
|
||||||
(when-let (args (evil-delimited-arguments (substring modifier 1) 2))
|
(let ((pattern (evil-transform-vim-style-regexp (car args)))
|
||||||
(let ((pattern (evil-transform-vim-style-regexp (car args)))
|
(replace (cadr args)))
|
||||||
(replace (cadr args)))
|
(replace-regexp-in-string
|
||||||
(replace-regexp-in-string
|
(if global pattern (concat "\\(" pattern "\\).*\\'"))
|
||||||
(if global pattern (concat "\\(" pattern "\\).*\\'"))
|
(evil-transform-vim-style-regexp replace) path t t
|
||||||
(evil-transform-vim-style-regexp replace) path t t
|
(unless global 1))))
|
||||||
(unless global 1))))
|
path))
|
||||||
path))
|
("P"
|
||||||
("P"
|
(let ((project-root (doom-project-root (file-name-directory (expand-file-name path)))))
|
||||||
(let ((project-root (doom-project-root (file-name-directory (expand-file-name path)))))
|
(unless project-root
|
||||||
(unless project-root
|
(user-error "Not in a project"))
|
||||||
(user-error "Not in a project"))
|
(abbreviate-file-name project-root)))))
|
||||||
(abbreviate-file-name project-root)))))
|
;; strip trailing slash, if applicable
|
||||||
""))
|
(or (string-empty-p path)
|
||||||
;; strip trailing slash, if applicable
|
(not (equal (substring path -1) "/"))
|
||||||
(or (string-empty-p path)
|
(setq path (substring path 0 -1))))))
|
||||||
(not (equal (substring path -1) "/"))
|
(replace-match path t t nil 2))))
|
||||||
(setq path (substring path 0 -1))))))
|
(replace-regexp-in-string "\\\\\\([#%]\\)" "\\1" (buffer-string) t)))))
|
||||||
(replace-match path t t nil 2))))
|
|
||||||
(replace-regexp-in-string "\\\\\\([#%]\\)" "\\1" (buffer-string) t))))
|
|
||||||
|
|
||||||
(defun +evil--insert-newline (&optional above _noextranewline)
|
(defun +evil--insert-newline (&optional above _noextranewline)
|
||||||
(let ((pos (save-excursion (beginning-of-line-text) (point)))
|
(let ((pos (save-excursion (beginning-of-line-text) (point)))
|
||||||
|
|
|
@ -108,7 +108,7 @@ g Repeat alignment on all matches in each line"
|
||||||
If BANG is non-nil, open compilation output in a comint buffer.
|
If BANG is non-nil, open compilation output in a comint buffer.
|
||||||
|
|
||||||
If BANG, then run ARGUMENTS as a full command. This command understands vim file
|
If BANG, then run ARGUMENTS as a full command. This command understands vim file
|
||||||
modifiers (like %:p:h). See `+evil-resolve-vim-path-a' for details."
|
modifiers (like %:p:h). See `+evil-replace-filename-modifiers-a' for details."
|
||||||
(interactive "<sh><!>")
|
(interactive "<sh><!>")
|
||||||
(let ((compile-command "make"))
|
(let ((compile-command "make"))
|
||||||
(+evil:compile (if (stringp arguments)
|
(+evil:compile (if (stringp arguments)
|
||||||
|
@ -122,7 +122,7 @@ modifiers (like %:p:h). See `+evil-resolve-vim-path-a' for details."
|
||||||
If BANG is non-nil, open compilation output in a comint buffer.
|
If BANG is non-nil, open compilation output in a comint buffer.
|
||||||
|
|
||||||
This command understands vim file modifiers (like %:p:h). See
|
This command understands vim file modifiers (like %:p:h). See
|
||||||
`+evil-resolve-vim-path-a' for details."
|
`+evil-replace-filename-modifiers-a' for details."
|
||||||
(interactive "<sh><!>")
|
(interactive "<sh><!>")
|
||||||
(compile (evil-ex-replace-special-filenames
|
(compile (evil-ex-replace-special-filenames
|
||||||
(format "%s %s"
|
(format "%s %s"
|
||||||
|
|
|
@ -159,7 +159,7 @@ directives. By default, this only recognizes C directives.")
|
||||||
;; monkey patch `evil-ex-replace-special-filenames' to improve support for
|
;; monkey patch `evil-ex-replace-special-filenames' to improve support for
|
||||||
;; file modifiers like %:p:h. This adds support for most of vim's modifiers,
|
;; file modifiers like %:p:h. This adds support for most of vim's modifiers,
|
||||||
;; and one custom one: %:P (expand to the project root).
|
;; and one custom one: %:P (expand to the project root).
|
||||||
(advice-add #'evil-ex-replace-special-filenames :override #'+evil-resolve-vim-path-a)
|
(advice-add #'evil-ex-replace-special-filenames :override #'+evil-replace-filename-modifiers-a)
|
||||||
|
|
||||||
;; make `try-expand-dabbrev' (from `hippie-expand') work in minibuffer
|
;; make `try-expand-dabbrev' (from `hippie-expand') work in minibuffer
|
||||||
(add-hook 'minibuffer-inactive-mode-hook #'+evil--fix-dabbrev-in-minibuffer-h)
|
(add-hook 'minibuffer-inactive-mode-hook #'+evil--fix-dabbrev-in-minibuffer-h)
|
||||||
|
|
|
@ -9,10 +9,10 @@
|
||||||
(load! "../autoload/evil")
|
(load! "../autoload/evil")
|
||||||
|
|
||||||
(before-each
|
(before-each
|
||||||
(fset 'resv #'+evil-resolve-vim-path-a)
|
(fset 'resv #'+evil-replace-filename-modifiers-a)
|
||||||
(spy-on 'doom-project-root :and-call-fake (lambda () project-root)))
|
(spy-on 'doom-project-root :and-call-fake (lambda () project-root)))
|
||||||
|
|
||||||
;; `evil-ex-replace-special-filenames' / `+evil-resolve-vim-path-a'
|
;; `evil-ex-replace-special-filenames' / `+evil-replace-filename-modifiers-a'
|
||||||
(describe "file modifiers"
|
(describe "file modifiers"
|
||||||
(it "supports basic vim file modifiers"
|
(it "supports basic vim file modifiers"
|
||||||
(let ((buffer-file-name "~/.emacs.d/test/modules/feature/test-evil.el")
|
(let ((buffer-file-name "~/.emacs.d/test/modules/feature/test-evil.el")
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
"TODO"
|
"TODO"
|
||||||
(interactive "<fsh><!>")
|
(interactive "<fsh><!>")
|
||||||
(let ((buffer (+eshell-last-buffer))
|
(let ((buffer (+eshell-last-buffer))
|
||||||
(command (+evil-resolve-vim-path-a command)))
|
(command (+evil-replace-filename-modifiers-a command)))
|
||||||
(cond (buffer
|
(cond (buffer
|
||||||
(select-window (get-buffer-window buffer))
|
(select-window (get-buffer-window buffer))
|
||||||
(+eshell-run-command command buffer))
|
(+eshell-run-command command buffer))
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue