diff --git a/notibox.el b/notibox.el index 945ab57..6ae3a64 100644 --- a/notibox.el +++ b/notibox.el @@ -59,9 +59,10 @@ If STACKDEPTH is non-nil and nonzero, return a position that far down." (let* ( ;; need to not overlap the gtk scrollbar (scrollbar-width (or (if (eq x-toolkit-scroll-bars 'gtk) - 30) ; wild guess... + 30) ; educated guess... 0)) - (stackdepth (or stackdepth 0)) + ;; (stackdepth (or stackdepth 0)) + (stackdepth 0) ; we do not care actually (parent-width (frame-pixel-width)) (child-width (* notibox-width (string-pixel-width " "))) (parent-height (frame-pixel-height)) @@ -86,8 +87,8 @@ If STACKDEPTH is non-nil and nonzero, return a position that far down." ;; (notibox--get-position 3) (defun notibox--prepare-buffer (title body &optional buffer) - "Populate the `*notibox*' buffer (or BUFFER if specified) with TITLE and BODY properly formatted." - (let ((buf (get-buffer-create (or buffer "*notibox*")))) + "Return the notibox buffer containing TITLE and BODY, properly formatted" + (let ((buf (get-buffer-create (format " *notibox-- %s: %s *" title body)))) (with-current-buffer buf (let ((inhibit-read-only t)) (erase-buffer) @@ -95,7 +96,8 @@ If STACKDEPTH is non-nil and nonzero, return a position that far down." title (propertize (make-string notibox-width ?─) 'face `((:foreground ,notibox-border-color))) - body)))))) + body)))) + buf)) ;; (notibox--prepare-buffer "test" "this better work gadahgit" (or nil "*notibox-2*")) ;; (get-buffer-create "*notibox-2*") ;; wait, we need to be actually basing the things on the buffers huh @@ -103,19 +105,26 @@ If STACKDEPTH is non-nil and nonzero, return a position that far down." (defvar notibox-current-posframes nil) (cl-defun notibox--show (&key timeout &key depth &key buf) "Show the notibox currently prepared, with optional TIMEOUT, at DEPTH, in BUF." - (add-to-list 'notibox-current-posframes - (let ((buffer (get-buffer-create (or buf "*notibox*")))) - (posframe-show buffer - :position (notibox--get-position depth) - :left-fringe 0 - :right-fringe 0 - :max-width notibox-width - :max-height notibox-height - :min-width notibox-width - :min-height notibox-height - :border-width 2 - :border-color notibox-border-color - :timeout timeout))) + (let ((this-notibox + (let ((buffer (get-buffer-create (or buf "*notibox*")))) + (posframe-show buffer + :position (notibox--get-position depth) + :left-fringe 0 + :right-fringe 0 + :max-width notibox-width + :max-height notibox-height + :min-width notibox-width + :min-height notibox-height + :border-width 2 + :border-color notibox-border-color + ;; :timeout timeout + )) + )) + (run-with-timer timeout nil #'notibox-delete this-notibox) + (mir/push-notibox this-notibox) + ;; (add-to-list 'notibox-current-posframes + ;; this-notibox) + ) nil) (defun notibox-alert (info) @@ -124,9 +133,10 @@ If STACKDEPTH is non-nil and nonzero, return a position that far down." (title (plist-get info :title)) (timeout (plist-get info :persistent)) (depth (plist-get info :depth))) - (notibox--prepare-buffer title message) + ;; gotta make it move the others down... (notibox--show :timeout (unless timeout alert-fade-time) - :depth (or depth (- (length notibox-current-posframes) 1))))) + ;; :depth (or depth (- (length notibox-current-posframes) 1)) + :buf (notibox--prepare-buffer title message)))) (defun notibox--resolve-frame (object) "Return the /frame reference/ signified by OBJECT, whatever it may be." @@ -144,7 +154,7 @@ If STACKDEPTH is non-nil and nonzero, return a position that far down." (defun notibox--hide (frame) "Stop showing FRAME." (if (frame-live-p frame) - (posframe-hide (window-buffer (frame-selected-window frame))))) + (posframe-delete (window-buffer (frame-selected-window frame))))) (defun notibox-delete (frame) "Delete the notibox FRAME. @@ -178,14 +188,17 @@ If the source is not obvious, use `current-buffer'." (2 (progn (setq source (car splooted)) (setq contents (cadr splooted)))) + (3 (progn + (setq source (car splooted)) + (setq contents (format "%s: %s" (cadr splooted) (caddr splooted))))) ) ;; (message "[debug] message: %s" msg) (cons source contents))) ;; (split-string "evil-forward-character: End of line" ": ") ;; (length '("evil-forward-character" "end of line")) ;; (split-string "this is a valid message" ": ") -;; (notibox--parse-message "evil-forward-char: End of line") -;; (notibox--parse-message "this is a badly formed message") +;; (message "evil-forward-char: End of line") +;; (message "%s" 'this\:\ is\ a\ \"badly\:\ formed\ message\") (defun buflast (buffer) "Return the last line of BUFFER as a string, without linebreaks." (with-current-buffer buffer @@ -194,22 +207,27 @@ If the source is not obvious, use `current-buffer'." (buffer-substring-no-properties (point-at-bol) (point-max))))) ;; (buflast (get-buffer "*Messages*")) +(defvar last-message nil + "Previous value of `current-message', stored for notibox.") (defun notibox--tail-echoarea () "Show `current-message' in the notibox. If that does not exist, probably hide it." (if (current-message) - (let* ((notibox-border-color "#0faa0f") ; hacky, can we set it elsewhere? - (parsed-msg - (notibox--parse-message - ;; (current-message) - (buflast (get-buffer "*Messages*")) ; workaround for abbreviated stuff - )) - (title (car parsed-msg)) - (contents (cdr parsed-msg))) - (notibox-alert `( :title ,title - :message ,contents - :depth 0))) - (if notibox-current-posframes - (notibox-delete (car notibox-current-posframes)))) + (unless (string= last-message (current-message)) + (let* ((notibox-border-color "#0faa0f") ; hacky, can we set it elsewhere? + (parsed-msg + (notibox--parse-message + ;; (current-message) + (buflast (get-buffer "*Messages*")) ; workaround for abbreviated stuff + )) + (title (car parsed-msg)) + (contents (cdr parsed-msg))) + (notibox-alert `( :title ,title + :message ,contents + ))) + (setq last-message (current-message))) + ;; (if notibox-current-posframes + ;; (notibox-delete (car notibox-current-posframes))) + ) ) (defun notibox/setup-timer () @@ -221,23 +239,34 @@ If the source is not obvious, use `current-buffer'." (defun notibox-test-alert () "Show a sample notibox to prove we can." (interactive) - (notibox-alert '(:title "five" :message "six"))) -;; (notibox-alert '(:title "一" :message "二" :timeout 5 :depth 0)) + (notibox-alert `(:title ,(random 8096) :message "test of notibox"))) +;; (notibox-test-alert) +;; (notibox-alert '(:title "一" :message "二" :timeout 5)) +;; (notibox-alert '(:title "三" :message "四" :timeout 5)) +;; wanna watch the variable. how do we do that +(add-variable-watcher 'notibox-current-posframes + (lambda (symbol newval operation where) + "Display the variable in *watched* buffer." + (with-current-buffer (get-buffer-create "*watched*") + (goto-char (point-max)) + (insert + (format "\n%s:\n was: %s\n now: %s" + symbol + (eval symbol) + newval))) + )) +(--map (remove-variable-watcher 'notibox-current-posframes it) + (get-variable-watchers 'notibox-current-posframes)) ;; begin frame moving experiments. thought we already did this... -(setq test-frame (posframe-show "*Messages*" - :position '(800 . 50) - :width 30 - :height 16)) (defun mir/move-frame (frame pos) "Move FRAME to POS, a cons of (top . left)." - (modify-frame-parameters frame - `( - (top . ,(car pos)) - (left . ,(cdr pos)) - ))) -;; (frame-parameters test-frame) -;; (mir/move-frame test-frame '(300 . 1200)) + (if (frame-live-p frame) + (modify-frame-parameters frame + `( + (top . ,(car pos)) + (left . ,(cdr pos)) + )))) (defvar mir/framove-update-interval 0.05 "How many seconds to wait before updating incremental frame positions.") @@ -282,8 +311,35 @@ intermediate positions are calculated via `mir/framove-update-interval'." ) nil ) -;; (mir/framove-gradual test-frame '(500 . 1400) 1) -;; (mir/move-frame test-frame '(500 . 500)) + +(defun mir/notibox-down-one (frame) + "Move FRAME down by `notibox-padding'." + (if (frame-live-p frame) + (let* ((parms (frame-parameters frame)) + (old-y (alist-get 'top parms)) + (old-x (alist-get 'left parms))) + (mir/framove-gradual frame (cons + (+ old-y ;; (- (* notibox-height + ;; (window-text-height)) + ;; notibox-padding) + (/ + (+ (* (window-text-height) notibox-height) + notibox-padding) + 2)) + old-x + ) 0.125)))) +;; (notibox-test-alert) +(defun notibox-test-message () + "Send a message and see if it gets picked up by notibox." + (message "test message %s: %s is a number" (random 40) (random 500))) +;; (notibox-test-message) + +(defun mir/push-notibox (frame) + "Push FRAME onto `notibox-current-posframes' and display it at the top of the stack." + (--map (mir/notibox-down-one it) ; move each by the interval - need more infra first + (reverse notibox-current-posframes)) + (push frame notibox-current-posframes) + ) (provide 'notibox) ;;; notibox.el ends here