GithubHelp home page GithubHelp logo

alphapapa / activities.el Goto Github PK

View Code? Open in Web Editor NEW
177.0 177.0 10.0 195 KB

Activities for Emacs (suspend and resume activities, i.e. frames/tabs and their windows, buffers)

License: GNU General Public License v3.0

Emacs Lisp 57.46% Shell 42.54%
emacs

activities.el's People

Contributors

alphapapa avatar jdtsmith avatar josephmturner 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

activities.el's Issues

Incomplete revert of saved state when buffer file goes missing

activities-revert from within a window in a modified activity frame (different buffers showing) reverts only some of the windows. When called from a window containing a correct buffer from the activity, it works as expected to restore other windows.

For example a given activity contains 3 window/buffer combos, A, B, and C. If A and B are altered to show other non-activity buffers (e.g. with winner), to say an A', B', C, calling activities-resume from A' might lead to a spurious C, B', C configuration.

I think I have identified the reason for this. If one of the files (say A's) has gone missing, due to changing git branches, for example, on revert its window will reappear, but the buffer contents of the window will be arbitrary, sometimes selecting a file from the activity, or another file altogether.

Here perhaps a warning would be appropriate, if attempting to restore a file-backed buffer which has gone missing (and also not creating the associated window).

Activities tabs should resize according to `tab-bar-auto-width`

Activities tabs are not resized even when the tab-bar-auto-width option is non-nil.

;; Create a bunch of activities, see the tab bar wrap 
(progn
  (setopt tab-bar-auto-width t)
  (activities-tabs-mode 1)
  (dotimes (i 10)
    (activities-new (format "test-long-name-%s" i))))

;; Clean up
(progn
  (dotimes (i 10)
    (let* ((name (format "test-long-name-%s" i))
           (activity (map-elt activities-activities name)))
      (ignore-errors
        (when (activities-activity-active-p activity)
          (activities-close activity)))
      (setf activities-activities (map-delete activities-activities name)))))

Internally, the tab-bar-auto-width function determines that a tab should be resized if its face is one of tab-bar-auto-width-faces. However, activities-tabs--tab-bar-tab-face-function (say that even once fast... πŸ˜‰) sets the activities tab face to (:inherit (activities-tabs ,face)), so the activities tabs are never resized.

Other ways to handle unrestorable buffers

My use-case: I use activities as a substitute for desktop-mode that improves the experience by providing the added benefit of working for many non-file-backed buffers.

I do this with code very similar to the following in at the top level of my init.el:

(run-with-idle-timer
  5
  nil
  (lambda () 
	(let ((my/default-activity-name "my/default"))
        ;; side note: please make `#'activities-named` be autoloaded; as can be seen here, it is an appropriate entry point and would allow me to remove this `#'require`. 
	    (require 'activities)
	    (activities-resume
	      (or
	        (activities-named my/default-activity-name)
	        (activities-define my/default-activity-name))))))

However, in doing so, I often hit

(with-current-buffer (get-buffer-create (concat "*Activities (error): " name "*"))

Such a customization would allow me to avoid saving such buffers that cannot be restored.

Hypothetical `activities-update-current-default`

I am still missing a simple command to quickly update the default state for the current activity (see #16). I came up with this:

(defun my/activities-update-default ()
    (interactive)
    (if-let ((current (activities-current)))
	(when (y-or-n-p
	       (format "Update default for activity %s with current state? "
		       (activities-activity-name current)))
	  (activities-save current :defaultp t :lastp t)
	  (message "Updated %s default state"
		   (activities-activity-name current)))
      (message "No current activity to update.")))

Which I bind to C-S-<f10>. This works perfectly: updating current activity (if any) after asking permission. I'm certain others would use this feature (and the method to update default would be more visible) if installed as a command.

[feature request] add an mode-line indicator as current activity name.

My daily workflow will open many different activities about 10 activities. But sometime want to know which activity currently after I leave for a while.

Can activities.el provide a minor-mode :lighter indicator in mode-line?

I tried to use existing variable to got current activty but failed with bellowing code:

(add-to-list 'mode-line-misc-info
               '(activities-mode (:eval (concat
                                         "[β€» "
                                         (activities-activity-name
                                          (cdar (cl-remove-if-not #'activities-activity-last ; FIXME: not current activity.
                                                                  activities-activities
                                                                  :key #'cdr)))
                                         "]"))))

Feedback on user expectation

This is less a bug report and more a brief account of what one user hoped to get from activities. I set up an activity that I usually build by hand on startup containing 4 buffers: two org-mode, one mastodon and my org agenda. Sadly the latter two do not support bookmark and so activities-resume failed (in a very helpful way that signposted the issue).

Anyway, the punchline is that the restriction to bookmark-able buffers will severely limit the usefulness of this package for me.

Add example to wiki of writing simple bookmark functions for modes not having them

Discussed in #39

Originally posted by amno1 February 16, 2024
Is there some before/after hook I can hook a function into before the bookmark is opened?

I would like to restore a Sly session, with sbcl and a custom saved image. I am thinking of:

open bookmarked asdf file or at least project directory
start sly with a given compiler (I have different builds of sbcl) and saved core image

I haven't looked much at the code; I have just installed it and played a bit with it, so I am not very familiar with it. I see the activities--bookmark-buffer function.; or in activites--serialize/deserialize?

I could then add something to before (deserialize) hook to run Sly and wait until repl is up and running.

Or perhaps there is already a better place or a better way?

Optionally do not `set-frame-name`

Many people customize the frame title to include other information (like full path). It would be great if activities had an option not to set the frame name. Then you can always include an :eval in frame-title-format with (activities-name-for (activities-current)).

Buffer not visiting a file or directory

The save timer occasionally throws this error when I've worked for a while on an activity:

Debugger entered--Lisp error: (error "Buffer not visiting a file or directory")
  signal(error ("Buffer not visiting a file or directory"))
  error("Buffer not visiting a file or directory")
  bookmark-buffer-file-name()
  bookmark-make-record-default()
  bookmark-make-record()
  #f(compiled-function (buffer) "Return `activities-buffer' struct for BUFFER." #<bytecode 0x1b6bf1082dc58a90>)(#<buffer *Messages*>)
  apply(#f(compiled-function (buffer) "Return `activities-buffer' struct for BUFFER." #<bytecode 0x1b6bf1082dc58a90>) #<buffer *Messages*> nil)
  activity--serialize(#<buffer *Messages*>)
  #<subr F616e6f6e796d6f75732d6c616d626461_anonymous_lambda_25>((leaf (pixel-width . 856) (pixel-height . 532) (total-width . 122) (total-height . 38) (normal-height . 0.5042654028436019) (normal-width . 1.0) (buffer "*Messages*" (selected . t) (hscroll . 0) (fringes 8 8 nil nil) (margins nil) (scroll-bars nil 0 t nil 0 t nil) (vscroll . 0) (dedicated) (point . 30028) (start . 28856)) (prev-buffers ("indent-bars" 1 166))))
  #f(compiled-function (state) "Set windows' buffers in STATE." #<bytecode 0x90264ea36ecc04b>)((leaf (pixel-width . 856) (pixel-height . 532) (total-width . 122) (total-height . 38) (normal-height . 0.5042654028436019) (normal-width . 1.0) (buffer "*Messages*" (selected . t) (hscroll . 0) (fringes 8 8 nil nil) (margins nil) (scroll-bars nil 0 t nil 0 t nil) (vscroll . 0) (dedicated) (point . 30028) (start . 28856)) (prev-buffers ("indent-bars" 1 166))))
  mapcar(#f(compiled-function (state) "Set windows' buffers in STATE." #<bytecode 0x90264ea36ecc04b>) (vc (last . t) (pixel-width . 856) (pixel-height . 1055) (total-width . 122) (total-height . 75) (normal-height . 1.0) (normal-width . 0.5005847953216375) (combination-limit) (leaf (pixel-width . 856) (pixel-height . 532) (total-width . 122) (total-height . 38) (normal-height . 0.5042654028436019) (normal-width . 1.0) (buffer "*Messages*" (selected . t) (hscroll . 0) (fringes 8 8 nil nil) (margins nil) (scroll-bars nil 0 t nil 0 t nil) (vscroll . 0) (dedicated) (point . 30028) (start . 28856)) (prev-buffers ("indent-bars" 1 166))) (leaf (last . t) (pixel-width . 856) (pixel-height . 523) (total-width . 122) (total-height . 37) (normal-height . 0.4957345971563981) (normal-width . 1.0) (buffer "indent-bars.el" (selected) (hscroll . 0) (fringes 8 8 nil nil) (margins nil) (scroll-bars nil 0 t nil 0 t nil) (vscroll . 0) (dedicated) (point . 1195) (start . 1)))))
  #f(compiled-function (--cl-translate-state-- state) #<bytecode -0x710bec22ed9f40>)((#f(compiled-function (state) "Set windows' buffers in STATE." #<bytecode 0x90264ea36ecc04b>)) (vc (last . t) (pixel-width . 856) (pixel-height . 1055) (total-width . 122) (total-height . 75) (normal-height . 1.0) (normal-width . 0.5005847953216375) (combination-limit) (leaf (pixel-width . 856) (pixel-height . 532) (total-width . 122) (total-height . 38) (normal-height . 0.5042654028436019) (normal-width . 1.0) (buffer "*Messages*" (selected . t) (hscroll . 0) (fringes 8 8 nil nil) (margins nil) (scroll-bars nil 0 t nil 0 t nil) (vscroll . 0) (dedicated) (point . 30028) (start . 28856)) (prev-buffers ("indent-bars" 1 166))) (leaf (last . t) (pixel-width . 856) (pixel-height . 523) (total-width . 122) (total-height . 37) (normal-height . 0.4957345971563981) (normal-width . 1.0) (buffer "indent-bars.el" (selected) (hscroll . 0) (fringes 8 8 nil nil) (margins nil) (scroll-bars nil 0 t nil 0 t nil) (vscroll . 0) (dedicated) (point . 1195) (start . 1)))))
  #f(compiled-function (state) "Set windows' buffers in STATE." #<bytecode 0x90264ea36ecc04b>)((vc (last . t) (pixel-width . 856) (pixel-height . 1055) (total-width . 122) (total-height . 75) (normal-height . 1.0) (normal-width . 0.5005847953216375) (combination-limit) (leaf (pixel-width . 856) (pixel-height . 532) (total-width . 122) (total-height . 38) (normal-height . 0.5042654028436019) (normal-width . 1.0) (buffer "*Messages*" (selected . t) (hscroll . 0) (fringes 8 8 nil nil) (margins nil) (scroll-bars nil 0 t nil 0 t nil) (vscroll . 0) (dedicated) (point . 30028) (start . 28856)) (prev-buffers ("indent-bars" 1 166))) (leaf (last . t) (pixel-width . 856) (pixel-height . 523) (total-width . 122) (total-height . 37) (normal-height . 0.4957345971563981) (normal-width . 1.0) (buffer "indent-bars.el" (selected) (hscroll . 0) (fringes 8 8 nil nil) (margins nil) (scroll-bars nil 0 t nil 0 t nil) (vscroll . 0) (dedicated) (point . 1195) (start . 1)))))
  mapcar(#f(compiled-function (state) "Set windows' buffers in STATE." #<bytecode 0x90264ea36ecc04b>) (((min-height . 8) (min-width . 20) (min-height-ignore . 6) (min-width-ignore . 10) (min-height-safe . 2) (min-width-safe . 4) (min-pixel-height . 112) (min-pixel-width . 140) (min-pixel-height-ignore . 84) (min-pixel-width-ignore . 70) (min-pixel-height-safe . 28) (min-pixel-width-safe . 28)) hc (pixel-width . 1710) (pixel-height . 1055) (total-width . 244) (total-height . 75) (normal-height . 1.0) (normal-width . 1.0) (combination-limit) (leaf (pixel-width . 854) (pixel-height . 1055) (total-width . 122) (total-height . 75) (normal-height . 1.0) (normal-width . 0.49941520467836253) (buffer "indent-bars-ts.el" (selected) (hscroll . 0) (fringes 8 8 nil nil) (margins nil) (scroll-bars nil 0 t nil 0 t nil) (vscroll . 0) (dedicated) (point . 5585) (start . 3078)) (prev-buffers ("indent-bars-ts.el" 304 3749) ("indent-bars" 1 166) ("activities.el" 1 94))) (vc (last . t) (pixel-width . 856) (pixel-height . 1055) (total-width . 122) (total-height . 75) (normal-height . 1.0) (normal-width . 0.5005847953216375) (combination-limit) (leaf (pixel-width . 856) (pixel-height . 532) (total-width . 122) (total-height . 38) (normal-height . 0.5042654028436019) (normal-width . 1.0) (buffer "*Messages*" (selected . t) (hscroll . 0) (fringes 8 8 nil nil) (margins nil) (scroll-bars nil 0 t nil 0 t nil) (vscroll . 0) (dedicated) (point . 30028) (start . 28856)) (prev-buffers ("indent-bars" 1 166))) (leaf (last . t) (pixel-width . 856) (pixel-height . 523) (total-width . 122) (total-height . 37) (normal-height . 0.4957345971563981) (normal-width . 1.0) (buffer "indent-bars.el" (selected) (hscroll . 0) (fringes 8 8 nil nil) (margins nil) (scroll-bars nil 0 t nil 0 t nil) (vscroll . 0) (dedicated) (point . 1195) (start . 1))))))
  #f(compiled-function (--cl-translate-state-- state) #<bytecode -0x710bec22ed9f40>)((#f(compiled-function (state) "Set windows' buffers in STATE." #<bytecode 0x90264ea36ecc04b>)) (((min-height . 8) (min-width . 20) (min-height-ignore . 6) (min-width-ignore . 10) (min-height-safe . 2) (min-width-safe . 4) (min-pixel-height . 112) (min-pixel-width . 140) (min-pixel-height-ignore . 84) (min-pixel-width-ignore . 70) (min-pixel-height-safe . 28) (min-pixel-width-safe . 28)) hc (pixel-width . 1710) (pixel-height . 1055) (total-width . 244) (total-height . 75) (normal-height . 1.0) (normal-width . 1.0) (combination-limit) (leaf (pixel-width . 854) (pixel-height . 1055) (total-width . 122) (total-height . 75) (normal-height . 1.0) (normal-width . 0.49941520467836253) (buffer "indent-bars-ts.el" (selected) (hscroll . 0) (fringes 8 8 nil nil) (margins nil) (scroll-bars nil 0 t nil 0 t nil) (vscroll . 0) (dedicated) (point . 5585) (start . 3078)) (prev-buffers ("indent-bars-ts.el" 304 3749) ("indent-bars" 1 166) ("activities.el" 1 94))) (vc (last . t) (pixel-width . 856) (pixel-height . 1055) (total-width . 122) (total-height . 75) (normal-height . 1.0) (normal-width . 0.5005847953216375) (combination-limit) (leaf (pixel-width . 856) (pixel-height . 532) (total-width . 122) (total-height . 38) (normal-height . 0.5042654028436019) (normal-width . 1.0) (buffer "*Messages*" (selected . t) (hscroll . 0) (fringes 8 8 nil nil) (margins nil) (scroll-bars nil 0 t nil 0 t nil) (vscroll . 0) (dedicated) (point . 30028) (start . 28856)) (prev-buffers ("indent-bars" 1 166))) (leaf (last . t) (pixel-width . 856) (pixel-height . 523) (total-width . 122) (total-height . 37) (normal-height . 0.4957345971563981) (normal-width . 1.0) (buffer "indent-bars.el" (selected) (hscroll . 0) (fringes 8 8 nil nil) (margins nil) (scroll-bars nil 0 t nil 0 t nil) (vscroll . 0) (dedicated) (point . 1195) (start . 1))))))
  #f(compiled-function (state) "Set windows' buffers in STATE." #<bytecode 0x90264ea36ecc04b>)((((min-height . 8) (min-width . 20) (min-height-ignore . 6) (min-width-ignore . 10) (min-height-safe . 2) (min-width-safe . 4) (min-pixel-height . 112) (min-pixel-width . 140) (min-pixel-height-ignore . 84) (min-pixel-width-ignore . 70) (min-pixel-height-safe . 28) (min-pixel-width-safe . 28)) hc (pixel-width . 1710) (pixel-height . 1055) (total-width . 244) (total-height . 75) (normal-height . 1.0) (normal-width . 1.0) (combination-limit) (leaf (pixel-width . 854) (pixel-height . 1055) (total-width . 122) (total-height . 75) (normal-height . 1.0) (normal-width . 0.49941520467836253) (buffer "indent-bars-ts.el" (selected) (hscroll . 0) (fringes 8 8 nil nil) (margins nil) (scroll-bars nil 0 t nil 0 t nil) (vscroll . 0) (dedicated) (point . 5585) (start . 3078)) (prev-buffers ("indent-bars-ts.el" 304 3749) ("indent-bars" 1 166) ("activities.el" 1 94))) (vc (last . t) (pixel-width . 856) (pixel-height . 1055) (total-width . 122) (total-height . 75) (normal-height . 1.0) (normal-width . 0.5005847953216375) (combination-limit) (leaf (pixel-width . 856) (pixel-height . 532) (total-width . 122) (total-height . 38) (normal-height . 0.5042654028436019) (normal-width . 1.0) (buffer "*Messages*" (selected . t) (hscroll . 0) (fringes 8 8 nil nil) (margins nil) (scroll-bars nil 0 t nil 0 t nil) (vscroll . 0) (dedicated) (point . 30028) (start . 28856)) (prev-buffers ("indent-bars" 1 166))) (leaf (last . t) (pixel-width . 856) (pixel-height . 523) (total-width . 122) (total-height . 37) (normal-height . 0.4957345971563981) (normal-width . 1.0) (buffer "indent-bars.el" (selected) (hscroll . 0) (fringes 8 8 nil nil) (margins nil) (scroll-bars nil 0 t nil 0 t nil) (vscroll . 0) (dedicated) (point . 1195) (start . 1))))))
  activities--window-serialized((((min-height . 8) (min-width . 20) (min-height-ignore . 6) (min-width-ignore . 10) (min-height-safe . 2) (min-width-safe . 4) (min-pixel-height . 112) (min-pixel-width . 140) (min-pixel-height-ignore . 84) (min-pixel-width-ignore . 70) (min-pixel-height-safe . 28) (min-pixel-width-safe . 28)) hc (pixel-width . 1710) (pixel-height . 1055) (total-width . 244) (total-height . 75) (normal-height . 1.0) (normal-width . 1.0) (combination-limit) (leaf (pixel-width . 854) (pixel-height . 1055) (total-width . 122) (total-height . 75) (normal-height . 1.0) (normal-width . 0.49941520467836253) (buffer "indent-bars-ts.el" (selected) (hscroll . 0) (fringes 8 8 nil nil) (margins nil) (scroll-bars nil 0 t nil 0 t nil) (vscroll . 0) (dedicated) (point . 5585) (start . 3078)) (prev-buffers ("indent-bars-ts.el" 304 3749) ("indent-bars" 1 166) ("activities.el" 1 94))) (vc (last . t) (pixel-width . 856) (pixel-height . 1055) (total-width . 122) (total-height . 75) (normal-height . 1.0) (normal-width . 0.5005847953216375) (combination-limit) (leaf (pixel-width . 856) (pixel-height . 532) (total-width . 122) (total-height . 38) (normal-height . 0.5042654028436019) (normal-width . 1.0) (buffer "*Messages*" (selected . t) (hscroll . 0) (fringes 8 8 nil nil) (margins nil) (scroll-bars nil 0 t nil 0 t nil) (vscroll . 0) (dedicated) (point . 30028) (start . 28856)) (prev-buffers ("indent-bars" 1 166))) (leaf (last . t) (pixel-width . 856) (pixel-height . 523) (total-width . 122) (total-height . 37) (normal-height . 0.4957345971563981) (normal-width . 1.0) (buffer "indent-bars.el" (selected) (hscroll . 0) (fringes 8 8 nil nil) (margins nil) (scroll-bars nil 0 t nil 0 t nil) (vscroll . 0) (dedicated) (point . 1195) (start . 1))))))
  activities--window-state(#<frame Ξ±: ind-bars 0x11f7ffd70>)
  activities-state()
  activities-save(#s(activities-activity :name "ind-bars" :default #s(activities-activity-state :window-state (((min-height . 8) (min-width . 20) (min-height-ignore . 6) (min-width-ignore . 10) (min-height-safe . 2) (min-width-safe . 4) (min-pixel-height . 112) (min-pixel-width . 140) (min-pixel-height-ignore . 84) (min-pixel-width-ignore . 70) (min-pixel-height-safe . 28) (min-pixel-width-safe . 28)) hc (pixel-width . 2560) (pixel-height . 1426) (total-width . 366) (total-height . 101) (normal-height . 1.0) (normal-width . 1.0) (combination-limit) (leaf (parameters (activities-buffer . #s(activities-buffer :bookmark ... :filename "/Users/jdsmith/code/emacs/indent-bars/indent-bars-..." :name "indent-bars-ts.el" :local-variables nil :etc ...))) (pixel-width . 1279) (pixel-height . 1426) (total-width . 183) (total-height . 101) (normal-height . 1.0) (normal-width . 0.5) (buffer "indent-bars-ts.el" (selected . t) (hscroll . 0) (fringes 8 8 nil nil) (margins nil) (scroll-bars nil 0 t nil 0 t nil) (vscroll . 0) (dedicated) (point . 3749) (start . 304)) (prev-buffers ("indent-bars-ts.el" 304 3749) ("indent-bars" 1 400) (".emacs" 14739 38168) ("activities.el" 1 94) ("emacs" 1 145) ("cond-let.el" 1 2729))) (vc (last . t) (pixel-width . 1281) (pixel-height . 1426) (total-width . 183) (total-height . 101) (normal-height . 1.0) (normal-width . 0.5) (combination-limit) (leaf (parameters (activities-buffer . ...)) (pixel-width . 1281) (pixel-height . 712) (total-width . 183) (total-height . 50) (normal-height . 0.5) (normal-width . 1.0) (buffer "indent-bars" (selected) (hscroll . 0) (fringes 8 8 nil nil) (margins nil) (scroll-bars nil 0 t nil 0 t nil) (vscroll . 0) (dedicated) (point . 469) (start . 1))) (leaf (parameters (activities-buffer . ...)) (last . t) (pixel-width . 1281) (pixel-height . 714) (total-width . 183) (total-height . 51) (normal-height . 0.5) (normal-width . 1.0) (buffer "indent-bars.el" (selected) (hscroll . 0) (fringes 8 8 nil nil) (margins nil) (scroll-bars nil 0 t nil 0 t nil) (vscroll . 0) (dedicated) (point . 1195) (start . 1))))) :etc nil) :last #s(activities-activity-state :window-state (((min-height . 8) (min-width . 20) (min-height-ignore . 6) (min-width-ignore . 10) (min-height-safe . 2) (min-width-safe . 4) (min-pixel-height . 112) (min-pixel-width . 140) (min-pixel-height-ignore . 84) (min-pixel-width-ignore . 70) (min-pixel-height-safe . 28) (min-pixel-width-safe . 28)) hc (pixel-width . 1710) (pixel-height . 1055) (total-width . 244) (total-height . 75) (normal-height . 1.0) (normal-width . 1.0) (combination-limit) (leaf (parameters (activities-buffer . #s(activities-buffer :bookmark ... :filename "/Users/jdsmith/code/emacs/indent-bars/indent-bars-..." :name "indent-bars-ts.el" :local-variables nil :etc ...))) (pixel-width . 854) (pixel-height . 1055) (total-width . 122) (total-height . 75) (normal-height . 1.0) (normal-width . 0.49941520467836253) (buffer "indent-bars-ts.el" (selected) (hscroll . 0) (fringes 8 8 nil nil) (margins nil) (scroll-bars nil 0 t nil 0 t nil) (vscroll . 0) (dedicated) (point . 4708) (start . 3078)) (prev-buffers ("indent-bars-ts.el" 304 3749) ("indent-bars" 1 166) ("activities.el" 1 94))) (vc (last . t) (pixel-width . 856) (pixel-height . 1055) (total-width . 122) (total-height . 75) (normal-height . 1.0) (normal-width . 0.5005847953216375) (combination-limit) (leaf (parameters (activities-buffer . ...)) (pixel-width . 856) (pixel-height . 532) (total-width . 122) (total-height . 38) (normal-height . 0.5042654028436019) (normal-width . 1.0) (buffer "indent-bars" (selected . t) (hscroll . 0) (fringes 8 8 nil nil) (margins nil) (scroll-bars nil 0 t nil 0 t nil) (vscroll . 0) (dedicated) (point . 166) (start . 1))) (leaf (parameters (activities-buffer . ...)) (last . t) (pixel-width . 856) (pixel-height . 523) (total-width . 122) (total-height . 37) (normal-height . 0.4957345971563981) (normal-width . 1.0) (buffer "indent-bars.el" (selected) (hscroll . 0) (fringes 8 8 nil nil) (margins nil) (scroll-bars nil 0 t nil 0 t nil) (vscroll . 0) (dedicated) (point . 1195) (start . 1))))) :etc ((time 26057 6834 165063 0))) :etc nil) :lastp t)
  activities-save-all()
  apply(activities-save-all nil)
  timer-event-handler([t 0 5 0 t activities-save-all nil idle 0 nil])

Adjust error message for a bookmark that doesn't change the buffer

  1. Activities was unable to get a buffer for bookmark:

(#("Activity: DC-13 " 0 16 (bmkp-full-record (#1 (time 26058 30868 176769 395000) (visits . 0) (activities-name . "DC-13 ") (handler . activities-bookmark-handler)))) (filename . " - no file -") (buffer-name . "Ibuffer") (front-context-string . " MRL Name ") (rear-context-string) (front-context-region-string) (rear-context-region-string) (visits . 1) (time 26058 31089 378453 71000) (created 26058 30967 111331 208000) (position . 1))

It's likely that the bookmark's file no longer exists, in which case you may need to relocate it and redefine this activity.

If this is not the case, please report this error to the `activities' maintainer.

from the "bookmarks" file -- it is there:
(#1=(#("Activity: DC-13 " 0 16
(bmkp-full-record #1#))
(time 26058 30868 176769 395000)
(visits . 0)
(activities-name . "DC-13 ")
(handler . activities-bookmark-handler))

  1. For other activities, no bookmark was automaticically created

Save activity on frame/tab close

If a frame/tab hosting an activity is closed, it would be great if that activity's state is saved via delete-frame-functions.

Error restoring last of 4 split windows of org-ql view buffers

I have an org-ql as part of "My daily review" activity called "Tasks done in the past week" that uses this query:

(or (and (todo "DONE") (closed :from -7)))

If I:

  • Evaluate (org-ql-view "Finished past week") in the scratch buffer
  • Call activities-new, type "new activity"
  • close emacs
  • open emacs, activities-resume, "new activity"

Things work as expected.

However in my case where I have 4 different org-ql views for some reason this one fails to load and I see this buffer instead:

Activities was unable to get a buffer named: *Org QL View: Finished past week*

It is likely that this buffer's major mode does not support the `bookmark' system, so it can't be restored properly.  Please ask the major mode's maintainer to add bookmark support.

If this is not the case, please report this error to the `activities' maintainer.

My only guess is that perhaps something about (closed :from -7) makes it harder to resume because those are translated to actual dats at some point.

I'm guessing you need to see the actual full AST of my activity to debug what's going on here, but I don't currently know how I can get that.

Note that if I manually call (org-ql-view "Finished past week") before resuming the activity then the buffer is there just fine. I'm assuming this is because no resume logic happens and it just uses the already open buffer.

Please advise.

Feature request: associate an activity a collection of frames?

I use a tiling window manager and run Emacs as a daemon, opening frames with a simple keyboard shortcut.

In my workflow, I tend to have five or six frames dedicated to a single project, each frame usually containing a single window (and at most three windows), which mostly display Org and PDF buffers.

I often switch projects during the day, which usually means switching to a different desktop "workspace" while leaving the previous project's frames open, and then opening a new set of frames, windows and buffers. Rinse and repeat.

I don't usually kill Emacs or restart my system more often than every three weeks or so, and in that time I can accumulate a lot of frames and buffers. I was hoping that activities.el would allow me to save or bookmark a collection of frames associated to one project, and then kill those frames when switching to another project, while being able to restore the first set of frames when I want to return to them.

Is this possible to implement in the future? I have seen a couple of similar requests on Reddit, and someone with a similar work flow opened a related issue here.

Improve experience with already activated frames

I think the user experience for a non-tabs-bar workflow could be improved. For reference, I use SwayWM on Wayland with system-configuration-options as -C --with-pgtk --with-native-compilation --with-json.

Expected behavior (activities-tabs-mode ON)

  1. In tab 1 activities-resume for activity "foo". This renames the tab to "a: foo".
  2. In tab 2 activities-resume for activity "foo". This correctly switches to tab 1.

Unexpected behavior (activities-tabs-mode OFF)

  1. In frame 1 activities-resume for activity "foo". This renames the Wayland window to "a: foo".
  2. In frame 2 activities-resume for activity "foo". This does nothing.

I believe activities-switch is interchangeable for activities-resume for both step 2's as they both use activities--switch.

--

My first suggestion was to use "window urgency", but I'm not aware if Emacs supports this, at least portably (SE ref).

Then I looked into how you handle already activated frames. I don't even know if select-frame (activities--switch) works on Wayland (similar bug-gnu-emacs ref). I relegate frame management to my WM, so don't really use select/raise-frame.

So my suggestion is to simply add a logging message in activities--switch that lets the user knows the selected activity is already activated somewhere.

Why persist?

On 29.1 we have multisession. Would that work too?

A frame should not be made just to be deleted (exposes bug on emacs-mac build)

Obviously my build (emacs-mac) shouldn't be crashing, but this is repeatable:

  • Load activities
  • M-x activities-discard (without an active activity)
  • Select one of the saved activities
  • Crash (from traceback, likely related to frame close)

Perhaps non-existent frames are being closed when a discarded activity is not actually active? Activating first then discarding works fine.

Reverting an activity should either remove the last state or immediately save

I tend to use revert on an activity when it has "drifted" and the buffers shown have changed. The new annotations PR #83 revealed that the last state remains set even after revert.

This is surprising because that state is no longer reachable while the activity is active, AFAIU, and it will eventually be overwritten when save-all is run during idle time. So it seems sensible either to remove the last state, or immediately save the activity, after it gets reverted.

v0.7 Changelog includes unreleased change.

Hi, and thanks again for this package.

It seems the v0.7 release made about 4 hours ago refers to an already existing tag from about 3 weeks ago, and as such, only contains commits made up till 3 weeks ago. This means the fix you pushed for #56 is not included in v0.7.

Idea: "soft-revert" activity without changing point(s) in open buffers

My favorite feature of activities is the ability to revert at any time, always there to save you when your activity has "gotten away from you", and you've introduced new or extraneous windows and buffers into the mix, or drifted away. But usually this comes from opening other windows I no longer need, and revert is just a quick way to sweep those away and restore my window/buffer setup.

In that case, I'd prefer for the current point in each of the already displayed buffers to be left unchanged β€” a "soft-revert" if you will. Soft revert is basically just like normal revert, except point is left alone (for already visited buffers, that is). Perhaps a prefix arg to revert would be a good interface for soft-revert? Or a separate (lesser used) command? Or an option (I would pretty much always prefer for point in opened buffers to remain unchanged)?

Suppressing errors in `activities-mode-timer`

Hi @alphapapa,

I often use Emacs with toggle-debug-on-error turned on, usually when developing a package. When the idle timer for activities fires (every five seconds by default), I get a backtrace popup for a buffer that could not be bookmarked -- eldoc for instance:

Debugger entered--Lisp error: (error "Buffer not visiting a file or directory")
  (error "Buffer not visiting a file or directory")
  (bookmark-buffer-file-name)
  (bookmark-make-record-default)
  (bookmark-make-record)
  (#f(compiled-function (buffer) "Return `activities-buffer' struct for BUFFER." #<bytecode 0x14b6006c580da493>) #<buffer *eldoc*>)
  (apply #f(compiled-function (buffer) "Return `activities-buffer' struct for BUFFER." #<bytecode 0x14b6006c580da493>) #<buffer *eldoc*> nil)
  (activity--serialize #<buffer *eldoc*>)
  (#<subr F616e6f6e796d6f75732d6c616d626461_anonymous_lambda_25> (leaf (last . t) (pixel-width . 1135) (pixel-height . 84) (total-width . 142) (total-height . 4) (normal-height . 0.07619477006311992) (normal-width . 1.0) (parameters (window-preserved-size #<buffer *eldoc*> nil nil) (no-other-window . t) (mode-line-format . none)) (buffer "*eldoc*" (selected) (hscroll . 0) (fringes 8 8 t nil) (margins nil) (scroll-bars nil 0 t nil 0 t nil) (vscroll . 0) (dedicated) (point . 1) (start . 1))))
;; stacks omitted here
  (activities--window-state #<frame karthinks:networked_oscillators.org 0x3f95c78>)
  (activities-state)
;; stacks omitted here
  (activities-save-all)
  (apply activities-save-all nil)
  (timer-event-handler [t 0 5 0 t activities-save-all nil idle 0 nil])

I understand that activities-save-all demotes errors (via condition-case-unless-debug), so this is only a problem because I've turned on debugging. But the result is that I've had to turn off activities-mode whenever I'm working on an Emacs lisp package, which sort of defeats the purpose of using it to save state.

Is it possible to make it (via a user option perhaps) so that the idle-timer function optionally uses condition-case instead of condition-case-unless-debug?

I understand that this is not an error on the part of activities.el, so feel free to close this issue if it's out of scope.

seems to interfere with mu4e

I'm a non programmer who uses emacs on linux for academic papers. When I run mu4e under an activity, the index area gets periodically taken over by a pop-up message "appease-gnus. I'm really loving activities, but I also love using emacs for email. Thanks for any help.

`C-x C-a' prefix is default key-prefix for dape and gud (gdb-mi)

Tag: discussion

The dape package which also includes gud or gdb-mi uses C-x C-a as their default prefix.

I prefer to use C-x C-a for activities. In case others struggle to change this for dape and gud, in dape use-package need to set in :preface the prefix keys for both in order to keep them from removing activities.

Example where I set prefix to C-x D:

  (use-package dape
    :preface
    ;; These need to be set at prefix, or else interferes with `C-x C-a` of `activities'
    ;; This is `C-x D prefix`
    (setq dape-key-prefix "\C-xD")
    (setq gud-key-prefix "\C-xD")) ;; gdb-mi

Consult-buffer integration

activities-switch-buffer works well, but I could not find a way to integrate it with consult's consult-buffer in a way where only buffers from the current activity are shown.

That being said, if it's not within the design scope, the package bufferlo provides provides for showing only tab (and frame) local buffers, which works well with activities-tabs-mode, and provides an integration with consult.

I might be missing something obvious, but thought I would post an issue about it in case anyone looks for a similar solution.

Emacs -nw seems lead to "Window too small to accommodate state" sometimes

(Vague) reproducer:
Have activities-mode enabled.
Define an activity using GUI emacs.
Close emacs.
Start emacs -nw on a terminal emulator.
(optional: run eval-buffer in activities.el)
Run activities-list (or resume), activate the recently-defined activity.
You get the following backtrace:

Debugger entered--Lisp error: (error "Window #<window 8 on *scratch*> too small to accom...")
  error("Window %s too small to accommodate state" #<window 8 on *scratch*>)
  window-state-put((((min-height . 4) (min-width . 10) (min-height-ignore . 3) (min-width-ignore . 2) (min-height-safe . 1) (min-width-safe . 2) (min-pixel-height . 92) (min-pixel-width . 100) (min-pixel-height-ignore . 69) (min-pixel-width-ignore . 20) (min-pixel-height-safe . 23) (min-pixel-width-safe . 20)) leaf (parameters (activities-buffer . #s(activities-buffer :bookmark ("init.el" (filename . "~/.config/emacs/init.el") (front-context-string . "\n(use-package us") (rear-context-string . "ire 'el-patch))\n") (position . 153) (last-modified 26114 36303 12855 111000) (defaults "init.el")) :filename "/home/jlicht/.config/emacs/init.el" :name "init.el" :local-variables nil :etc ((indirectp) (narrowedp))))) (pixel-width . 956) (pixel-height . 1003) (total-width . 96) (total-height . 44) (normal-height . 1.0) (normal-width . 1.0) (buffer #<buffer init.el> (selected . t) (hscroll . 0) (fringes 0 0 nil nil) (margins nil) (scroll-bars nil 0 t nil 0 t nil) (vscroll . 0) (dedicated) (point . 153) (start . 1))) #<window 5>)
  (closure ((state ((min-height . 4) (min-width . 10) (min-height-ignore . 3) (min-width-ignore . 2) (min-height-safe . 1) (min-width-safe . 2) (min-pixel-height . 92) (min-pixel-width . 100) (min-pixel-height-ignore . 69) (min-pixel-width-ignore . 20) (min-pixel-height-safe . 23) (min-pixel-width-safe . 20)) leaf (parameters (activities-buffer . #s(activities-buffer :bookmark ("init.el" (filename . "~/.config/emacs/init.el") (front-context-string . "\n(use-package us") (rear-context-string . "ire 'el-patch))\n") (position . 153) (last-modified 26114 36303 12855 111000) (defaults "init.el")) :filename "/home/jlicht/.config/emacs/init.el" :name "init.el" :local-variables nil :etc ((indirectp) (narrowedp))))) (pixel-width . 956) (pixel-height . 1003) (total-width . 96) (total-height . 44) (normal-height . 1.0) (normal-width . 1.0) (buffer #<buffer init.el> (selected . t) (hscroll . 0) (fringes 0 0 nil nil) (margins nil) (scroll-bars nil 0 t nil 0 t nil) (vscroll . 0) (dedicated) (point . 153) (start . 1)))) nil (window-state-put state (frame-root-window)))()
  apply((closure ((state ((min-height . 4) (min-width . 10) (min-height-ignore . 3) (min-width-ignore . 2) (min-height-safe . 1) (min-width-safe . 2) (min-pixel-height . 92) (min-pixel-width . 100) (min-pixel-height-ignore . 69) (min-pixel-width-ignore . 20) (min-pixel-height-safe . 23) (min-pixel-width-safe . 20)) leaf (parameters (activities-buffer . #s(activities-buffer :bookmark ("init.el" ... ... ... ... ... ...) :filename "/home/jlicht/.config/emacs/init.el" :name "init.el" :local-variables nil :etc (... ...)))) (pixel-width . 956) (pixel-height . 1003) (total-width . 96) (total-height . 44) (normal-height . 1.0) (normal-width . 1.0) (buffer #<buffer init.el> (selected . t) (hscroll . 0) (fringes 0 0 nil nil) (margins nil) (scroll-bars nil 0 t nil 0 t nil) (vscroll . 0) (dedicated) (point . 153) (start . 1)))) nil (window-state-put state (frame-root-window))) nil)
  timer-event-handler([t 26114 36322 468784 nil (closure ((state ((min-height . 4) (min-width . 10) (min-height-ignore . 3) (min-width-ignore . 2) (min-height-safe . 1) (min-width-safe . 2) (min-pixel-height . 92) (min-pixel-width . 100) (min-pixel-height-ignore . 69) (min-pixel-width-ignore . 20) (min-pixel-height-safe . 23) (min-pixel-width-safe . 20)) leaf (parameters (activities-buffer . #s(activities-buffer :bookmark ... :filename "/home/jlicht/.config/emacs/init.el" :name "init.el" :local-variables nil :etc ...))) (pixel-width . 956) (pixel-height . 1003) (total-width . 96) (total-height . 44) (normal-height . 1.0) (normal-width . 1.0) (buffer #<buffer init.el> (selected . t) (hscroll . 0) (fringes 0 0 nil nil) (margins nil) (scroll-bars nil 0 t nil 0 t nil) (vscroll . 0) (dedicated) (point . 153) (start . 1)))) nil (window-state-put state (frame-root-window))) nil nil 775000 nil])

I've locally worked around the issue by patching the following in activities--windows-set, but this may be more of a hack than a solution:

*** /tmp/ediffiSUjfY	2024-03-26 10:01:19.456778031 +0100
--- /tmp/ediffijbyJq	2024-03-26 10:01:19.456778031 +0100
***************
*** 12,15 ****
      (run-at-time nil nil
  		 (lambda nil
  		   (window-state-put state
! 				     (frame-root-window))))))
--- 12,16 ----
      (run-at-time nil nil
  		 (lambda nil
  		   (window-state-put state
! 				     (frame-root-window)
! 				     'safe)))))

Streamline interaction

I instinctively expected to be able to make a new activity if I enter a new name with activities-resume (possibly with a y/n prompt). And if I activity-new and re-use an existing name, I'd expect to be prompted y/n to update the default saved value of that known activity.

Multiple activities per project, automatic activity definition

This is a proposal for project integration, at least what would drive requirements.

Let's say I work on microservices.com and they use a git repository per microservice. The engineers typically work on 3-4 sets of files depending on which aspect of the service they are working on:

  1. Feature work, working on source and unit tests
  2. CI & CD, working on Github actions and Nix flakes
  3. K8's diagnosis and designing production tests, building and deploying ephemeral debugging containers
  4. Network, retry, metrics definitions for assimilation by Linkerd
  5. Common data model definition that creates tables and API endpoints through code generation

Since microservices.com has 100 services and each engineer works on at least 10 services, automating the project navigation by automatically generating activities has been requested by the CTO.

The implementation would rely on the current project. It would be configured with a list of (NAME PREDICATE ACTIVITY-FUNCTION). If PREDICATE passes, NAME-<PROJECT> is available and can be generated if it doesn't exist already by calling ACTIVITY-FUNCTION

Don't hardcode activities-tabs-face foreground

Enjoying this take on workspace management! Thank you for this package.

As a consequence of defining activities-tabs-face like this:

(defface activities-tabs-face
  `((t :foreground ,(face-foreground 'font-lock-function-name-face nil 'default)))
  "Applied to tab-bar faces for tabs representing activities.")

the face does not change when the theme does, leading to mismatched/low-contrast tab bar name displays when I switch from a light to a dark theme. Consider replacing this with some combination of :inherit and the tab-bar defaults?

activities-tab-face overrides tab-bar and tab-bar-inactive faces

I use the :foreground attribute of tab-bar and tab-bar-inactive faces to highlight the active tab. The activities package overrides this making all the activities tabs not only look different to the other tabs (which is okay, I guess, but not necessary for me) but makes it impossible for me to know which is the active tab.

I am not sure how to get around this. I tried setting the activities-tab-face to an empty list in my theme but that just makes it default to the default face (for some unknown reason). Any suggestions welcome!

Thank you for an otherwise very interesting and useful package.

activities-save-all adjusts height minibuffer when framed mode

Using activities in framed mode the activities-save-all function will adjust the minibuffer of current activity usually shrinking it.

This happens when minibuffer is currently being used with a larger feature, such as consult-line.

Steps to reproduce

  1. 2 framed activities open.
  2. Launch consult-line in current frame.
  3. Wait until activities idle timer which calls activities-save-all.
  4. a. During activities-save-all the frame switches to other frame,
    b. consult-line minibuffer adjusts for the other frame which changes across frames,
    c. save happens,
    d. switches back to original frame with smaller minibuffer.

If continue to leave up consult-line, the minibuffer may continue to shrink with each activities-save-all call.

Here's a screen recording of issue:

activities-frame-minibuffer-issue

Too many ideas

What a breath of fresh air activities is! I've never stuck with any workplace tool because I find them too rigid and far too complex. I also tend to bounce around in my layout quite a bit and they punish me for that. I use project.el but find it confining sometimes (many activities span projects!). I just wanted a simple tool that saves all my relevant state related to some given activity,and restores it easily. activities seems perfect for this; thanks for much for bringing it to life. It's literally a one key interface for me: f10 to jump to an activity, C-f10 to revert the current one (OK two keys).

Some ideas from my first 10min of usage below (too many, but take it as the sign of real interest it represents ;):

Frame-wrapping

I'd like to use frames and not tabs, so I leave (activities-tabs-mode) out, but in reality I'd like to use mac native tabs (which are just frames from emacs' perspective). To do so, I just need to wrap frame-creating code with (let ((mac-frame-tabbing t)).... I could easily advise activities--switch to do this, but I wonder if there are other uses for a list of custom variables that will be dynamically bound around make-frame (e.g. an activities-make-frame-variables alist)?

Automatic Updates and Updating the Default State

I'm a little concerned about the automatic activities updating. The reason is that I've found I often "drift away" from an activity, reusing windows to put out some other fire as they pop up. I think I'd prefer to "opt in" to the saving of state. But then on closer look, I see activities-revert is always there, ready to save my bacon and get me back on track when I inevitably mess things up. So that's very comforting.

But then I wonder, how do I update an activity's "default state" when my needs evolve? Just M-x activities-new again, reusing the same name? Do I have to delete it first? Some way to update the default state of the current activity (activities-update-default?) would be nice.

Frame title

It's nice to see activity name in the frame title. But set-frame-name is a heavy hammer and removes any frame-title-format customizations the user has done. It's easy for such a user to add an :eval section to frame-title-format to mention the frame's activity name (if any), but then we need some way to inhibit set-frame-name.

It would also be nice if you could see in the frame title that the default activity state has been modified, so a predicate to test for that would be wonderful. This predicate would probably need to compute a "coarse modification" flag, i.e. testing only the most important configuration parameters (buffer list, number of windows, etc.) against their default values. Changing frame size/moving point/etc. shouldn't count as a true change IMO.

Bookmark support for processes?

I wonder, does bookmark-based restore allow re-opening existing processes and associated buffers? You could then imagine restoring (remote?) shells with the right virtual environment, etc. with a single key.

Dream feature

The only dream feature I could imagine for now: often times my activities are 4-6 windows on a large external monitor, but I can "afford" only 3 or so when on my laptop. It would be fantastic if activities had some sort of frame size awareness on invocation/revert. I'm not talking CSS responsive design here, just optional min-width/min-height parameters for a given activity, with several parallel sets available under the same activity name. The appropriate "sub-layout" would be selected when you first load or revert the activity, depending on available size.

Bonus point

Bonus point for the best symbol name I've ever seen: activities-activity-active-p.

`global-auto-revert-non-file-buffers` may cause unintended buffer reverting

Activities version: 0.7
Emacs version: 29.2

In certain cases the cursor may jump to previous location when activities is active. This happens most frequently in cases when another window is opened in the same frame from a previous selection of the current window, e.g. in buffer list or Gnus summary page.

For example, I am in the buffer list window, and I select buffer A and A was opened in a new window in the same frame, and I move cursor to buffer B in the buffer list. After a few seconds, the cursor will jump back to the buffer A entry in the buffer list window (which I assume may be a side effect of activities auto save.) Similarly in Gnus summary, if I select a message which opens it in another window in the same frame, and I navigate to another message, if I wait a few seconds, it will jump back to the previous selected message.

Would be great if this doesn't happen.

Bookmark for magit-status fails to open

I get this error when I reopen an activity having a magit buffer open after emacs have been closed.

Activities was unable to get a buffer for bookmark:

("magit: something" (front-context-string . "Stashes (1)
stas") (rear-context-string . ".json
tmp.yaml

") (position . 715) (last-modified 26126 59456 765990 0) (handler . magit--handle-bookmark) (mode . magit-status-mode) (filename . "/a/path/toproject/tooling/something/") (defaults "magit-status" "magit: something") (magit-hidden-sections (stashes . "refs/stash")))

Error: "Error while opening bookmark: ERROR:(cl-no-applicable-method magit-bookmark-get-buffer-create (\"magit: something\" (front-context-string . \"Stashes (1)
stas\") (rear-context-string . \".json
tmp.yaml

\") (position . 715) (last-modified 26126 59456 765990 0) (handler . magit--handle-bookmark) (mode . magit-status-mode) (filename . \"/a/path/toproject/tooling/something/\") (defaults \"magit-status\" \"magit: something\") (magit-hidden-sections (stashes . \"refs/stash\"))) magit-status-mode)  RECORD:#s(activities-buffer (\"magit: something\" (front-context-string . \"Stashes (1)
stas\") (rear-context-string . \".json
tmp.yaml

\") (position . 715) (last-modified 26126 59456 765990 0) (handler . magit--handle-bookmark) (mode . magit-status-mode) (filename . \"/a/path/toproject/tooling/something/\") (defaults \"magit-status\" \"magit: something\") (magit-hidden-sections (stashes . \"refs/stash\"))) nil \"magit: something\" nil ((indirectp) (narrowedp)))"

It's likely that the bookmark's file no longer exists, in which case you may need to relocate it and redefine this activity.

If this is not the case, please report this error to the `activities' maintainer.

In the meantime, you may ignore this error and use the other buffers in the activity.

On latest MacOs with emacs 30 latest magit and latest activeties.el

I just started using this package, and I have to say it really hits a sweet spot between a project and mayhem, so thank you :)

`persist/activities-activities` can disappear during development

I have noticed that (rarely) the persist file persist/activities-activities has gone missing a couple of times during development (of #83). It's possible this variable was somehow set to nil, and auto-save with persist deletes the file if this occurs, but I don't have a reasonable explanation for that. I wanted to open this in case others have experienced this.

One remedy might be to make the default value for that variable 'unspecified or similar, that way it's unlikely for the variable's value to match, and for persist to remove the file.

Error when trying to restore/revert activity: (wrong-type-argument stringp nil)

Hi @alphapapa,

I'm having trouble diagnosing this error when I tried to resume/revert one of my activities, since it's referring to compiled functions without names. Does this stack trace make sense to you?

Debugger entered--Lisp error: (wrong-type-argument stringp nil)
  (get-buffer nil)
  (#f(compiled-function (arg0) #<bytecode 0x4f0cb915c6a4072>) (nil nil nil))
  (#<subr F616e6f6e796d6f75732d6c616d626461_anonymous_lambda_36> (leaf (last . t) (pixel-width . 959) (pixel-height . 1133) (total-width . 120) (total-height . 54) (normal-height . 1.0) (normal-width . 0.5) (parameters (activities-buffer . #s(activities-buffer :bookmark ("Activity: gptel" (filename . "~/.local/share/git/elpaca/repos/gptel/gptel.el") (front-context-string . "(defun gptel--sa") (rear-context-string . "kend-name)))))\n\n") (position . 23839) (last-modified 26076 6795 789859 385000) (defaults "Activity: gptel" "gptel.el")) :filename "/home/karthik/.local/share/git/elpaca/repos/gptel/gptel.el" :name "gptel.el" :local-variables nil :etc ((indirectp) (narrowedp)))) (window-preserved-size nil nil nil)) (buffer #<buffer gptel.el> (selected . t) (hscroll . 0) (fringes 8 8 t nil) (margins nil) (scroll-bars nil 0 t nil 0 t nil) (vscroll . 0) (dedicated) (point . 23839) (start . 23839)) (next-buffers "init.el") (prev-buffers ("init.el" 20264 36480) ("gptel.el" 23839 23839) ("gptel-ollama.el" 3219 3908) ("magit: gptel" 1 1) ("inbox.org" 2163 3559) ("*Help*" 1 1) ("sim86_instruction_table.inl" 1033 1056) ("gptel-openai.el" 8061 9053) ("magit-diff: gptel" 1 1) ("ring_network_stability_notes.org" 1 51))))
  (#f(compiled-function (state) "Set windows' buffers in STATE." #<bytecode -0x199f2c9b98e46950>) (leaf (last . t) (pixel-width . 959) (pixel-height . 1133) (total-width . 120) (total-height . 54) (normal-height . 1.0) (normal-width . 0.5) (parameters (activities-buffer . #s(activities-buffer :bookmark ("Activity: gptel" (filename . "~/.local/share/git/elpaca/repos/gptel/gptel.el") (front-context-string . "(defun gptel--sa") (rear-context-string . "kend-name)))))\n\n") (position . 23839) (last-modified 26076 6795 789859 385000) (defaults "Activity: gptel" "gptel.el")) :filename "/home/karthik/.local/share/git/elpaca/repos/gptel/gptel.el" :name "gptel.el" :local-variables nil :etc ((indirectp) (narrowedp)))) (window-preserved-size nil nil nil)) (buffer #<buffer gptel.el> (selected . t) (hscroll . 0) (fringes 8 8 t nil) (margins nil) (scroll-bars nil 0 t nil 0 t nil) (vscroll . 0) (dedicated) (point . 23839) (start . 23839)) (next-buffers "init.el") (prev-buffers ("init.el" 20264 36480) ("gptel.el" 23839 23839) ("gptel-ollama.el" 3219 3908) ("magit: gptel" 1 1) ("inbox.org" 2163 3559) ("*Help*" 1 1) ("sim86_instruction_table.inl" 1033 1056) ("gptel-openai.el" 8061 9053) ("magit-diff: gptel" 1 1) ("ring_network_stability_notes.org" 1 51))))
  (mapcar #f(compiled-function (state) "Set windows' buffers in STATE." #<bytecode -0x199f2c9b98e46950>) (((min-height . 8) (min-width . 20) (min-height-ignore . 5) (min-width-ignore . 8) (min-height-safe . 2) (min-width-safe . 4) (min-pixel-height . 168) (min-pixel-width . 160) (min-pixel-height-ignore . 105) (min-pixel-width-ignore . 64) (min-pixel-height-safe . 42) (min-pixel-width-safe . 32)) hc (pixel-width . 1918) (pixel-height . 1133) (total-width . 240) (total-height . 54) (normal-height . 1.0) (normal-width . 1.0) (combination-limit . t) (vc (pixel-width . 959) (pixel-height . 1133) (total-width . 120) (total-height . 54) (normal-height . 1.0) (normal-width . 0.5) (combination-limit) (leaf (pixel-width . 959) (pixel-height . 819) (total-width . 120) (total-height . 39) (normal-height . 0.7224183583406885) (normal-width . 1.0) (parameters (activities-buffer . #s(activities-buffer :bookmark ("magit: gptel" (front-context-string . "Recent commits\n8") (rear-context-string . "ll no-defalias\n\n") (position . 143) (last-modified 26076 6795 779960 472000) (handler . magit--handle-bookmark) (mode . magit-status-mode) (filename . "/home/karthik/.local/share/git/elpaca/repos/gptel/") (defaults "magit-status" "magit: gptel") (magit-hidden-sections (stashes . "refs/stash") (unpushed . "@{upstream}..") (issues))) :filename nil :name "magit: gptel" :local-variables nil :etc ((indirectp) (narrowedp)))) (no-other-window) (no-delete-other-windows) (window-side)) (buffer #<buffer magit: gptel> (selected) (hscroll . 0) (fringes 8 8 t nil) (margins nil) (scroll-bars nil 0 t nil 0 t nil) (vscroll . 0) (dedicated) (point . 143) (start . 1)) (prev-buffers ("magit: gptel" 1 143) ("do.org::TODO gptel: always-available diffing" 168160 168160) ("gptel" 1 98) ("Chat.org" 1 1085) ("magit-process: gptel" 1 533) ("*eshell*" 32162 32270))) (leaf (last . t) (pixel-width . 959) (pixel-height . 314) (total-width . 120) (total-height . 15) (normal-height . 0.27758164165931154) (normal-width . 1.0) (parameters (activities-buffer . #s(activities-buffer :bookmark ("Org QL View: " (org-ql-view-plist :buffers-files ("~/Documents/org/inbox.org" "~/Documents/org/do.org" "~/Documents/org/gmail-cal.org" "~/Documents/org/ucsb-cal.org") :query (and (not (done)) (parent (and (todo "PROJECT") (heading "gptel")))) :sort (date) :narrow nil :super-groups nil :title nil) (handler . org-ql-view-bookmark-handler) (position . 1) (defaults "Org QL View: " "*Org QL View: (and (not (done)) (parent (and (todo...")) :filename nil :name "*Org QL View: (and (not (done)) (parent (and (todo PROJECT) (heading gptel))))*" :local-variables nil :etc ((indirectp) (narrowedp)))) (no-other-window) (no-delete-other-windows)) (buffer #<buffer *Org QL View: (and (not (done)) (parent (and (todo PROJECT) (heading gptel))))*> (selected) (hscroll . 0) (fringes 8 8 t nil) (margins nil) (scroll-bars nil 0 t nil 0 t nil) (vscroll . 0) (dedicated) (point . 1) (start . 1)) (prev-buffers ("*Org QL View: (and (not (done)) (parent (and (todo PROJECT) (heading gptel))))*" 1 1) ("magit-diff: gptel" 1 1) ("gptel" 1 98)))) (leaf (last . t) (pixel-width . 959) (pixel-height . 1133) (total-width . 120) (total-height . 54) (normal-height . 1.0) (normal-width . 0.5) (parameters (activities-buffer . #s(activities-buffer :bookmark ("Activity: gptel" (filename . "~/.local/share/git/elpaca/repos/gptel/gptel.el") (front-context-string . "(defun gptel--sa") (rear-context-string . "kend-name)))))\n\n") (position . 23839) (last-modified 26076 6795 789859 385000) (defaults "Activity: gptel" "gptel.el")) :filename "/home/karthik/.local/share/git/elpaca/repos/gptel/gptel.el" :name "gptel.el" :local-variables nil :etc ((indirectp) (narrowedp)))) (window-preserved-size nil nil nil)) (buffer #<buffer gptel.el> (selected . t) (hscroll . 0) (fringes 8 8 t nil) (margins nil) (scroll-bars nil 0 t nil 0 t nil) (vscroll . 0) (dedicated) (point . 23839) (start . 23839)) (next-buffers "init.el") (prev-buffers ("init.el" 20264 36480) ("gptel.el" 23839 23839) ("gptel-ollama.el" 3219 3908) ("magit: gptel" 1 1) ("inbox.org" 2163 3559) ("*Help*" 1 1) ("sim86_instruction_table.inl" 1033 1056) ("gptel-openai.el" 8061 9053) ("magit-diff: gptel" 1 1) ("ring_network_stability_notes.org" 1 51)))))
  (#f(compiled-function (--cl-bufferize-state-- state) #<bytecode -0x788ae464ce256ab>) (#f(compiled-function (state) "Set windows' buffers in STATE." #<bytecode -0x199f2c9b98e46950>)) (((min-height . 8) (min-width . 20) (min-height-ignore . 5) (min-width-ignore . 8) (min-height-safe . 2) (min-width-safe . 4) (min-pixel-height . 168) (min-pixel-width . 160) (min-pixel-height-ignore . 105) (min-pixel-width-ignore . 64) (min-pixel-height-safe . 42) (min-pixel-width-safe . 32)) hc (pixel-width . 1918) (pixel-height . 1133) (total-width . 240) (total-height . 54) (normal-height . 1.0) (normal-width . 1.0) (combination-limit . t) (vc (pixel-width . 959) (pixel-height . 1133) (total-width . 120) (total-height . 54) (normal-height . 1.0) (normal-width . 0.5) (combination-limit) (leaf (pixel-width . 959) (pixel-height . 819) (total-width . 120) (total-height . 39) (normal-height . 0.7224183583406885) (normal-width . 1.0) (parameters (activities-buffer . #s(activities-buffer :bookmark ("magit: gptel" ... ... ... ... ... ... ... ... ...) :filename nil :name "magit: gptel" :local-variables nil :etc (... ...))) (no-other-window) (no-delete-other-windows) (window-side)) (buffer #<buffer magit: gptel> (selected) (hscroll . 0) (fringes 8 8 t nil) (margins nil) (scroll-bars nil 0 t nil 0 t nil) (vscroll . 0) (dedicated) (point . 143) (start . 1)) (prev-buffers ("magit: gptel" 1 143) ("do.org::TODO gptel: always-available diffing" 168160 168160) ("gptel" 1 98) ("Chat.org" 1 1085) ("magit-process: gptel" 1 533) ("*eshell*" 32162 32270))) (leaf (last . t) (pixel-width . 959) (pixel-height . 314) (total-width . 120) (total-height . 15) (normal-height . 0.27758164165931154) (normal-width . 1.0) (parameters (activities-buffer . #s(activities-buffer :bookmark ("Org QL View: " ... ... ... ...) :filename nil :name "*Org QL View: (and (not (done)) (parent (and (todo..." :local-variables nil :etc (... ...))) (no-other-window) (no-delete-other-windows)) (buffer #<buffer *Org QL View: (and (not (done)) (parent (and (todo PROJECT) (heading gptel))))*> (selected) (hscroll . 0) (fringes 8 8 t nil) (margins nil) (scroll-bars nil 0 t nil 0 t nil) (vscroll . 0) (dedicated) (point . 1) (start . 1)) (prev-buffers ("*Org QL View: (and (not (done)) (parent (and (todo..." 1 1) ("magit-diff: gptel" 1 1) ("gptel" 1 98)))) (leaf (last . t) (pixel-width . 959) (pixel-height . 1133) (total-width . 120) (total-height . 54) (normal-height . 1.0) (normal-width . 0.5) (parameters (activities-buffer . #s(activities-buffer :bookmark ("Activity: gptel" (filename . "~/.local/share/git/elpaca/repos/gptel/gptel.el") (front-context-string . "(defun gptel--sa") (rear-context-string . "kend-name)))))\n\n") (position . 23839) (last-modified 26076 6795 789859 385000) (defaults "Activity: gptel" "gptel.el")) :filename "/home/karthik/.local/share/git/elpaca/repos/gptel/..." :name "gptel.el" :local-variables nil :etc ((indirectp) (narrowedp)))) (window-preserved-size nil nil nil)) (buffer #<buffer gptel.el> (selected . t) (hscroll . 0) (fringes 8 8 t nil) (margins nil) (scroll-bars nil 0 t nil 0 t nil) (vscroll . 0) (dedicated) (point . 23839) (start . 23839)) (next-buffers "init.el") (prev-buffers ("init.el" 20264 36480) ("gptel.el" 23839 23839) ("gptel-ollama.el" 3219 3908) ("magit: gptel" 1 1) ("inbox.org" 2163 3559) ("*Help*" 1 1) ("sim86_instruction_table.inl" 1033 1056) ("gptel-openai.el" 8061 9053) ("magit-diff: gptel" 1 1) ("ring_network_stability_notes.org" 1 51)))))
  (#f(compiled-function (state) "Set windows' buffers in STATE." #<bytecode -0x199f2c9b98e46950>) (((min-height . 8) (min-width . 20) (min-height-ignore . 5) (min-width-ignore . 8) (min-height-safe . 2) (min-width-safe . 4) (min-pixel-height . 168) (min-pixel-width . 160) (min-pixel-height-ignore . 105) (min-pixel-width-ignore . 64) (min-pixel-height-safe . 42) (min-pixel-width-safe . 32)) hc (pixel-width . 1918) (pixel-height . 1133) (total-width . 240) (total-height . 54) (normal-height . 1.0) (normal-width . 1.0) (combination-limit . t) (vc (pixel-width . 959) (pixel-height . 1133) (total-width . 120) (total-height . 54) (normal-height . 1.0) (normal-width . 0.5) (combination-limit) (leaf (pixel-width . 959) (pixel-height . 819) (total-width . 120) (total-height . 39) (normal-height . 0.7224183583406885) (normal-width . 1.0) (parameters (activities-buffer . #s(activities-buffer :bookmark ("magit: gptel" ... ... ... ... ... ... ... ... ...) :filename nil :name "magit: gptel" :local-variables nil :etc (... ...))) (no-other-window) (no-delete-other-windows) (window-side)) (buffer #<buffer magit: gptel> (selected) (hscroll . 0) (fringes 8 8 t nil) (margins nil) (scroll-bars nil 0 t nil 0 t nil) (vscroll . 0) (dedicated) (point . 143) (start . 1)) (prev-buffers ("magit: gptel" 1 143) ("do.org::TODO gptel: always-available diffing" 168160 168160) ("gptel" 1 98) ("Chat.org" 1 1085) ("magit-process: gptel" 1 533) ("*eshell*" 32162 32270))) (leaf (last . t) (pixel-width . 959) (pixel-height . 314) (total-width . 120) (total-height . 15) (normal-height . 0.27758164165931154) (normal-width . 1.0) (parameters (activities-buffer . #s(activities-buffer :bookmark ("Org QL View: " ... ... ... ...) :filename nil :name "*Org QL View: (and (not (done)) (parent (and (todo..." :local-variables nil :etc (... ...))) (no-other-window) (no-delete-other-windows)) (buffer #<buffer *Org QL View: (and (not (done)) (parent (and (todo PROJECT) (heading gptel))))*> (selected) (hscroll . 0) (fringes 8 8 t nil) (margins nil) (scroll-bars nil 0 t nil 0 t nil) (vscroll . 0) (dedicated) (point . 1) (start . 1)) (prev-buffers ("*Org QL View: (and (not (done)) (parent (and (todo..." 1 1) ("magit-diff: gptel" 1 1) ("gptel" 1 98)))) (leaf (last . t) (pixel-width . 959) (pixel-height . 1133) (total-width . 120) (total-height . 54) (normal-height . 1.0) (normal-width . 0.5) (parameters (activities-buffer . #s(activities-buffer :bookmark ("Activity: gptel" (filename . "~/.local/share/git/elpaca/repos/gptel/gptel.el") (front-context-string . "(defun gptel--sa") (rear-context-string . "kend-name)))))\n\n") (position . 23839) (last-modified 26076 6795 789859 385000) (defaults "Activity: gptel" "gptel.el")) :filename "/home/karthik/.local/share/git/elpaca/repos/gptel/..." :name "gptel.el" :local-variables nil :etc ((indirectp) (narrowedp)))) (window-preserved-size nil nil nil)) (buffer #<buffer gptel.el> (selected . t) (hscroll . 0) (fringes 8 8 t nil) (margins nil) (scroll-bars nil 0 t nil 0 t nil) (vscroll . 0) (dedicated) (point . 23839) (start . 23839)) (next-buffers "init.el") (prev-buffers ("init.el" 20264 36480) ("gptel.el" 23839 23839) ("gptel-ollama.el" 3219 3908) ("magit: gptel" 1 1) ("inbox.org" 2163 3559) ("*Help*" 1 1) ("sim86_instruction_table.inl" 1033 1056) ("gptel-openai.el" 8061 9053) ("magit-diff: gptel" 1 1) ("ring_network_stability_notes.org" 1 51)))))
  (activities--bufferize-window-state (((min-height . 8) (min-width . 20) (min-height-ignore . 5) (min-width-ignore . 8) (min-height-safe . 2) (min-width-safe . 4) (min-pixel-height . 168) (min-pixel-width . 160) (min-pixel-height-ignore . 105) (min-pixel-width-ignore . 64) (min-pixel-height-safe . 42) (min-pixel-width-safe . 32)) hc (pixel-width . 1918) (pixel-height . 1133) (total-width . 240) (total-height . 54) (normal-height . 1.0) (normal-width . 1.0) (combination-limit . t) (vc (pixel-width . 959) (pixel-height . 1133) (total-width . 120) (total-height . 54) (normal-height . 1.0) (normal-width . 0.5) (combination-limit) (leaf (pixel-width . 959) (pixel-height . 819) (total-width . 120) (total-height . 39) (normal-height . 0.7224183583406885) (normal-width . 1.0) (parameters (activities-buffer . #s(activities-buffer :bookmark ("magit: gptel" ... ... ... ... ... ... ... ... ...) :filename nil :name "magit: gptel" :local-variables nil :etc (... ...))) (no-other-window) (no-delete-other-windows) (window-side)) (buffer #<buffer magit: gptel> (selected) (hscroll . 0) (fringes 8 8 t nil) (margins nil) (scroll-bars nil 0 t nil 0 t nil) (vscroll . 0) (dedicated) (point . 143) (start . 1)) (prev-buffers ("magit: gptel" 1 143) ("do.org::TODO gptel: always-available diffing" 168160 168160) ("gptel" 1 98) ("Chat.org" 1 1085) ("magit-process: gptel" 1 533) ("*eshell*" 32162 32270))) (leaf (last . t) (pixel-width . 959) (pixel-height . 314) (total-width . 120) (total-height . 15) (normal-height . 0.27758164165931154) (normal-width . 1.0) (parameters (activities-buffer . #s(activities-buffer :bookmark ("Org QL View: " ... ... ... ...) :filename nil :name "*Org QL View: (and (not (done)) (parent (and (todo..." :local-variables nil :etc (... ...))) (no-other-window) (no-delete-other-windows)) (buffer #<buffer *Org QL View: (and (not (done)) (parent (and (todo PROJECT) (heading gptel))))*> (selected) (hscroll . 0) (fringes 8 8 t nil) (margins nil) (scroll-bars nil 0 t nil 0 t nil) (vscroll . 0) (dedicated) (point . 1) (start . 1)) (prev-buffers ("*Org QL View: (and (not (done)) (parent (and (todo..." 1 1) ("magit-diff: gptel" 1 1) ("gptel" 1 98)))) (leaf (last . t) (pixel-width . 959) (pixel-height . 1133) (total-width . 120) (total-height . 54) (normal-height . 1.0) (normal-width . 0.5) (parameters (activities-buffer . #s(activities-buffer :bookmark ("Activity: gptel" (filename . "~/.local/share/git/elpaca/repos/gptel/gptel.el") (front-context-string . "(defun gptel--sa") (rear-context-string . "kend-name)))))\n\n") (position . 23839) (last-modified 26076 6795 789859 385000) (defaults "Activity: gptel" "gptel.el")) :filename "/home/karthik/.local/share/git/elpaca/repos/gptel/..." :name "gptel.el" :local-variables nil :etc ((indirectp) (narrowedp)))) (window-preserved-size nil nil nil)) (buffer #<buffer gptel.el> (selected . t) (hscroll . 0) (fringes 8 8 t nil) (margins nil) (scroll-bars nil 0 t nil 0 t nil) (vscroll . 0) (dedicated) (point . 23839) (start . 23839)) (next-buffers "init.el") (prev-buffers ("init.el" 20264 36480) ("gptel.el" 23839 23839) ("gptel-ollama.el" 3219 3908) ("magit: gptel" 1 1) ("inbox.org" 2163 3559) ("*Help*" 1 1) ("sim86_instruction_table.inl" 1033 1056) ("gptel-openai.el" 8061 9053) ("magit-diff: gptel" 1 1) ("ring_network_stability_notes.org" 1 51)))))
  (activities--windows-set (((min-height . 8) (min-width . 20) (min-height-ignore . 5) (min-width-ignore . 8) (min-height-safe . 2) (min-width-safe . 4) (min-pixel-height . 168) (min-pixel-width . 160) (min-pixel-height-ignore . 105) (min-pixel-width-ignore . 64) (min-pixel-height-safe . 42) (min-pixel-width-safe . 32)) hc (pixel-width . 1918) (pixel-height . 1133) (total-width . 240) (total-height . 54) (normal-height . 1.0) (normal-width . 1.0) (combination-limit . t) (vc (pixel-width . 959) (pixel-height . 1133) (total-width . 120) (total-height . 54) (normal-height . 1.0) (normal-width . 0.5) (combination-limit) (leaf (pixel-width . 959) (pixel-height . 819) (total-width . 120) (total-height . 39) (normal-height . 0.7224183583406885) (normal-width . 1.0) (parameters (activities-buffer . #s(activities-buffer :bookmark ("magit: gptel" ... ... ... ... ... ... ... ... ...) :filename nil :name "magit: gptel" :local-variables nil :etc (... ...))) (no-other-window) (no-delete-other-windows) (window-side)) (buffer "magit: gptel" (selected) (hscroll . 0) (fringes 8 8 t nil) (margins nil) (scroll-bars nil 0 t nil 0 t nil) (vscroll . 0) (dedicated) (point . 143) (start . 1)) (prev-buffers ("magit: gptel" 1 143) ("do.org::TODO gptel: always-available diffing" 168160 168160) ("gptel" 1 98) ("Chat.org" 1 1085) ("magit-process: gptel" 1 533) ("*eshell*" 32162 32270))) (leaf (last . t) (pixel-width . 959) (pixel-height . 314) (total-width . 120) (total-height . 15) (normal-height . 0.27758164165931154) (normal-width . 1.0) (parameters (activities-buffer . #s(activities-buffer :bookmark ("Org QL View: " ... ... ... ...) :filename nil :name "*Org QL View: (and (not (done)) (parent (and (todo..." :local-variables nil :etc (... ...))) (no-other-window) (no-delete-other-windows)) (buffer "*Org QL View: (and (not (done)) (parent (and (todo..." (selected) (hscroll . 0) (fringes 8 8 t nil) (margins nil) (scroll-bars nil 0 t nil 0 t nil) (vscroll . 0) (dedicated) (point . 1) (start . 1)) (prev-buffers ("*Org QL View: (and (not (done)) (parent (and (todo..." 1 1) ("magit-diff: gptel" 1 1) ("gptel" 1 98)))) (leaf (last . t) (pixel-width . 959) (pixel-height . 1133) (total-width . 120) (total-height . 54) (normal-height . 1.0) (normal-width . 0.5) (parameters (activities-buffer . #s(activities-buffer :bookmark ("Activity: gptel" (filename . "~/.local/share/git/elpaca/repos/gptel/gptel.el") (front-context-string . "(defun gptel--sa") (rear-context-string . "kend-name)))))\n\n") (position . 23839) (last-modified 26076 6795 789859 385000) (defaults "Activity: gptel" "gptel.el")) :filename "/home/karthik/.local/share/git/elpaca/repos/gptel/..." :name "gptel.el" :local-variables nil :etc ((indirectp) (narrowedp)))) (window-preserved-size nil nil nil)) (buffer "gptel.el" (selected . t) (hscroll . 0) (fringes 8 8 t nil) (margins nil) (scroll-bars nil 0 t nil 0 t nil) (vscroll . 0) (dedicated) (point . 23839) (start . 23839)) (next-buffers "init.el") (prev-buffers ("init.el" 20264 36480) ("gptel.el" 23839 23839) ("gptel-ollama.el" 3219 3908) ("magit: gptel" 1 1) ("inbox.org" 2163 3559) ("*Help*" 1 1) ("sim86_instruction_table.inl" 1033 1056) ("gptel-openai.el" 8061 9053) ("magit-diff: gptel" 1 1) ("ring_network_stability_notes.org" 1 51)))))
  (activities-set #s(activities-activity :name "gptel" :default #s(activities-activity-state :window-state (((min-height . 8) (min-width . 20) (min-height-ignore . 5) (min-width-ignore . 8) (min-height-safe . 2) (min-width-safe . 4) (min-pixel-height . 168) (min-pixel-width . 160) (min-pixel-height-ignore . 105) (min-pixel-width-ignore . 64) (min-pixel-height-safe . 42) (min-pixel-width-safe . 32)) hc (pixel-width . 1918) (pixel-height . 1133) (total-width . 240) (total-height . 54) (normal-height . 1.0) (normal-width . 1.0) (combination-limit . t) (vc (pixel-width . 959) (pixel-height . 1133) (total-width . 120) (total-height . 54) (normal-height . 1.0) (normal-width . 0.5) (combination-limit) (leaf (pixel-width . 959) (pixel-height . 819) (total-width . 120) (total-height . 39) (normal-height . 0.7224183583406885) (normal-width . 1.0) (parameters (activities-buffer . ...) (no-other-window) (no-delete-other-windows) (window-side)) (buffer "magit: gptel" (selected) (hscroll . 0) (fringes 8 8 t nil) (margins nil) (scroll-bars nil 0 t nil 0 t nil) (vscroll . 0) (dedicated) (point . 143) (start . 1)) (prev-buffers ("magit: gptel" 1 143) ("do.org::TODO gptel: always-available diffing" 168160 168160) ("gptel" 1 98) ("Chat.org" 1 1085) ("magit-process: gptel" 1 533) ("*eshell*" 32162 32270))) (leaf (last . t) (pixel-width . 959) (pixel-height . 314) (total-width . 120) (total-height . 15) (normal-height . 0.27758164165931154) (normal-width . 1.0) (parameters (activities-buffer . ...) (no-other-window) (no-delete-other-windows)) (buffer "*Org QL View: (and (not (done)) (parent (and (todo..." (selected) (hscroll . 0) (fringes 8 8 t nil) (margins nil) (scroll-bars nil 0 t nil 0 t nil) (vscroll . 0) (dedicated) (point . 1) (start . 1)) (prev-buffers ("*Org QL View: (and (not (done)) (parent (and (todo..." 1 1) ("magit-diff: gptel" 1 1) ("gptel" 1 98)))) (leaf (last . t) (pixel-width . 959) (pixel-height . 1133) (total-width . 120) (total-height . 54) (normal-height . 1.0) (normal-width . 0.5) (parameters (activities-buffer . #s(activities-buffer :bookmark ... :filename "/home/karthik/.local/share/git/elpaca/repos/gptel/..." :name "gptel.el" :local-variables nil :etc ...)) (window-preserved-size nil nil nil)) (buffer "gptel.el" (selected . t) (hscroll . 0) (fringes 8 8 t nil) (margins nil) (scroll-bars nil 0 t nil 0 t nil) (vscroll . 0) (dedicated) (point . 23839) (start . 23839)) (next-buffers "init.el") (prev-buffers ("init.el" 20264 36480) ("gptel.el" 23839 23839) ("gptel-ollama.el" 3219 3908) ("magit: gptel" 1 1) ("inbox.org" 2163 3559) ("*Help*" 1 1) ("sim86_instruction_table.inl" 1033 1056) ("gptel-openai.el" 8061 9053) ("magit-diff: gptel" 1 1) ("ring_network_stability_notes.org" 1 51)))) :etc ((time 26076 6795 789872 725000))) :last #s(activities-activity-state :window-state (((min-height . 4) (min-width . 30) (min-height-ignore . 3) (min-width-ignore . 12) (min-height-safe . 1) (min-width-safe . 6) (min-pixel-height . 84) (min-pixel-width . 240) (min-pixel-height-ignore . 63) (min-pixel-width-ignore . 96) (min-pixel-height-safe . 21) (min-pixel-width-safe . 48)) hc (pixel-width . 2370) (pixel-height . 1325) (total-width . 296) (total-height . 63) (normal-height . 1.0) (normal-width . 1.0) (combination-limit . t) (leaf (parameters (activities-buffer . #s(activities-buffer :bookmark nil :filename nil :name "*Scratch for emacs-lisp-mode*" :local-variables nil :etc ...))) (pixel-width . 792) (pixel-height . 1325) (total-width . 99) (total-height . 63) (normal-height . 1.0) (normal-width . 0.3341772151898734) (buffer "*Scratch for emacs-lisp-mode*" (selected) (hscroll . 0) (fringes 8 8 t nil) (margins nil) (scroll-bars nil 0 t nil 0 t nil) (vscroll . 0) (dedicated) (point . 990) (start . 1)) (prev-buffers ("*Scratch for emacs-lisp-mode*" 1 990))) (hc (last . t) (pixel-width . 1578) (pixel-height . 1325) (total-width . 197) (total-height . 63) (normal-height . 1.0) (normal-width . 0.6658227848101266) (combination-limit . t) (leaf (parameters (activities-buffer . ...)) (pixel-width . 784) (pixel-height . 1325) (total-width . 98) (total-height . 63) (normal-height . 1.0) (normal-width . 0.4968314321926489) (buffer "*forge: karthink/gptel #224*" (selected) (hscroll . 0) (fringes 8 8 t nil) (margins nil) (scroll-bars nil 0 t nil 0 t nil) (vscroll . 0) (dedicated) (point . 5748) (start . 1091)) (prev-buffers ("*Scratch for emacs-lisp-mode*" 1 707))) (leaf (parameters (activities-buffer . ...)) (last . t) (pixel-width . 794) (pixel-height . 1325) (total-width . 99) (total-height . 63) (normal-height . 1.0) (normal-width . 0.5031685678073511) (buffer "gptel-ollama.el" (selected . t) (hscroll . 0) (fringes 8 8 t nil) (margins nil) (scroll-bars nil 0 t nil 0 t nil) (vscroll . 0) (dedicated) (point . 3908) (start . 3846)) (prev-buffers ("init.el" 149155 150205) ("*Scratch for emacs-lisp-mode*" 1 707))))) :etc ((time 26076 63502 635348 879000))) :etc nil) :state default)
  (activities-revert #s(activities-activity :name "gptel" :default #s(activities-activity-state :window-state (((min-height . 8) (min-width . 20) (min-height-ignore . 5) (min-width-ignore . 8) (min-height-safe . 2) (min-width-safe . 4) (min-pixel-height . 168) (min-pixel-width . 160) (min-pixel-height-ignore . 105) (min-pixel-width-ignore . 64) (min-pixel-height-safe . 42) (min-pixel-width-safe . 32)) hc (pixel-width . 1918) (pixel-height . 1133) (total-width . 240) (total-height . 54) (normal-height . 1.0) (normal-width . 1.0) (combination-limit . t) (vc (pixel-width . 959) (pixel-height . 1133) (total-width . 120) (total-height . 54) (normal-height . 1.0) (normal-width . 0.5) (combination-limit) (leaf (pixel-width . 959) (pixel-height . 819) (total-width . 120) (total-height . 39) (normal-height . 0.7224183583406885) (normal-width . 1.0) (parameters (activities-buffer . ...) (no-other-window) (no-delete-other-windows) (window-side)) (buffer "magit: gptel" (selected) (hscroll . 0) (fringes 8 8 t nil) (margins nil) (scroll-bars nil 0 t nil 0 t nil) (vscroll . 0) (dedicated) (point . 143) (start . 1)) (prev-buffers ("magit: gptel" 1 143) ("do.org::TODO gptel: always-available diffing" 168160 168160) ("gptel" 1 98) ("Chat.org" 1 1085) ("magit-process: gptel" 1 533) ("*eshell*" 32162 32270))) (leaf (last . t) (pixel-width . 959) (pixel-height . 314) (total-width . 120) (total-height . 15) (normal-height . 0.27758164165931154) (normal-width . 1.0) (parameters (activities-buffer . ...) (no-other-window) (no-delete-other-windows)) (buffer "*Org QL View: (and (not (done)) (parent (and (todo..." (selected) (hscroll . 0) (fringes 8 8 t nil) (margins nil) (scroll-bars nil 0 t nil 0 t nil) (vscroll . 0) (dedicated) (point . 1) (start . 1)) (prev-buffers ("*Org QL View: (and (not (done)) (parent (and (todo..." 1 1) ("magit-diff: gptel" 1 1) ("gptel" 1 98)))) (leaf (last . t) (pixel-width . 959) (pixel-height . 1133) (total-width . 120) (total-height . 54) (normal-height . 1.0) (normal-width . 0.5) (parameters (activities-buffer . #s(activities-buffer :bookmark ... :filename "/home/karthik/.local/share/git/elpaca/repos/gptel/..." :name "gptel.el" :local-variables nil :etc ...)) (window-preserved-size nil nil nil)) (buffer "gptel.el" (selected . t) (hscroll . 0) (fringes 8 8 t nil) (margins nil) (scroll-bars nil 0 t nil 0 t nil) (vscroll . 0) (dedicated) (point . 23839) (start . 23839)) (next-buffers "init.el") (prev-buffers ("init.el" 20264 36480) ("gptel.el" 23839 23839) ("gptel-ollama.el" 3219 3908) ("magit: gptel" 1 1) ("inbox.org" 2163 3559) ("*Help*" 1 1) ("sim86_instruction_table.inl" 1033 1056) ("gptel-openai.el" 8061 9053) ("magit-diff: gptel" 1 1) ("ring_network_stability_notes.org" 1 51)))) :etc ((time 26076 6795 789872 725000))) :last #s(activities-activity-state :window-state (((min-height . 4) (min-width . 30) (min-height-ignore . 3) (min-width-ignore . 12) (min-height-safe . 1) (min-width-safe . 6) (min-pixel-height . 84) (min-pixel-width . 240) (min-pixel-height-ignore . 63) (min-pixel-width-ignore . 96) (min-pixel-height-safe . 21) (min-pixel-width-safe . 48)) hc (pixel-width . 2370) (pixel-height . 1325) (total-width . 296) (total-height . 63) (normal-height . 1.0) (normal-width . 1.0) (combination-limit . t) (leaf (parameters (activities-buffer . #s(activities-buffer :bookmark nil :filename nil :name "*Scratch for emacs-lisp-mode*" :local-variables nil :etc ...))) (pixel-width . 792) (pixel-height . 1325) (total-width . 99) (total-height . 63) (normal-height . 1.0) (normal-width . 0.3341772151898734) (buffer "*Scratch for emacs-lisp-mode*" (selected) (hscroll . 0) (fringes 8 8 t nil) (margins nil) (scroll-bars nil 0 t nil 0 t nil) (vscroll . 0) (dedicated) (point . 990) (start . 1)) (prev-buffers ("*Scratch for emacs-lisp-mode*" 1 990))) (hc (last . t) (pixel-width . 1578) (pixel-height . 1325) (total-width . 197) (total-height . 63) (normal-height . 1.0) (normal-width . 0.6658227848101266) (combination-limit . t) (leaf (parameters (activities-buffer . ...)) (pixel-width . 784) (pixel-height . 1325) (total-width . 98) (total-height . 63) (normal-height . 1.0) (normal-width . 0.4968314321926489) (buffer "*forge: karthink/gptel #224*" (selected) (hscroll . 0) (fringes 8 8 t nil) (margins nil) (scroll-bars nil 0 t nil 0 t nil) (vscroll . 0) (dedicated) (point . 5748) (start . 1091)) (prev-buffers ("*Scratch for emacs-lisp-mode*" 1 707))) (leaf (parameters (activities-buffer . ...)) (last . t) (pixel-width . 794) (pixel-height . 1325) (total-width . 99) (total-height . 63) (normal-height . 1.0) (normal-width . 0.5031685678073511) (buffer "gptel-ollama.el" (selected . t) (hscroll . 0) (fringes 8 8 t nil) (margins nil) (scroll-bars nil 0 t nil 0 t nil) (vscroll . 0) (dedicated) (point . 3908) (start . 3846)) (prev-buffers ("init.el" 149155 150205) ("*Scratch for emacs-lisp-mode*" 1 707))))) :etc ((time 26076 63502 635348 879000))) :etc nil))
  (funcall-interactively activities-revert #s(activities-activity :name "gptel" :default #s(activities-activity-state :window-state (((min-height . 8) (min-width . 20) (min-height-ignore . 5) (min-width-ignore . 8) (min-height-safe . 2) (min-width-safe . 4) (min-pixel-height . 168) (min-pixel-width . 160) (min-pixel-height-ignore . 105) (min-pixel-width-ignore . 64) (min-pixel-height-safe . 42) (min-pixel-width-safe . 32)) hc (pixel-width . 1918) (pixel-height . 1133) (total-width . 240) (total-height . 54) (normal-height . 1.0) (normal-width . 1.0) (combination-limit . t) (vc (pixel-width . 959) (pixel-height . 1133) (total-width . 120) (total-height . 54) (normal-height . 1.0) (normal-width . 0.5) (combination-limit) (leaf (pixel-width . 959) (pixel-height . 819) (total-width . 120) (total-height . 39) (normal-height . 0.7224183583406885) (normal-width . 1.0) (parameters (activities-buffer . ...) (no-other-window) (no-delete-other-windows) (window-side)) (buffer "magit: gptel" (selected) (hscroll . 0) (fringes 8 8 t nil) (margins nil) (scroll-bars nil 0 t nil 0 t nil) (vscroll . 0) (dedicated) (point . 143) (start . 1)) (prev-buffers ("magit: gptel" 1 143) ("do.org::TODO gptel: always-available diffing" 168160 168160) ("gptel" 1 98) ("Chat.org" 1 1085) ("magit-process: gptel" 1 533) ("*eshell*" 32162 32270))) (leaf (last . t) (pixel-width . 959) (pixel-height . 314) (total-width . 120) (total-height . 15) (normal-height . 0.27758164165931154) (normal-width . 1.0) (parameters (activities-buffer . ...) (no-other-window) (no-delete-other-windows)) (buffer "*Org QL View: (and (not (done)) (parent (and (todo..." (selected) (hscroll . 0) (fringes 8 8 t nil) (margins nil) (scroll-bars nil 0 t nil 0 t nil) (vscroll . 0) (dedicated) (point . 1) (start . 1)) (prev-buffers ("*Org QL View: (and (not (done)) (parent (and (todo..." 1 1) ("magit-diff: gptel" 1 1) ("gptel" 1 98)))) (leaf (last . t) (pixel-width . 959) (pixel-height . 1133) (total-width . 120) (total-height . 54) (normal-height . 1.0) (normal-width . 0.5) (parameters (activities-buffer . #s(activities-buffer :bookmark ... :filename "/home/karthik/.local/share/git/elpaca/repos/gptel/..." :name "gptel.el" :local-variables nil :etc ...)) (window-preserved-size nil nil nil)) (buffer "gptel.el" (selected . t) (hscroll . 0) (fringes 8 8 t nil) (margins nil) (scroll-bars nil 0 t nil 0 t nil) (vscroll . 0) (dedicated) (point . 23839) (start . 23839)) (next-buffers "init.el") (prev-buffers ("init.el" 20264 36480) ("gptel.el" 23839 23839) ("gptel-ollama.el" 3219 3908) ("magit: gptel" 1 1) ("inbox.org" 2163 3559) ("*Help*" 1 1) ("sim86_instruction_table.inl" 1033 1056) ("gptel-openai.el" 8061 9053) ("magit-diff: gptel" 1 1) ("ring_network_stability_notes.org" 1 51)))) :etc ((time 26076 6795 789872 725000))) :last #s(activities-activity-state :window-state (((min-height . 4) (min-width . 30) (min-height-ignore . 3) (min-width-ignore . 12) (min-height-safe . 1) (min-width-safe . 6) (min-pixel-height . 84) (min-pixel-width . 240) (min-pixel-height-ignore . 63) (min-pixel-width-ignore . 96) (min-pixel-height-safe . 21) (min-pixel-width-safe . 48)) hc (pixel-width . 2370) (pixel-height . 1325) (total-width . 296) (total-height . 63) (normal-height . 1.0) (normal-width . 1.0) (combination-limit . t) (leaf (parameters (activities-buffer . #s(activities-buffer :bookmark nil :filename nil :name "*Scratch for emacs-lisp-mode*" :local-variables nil :etc ...))) (pixel-width . 792) (pixel-height . 1325) (total-width . 99) (total-height . 63) (normal-height . 1.0) (normal-width . 0.3341772151898734) (buffer "*Scratch for emacs-lisp-mode*" (selected) (hscroll . 0) (fringes 8 8 t nil) (margins nil) (scroll-bars nil 0 t nil 0 t nil) (vscroll . 0) (dedicated) (point . 990) (start . 1)) (prev-buffers ("*Scratch for emacs-lisp-mode*" 1 990))) (hc (last . t) (pixel-width . 1578) (pixel-height . 1325) (total-width . 197) (total-height . 63) (normal-height . 1.0) (normal-width . 0.6658227848101266) (combination-limit . t) (leaf (parameters (activities-buffer . ...)) (pixel-width . 784) (pixel-height . 1325) (total-width . 98) (total-height . 63) (normal-height . 1.0) (normal-width . 0.4968314321926489) (buffer "*forge: karthink/gptel #224*" (selected) (hscroll . 0) (fringes 8 8 t nil) (margins nil) (scroll-bars nil 0 t nil 0 t nil) (vscroll . 0) (dedicated) (point . 5748) (start . 1091)) (prev-buffers ("*Scratch for emacs-lisp-mode*" 1 707))) (leaf (parameters (activities-buffer . ...)) (last . t) (pixel-width . 794) (pixel-height . 1325) (total-width . 99) (total-height . 63) (normal-height . 1.0) (normal-width . 0.5031685678073511) (buffer "gptel-ollama.el" (selected . t) (hscroll . 0) (fringes 8 8 t nil) (margins nil) (scroll-bars nil 0 t nil 0 t nil) (vscroll . 0) (dedicated) (point . 3908) (start . 3846)) (prev-buffers ("init.el" 149155 150205) ("*Scratch for emacs-lisp-mode*" 1 707))))) :etc ((time 26076 63502 635348 879000))) :etc nil))
  (command-execute activities-revert)
  • activities.el version: 83db6b5, installed via elpaca
  • Emacs 29.1

Ability to open/switch to activities in same Emacs frame?

To begin with, I want to express my gratitude for developing such an amazing package! Now, I want to ask if it would be possible to implement a feature that would allow us to open/switch to activities in the same frame without creating one.

I am more accustomed to having one scratchpad buffer of Emacs and calling it on demand and later hiding than I am used to having new frames created. (a habit I perhaps should get rid of, hehe) Therefore having the ability to keep using my scratchpad buffer would be delightful!

Feedback

Sorry for this immense lack of effort. Writing my initial impressions, while fresh and ignorant.

  1. There needs to be an activities-save command that explicitly only updates the persisted state of the current activity and leaves others alone
  2. Separate the intentionally saved durable state and the automatically saved live-updating state. Use "set" and "save" semantics. The activities-mode should "set" the live updating state while "save" should be more durable. This way, if I get too far off of what that activity actually is, I can get back to what it was intended to be. Both "set" and "save" states should persist, but independently.
  3. I have anxiety about the minor mode. I want to ignore buffers that return t for any function in a list so I can filter out my usual carousing. Ignore buffers that belong to other activities but not the current activity.
  4. An activity could count as a buffer in completions, though I'm not sure if I want to do this from the completions side or by having activities provide completions. When I go to change buffer, my bookmarks, activities, and buffers should all be able to live in one completion list

I did not look in depth. My thoughts reflect first impressions.

Resuming an activity will create a new frame but using my default frame alist instead of copying the current frame. Since my frame almost never matches the default while setting up for screencaps etc, I wind up with frames spawning when I just want to re-use the existing one.

Some thoughts on Activities

Overall, I think Activities is really promising. I have a few questions/suggestions:

  • What’s the difference between activities-resume and activities-switch. They seem to do the same thing, so maybe they can just be one command? Maybe activities-new can also be consolidated into the same command.
  • I’m not sure how to remove a buffer from an activity.
  • I’d like a way to make a blank activity, rather than one that inherits the buffer list.

Reuse only default frame

I use activities-resume 'new and it's great, but I think it would be even cooler if a further usecase could be supported: I always want activities to open a in a new frame (as I like to use my window manager for that), unless it's the default frame -- in which case I want activities-resume to behave as if activities-resume-into-frame was set to current.

This is because typically, I'll start Emacs and the first thing I'll do is resume an activity with M-x activities-resume, which then leaves the default frame open undefinitely, doing nothing.

A further improvement (which I'm not sure it's possible to implement) would be if the splash screen could prompt me about the activity I want to resume, and reuse that frame (which is the default one). Activities resumed via M-x would instead be resumed in new frames.

NOTES.org is a broken link

NOTES.org seems to be a symlink to NOTES/NOTES.org, but the latter is not included in the repo.

This is also the case in the 0.7 release.

Calling activities-list when there are no activities causes an error

Here is the backtrace:

Details

Debugger entered--Lisp error: (wrong-number-of-arguments # 0)
max()
apply(max nil)
seq-max(nil)
#f(compiled-function (column index) #<bytecode -0x1ca768627d88b573>)(#s(vtable-column :name "Active" :width nil :min-width nil :max-width nil :primary descend :align right :getter (lambda (object _table) (if (activities-activity-active-p object) "" " ")) :formatter nil :displayer nil :-numerical t) 0)
#f(compiled-function (elt) #<bytecode -0x13aa50143314c409>)(#s(vtable-column :name "Active" :width nil :min-width nil :max-width nil :primary descend :align right :getter (lambda (object _table) (if (activities-activity-active-p object) "
" " ")) :formatter nil :displayer nil :-numerical t))
mapcar(#f(compiled-function (elt) #<bytecode -0x13aa50143314c409>) (#s(vtable-column :name "Active" :width nil :min-width nil :max-width nil :primary descend :align right :getter (lambda (object _table) (if (activities-activity-active-p object) "" " ")) :formatter nil :displayer nil :-numerical t) #s(vtable-column :name "Name" :width nil :min-width nil :max-width nil :primary nil :align right :getter (lambda (object _table) (activities-activity-name object)) :formatter nil :displayer nil :-numerical t) #s(vtable-column :name "Last saved" :width nil :min-width nil :max-width nil :primary nil :align right :getter (lambda (activity _table) (or (map-elt (activities-activity-state-etc (activities-activity-last activity)) 'time) 0)) :formatter activities-list--format-time :displayer nil :-numerical t) #s(vtable-column :name "Default saved" :width nil :min-width nil :max-width nil :primary nil :align right :getter (lambda (activity _table) (or (map-elt (activities-activity-state-etc (activities-activity-default activity)) 'time) 0)) :formatter activities-list--format-time :displayer nil :-numerical t)))
#f(compiled-function #'sequence #<bytecode 0x18576f7298331fb4>)(#f(compiled-function (elt) #<bytecode -0x13aa50143314c409>) (#s(vtable-column :name "Active" :width nil :min-width nil :max-width nil :primary descend :align right :getter (lambda (object _table) (if (activities-activity-active-p object) "
" " ")) :formatter nil :displayer nil :-numerical t) #s(vtable-column :name "Name" :width nil :min-width nil :max-width nil :primary nil :align right :getter (lambda (object _table) (activities-activity-name object)) :formatter nil :displayer nil :-numerical t) #s(vtable-column :name "Last saved" :width nil :min-width nil :max-width nil :primary nil :align right :getter (lambda (activity _table) (or (map-elt (activities-activity-state-etc (activities-activity-last activity)) 'time) 0)) :formatter activities-list--format-time :displayer nil :-numerical t) #s(vtable-column :name "Default saved" :width nil :min-width nil :max-width nil :primary nil :align right :getter (lambda (activity _table) (or (map-elt (activities-activity-state-etc (activities-activity-default activity)) 'time) 0)) :formatter activities-list--format-time :displayer nil :-numerical t)))
apply(#f(compiled-function #'sequence #<bytecode 0x18576f7298331fb4>) #f(compiled-function (elt) #<bytecode -0x13aa50143314c409>) (#s(vtable-column :name "Active" :width nil :min-width nil :max-width nil :primary descend :align right :getter (lambda (object _table) (if (activities-activity-active-p object) "" " ")) :formatter nil :displayer nil :-numerical t) #s(vtable-column :name "Name" :width nil :min-width nil :max-width nil :primary nil :align right :getter (lambda (object _table) (activities-activity-name object)) :formatter nil :displayer nil :-numerical t) #s(vtable-column :name "Last saved" :width nil :min-width nil :max-width nil :primary nil :align right :getter (lambda (activity _table) (or (map-elt (activities-activity-state-etc (activities-activity-last activity)) 'time) 0)) :formatter activities-list--format-time :displayer nil :-numerical t) #s(vtable-column :name "Default saved" :width nil :min-width nil :max-width nil :primary nil :align right :getter (lambda (activity _table) (or (map-elt (activities-activity-state-etc (activities-activity-default activity)) 'time) 0)) :formatter activities-list--format-time :displayer nil :-numerical t)) nil)
seq-map(#f(compiled-function (elt) #<bytecode -0x13aa50143314c409>) (#s(vtable-column :name "Active" :width nil :min-width nil :max-width nil :primary descend :align right :getter (lambda (object _table) (if (activities-activity-active-p object) "
" " ")) :formatter nil :displayer nil :-numerical t) #s(vtable-column :name "Name" :width nil :min-width nil :max-width nil :primary nil :align right :getter (lambda (object _table) (activities-activity-name object)) :formatter nil :displayer nil :-numerical t) #s(vtable-column :name "Last saved" :width nil :min-width nil :max-width nil :primary nil :align right :getter (lambda (activity _table) (or (map-elt (activities-activity-state-etc (activities-activity-last activity)) 'time) 0)) :formatter activities-list--format-time :displayer nil :-numerical t) #s(vtable-column :name "Default saved" :width nil :min-width nil :max-width nil :primary nil :align right :getter (lambda (activity _table) (or (map-elt (activities-activity-state-etc (activities-activity-default activity)) 'time) 0)) :formatter activities-list--format-time :displayer nil :-numerical t)))
seq-map-indexed(#f(compiled-function (column index) #<bytecode -0x1ca768627d88b573>) (#s(vtable-column :name "Active" :width nil :min-width nil :max-width nil :primary descend :align right :getter (lambda (object _table) (if (activities-activity-active-p object) "" " ")) :formatter nil :displayer nil :-numerical t) #s(vtable-column :name "Name" :width nil :min-width nil :max-width nil :primary nil :align right :getter (lambda (object _table) (activities-activity-name object)) :formatter nil :displayer nil :-numerical t) #s(vtable-column :name "Last saved" :width nil :min-width nil :max-width nil :primary nil :align right :getter (lambda (activity _table) (or (map-elt (activities-activity-state-etc (activities-activity-last activity)) 'time) 0)) :formatter activities-list--format-time :displayer nil :-numerical t) #s(vtable-column :name "Default saved" :width nil :min-width nil :max-width nil :primary nil :align right :getter (lambda (activity _table) (or (map-elt (activities-activity-state-etc (activities-activity-default activity)) 'time) 0)) :formatter activities-list--format-time :displayer nil :-numerical t)))
vtable--compute-widths(# nil)
vtable--recompute-cache(#)
vtable--ensure-cache(#)
vtable-insert(#)
make-vtable(:columns ((:name "Active" :primary descend :getter (lambda (object _table) (if (activities-activity-active-p object) "
" " "))) (:name "Name" :getter (lambda (object _table) (activities-activity-name object))) (:name "Last saved" :getter (lambda (activity _table) (or (map-elt (activities-activity-state-etc (activities-activity-last activity)) 'time) 0)) :formatter activities-list--format-time) (:name "Default saved" :getter (lambda (activity _table) (or (map-elt (activities-activity-state-etc (activities-activity-default activity)) 'time) 0)) :formatter activities-list--format-time)) :objects-function #f(compiled-function () #<bytecode 0x1980f6ff483e>) :sort-by ((2 . ascend) (0 . descend)) :actions ("q" (lambda (&rest _) (bury-buffer)) "n" (lambda (&rest _) (forward-line 1)) "p" (lambda (&rest _) (forward-line -1)) "RET" #f(compiled-function (&rest args) #<bytecode 0xbe6dddefbe4b752>) "k" #f(compiled-function (&rest args) #<bytecode 0xbe6ddd48725af52>) "s" #f(compiled-function (&rest args) #<bytecode 0xbe6ddd487256352>) "D" #f(compiled-function (&rest args) #<bytecode 0xbe6ddd7899e4352>)))
activities-list()
funcall-interactively(activities-list)
command-execute(activities-list)

Add example to wiki of writing simple bookmark functions for modes not having them

Is there some before/after hook I can hook a function into before the bookmark is opened?

I would like to restore a Sly session, with sbcl and a custom saved image. I am thinking of:

open bookmarked asdf file or at least project directory
start sly with a given compiler (I have different builds of sbcl) and saved core image

I haven't looked much at the code; I have just installed it and played a bit with it, so I am not very familiar with it. I see the activities--bookmark-buffer function.; or in activites--serialize/deserialize?

I could then add something to before (deserialize) hook to run Sly and wait until repl is up and running.

Or perhaps there is already a better place or a better way?

Compilation warning about buffer-local-value

During M-x package-install activities.el, I got the following warnings:

In toplevel form:
activities-list.el: Warning: `buffer-local-value' is an obsolete generalized variable.

In toplevel form:
activities.el:653:34: Warning: `buffer-local-value' is an obsolete generalized variable.

I investigated a bit, and it seems like `buffer-local-value has been made obsolete with Emacs 29.1 (found within NEWS):

Many seldom-used generalized variables have been made obsolete.

Emacs has a number of rather obscure generalized variables defined, […]
[…]
These never caught on and have been made obsolete. […]

The following generalized variables have been made obsolete:
'buffer-file-name', 'buffer-local-value', […] [emphasis mine]

This seems to affect the following loop:

              (cl-loop for (variable . value) in local-variable-map
                       do (setf (buffer-local-value variable (current-buffer)) value))))

I'm not too familiar with buffer-local-variables set without setq-local, but

              (cl-loop for (variable . value) in local-variable-map
                       do (set (make-local-variable variable) value))))

might already fix that?

Hope that helps!

Enable wiki to share community accomplishments?

As title mentions. And allow me to be the first one to share my accomplishment of creating a simple hydra menu for quicker access to activities many useful functions!

Preview:
Workspace 2024-02-04 22:19:35

Requirements:

Snippet to create the titles of our pretty-hydra's:

Note

I do not recall where I got this snippet from but the credits belong to the original author who wrote this snippet!

(cl-defun pretty-hydra-title (title &optional icon-type icon-name
                                      &key face height v-adjust)
    "Add an icon to our pretty-hydra title(s)."
    (let ((face (or face `(:inherit hydra-face-pink :height 1.2 :slant italic)))
          (height (or height 1.2))
          (v-adjust (or v-adjust 0.0)))
      (concat
       (when (and (display-graphic-p) icon-type icon-name)
         (let ((f (intern (format "nerd-icons-%s" icon-type))))
           (when (fboundp f)
             (concat
              (apply f (list icon-name :face face :height height :v-adjust v-adjust))
              "  "))))
       (propertize title 'face face))))
(with-eval-after-load 'pretty-hydra
  (pretty-hydra-define activities-hydra
    (:title (pretty-hydra-title "──r Utilities: Activities 」──" 'mdicon "nf-md-file_tree")
            :color teal :quit-key "q")
    ("Main"
     (("l"   activities-list   "List")
      ("RET" activities-switch "Switch"))
     "Working"
     (("n"   activities-new     "Create")
      ("k"   activities-kill    "Kill")
      ("u"   activities-revert  "Revert"))
     "Breaktime"
     (("s"   activities-suspend "Suspend")
      ("r"   activities-resume  "Resume")))))

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.