Modeline cleanup, agenda bindings, dynamic tab helpers etc
This commit is contained in:
parent
e381030890
commit
0edb7ab98f
|
|
@ -3,4 +3,4 @@
|
|||
This is a modernised GNU Emacs Configuration, an evolution of my old emacs configuration:
|
||||
`https://git.cspark.dev/cspark/Emacs-Configuration`
|
||||
|
||||
It is intended to be more focused and clean, using modern more modular/simpler packages or the builtins.
|
||||
Using more modern packages (Switching from company, lsp mode, EXWM to consult/vertico, eglot mode, EWM for example) and personal built emacs lisp.
|
||||
|
|
|
|||
180
init.el
180
init.el
|
|
@ -61,6 +61,14 @@
|
|||
(`(:propertize (,_ minor-mode-alist . ,_) . ,_) "")
|
||||
(t elem)))
|
||||
mode-line-modes))
|
||||
; Hide other items
|
||||
(line-number-mode -1)
|
||||
(column-number-mode -1)
|
||||
(setq mode-line-percent-position nil)
|
||||
(with-eval-after-load 'evil
|
||||
(setq evil-mode-line-format nil))
|
||||
; Emacs 31 feature only - Collapse minor modes into one
|
||||
(setq mode-line-collapse-minor-modes '(not))
|
||||
|
||||
;; Clipboard config
|
||||
(setopt select-active-regions nil)
|
||||
|
|
@ -204,6 +212,7 @@
|
|||
(evil-define-key* '(normal) org-mode-map (kbd "M-h") nil)
|
||||
(evil-define-key* '(normal) org-mode-map (kbd "M-l") nil)))
|
||||
(with-eval-after-load 'org-agenda
|
||||
(with-eval-after-load 'evil
|
||||
(setq org-agenda-files '("~/Nextcloud/Agenda"))
|
||||
;This is will integrate the Calendar/Diary into Org-Agenda, so you can get access to dates on public holidays etc. Set diary to true:
|
||||
(setq org-agenda-include-diary t)
|
||||
|
|
@ -219,15 +228,30 @@
|
|||
;Autostart in day view
|
||||
(setq org-agenda-span 'day)
|
||||
|
||||
;Auto save agenda buffers on refresh
|
||||
(advice-add 'org-agenda-redo :before #'org-save-all-org-buffers)
|
||||
|
||||
(add-hook 'org-agenda-mode-hook #'(lambda ()
|
||||
(org-agenda-entry-text-mode 1)))
|
||||
|
||||
(define-key org-agenda-mode-map (kbd "C-j") 'evil-next-line)
|
||||
(define-key org-agenda-mode-map (kbd "C-k") 'evil-previous-line)
|
||||
(define-key org-agenda-mode-map "d" 'org-agenda-toggle-day-view)
|
||||
(define-key org-agenda-mode-map "p" 'org-pomodoro))
|
||||
(define-key org-agenda-mode-map (kbd "C-j") 'org-agenda-goto-date)
|
||||
(define-key org-agenda-mode-map "j" 'evil-next-line)
|
||||
(define-key org-agenda-mode-map "k" 'evil-previous-line)
|
||||
|
||||
; For Org Pomodoro notification sound
|
||||
(define-key org-agenda-mode-map (kbd "V") nil)
|
||||
(define-key org-agenda-mode-map (kbd "V") 'evil-visual-line)
|
||||
|
||||
(define-key org-agenda-mode-map "g" nil)
|
||||
(define-key org-agenda-mode-map (kbd "g g") 'evil-goto-first-line)
|
||||
(define-key org-agenda-mode-map (kbd "G") 'evil-goto-line)
|
||||
|
||||
(define-key org-agenda-mode-map "s" 'org-agenda-schedule)
|
||||
(define-key org-agenda-mode-map "d" 'org-agenda-schedule)
|
||||
|
||||
(define-key org-agenda-mode-map (kbd "C-d") 'org-agenda-toggle-day-view)
|
||||
(define-key org-agenda-mode-map "p" 'org-pomodoro)))
|
||||
|
||||
; For Org Pomodoro notification sound
|
||||
(use-package sound-wav
|
||||
:ensure t
|
||||
:demand t)
|
||||
|
|
@ -236,13 +260,13 @@
|
|||
"Play a sound notification and show message ALERT."
|
||||
(sound-wav-play (expand-file-name (concat user-emacs-directory "elpaca/builds/org-pomodoro/resources/bell.wav")))
|
||||
(message alert))
|
||||
; Org timer custom alert
|
||||
; Org timer custom alert
|
||||
(defun org-timer-sound-alert ()
|
||||
"Sound notification on org timer finish."
|
||||
(sound-alert "Timer done!"))
|
||||
(add-hook 'org-timer-done-hook 'org-timer-sound-alert))
|
||||
|
||||
; Org Pomodoro
|
||||
; Org Pomodoro
|
||||
(use-package org-pomodoro
|
||||
:ensure t
|
||||
:after (org org-agenda sound-wav)
|
||||
|
|
@ -260,7 +284,7 @@
|
|||
:title "Custom Notification"
|
||||
:notifier
|
||||
(lambda (info)
|
||||
; 'info' is a plist containing :title, :message, :severity, etc.
|
||||
; 'info' is a plist containing :title, :message, :severity, etc.
|
||||
(notifications-notify
|
||||
:title "Emacs Alert"
|
||||
:body (plist-get info :message))
|
||||
|
|
@ -269,7 +293,7 @@
|
|||
(plist-get info :message)))))
|
||||
(setq alert-default-style 'custom-org-alert-notification))
|
||||
|
||||
; System notifications of org agenda items
|
||||
; System notifications of org agenda items
|
||||
(use-package org-wild-notifier
|
||||
:ensure t
|
||||
:after org-agenda
|
||||
|
|
@ -289,14 +313,14 @@
|
|||
(setq org-wild-notifier-extra-alert-plist '(:persistent t))
|
||||
(org-wild-notifier-mode))
|
||||
|
||||
; Upcoming agenda items in modeline
|
||||
; Upcoming agenda items in modeline
|
||||
(use-package org-upcoming-modeline
|
||||
:ensure t
|
||||
:after org-agenda ; if you don't want it to start until org has been loaded
|
||||
:after org-agenda
|
||||
:config
|
||||
(org-upcoming-modeline-mode))
|
||||
|
||||
; Org Mode Journalling
|
||||
; Org Mode Journalling
|
||||
(use-package org-journal
|
||||
:ensure t
|
||||
:after org-agenda
|
||||
|
|
@ -306,7 +330,7 @@
|
|||
(setq org-journal-file-format "%Y%m%d.org"))
|
||||
|
||||
;; Org Latex Preview Scale
|
||||
; Automatically toggle Org mode LaTeX fragment previews as the cursor enters and exits them
|
||||
; Automatically toggle Org mode LaTeX fragment previews as the cursor enters and exits them
|
||||
(use-package org-fragtog
|
||||
:ensure t
|
||||
:after org
|
||||
|
|
@ -741,12 +765,17 @@
|
|||
(setq emms-source-file-directory-tree-function 'emms-source-file-directory-tree-find)
|
||||
(setq emms-cache-set-all-from-mpd t)
|
||||
|
||||
(setq emms-browser-makes-thumbnails t)
|
||||
(setq emms-browser-thumbnail-small-width 100)
|
||||
|
||||
(setq emms-mode-line-length-limit 20)
|
||||
|
||||
(emms-all)
|
||||
(emms-player-mpd-connect)
|
||||
(add-hook 'emms-playlist-cleared-hook 'emms-player-mpd-clear)
|
||||
|
||||
(setq emms-player-list '(emms-player-mpd))
|
||||
(setq emms-player-mpd-supported-regexp ".")
|
||||
(setq emms-player-mpd-supported-regexp "\\`http[s]?://\\|\\.\\([Mm]3[Uu]\\|[Oo][Gg][Gg]\\|[Ff][Ll][Aa][Cc]\\|[Mm][Pp]3\\|[Ww][Aa][Vv]\\|[Mm][Oo][Dd]\\|[Aa][Uu]\\|[Aa][Ii][Ff][Ff]\\|[Oo][Pp][Uu][Ss]\\)\\'")
|
||||
(add-to-list 'emms-info-functions 'emms-info-mpd)
|
||||
|
||||
(define-key emms-playlist-mode-map (kbd "d") nil)
|
||||
|
|
@ -1053,7 +1082,7 @@
|
|||
(setq tab-bar-show 1) ; Hide the bar if only 1 tab exists
|
||||
(setq tab-bar-new-tab-choice "*scratch*")
|
||||
|
||||
(defun dynamic-tab-ensure-scratch-tab (&rest _)
|
||||
(defun dynamic-tab--ensure-scratch-tab (&rest _)
|
||||
"Ensure dynamic scratch tab available if there are active buffers."
|
||||
(let* ((tabs (funcall tab-bar-tabs-function))
|
||||
(tab-names (mapcar (lambda (tab) (alist-get 'name tab)) tabs))
|
||||
|
|
@ -1081,28 +1110,28 @@
|
|||
;; Return to original tab if we were just initializing
|
||||
(tab-bar-select-tab (1+ current-tab))))))
|
||||
|
||||
(defvar dynamic-tab-is-already-redirecting-p nil
|
||||
(defvar dynamic-tab--is-already-redirecting-p nil
|
||||
"Whether we are already redirecting to scratch tab or not.")
|
||||
(defun dynamic-tab-redirect-to-scratch-tab ()
|
||||
(defun dynamic-tab--redirect-to-scratch-tab ()
|
||||
"Redirect to dedicated scratch tab if scratch buffer accessed on other tab."
|
||||
(when (and (not dynamic-tab-is-already-redirecting-p)
|
||||
(when (and (not dynamic-tab--is-already-redirecting-p)
|
||||
(string= (buffer-name) "*scratch*")
|
||||
(string= (buffer-name) "dynamic *scratch*"))
|
||||
(setq dynamic-tab-is-already-redirecting-p t)
|
||||
(setq dynamic-tab--is-already-redirecting-p t)
|
||||
(unwind-protect
|
||||
(switch-to-buffer nil)
|
||||
(tab-bar-select-tab-by-name "dynamic *scratch*")
|
||||
(setq dynamic-tab-is-already-redirecting-p nil))))
|
||||
(setq dynamic-tab--is-already-redirecting-p nil))))
|
||||
|
||||
(defvar dynamic-tab-soft-kill-p nil
|
||||
(defvar dynamic-tab--soft-kill-p nil
|
||||
"When t, do not kill buffers only send them to background unless one tab open.")
|
||||
(defun dynamic-tab-handle-buffer-check-and-close-tab ()
|
||||
(defun dynamic-tab--handle-buffer-check-and-close-tab ()
|
||||
"Check if we need to close the tab and action accordingly."
|
||||
(let* ((is-last-tab (<= (length (tab-bar-tabs)) 2))
|
||||
(is-last-buffer (<= (length (tab-line-tabs-window-buffers)) 1)))
|
||||
(when (and (not is-last-tab) is-last-buffer)
|
||||
(tab-close))))
|
||||
(defun dynamic-tab-handle-tab-cleanup-kill ()
|
||||
(defun dynamic-tab--handle-tab-cleanup-kill ()
|
||||
"Check if we can kill buffer and free tab if no more reserved buffers in tab."
|
||||
(let* ((is-last-tab (<= (length (tab-bar-tabs)) 2))
|
||||
(is-last-buffer (<= (length (tab-line-tabs-window-buffers)) 2))
|
||||
|
|
@ -1111,27 +1140,27 @@
|
|||
;((and is-last-tab (not is-last-buffer)) t)
|
||||
;((and is-last-tab (not is-last-buffer) (bury-buffer)))
|
||||
|
||||
((and (not is-last-tab) (not is-last-buffer) dynamic-tab-soft-kill-p) (bury-buffer))
|
||||
((and (not is-last-tab) (not is-last-buffer) dynamic-tab--soft-kill-p) (bury-buffer))
|
||||
|
||||
(t t))))
|
||||
|
||||
(dynamic-tab-handle-buffer-check-and-close-tab)
|
||||
(dynamic-tab--handle-buffer-check-and-close-tab)
|
||||
is-marked-to-kill))
|
||||
|
||||
(defun dynamic-tab-block-buffer-kill ()
|
||||
(defun dynamic-tab--block-buffer-kill ()
|
||||
"Block buffer from being killed."
|
||||
(message "You cannot kill the dynamic buffer")
|
||||
nil)
|
||||
(defun dynamic-tab-mark-buffer-unkillable ()
|
||||
(defun dynamic-tab--mark-buffer-unkillable ()
|
||||
"Mark buffer as unkillable."
|
||||
(add-hook 'kill-buffer-query-functions #'dynamic-tab-block-buffer-kill nil t))
|
||||
(defun dynamic-tab-mark-buffer-reserved ()
|
||||
(add-hook 'kill-buffer-query-functions #'dynamic-tab--block-buffer-kill nil t))
|
||||
(defun dynamic-tab--mark-buffer-reserved ()
|
||||
"Mark buffer as reserved."
|
||||
(add-hook 'kill-buffer-query-functions #'dynamic-tab-handle-tab-cleanup-kill nil t))
|
||||
(defun dynamic-tab-unmark-buffer-reserved ()
|
||||
(add-hook 'kill-buffer-query-functions #'dynamic-tab--handle-tab-cleanup-kill nil t))
|
||||
(defun dynamic-tab--unmark-buffer-reserved ()
|
||||
"Unmark buffer as reserved."
|
||||
(remove-hook 'kill-buffer-query-functions #'dynamic-tab-handle-tab-cleanup-kill t))
|
||||
(defun dynamic-tab-refresh-listeners ()
|
||||
(remove-hook 'kill-buffer-query-functions #'dynamic-tab--handle-tab-cleanup-kill t))
|
||||
(defun dynamic-tab--refresh-listeners ()
|
||||
"Refresh hooks to listen on reserved buffers."
|
||||
(dolist (buf (tab-line-tabs-window-buffers))
|
||||
(with-current-buffer buf
|
||||
|
|
@ -1142,33 +1171,57 @@
|
|||
(cond
|
||||
(is-child-buffer nil)
|
||||
(is-mini-buffer nil)
|
||||
(is-dynamic-buffer (dynamic-tab-mark-buffer-unkillable))
|
||||
(is-scratch-buffer (dynamic-tab-mark-buffer-unkillable))
|
||||
(is-dynamic-buffer (dynamic-tab--mark-buffer-unkillable))
|
||||
(is-scratch-buffer (dynamic-tab--mark-buffer-unkillable))
|
||||
|
||||
(t (dynamic-tab-mark-buffer-reserved)))))))
|
||||
(defun dynamic-tab-remove-listeners ()
|
||||
(t (dynamic-tab--mark-buffer-reserved)))))))
|
||||
(defun dynamic-tab--remove-listeners ()
|
||||
"Remove all hooks on reserved buffers."
|
||||
(dolist (buf (buffer-list))
|
||||
(with-current-buffer buf
|
||||
(dynamic-tab-unmark-buffer-reserved))))
|
||||
(dynamic-tab--unmark-buffer-reserved))))
|
||||
|
||||
(defvar dynamic-tab-last-buffer nil)
|
||||
(defun dynamic-tab-handle-buffer-switch (&rest _)
|
||||
(defvar dynamic-tab--last-buffer nil)
|
||||
(defun dynamic-tab--handle-buffer-switch (&rest _)
|
||||
"Checks to run when buffer is switched."
|
||||
(unless (eq (current-buffer) dynamic-tab-last-buffer)
|
||||
(setq dynamic-tab-last-buffer (current-buffer))
|
||||
(unless (eq (current-buffer) dynamic-tab--last-buffer)
|
||||
(setq dynamic-tab--last-buffer (current-buffer))
|
||||
;; Put your "on switch" logic here
|
||||
(dynamic-tab-ensure-scratch-tab)
|
||||
(dynamic-tab-redirect-to-scratch-tab)))
|
||||
(defun dynamic-tab-handle-buffer-create (&rest _)
|
||||
(dynamic-tab--ensure-scratch-tab)
|
||||
(dynamic-tab--redirect-to-scratch-tab)))
|
||||
(defun dynamic-tab--handle-buffer-create (&rest _)
|
||||
"Checks to run when buffer is created."
|
||||
(dynamic-tab-ensure-scratch-tab)
|
||||
(dynamic-tab-refresh-listeners))
|
||||
(dynamic-tab--ensure-scratch-tab)
|
||||
(dynamic-tab--refresh-listeners))
|
||||
|
||||
(defun dynamic-tab-init ()
|
||||
"Initialise dynamic tabs."
|
||||
(add-hook 'window-buffer-change-functions #'dynamic-tab-handle-buffer-switch)
|
||||
(add-hook 'after-change-major-mode-hook #'dynamic-tab-handle-buffer-create))
|
||||
(add-hook 'window-buffer-change-functions #'dynamic-tab--handle-buffer-switch)
|
||||
(add-hook 'after-change-major-mode-hook #'dynamic-tab--handle-buffer-create))
|
||||
|
||||
(defun dynamic-tab-move-tab-left ()
|
||||
"Move tab left, no wrapping or moving the dedicated dynamic tab."
|
||||
(let* ((is-first-tab (= (tab-bar--current-tab-index) 0))
|
||||
(is-dynamic-tab-focused (string= (alist-get 'name (tab-bar--current-tab)) "dynamic *scratch*")))
|
||||
(when (and (not is-first-tab)
|
||||
(not is-dynamic-tab-focused))
|
||||
(tab-bar-move-tab-backward))))
|
||||
(defun dynamic-tab-move-tab-right ()
|
||||
"Move tab right, no wrapping or moving past the dedicated dynamic tab."
|
||||
(let* ((is-last-tab (= (tab-bar--current-tab-index) (- (length (tab-bar-tabs)) 2)))
|
||||
(is-dynamic-tab-focused (string= (alist-get 'name (tab-bar--current-tab)) "dynamic *scratch*")))
|
||||
(when (and (not is-last-tab)
|
||||
(not is-dynamic-tab-focused))
|
||||
(tab-bar-move-tab 1))))
|
||||
|
||||
; Generic tab helper functions
|
||||
(defun delete-window-override (&rest _)
|
||||
"Override for delete window, close tab if only one window instead."
|
||||
(if (<= (length (window-list)) 1)
|
||||
(progn
|
||||
(tab-close)
|
||||
nil)
|
||||
t))
|
||||
|
||||
;; Helper functions for EWM
|
||||
; Switch monitor
|
||||
|
|
@ -1228,12 +1281,12 @@
|
|||
"grim -g \"$(slurp)\" - | wl-copy")))
|
||||
("M-w" . (lambda ()
|
||||
(interactive)
|
||||
(setq dynamic-tab-soft-kill-p t)
|
||||
(setq dynamic-tab--soft-kill-p t)
|
||||
(kill-buffer)
|
||||
(setq dynamic-tab-soft-kill-p nil)))
|
||||
(setq dynamic-tab--soft-kill-p nil)))
|
||||
("C-x k" . (lambda ()
|
||||
(interactive)
|
||||
(setq dynamic-tab-soft-kill-p nil)
|
||||
(setq dynamic-tab--soft-kill-p nil)
|
||||
(call-interactively 'kill-buffer)))
|
||||
|
||||
; Monitor switching, find current focused monitor name via
|
||||
|
|
@ -1254,6 +1307,12 @@
|
|||
|
||||
("M-h" . tab-bar-switch-to-prev-tab)
|
||||
("M-l" . tab-bar-switch-to-next-tab)
|
||||
("M-H" . (lambda ()
|
||||
(interactive)
|
||||
(dynamic-tab-move-tab-left)))
|
||||
("M-L" . (lambda ()
|
||||
(interactive)
|
||||
(dynamic-tab-move-tab-right)))
|
||||
("M-k" . windmove-up)
|
||||
("M-j" . windmove-down))
|
||||
:config
|
||||
|
|
@ -1264,13 +1323,16 @@
|
|||
(add-to-list 'ewm-intercept-prefixes ?\M-p)
|
||||
(add-to-list 'ewm-intercept-prefixes ?\M-h)
|
||||
(add-to-list 'ewm-intercept-prefixes ?\M-j)
|
||||
(add-to-list 'ewm-intercept-prefixes ?\M-H)
|
||||
(add-to-list 'ewm-intercept-prefixes ?\M-J)
|
||||
(add-to-list 'ewm-intercept-prefixes ?\M-k)
|
||||
(add-to-list 'ewm-intercept-prefixes ?\M-l)
|
||||
(ewm--send-intercept-keys)
|
||||
:init
|
||||
;; Dynamic Tabs
|
||||
(dynamic-tab-init)
|
||||
|
||||
(advice-add 'delete-window :before-while #'delete-window-override))
|
||||
(with-eval-after-load 'ewm
|
||||
;; Autostart
|
||||
(ewm-autostart-application "qpwgraph")
|
||||
(ewm-autostart-application "kdeconnect-indicator")
|
||||
|
|
@ -1286,7 +1348,8 @@
|
|||
:after posframe
|
||||
:init
|
||||
(defun simple-notification-popup (old-notification new-notification)
|
||||
(unless (eq old-notification new-notification)
|
||||
(ignore-errors
|
||||
(when new-notification
|
||||
(posframe-show
|
||||
" *simple-notification-popup-alert*"
|
||||
:string (concat
|
||||
|
|
@ -1297,8 +1360,7 @@
|
|||
:poshandler #'posframe-poshandler-frame-top-right-corner
|
||||
:background-color "gold"
|
||||
:foreground-color "black"
|
||||
:timeout 5)))
|
||||
|
||||
:timeout 5))))
|
||||
(add-hook 'ednc-notification-presentation-functions
|
||||
#'simple-notification-popup)
|
||||
(ednc-mode))
|
||||
|
|
@ -1315,6 +1377,12 @@
|
|||
(setq kdeconnect-devices '(("My Phone" . "378230a2e3c24b9a9904e7ffb0dfeb07")))
|
||||
(setq kdeconnect-active-device '("My Phone" . "378230a2e3c24b9a9904e7ffb0dfeb07"))))
|
||||
|
||||
;(use-package elcord
|
||||
; :ensure t
|
||||
; :config
|
||||
; (setq elcord-display-buffer-details nil)
|
||||
; (elcord-mode)))
|
||||
|
||||
(custom-set-variables
|
||||
;; custom-set-variables was added by Custom.
|
||||
;; If you edit it by hand, you could mess it up, so be careful.
|
||||
|
|
|
|||
Loading…
Reference in New Issue