Helm: Include push-mark patch to fix helm-mark-ring with Evil

master
Pierre Neidhardt 2017-10-27 09:55:34 +01:00
parent 261ed9f0ec
commit 43fd9ceed9
3 changed files with 38 additions and 5 deletions

View File

@ -49,4 +49,7 @@
(define-keys exwm/helm-browser-map "M-d" 'helm-buffer-run-kill-persistent)
(define-keys exwm/helm-browser-map "M-o" 'helm-buffer-switch-other-window))
;; `helm-mark-or-exchange-rect' is not needed with Evil.
(global-set-key (kbd "C-x C-x") 'helm-all-mark-rings)
(provide 'init-evil-helm)

View File

@ -1,11 +1,9 @@
;;; Evil
;;; TODO: helm-show-kill-ring behaves like Emacs when pasting whole lines, not like Vim.
;;; REVIEW: helm-mark-ring seems to have issues with Evil.
(require 'patch-mark)
;;; TODO: helm-mark-ring seems to have issues with Evil:
;;; - The first entry is not the last position but the current one.
;;; - Navigating through the marks randomly produces a "Marker points into wrong buffer" error.
;;; https://github.com/emacs-evil/evil/issues/845#issuecomment-306050231
;;; TODO: helm-show-kill-ring behaves like Emacs when pasting whole lines, not like Vim.
;;; TODO: Make Evil commands react more dynamically with read-only text, like eshell, wdired.
;;; Add support for I, C, D, S, s, c*, d*, R, r.
@ -58,6 +56,7 @@
;;; For git commit, web edits and others.
;;; Since `with-editor-mode' is not a major mode, `evil-set-initial-state' cannot
;;; be used.
;;; This requires Eshell, shells and more.
(when (require 'with-editor nil t)
(add-hook 'with-editor-mode-hook 'evil-insert-state))

View File

@ -0,0 +1,31 @@
;;; Fix https://github.com/emacs-helm/helm/issues/1891
;;; TODO: Report upstream?
(defun tv/advice-push-mark (&optional location nomsg activate)
(unless (null (mark t))
(let ((marker (copy-marker (mark-marker))))
(setq mark-ring (cons marker (delete marker mark-ring))))
(when (> (length mark-ring) mark-ring-max)
;; Move marker to nowhere.
(set-marker (car (nthcdr mark-ring-max mark-ring)) nil)
(setcdr (nthcdr (1- mark-ring-max) mark-ring) nil)))
(set-marker (mark-marker) (or location (point)) (current-buffer))
;; Now push the mark on the global mark ring.
(setq global-mark-ring (cons (copy-marker (mark-marker))
;; Avoid having multiple entries
;; for same buffer in `global-mark-ring'.
(cl-loop with mb = (current-buffer)
for m in global-mark-ring
for nmb = (marker-buffer m)
unless (eq mb nmb)
collect m)))
(when (> (length global-mark-ring) global-mark-ring-max)
(set-marker (car (nthcdr global-mark-ring-max global-mark-ring)) nil)
(setcdr (nthcdr (1- global-mark-ring-max) global-mark-ring) nil))
(or nomsg executing-kbd-macro (> (minibuffer-depth) 0)
(message "Mark set"))
(when (or activate (not transient-mark-mode))
(set-mark (mark t)))
nil)
(advice-add 'push-mark :override #'tv/advice-push-mark)
(provide 'patch-mark)