Git Product home page Git Product logo

dogears.el's Introduction

dogears.el

Never lose your place in Emacs again!

This library automatically and smartly remembers where you’ve been, in and across buffers, and helps you quickly return to any of those places. It works similarly to a Web browser’s history list and back/forward commands, but with more contextual information and customization. As well, for most modes, it can return to a place even if its buffer no longer exists.

It’s configurable to suit each user, with regard to how often places are remembered, which ones, and for how long. It uses standard Emacs completion, so it works with Helm, Ivy, Selectrum, Vertico, etc. For Helm users, a helm-dogears-source is also provided in helm-dogears.el that can be used with any Helm command.

Screenshots

This shows the dogears-list buffer, in which you can browse entries, sort them, etc.

images/screenshot.png

This screenshot shows it while using the theme doom-solarized-dark, and the Line column shows some source code snippets with highlighting by prism.el.

images/screenshot2.png

Contents

Installation

MELPA

If you installed from MELPA, you’re done. Just run one of the commands below.

Quelpa

The recommended way to install is with quelpa-use-package, like this:

;; Install and load `quelpa-use-package'.
(package-install 'quelpa-use-package)
(require 'quelpa-use-package)

(use-package dogears
  :quelpa (dogears :fetcher github :repo "alphapapa/dogears.el"
                   :files (:defaults (:exclude "helm-dogears.el")))

  ;; These bindings are optional, of course:
  :bind (:map global-map
              ("M-g d" . dogears-go)
              ("M-g M-b" . dogears-back)
              ("M-g M-f" . dogears-forward)
              ("M-g M-d" . dogears-list)
              ("M-g M-D" . dogears-sidebar)))

Manual

If you want to install it manually, it’s simple enough, but you should know what you’re doing, and you’re on your own.

Usage

It works by automatically remembering (“dogearing”) the place at point when any of three things happens:

  • The dogears idle timer runs (after 5 seconds idle, by default).
  • One of the dogears-hooks is run (only including imenu-after-jump-hook by default).
  • One of the functions listed in dogears-functions is called (none, by default).

Then the user can run a command to view or go to places in the list.

CommandAction
dogears-modeAutomatically remember places, according to configuration.
dogears-rememberManually remember the place at point.
dogears-goGo to a dogeared place, selected with completion.
dogears-backGo to previous dogeared place.
dogears-forwardGo to next dogeared place.
dogears-listShow dogeared places in a tabulated list buffer.
dogears-sidebarShow Dogears list in a side window.

Tips

  • You can customize settings in the dogears group.

Changelog

0.2-pre

Additions

  • Commands dogears-forward and dogears-back accept a universal prefix argument to move to manually remembered places.
  • Highlight index of last-selected place in dogears-list buffer.

Changes

  • Command dogears-go offers only “relevant” places by default; with universal prefix, it offers all places.
  • Commands dogears-forward and dogears-backward corrected: “backward” means to go to older places in history, and “forward” to go to more recent ones.

Fixes

  • Various logic regarding moving between remembered places.
  • Mark for manually remembered places in dogears-list completion.
  • Truncate path segments with ellipsis.

0.1

First tagged release.

Development

Bug reports, feature requests, suggestions — oh my!

Implementation

Internally, Dogears uses the built-in Emacs bookmark library to make bookmark-like records, however they are stored in dogears-list rather than bookmark-alist, so they are not accessible with bookmark commands. Nor is the dogears-list persisted to a file; it is empty when Emacs starts. If the bookmark-make-record-function does not return a record for a place, Dogears uses a simple fallback that saves a record referring to the buffer by name, which allows it to remember places in, e.g. the *scratch* buffer. When returning to a place, Dogears uses bookmark-jump, which for many, if not most, modes returns not only to the buffer or file but to the specific location in it. And by using bookmark internally, Dogears benefits from packages that extend it, like org-bookmark-heading.

Dogears also uses other built-in Emacs libraries, such as which-function and imenu, to provide information about the context surrounding a place, such as a function or variable definition, an outline heading, etc.

Alternatives

Some other, similar packages:

gumshoe
Gumshoe is a collection of global minor modes 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. 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.
Bookmark+ Automatic Idle-Period Bookmarking
Automatic idle-period bookmarking uses autonamed bookmarks. It lets you navigate among them to visit spots where you spent some time (idly).

License

GPLv3

dogears.el's People

Contributors

alphapapa avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

dogears.el's Issues

dogears-back and dogears-forward do nothing

Just installed the latest version from melpa. I can see the list of dogears with dogears-list, but executing dogears-back and dogears-foward doesn't change between dogears. I would expect it to go back and forward through the list, but that doesn't happen.

typo in customise dogears

i get this as a customisation option:

Show Value Dogears Sidebar Alist
Alist passed to ‘display-buffer-in-side-window’, which see.

i think that should probably be 'which side', not 'which see'?

Ignore derived modes in dogears-ignore-modes

Hello again Adam!

I noticed that dogears-ignore-modes does not exclude derived modes. So passing it something like fundamental-mode only excludes buffers whose major-mode is that.

A search for derived-mode-p yields no results. Is this by design? Because I feel that it is more difficult to exclude every single major-mode I do not want to track.

dogears-functions can break interactive commands

Hello Adam and thanks for sharing this package!

Here is a bug I found on Emacs 28. With emacs -Q I evaluate this:

(require 'dogears "/path/to/dogears.el")

(setq dogears-functions '(find-file switch-to-buffer))

(dogears-mode 1)

Then when I try to use either of the dogears-functions, I get these messages:

apply: Wrong number of arguments: #<subr find-file>, 0

apply: Wrong number of arguments: #<subr switch-to-buffer>, 0

Let the bookmark system know it's called by dogears

Hi,

I do have a "funny" request. As you can read on reddit, I forgot that I added dogears to my config. As I added ID property support for my bookmark system using my own my-id-get-or-generate function to generate human-readable ID properties on bookmarking, I noticed that IDs were generated without my interaction.

oantolin reminded me of debug-on-entry which revealed the forgotten nugget of dogears.

Therefore: is there a sane way of letting my custom bookmark function that it is called by dogears in order to omit generating IDs and using the default bookmark concept?

So far, I setup dogears for testing purposes and I'm not sure if it brings much benefit to my current situation. So if the answer is "yes but this requires ugly hacks", we can agree on closing this issue.

Thanks for you thoughts on that!

Marker triggers

Hi, I spent some time working on similar functionality a few years ago, but never got to a point of publishing anything. I just wanted to point you to a resource I found that describes some good triggers to consider for recording markers:

https://docs.wholetomato.com/default.asp?W197 (scroll down to the Waypoints section)

*appease-gnus* keeps popus while reading mails in mu4e

Whenever I'm reading emails in mu4e I get a popup (op top, which steals cursor) for appease-gnus buffer. I do not use gnus, and have never configured it. Apparently I'm not alone in this either --> https://teddit.net/r/emacs/comments/q1podp/mu4e_new_message_view_popping_window_appeasegnus/

Fix provided within the discussion has worked for me, but its good to fix it at source.

More details:
OS: NixOS Unstable
Emacs 29.0.50 with --with-native-compilation
Doom-emacs develop branch

I do not know what else could be the cause, but can test/provide logs if needed

Function helm-make-source called during package-initialize before helm is loaded

Hi,
I installed dogears using elpa/quelpa.
It installs fine and runs fine after installation.
When I re-start emacs, the call to (package-initialize) early on on my init file causes the error (void-function helm-make-source) since helm has not been loaded yet. I am running
Is there a way to load helm before dogears is loaded?

I compile emacs from source and I am using the latest version from git on MacOs BigSur 11.6:
Emacs git commit:
commit 338af9213d6cb47da9c1835d20d8db27b915b3d1 (HEAD -> master, origin/master, origin/HEAD)
Author: Lars Ingebrigtsen [email protected]
Date: Fri Sep 17 18:37:51 2021 +0200

Stack trace for the error:

Debugger entered--Lisp error: (void-function helm-make-source)
(helm-make-source "Dogears" 'helm-source-sync :candidates #'(lambda nil (let* ((--cl-var-- dogears-list) (place nil) (--cl-var-- nil)) (while (consp --cl-var--) (setq place (car --cl-var--)) (setq --cl-var-- (cons (cons ... place) --cl-var--)) (setq --cl-var-- (cdr --cl-var--))) (nreverse --cl-var--))) :action (list (cons "Go to place" #'dogears-go)))
(defvar helm-dogears-source (helm-make-source "Dogears" 'helm-source-sync :candidates #'(lambda nil (let* ((--cl-var-- dogears-list) (place nil) (--cl-var-- nil)) (while (consp --cl-var--) (setq place (car --cl-var--)) (setq --cl-var-- (cons ... --cl-var--)) (setq --cl-var-- (cdr --cl-var--))) (nreverse --cl-var--))) :action (list (cons "Go to place" #'dogears-go))))
eval-buffer(#<buffer load-271998> nil "/Users/marcelbecker/Dropbox/.emacs.d/elpa/dogears-..." nil t) ; Reading at buffer position 2249
load-with-code-conversion("/Users/marcelbecker/Dropbox/.emacs.d/elpa/dogears-..." "/Users/marcelbecker/Dropbox/.emacs.d/elpa/dogears-..." nil t)
load("/Users/marcelbecker/Dropbox/.emacs.d/elpa/dogears-..." nil t)
package--activate-autoloads-and-load-path(#s(package-desc :name dogears :version (20210902 2214) :summary "Never lose your place again" :reqs ((emacs (26 3)) (map (2 1))) :kind nil :archive nil :dir "/Users/marcelbecker/Dropbox/.emacs.d/elpa/dogears-..." :extras ((:url . "https://github.com/alphapapa/dogears.el") (:keywords "convenience") (:maintainer "Adam Porter" . "[email protected]") (:authors ("Adam Porter" . "[email protected]"))) :signed nil))
package--load-files-for-activation(#s(package-desc :name dogears :version (20210902 2214) :summary "Never lose your place again" :reqs ((emacs (26 3)) (map (2 1))) :kind nil :archive nil :dir "/Users/marcelbecker/Dropbox/.emacs.d/elpa/dogears-..." :extras ((:url . "https://github.com/alphapapa/dogears.el") (:keywords "convenience") (:maintainer "Adam Porter" . "[email protected]") (:authors ("Adam Porter" . "[email protected]"))) :signed nil) nil)
package-activate-1(#s(package-desc :name dogears :version (20210902 2214) :summary "Never lose your place again" :reqs ((emacs (26 3)) (map (2 1))) :kind nil :archive nil :dir "/Users/marcelbecker/Dropbox/.emacs.d/elpa/dogears-..." :extras ((:url . "https://github.com/alphapapa/dogears.el") (:keywords "convenience") (:maintainer "Adam Porter" . "[email protected]") (:authors ("Adam Porter" . "[email protected]"))) :signed nil) nil deps)
package-activate(dogears)
package--activate-all()
package-activate-all()
package-initialize()

EXWM issue

https://www.reddit.com/r/emacs/comments/p3mdyg/ann_dogearsel_never_lose_your_place_in_emacs_again/h8txyey/

this package does not work with exwm-mode buffers. Not only does it not work with exwm-mode buffers, but if a mark is created in an exwm-mode buffer (by say a timer) then if I try to call either dogears-go or dogears-list then I get the error Wrong type argument: stringp, nil, and now the package is broken unless I remove certain elements from the dogears-list or restart my emacs.

    Debugger entered--Lisp error: (wrong-type-argument stringp nil)
      string-match("/" nil 0)
      split-string(nil "/" t)
      dogears--format-record-list(("" (line . "") (mode . exwm-mode) (within . "") (buffer . #("firefox" 0 7 (charset iso-8859-1))) (filename . "   - no file -") (manual . " ") (buffer-name . #("firefox" 0 7 (charset iso-8859-1))) (front-context-string) (rear-context-string) (front-context-region-string) (rear-context-region-string) (visits . 0) (time 24854 57805 389235 715000) (created 24854 57805 389235 715000) (position . 1)))
      dogears--format-record(("" (line . "") (mode . exwm-mode) (within . "") (buffer . #("firefox" 0 7 (charset iso-8859-1))) (filename . "   - no file -") (manual . " ") (buffer-name . #("firefox" 0 7 (charset iso-8859-1))) (front-context-string) (rear-context-string) (front-context-region-string) (rear-context-region-string) (visits . 0) (time 24854 57805 389235 715000) (created 24854 57805 389235 715000) (position . 1)))
      byte-code("\10\301\211\211\3:\203 \0\3@\262\3\302\3!\262\2\1\3B\1B\262\1\3A\262\4\202\4\0\211\237\266\204\303\304\2\301\305$\306\1\3\301\211\307%C..." [dogears-list nil dogears--format-record completing-read "Place: " t alist-get equal] 8)
      call-interactively(dogears-go record nil)
      command-execute(dogears-go record)
      execute-extended-command(nil "dogears-go" nil)
      funcall-interactively(execute-extended-command nil "dogears-go" nil)
      call-interactively(execute-extended-command nil nil)
      command-execute(execute-extended-command)

dogears-index can become negative

When you repeatedly run dogears-forward, the index can become negative:

Dogears: Forward to -14/6

(nth N LIST) returns the first element of the list if N is less than zero.

Possibly bugs in `dogears-go` and `dogears-forward`?

First of all, thanks for the package!

I see 2 places that might be bugs. (Disclaimer: relatively new to Emacs and don't understand how bookmarks work.)

  • In dogears-forward, it seems (nth -1000 '(a b c)) returns a, so dogears-index could go negative?
  • In dogears-go, (bookmark-jump place) returns nil after jumping (at least for me) so the or below is kind of pointless.

    dogears.el/dogears.el

    Lines 234 to 236 in c05b69e

    (or (ignore-errors
    (bookmark-jump place))
    (when-let ((buffer (map-elt (cdr place) 'buffer)))

Error with nov.el

Routinely get this error when an .epub is open in nov.el mode.

Error running timer ‘dogears-remember’: (wrong-type-argument plistp ("Moby-Dick (Unabridged) _ D. H. Lawrence's - Herman Melville.epub" (filename . "/Users/hrizvi/calibre/Herman Melville/Moby-Dick (Unabridged) _ D. H. Lawrence's Critique of Moby-Dick (1419)/Moby-Dick (Unabridged) _ D. H. Lawrence's - Herman Melville.epub") (index . 72) (position . 1) (handler . nov-bookmark-jump-handler)))

Coming from dogears-remember:

Debugger entered--Lisp error: (wrong-type-argument plistp ("Moby-Dick (Unabridged) _ D. H. Lawrence's Critique..." (filename . "/Users/hrizvi/calibre/Herman Melville/Moby-Dick (U...") (index . 105) (position . 1) (handler . nov-bookmark-jump-handler))) plist-put(("Moby-Dick (Unabridged) _ D. H. Lawrence's Critique..." (filename . "/Users/hrizvi/calibre/Herman Melville/Moby-Dick (U...") (index . 105) (position . 1) (handler . nov-bookmark-jump-handler)) manual " ") map-put!(("Moby-Dick (Unabridged) _ D. H. Lawrence's Critique..." (filename . "/Users/hrizvi/calibre/Herman Melville/Moby-Dick (U...") (index . 105) (position . 1) (handler . nov-bookmark-jump-handler)) manual " " nil) dogears-remember() apply(dogears-remember nil) timer-event-handler([t 0 5 0 repeat dogears-remember nil idle 0])

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.