TatriX / pomidor

Pomidor is a simple and cool pomodoro technique timer.
239 stars 17 forks source link

Some config tricks others may find useful #57

Closed mcrosson closed 1 month ago

mcrosson commented 1 month ago

Not A Bug

This is not a bug report.

I setup pomidor to be run in a few different ways and wanted to share the config so others wouldn't have to re-create things from scratch if they have similar needs.

What's Below?

As I've spent time with pomidor, I discovered I needed a couple different ways to work with pomidor as well as a few helper functions and tweaks.

The below config snippets are what I was able to put together for my different use cases and needs.

Full config

If you'd like to see my full pomidor config; I've published the full code here.

Invoke pomidor without resetting existing state

As I worked to setup different ways of interacting with pomidor I noticed that the state can be reset when it's invoked via the (pomidor) function if it's already running.

Since I want only a single instance of pomidor running and no automatic state resets but I do want it invoked it not already running, I setup a function to manage this programatically.

This function also calls (previous-buffer) as I generally don't want pomidor to take over the current, active buffer. Remove this line of code if you are ok with pomidor taking over the current, active buffer.

; safely run pomidor in a buffer programatically
;    doesnt mung or reset state
(defun my-pomidor-run-safe ()
  ; make sure pomidor is running + active w/o resetting the current state
  (when (or (not (boundp 'pomidor-buffer-name))
            (not (get-buffer pomidor-buffer-name)))
    (pomidor)
    (previous-buffer) ; pomidor switches buffers -- go back to orig buffer
  )
)

Buffer cursor positioning

I've been running pomidor in a small, dedicated frame (smaller than the full pomidor output) a lot and the rendering puts the cursor at the end of the buffer (when the frame is active) which can be problematic when I click into the frame to use hot keys like 'hold' and 'un-hold' of the active session.

To make it a bit easier to work with a small frame holding pomidor, I setup a function that's called after pomidor renders to always position the cursor at the start of the buffer. This allows me to always see the timer. If I need to see 'more', I'll use a different way of viewing pomidor. The different methods I use to view pomodor are described below.

; position cursor @ top of pomidor buffer after rendering
(defun my-pomidor-beginning-of-buffer (buffer states)
  (interactive)
  (with-current-buffer (get-buffer pomidor-buffer-name)
    (goto-char (point-min))
  )
)
(advice-add #'pomidor--render :after #'my-pomidor-beginning-of-buffer)

Warmup interval

I have a hard time 'getting into' a task which can be incredibly frustrating as pomodoro timers 'keeps going' even though I'm actively working to get under way with a task and it feels like I'm wasting my session. I don't want this warm up period to 'count against' my focused work time. Instead of trying to monkey patch another state into pomidor, I setup a custom separator so I can tell the 'warmup period' and 'focused work period' apart from each other. This also allows me to get a little extra focused work in if my warm up is complete prior to the timeout.

I will also use this warmup period to peform mini tasks like 'respond to email and chat' to clear small items that may have piled up during prior sessions.

(setq pomidor-warmup-seconds (* 15 60)) ; warmup time
; setup 'warmup period' functionality
(defun my-pomidor-update-hook ()
  (let* ((state (pomidor--current-state))
         (total (pomidor--total-duration state))
         (ellapsed (round (time-to-seconds total))))
      (if (<= ellapsed pomidor-warmup-seconds)
        (setq pomidor-header-separator " 🌡️↑ ")
        (setq pomidor-header-separator " — ")
      )
  )
)
(add-hook 'pomidor-update-hook #'my-pomidor-update-hook)

Dedicated timer frame

I try to keep the pomidor timer 'always on top' in my GUI environments (Windows 11 in particular). I position it at the bottom, center of my primary monitor (I have multiple monitors). I use this as a kind of overview of the current session with just the timer shown.

I use an external utility (Power Toys - Always On Top in Windows) to mark the frame as always on top of other windows. This is important as I usually have windows overlapping with the pomidor timer frame.

; frame for pomidor, just the main timer text visible
;   centered at bottom of the screen
(defun my-pomidor-frame ()
  (interactive)
  (select-frame (make-frame '(
    (name . "Pomidor")
    (menu-bar-lines 0)
    (tool-bar-lines 0)
    (width . (text-pixels . 818))
    (height . (text-pixels . 144))
  )))
  ; single monitor / main monitor positing
  (let* ((dw (display-pixel-width))
         (dh (display-pixel-height))
         (f  (selected-frame))
         (fw (frame-pixel-width f))
         (fh (frame-pixel-height f))
         (x  (- (/ dw 2) (/ fw 2)))
         (y  (- (- dh fh ) 100)))
    (set-frame-position f x y)
  )
  ; ensure pomidor is running & do /not/ reset state
  (my-pomidor-run-safe)
  ; switch to pomidor buffer
  (switch-to-buffer pomidor-buffer-name)
)
(global-set-key (kbd "C-M-p") 'my-pomidor-frame) ; adjust key binding as appropriate

Pop up window

There are times I want to see 'more' of pomidor than just the timer text and to quickly get status information and/or interact with the buffer. I setup popwin to show the buffer as a sticky pop up window that I can show/hide freely.

This allows me to pop up the pomidor buffer from anywhere within my emacs window layout to see more information than just the current timer and to interact with the pomidor buffer (hold/un-hold in particular).

; pop win pomidor setup
;   main way to invoke
;   ensure pomidor is running before trying to open the buffer
;   use global buffer name for pomidor
;   make the popwin window 'sticky'
;   position sticky popwin @ top
(push '(pomidor-mode :position top :stick t) popwin:special-display-config) ; use major mode as the buffer name won't be set when emacs evaluates this portion of the config if you don't `setq` the buffer name as part of your config
(global-set-key (kbd "C-w p") ; adjust key binding as appropriate
  (lambda () (interactive)
    (my-pomidor-run-safe)
    ; open pomidor in popwin
    (popwin:display-buffer (get-buffer pomidor-buffer-name))
  )
)
TatriX commented 1 month ago

Hi! Perhaps let's create a wiki page and then mention it in README?

mcrosson commented 1 month ago

That would be great. Is there anything you'd need/want from me when creating the page?

TatriX commented 1 month ago

I've copied your post over there: https://github.com/TatriX/pomidor/wiki/Tips-and-Tricks Feel free to edit it however you see fit. Thank you for the contribution!