Moving around should be fun.
;;; wal-movement.el --- Movement. -*- lexical-binding: t -*-
;;; Commentary:
;;
;; Provide movement packages.
;;; Code:
(eval-when-compile
(require 'wal-useful nil t)
(require 'wal-key-bindings nil t))
(declare-function avy-goto-end-of-line "ext:avy.el")
(declare-function avy-goto-line "ext:avy.el")
(declare-function avy-goto-word-0 "ext:avy.el")
(declare-function org-at-heading-p "ext:org.el")
(declare-function wal-univ-p "wal-useful.el")
(declare-function wdb-nearby "wal-useful.el")
Line-(as well as word- and character-)based movement and actions.
Configured to go to beginnning-of-line
for Org buffers (because of org-speed-commands
). The scope (current line, current window, all windows) of jumping to words can be extended using C-u
. The dispatch is extended with functionality to mark the section between point and jump target.
(defun wal-avy-goto-word (&optional scope)
"Jump to a word.
SCOPE will consume `universal-argument' to determine whether to
jump to a word in the buffer or anywhere."
(interactive "P")
(require 'avy nil t)
(defvar avy-style)
(let ((avy-style (if scope 'words 'at-full)))
(if scope
(let ((flip (or (and (listp scope) (> 5 (prefix-numeric-value scope)))
(and (numberp scope) (> 2 scope)))))
(setq current-prefix-arg nil)
(avy-goto-word-0 flip))
(eval (macroexpand
'(avy-with avy-goto-word-0
(avy-jump avy-goto-word-0-regexp
:beg (line-beginning-position)
:end (line-end-position)
:window-flip t)))))))
(defun wal-avy-goto-line (&optional beginning)
"Go to line or BEGINNING of line."
(interactive "P")
(require 'avy nil t)
(if beginning
(progn
(avy-goto-line)
(beginning-of-line-text))
(avy-goto-end-of-line)))
(defun wal-avy-order-closest-line (location)
"Get how close LOCATION is to the current point.
This compares the line numbers of the two points."
(let* ((pos (car location))
(win (cdr location)))
(with-selected-window win
(abs (- (line-number-at-pos pos)
(line-number-at-pos))))))
(defun avy-action-zip-to-char (pt)
"Zip (just mark) from current point up to PT."
(set-mark (point))
(goto-char pt))
(defun wal-then-goto-beginning-for-org-headings (&rest _args)
"Advise `avy-goto-end-of-line' to go to beginning for `org' headings.
When called with `universal-argument', this also goes to the
beginning."
(when (or (wal-univ-p)
(and (eq major-mode 'org-mode) (org-at-heading-p)))
(goto-char (line-beginning-position))))
(use-package avy
:commands (avy-with)
:config
;; Extend the dispatch with a way to delete up to a char.
(add-to-list 'avy-dispatch-alist '(?q . avy-action-zip-to-char))
;; Make sure we go to the start of the line for org headings.
(advice-add
'avy-goto-end-of-line :after
#'wal-then-goto-beginning-for-org-headings)
:custom
(avy-background t)
(avy-timeout-seconds 0.8)
(avy-style 'words)
(avy-styles-alist '((avy-goto-line . at-full)))
(avy-keys '(?j ?k ?l ?\; ?h ?f ?d ?s ?a ?g))
(avy-orders-alist '((avy-goto-word-0 . avy-order-closest)
(avy-goto-char . avy-order-closest)
(avy-goto-line . wal-avy-order-closest-line)))
:wal-bind
(("l" . wal-avy-goto-line)
("j" . wal-avy-goto-word)
("M-j" . avy-goto-char-in-line))
:general
;; Lines.
(editors "c" 'avy-copy-line 'avy-copy-region)
(editors "x" 'avy-kill-whole-line 'avy-kill-region)
(editors "m" 'avy-move-line 'avy-move-region)
(editors "w"
'avy-kill-ring-save-whole-line
'avy-kill-ring-save-region))
Leave a bookmark why don’t you. Binds the keymap and sets up annotations.
(use-package bookmark
:init
(that-key "bookmark" :key "C-c b")
:config
(wdb-nearby "\\*Bookmark Annotation\\*" :side 'left :no-other t)
:custom
(bookmark-use-annotations t)
(bookmark-menu-confirm-deletion t)
(bookmark-fringe-mark nil)
:bind-keymap
(("C-c b" . bookmark-map))
:bind
(:map bookmark-map
("b" . bookmark-set)
("l" . bookmark-bmenu-list)
("L" . bookmark-load)))
Navigate outline.
(use-package outline
:hook ((text-mode prog-mode harpoon-prog-like) . outline-minor-mode)
:delight
(outline-minor-mode " out")
:config
(that-key "outline" :key "C-c d")
:custom
(outline-minor-mode-prefix (kbd "C-c d")))
No offender.
(defun wal-clear-registers ()
"Clear all registers."
(interactive)
(setq register-alist nil))
(defun wal-point-to-register (register &optional arg)
"Store current location of point in REGISTER.
With prefix argument ARG, store current window configuration.
This is otherwise a copy of `point-to-register'."
(interactive (list (register-read-with-preview
(if current-prefix-arg
"Window configuration to register: "
"Point to register: "))
current-prefix-arg))
(add-hook 'kill-buffer-hook 'register-swap-out nil t)
(set-register
register
(if arg
(list (current-window-configuration) (point-marker))
(point-marker))))
(use-package register
:config
;; Make sure that jumping to a marker attempts to select a window
;; already displaying the buffer first.
(cl-defmethod register-val-jump-to :before ((val marker) arg)
(when-let* ((buffer (marker-buffer val))
(windows (window-list-1))
(live (seq-find (lambda (it) (eq (window-buffer it) buffer))
windows)))
(select-window live)))
:custom
(register-preview-delay 0.8)
:general
(adjunct "r" 'wal-clear-registers)
:wal-bind
(("y" . jump-to-register)
("M-y" . wal-point-to-register)))
(provide 'wal-movement)
;;; wal-movement.el ends here