Skip to content

Latest commit

 

History

History
261 lines (198 loc) · 6.73 KB

wal-movement.org

File metadata and controls

261 lines (198 loc) · 6.73 KB

Movement

Moving around should be fun.

Header

;;; 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")

Packages

avy

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))

bookmark

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)))

outline

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")))

register

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)))

Footer

(provide 'wal-movement)

;;; wal-movement.el ends here