Skip to content

Overdr0ne/gumshoe

Repository files navigation

Gumshoe: a smart POINT tracker

https://github.com/Overdr0ne/gumshoe/actions/workflows/test.yml/badge.svg https://melpa.org/packages/gumshoe-badge.svg

./noir.jpg

Introduction

Gumshoe is a daemon that quietly keep tabs on your Point movements so you can retrace your steps if you ever need a reminder of where you’ve been. Each mode keeps a log local to some scope.

./peruse-demo.gif (This demonstrates the non-built-in gumshoe-peruse-globally command described below, because it’s the most visual. I usually just use gumshoe–backtrack-back/forward and its variants.)

Gumshoe does not keep track of every move you make, rather, only at increments of some minimum Euclidean distance from the last tracked position, like a leash. It will also automatically log a position if you’ve idled there for a configurable amount of time. This package is very similar to Vim’s jump list, just generalized for Emacs.

Installation

I just use straight+use-package like so:

(use-package gumshoe
  :straight (gumshoe :type git
                     :host github
                     :repo "Overdr0ne/gumshoe"
                     :branch "master")
  :init
  ;; Enabing global-gumshoe-mode will initiate tracking
  (global-gumshoe-mode +1)
  ;; customize peruse slot display if you like
  (setf gumshoe-slot-schema '(time buffer position line))
  ;; personally, I use perspectives
  ;; (setf gumshoe-slot-schema '(perspective time buffer position line))
  ;; disable auto-cancel of backtracking
  (setf gumshoe-auto-cancel-backtracking-p nil)
  )

Usage

  • Once global-gumshoe-mode is enabled, gumshoe will automatically start recording movements into the backlog.
  • Configure the backlog data structure with gumshoe-backlog-type: 'ring (default, circular buffer) or 'tree (branching timeline).
  • Configure Gumshoe’s euclidean follow distance by customizing the gumshoe-follow-distance variable.
  • Configure Gumshoe’s idle time by customizing the gumshoe-idle-time variable.
  • Configure the number of locations logged with the gumshoe-log-len variable (applies to ring mode).
  • Horizontal distance is scaled down by a factor of 4 by default via context-horizontal-scale, since columns are approximately that much narrower than rows.
  • If you would like to disable gumshoe tracking in some contexts, you may use gumshoe-ignored-minor-modes or gumshoe-ignored-major-modes, to ignore by mode, or more generically just add to gumshoe-ignore-predicates any condition where you would like gumshoe to stop tracking, like minibufferp, added by default.

Backtracking

Backtracking works a bit like isearch or Vim’s jump-list. Point will jump sequentially between points in the backlog. ./backtrack-demo.gif

  • Use gumshoe-backtrack to enter backtracking mode and start navigating the global log. Once in backtracking mode, use backward-paragraph and forward-paragraph (usually { and }) to navigate.
  • There is built-in support for filtered backtracking:
    • gumshoe-buf-backtrack - Navigate entries only in the current buffer
    • gumshoe-win-backtrack - Navigate entries only in the current window
    • gumshoe-marker-backtrack - Navigate only manually dropped markers
  • Perspective.el integration available via persp-gumshoe (see *Extensions).
  • Gumshoe activates global-gumshoe-backtracking-mode during backtracking. Leave this mode with keyboard-quit (usually C-g).
  • Additional backtracking commands (while in backtracking mode):
    • C-r (gumshoe-backtrack-restart) - Reset to the latest (most recent) entry in the backlog while staying in backtracking mode
    • C-c (gumshoe-backtrack-cancel) - Jump to the latest entry and quit backtracking
    • C-v (gumshoe-backtrack-resume) - Resume backtracking at the entry where you previously stopped. If never backtracked, starts at latest entry. If the previous entry was cleaned or wrapped, starts at earliest entry with notification
  • Customize the backtracking keymap via gumshoe-backtracking-mode-map.
  • By default, Gumshoe marks “footprints” (overlays indicating entry points). Toggle gumshoe-show-footprints-p to disable them.
  • By default, backtracking auto-cancels when you type a non-backtracking command. Disable with (setf gumshoe-auto-cancel-backtracking-p nil).
  • Footprint strategy via gumshoe-footprint-strategy:
    • 'cover-old (default) - Only show most recent footprint within gumshoe-footprint-radius
    • 'delete-overlapping - Delete old overlapping footprints
    • nil - Show all footprints

Perusing

You can also visually browse the backlog in the minibuffer with the peruse commands:

  • gumshoe-peruse-globally - Browse all entries via completing-read
  • gumshoe-peruse-in-buffer - Browse entries in current buffer
  • gumshoe-peruse-in-window - Browse entries in current window
  • gumshoe-peruse-markers - Browse manually dropped markers
  • Customize gumshoe-slot-schema to specify which fields are displayed and in what order (default: '(time buffer position line)).
  • Make your own peruse commands by providing a filter predicate to gumshoe--peruse.

Manual Markers

You may manually drop a marker at any time with gumshoe-drop-marker. These markers can be navigated independently with gumshoe-marker-backtrack and gumshoe-peruse-markers.

Change log

4.0

  • Extracted optional integrations into separate packages under extensions/ to avoid conditional loading. See *Extensions.

3.1

  • Abstracted backlog implementation: Users can now choose between ring (circular buffer) and tree (branching timeline) via gumshoe-backlog-type.
  • Unified command interface: Backtracking commands now enter a transient mode (global-gumshoe-backtracking-mode) where movement keys navigate the timeline. No more separate -back/-forward commands.
  • Added gumshoe-backtrack-resume command to resume backtracking at the last position where you stopped. Remembers position across backtracking sessions and handles cleaned/wrapped entries gracefully.
  • Improved EIEIO method dispatch with proper class wrappers for both ring and tree implementations.
  • Fixed cover-old footprint strategy to properly hide overlapping footprints.
  • Moved shared entry creation logic to gumshoe--make-entry in gumshoe-lib.el for consistency.

3.0

  • Turned backtracking into a minor mode. This better isolates backtracking state, allows customizable keybindings via the minor mode map, and lets users move around with footprints still active.
  • Fixed bugs associated with cleaning up dead entries.

2.0

  • Gumshoe now uses ‘gumshoe–entries’ in the backlog instead of marks or bookmarks. I tried to make bookmarks work for me, but found the bookmark-alist far too ingrained into their interface and ended up finding it easier and more extensible to just make my own abstraction. It contains basically all the same metadata as a bookmark, but users/developers may add whatever metadata they want, by inheriting from it. That’s how I added the perspective field.
  • peruse: this is my take on `dogears-list`. It uses completing read to browse through the backlog. The display is customizable, allowing users to specify what and in what order gumshoe–entry fields are selected.
  • Noticing how similar backtracking is to isearch, I upgraded backtracking to also display ‘footprints’ which visually indicate maked positions while backtracking.
  • Both backtracking and perusing be filtered programmatically by passing in a predicate function.

Why the big change? Why all the OO complexity?

I generally noticed that the thing I was tracking was not so much the point position, but user context. And context I realized can cover a lot, and arguably, could cover the entire state of Emacs, or your computer, or, well, the universe at the moment that context is recorded. So rather than try to have gumshoe cover all possible definitions of context, I tried to just focus on the interface, and provide a clear path to extension, for me or anyone. So that’s where all the OO stuff came from. It’s not complete, but that’s where I’m going with it. The benefits may not be obvious at the time of this writing, but I hope will be as I add things.

Similar Packages

If Gumshoe doesn’t suit you, here are some more Point history tracking packages that may.

So why do we need gumshoe then? Gumshoe has:

  • automatic temporal tracking and spatial tracking
  • customizable log filters allow you to see just the information you want.
  • customizable context metadata allows you to tell gumshoe exactly what you want logged.
  • Built-in autocompletion using only completing-read.
  • extensible scoping: if you can make arbitrary variables local to your scope, you can make a gumshoe mode for that scope. Scoped logs work independently, and don’t interfere with the global-mark-ring.
  • works ootb without much configuration or dependency on external packages

Packages above may have one or two of these features, but changes on the order of a complete rewrite would be required to make them work like gumshoe. But comments are totally welcome if you’d like to open an issue.

Extensions

Migration from gumshoe 3.x

Architecture

  • gumshoe.el - Main entry point and mode definition
  • context.el - Context object for storing position metadata
  • gumshoe-lib.el - Shared utilities and customization
  • gumshoe-backtracker.el - Backtracking state management
  • gumshoe-ring.el - Ring buffer backlog implementation
  • gumshoe-tree.el - Tree-based backlog implementation (optional)
  • gumshoe-footprints.el - Visual overlay management
  • gumshoe-peruse.el - Completion-based browsing
  • etree.el - Mutable tree library

Outstanding Issues

Dynamic Entry Format Changes

  • Gumshoe needs to know entry format before tracking begins. Dynamically changing the format requires reinitializing the mode.
  • Adding fields from multiple packages requires defining a new class for each combination (to avoid multiple inheritance).

Common Context Interface

  • The context class is effectively a bookmark replacement. Consider defining a generic interface using cl-defgeneric that works for bookmarks, contexts, and other navigation targets.

Alternative Browsing UIs

  • Add an ‘ibacklog’ buffer interface (like ibuffer) as an alternative to peruse’s completing-read interface.

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 3

  •  
  •  
  •