initial commit
This commit is contained in:
commit
d3f34301de
10 changed files with 1181 additions and 0 deletions
629
.config/emacs/config.org
Normal file
629
.config/emacs/config.org
Normal file
|
|
@ -0,0 +1,629 @@
|
||||||
|
#+TITLE: >.<macs
|
||||||
|
#+AUTHOR: mux
|
||||||
|
|
||||||
|
#+STARTUP: shrink
|
||||||
|
|
||||||
|
* SANE DEFAULTS
|
||||||
|
** Generic optimizations
|
||||||
|
#+begin_src emacs-lisp
|
||||||
|
(setq gc-cons-threshold most-positive-fixnum)
|
||||||
|
(add-hook 'emacs-startup-hook
|
||||||
|
(lambda ()
|
||||||
|
(setq gc-cons-threshold (* 50 1024 1024))))
|
||||||
|
|
||||||
|
(setq backup-directory-alist '(("." . "~/.config/emacs/backups")))
|
||||||
|
(setq auto-save-file-name-transforms '((".*" "~/.config/emacs/auto-save-list/" t)))
|
||||||
|
(setq delete-old-versions t
|
||||||
|
kept-new-versions 6
|
||||||
|
kept-old-versions 2
|
||||||
|
version-control t)
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
** Declutter user interface
|
||||||
|
#+begin_src emacs-lisp
|
||||||
|
(menu-bar-mode -1)
|
||||||
|
(tool-bar-mode -1)
|
||||||
|
(scroll-bar-mode -1)
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
** Tweak appearance
|
||||||
|
#+begin_src emacs-lisp
|
||||||
|
(set-face-attribute 'default nil
|
||||||
|
:family "ShureTechMono Nerd Font"
|
||||||
|
:height 190)
|
||||||
|
(global-display-line-numbers-mode 1)
|
||||||
|
(setq display-line-numbers 'relative)
|
||||||
|
(setq-default line-spacing 5)
|
||||||
|
(setq-default
|
||||||
|
inhibit-startup-message t
|
||||||
|
initial-scratch-message nil
|
||||||
|
sentence-end-double-space nil
|
||||||
|
ring-bell-function 'ignore
|
||||||
|
make-backup-files t
|
||||||
|
vc-follow-symlinks t
|
||||||
|
ad-redefinition-action 'accept
|
||||||
|
help-window-select t
|
||||||
|
use-short-answers t)
|
||||||
|
|
||||||
|
(dolist (mode '(term-mode-hook
|
||||||
|
shell-mode-hook
|
||||||
|
treemacs-mode-hook
|
||||||
|
eshell-mode-hook
|
||||||
|
help-mode-hook
|
||||||
|
vterm-mode-hook))
|
||||||
|
(add-hook mode (lambda () (display-line-numbers-mode 0))))
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
* PACKAGE MANAGEMENT
|
||||||
|
** Elpaca package manager
|
||||||
|
#+begin_src emacs-lisp
|
||||||
|
(defvar elpaca-installer-version 0.11)
|
||||||
|
(defvar elpaca-directory (expand-file-name "elpaca/" user-emacs-directory))
|
||||||
|
(defvar elpaca-builds-directory (expand-file-name "builds/" elpaca-directory))
|
||||||
|
(defvar elpaca-repos-directory (expand-file-name "repos/" elpaca-directory))
|
||||||
|
(defvar elpaca-order '(elpaca :repo "https://github.com/progfolio/elpaca.git"
|
||||||
|
:ref nil :depth 1 :inherit ignore
|
||||||
|
:files (:defaults "elpaca-test.el" (:exclude "extensions"))
|
||||||
|
:build (:not elpaca--activate-package)))
|
||||||
|
(let* ((repo (expand-file-name "elpaca/" elpaca-repos-directory))
|
||||||
|
(build (expand-file-name "elpaca/" elpaca-builds-directory))
|
||||||
|
(order (cdr elpaca-order))
|
||||||
|
(default-directory repo))
|
||||||
|
(add-to-list 'load-path (if (file-exists-p build) build repo))
|
||||||
|
(unless (file-exists-p repo)
|
||||||
|
(make-directory repo t)
|
||||||
|
(when (<= emacs-major-version 28) (require 'subr-x))
|
||||||
|
(condition-case-unless-debug err
|
||||||
|
(if-let* ((buffer (pop-to-buffer-same-window "*elpaca-bootstrap*"))
|
||||||
|
((zerop (apply #'call-process `("git" nil ,buffer t "clone"
|
||||||
|
,@(when-let* ((depth (plist-get order :depth)))
|
||||||
|
(list (format "--depth=%d" depth) "--no-single-branch"))
|
||||||
|
,(plist-get order :repo) ,repo))))
|
||||||
|
((zerop (call-process "git" nil buffer t "checkout"
|
||||||
|
(or (plist-get order :ref) "--"))))
|
||||||
|
(emacs (concat invocation-directory invocation-name))
|
||||||
|
((zerop (call-process emacs nil buffer nil "-Q" "-L" "." "--batch"
|
||||||
|
"--eval" "(byte-recompile-directory \".\" 0 'force)")))
|
||||||
|
((require 'elpaca))
|
||||||
|
((elpaca-generate-autoloads "elpaca" repo)))
|
||||||
|
(progn (message "%s" (buffer-string)) (kill-buffer buffer))
|
||||||
|
(error "%s" (with-current-buffer buffer (buffer-string))))
|
||||||
|
((error) (warn "%s" err) (delete-directory repo 'recursive))))
|
||||||
|
(unless (require 'elpaca-autoloads nil t)
|
||||||
|
(require 'elpaca)
|
||||||
|
(elpaca-generate-autoloads "elpaca" repo)
|
||||||
|
(let ((load-source-file-function nil)) (load "./elpaca-autoloads"))))
|
||||||
|
(add-hook 'after-init-hook #'elpaca-process-queues)
|
||||||
|
(elpaca `(,@elpaca-order))
|
||||||
|
|
||||||
|
;; Install use-package support
|
||||||
|
(elpaca elpaca-use-package
|
||||||
|
(elpaca-use-package-mode))
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
* EDITING & MODAL INPUT
|
||||||
|
** Meow modal editing
|
||||||
|
#+begin_src emacs-lisp
|
||||||
|
(use-package meow
|
||||||
|
:ensure t
|
||||||
|
:preface
|
||||||
|
(defun meow-word ()
|
||||||
|
"Expand word/symbol under cursor."
|
||||||
|
(interactive)
|
||||||
|
(if (and (use-region-p)
|
||||||
|
(equal (car (region-bounds))
|
||||||
|
(bounds-of-thing-at-point 'word)))
|
||||||
|
(meow-mark-symbol 1)
|
||||||
|
(progn
|
||||||
|
(when (and (mark)
|
||||||
|
(equal (car (region-bounds))
|
||||||
|
(bounds-of-thing-at-point 'symbol)))
|
||||||
|
(meow-pop-selection))
|
||||||
|
(meow-mark-word 1))))
|
||||||
|
|
||||||
|
(defun meow-kill-line ()
|
||||||
|
"Kill till the end of line."
|
||||||
|
(interactive)
|
||||||
|
(let ((select-enable-clipboard meow-use-clipboard))
|
||||||
|
(kill-line)))
|
||||||
|
|
||||||
|
(defun meow-change-line ()
|
||||||
|
"Kill till end of line and switch to INSERT state."
|
||||||
|
(interactive)
|
||||||
|
(meow--cancel-selection)
|
||||||
|
(meow-end-of-thing
|
||||||
|
(car (rassoc 'line meow-char-thing-table)))
|
||||||
|
(meow-change))
|
||||||
|
|
||||||
|
(defun meow-save-clipboard ()
|
||||||
|
"Copy in clipboard."
|
||||||
|
(interactive)
|
||||||
|
(let ((meow-use-clipboard t))
|
||||||
|
(meow-save)))
|
||||||
|
|
||||||
|
(defvar meow--trim-yank nil)
|
||||||
|
|
||||||
|
(defun meow-insert-for-yank-advice (orig-fn str)
|
||||||
|
"Advice for `insert-for-yank' function to correctly insert lines."
|
||||||
|
(when meow--trim-yank
|
||||||
|
(set 'str (string-trim-right str "\n")))
|
||||||
|
(if (and (not (eq (point) (+ 1 (line-end-position 0))))
|
||||||
|
(string-match-p "^.+\n$" str))
|
||||||
|
(save-excursion
|
||||||
|
(beginning-of-line)
|
||||||
|
(funcall orig-fn str))
|
||||||
|
(funcall orig-fn str)))
|
||||||
|
|
||||||
|
(defun meow-yank-dwim ()
|
||||||
|
"Smart yank."
|
||||||
|
(interactive)
|
||||||
|
(advice-add 'insert-for-yank :around 'meow-insert-for-yank-advice)
|
||||||
|
(if (use-region-p)
|
||||||
|
(let ((meow--trim-yank t))
|
||||||
|
(delete-region (region-beginning) (region-end))
|
||||||
|
(meow-yank))
|
||||||
|
(meow-yank))
|
||||||
|
(advice-remove 'insert-for-yank 'meow-insert-for-yank-advice))
|
||||||
|
|
||||||
|
(defun meow-yank-pop-dwim ()
|
||||||
|
"Smart yank pop."
|
||||||
|
(interactive)
|
||||||
|
(advice-add 'insert-for-yank :around 'meow-insert-for-yank-advice)
|
||||||
|
(if (use-region-p)
|
||||||
|
(let ((meow--trim-yank t))
|
||||||
|
(delete-region (region-beginning) (region-end))
|
||||||
|
(meow-yank-pop))
|
||||||
|
(meow-yank-pop))
|
||||||
|
(advice-remove 'insert-for-yank 'meow-insert-for-yank-advice))
|
||||||
|
|
||||||
|
(defun meow-smart-reverse ()
|
||||||
|
"Reverse selection or begin negative argument."
|
||||||
|
(interactive)
|
||||||
|
(if (use-region-p)
|
||||||
|
(meow-reverse)
|
||||||
|
(negative-argument nil)))
|
||||||
|
|
||||||
|
(defun meow-kmacro ()
|
||||||
|
"Toggle recording of kmacro."
|
||||||
|
(interactive)
|
||||||
|
(if defining-kbd-macro
|
||||||
|
(meow-end-kmacro)
|
||||||
|
(meow-start-kmacro)))
|
||||||
|
|
||||||
|
(defun meow-eldoc ()
|
||||||
|
"Toggle the display of the eldoc window."
|
||||||
|
(interactive)
|
||||||
|
(if (get-buffer-window eldoc--doc-buffer)
|
||||||
|
(delete-window (get-buffer-window eldoc--doc-buffer))
|
||||||
|
(eldoc-doc-buffer t)))
|
||||||
|
|
||||||
|
(defun meow-ergo-setup ()
|
||||||
|
(setq meow-cheatsheet-layout meow-cheatsheet-layout-qwerty)
|
||||||
|
(setq meow-normal-state-keymap (make-sparse-keymap))
|
||||||
|
(setf (alist-get 'normal meow-keymap-alist) meow-normal-state-keymap)
|
||||||
|
(meow-motion-define-key
|
||||||
|
'("l" . meow-next)
|
||||||
|
'("j" . meow-prev)
|
||||||
|
'("<escape>" . ignore))
|
||||||
|
(meow-leader-define-key
|
||||||
|
'("1" . meow-digit-argument)
|
||||||
|
'("2" . meow-digit-argument)
|
||||||
|
'("3" . meow-digit-argument)
|
||||||
|
'("4" . meow-digit-argument)
|
||||||
|
'("5" . meow-digit-argument)
|
||||||
|
'("6" . meow-digit-argument)
|
||||||
|
'("7" . meow-digit-argument)
|
||||||
|
'("8" . meow-digit-argument)
|
||||||
|
'("9" . meow-digit-argument)
|
||||||
|
'("0" . meow-digit-argument)
|
||||||
|
'("/" . meow-keypad-describe-key)
|
||||||
|
'("?" . meow-cheatsheet))
|
||||||
|
|
||||||
|
(meow-thing-register 'angle
|
||||||
|
'(pair ("<") (">"))
|
||||||
|
'(pair ("<") (">")))
|
||||||
|
|
||||||
|
(setq meow-char-thing-table
|
||||||
|
'((?f . round)
|
||||||
|
(?d . square)
|
||||||
|
(?s . curly)
|
||||||
|
(?a . angle)
|
||||||
|
(?r . string)
|
||||||
|
(?v . paragraph)
|
||||||
|
(?c . line)
|
||||||
|
(?x . buffer)))
|
||||||
|
|
||||||
|
(meow-normal-define-key
|
||||||
|
;; Expansion
|
||||||
|
'("0" . meow-expand-0)
|
||||||
|
'("1" . meow-expand-1)
|
||||||
|
'("2" . meow-expand-2)
|
||||||
|
'("3" . meow-expand-3)
|
||||||
|
'("4" . meow-expand-4)
|
||||||
|
'("5" . meow-expand-5)
|
||||||
|
'("6" . meow-expand-6)
|
||||||
|
'("7" . meow-expand-7)
|
||||||
|
'("8" . meow-expand-8)
|
||||||
|
'("9" . meow-expand-9)
|
||||||
|
'("'" . meow-reverse)
|
||||||
|
|
||||||
|
;; Movement
|
||||||
|
'("i" . meow-prev)
|
||||||
|
'("k" . meow-next)
|
||||||
|
'("j" . meow-left)
|
||||||
|
'("l" . meow-right)
|
||||||
|
'("y" . meow-search)
|
||||||
|
'("/" . meow-visit)
|
||||||
|
|
||||||
|
;; Expansion
|
||||||
|
'("I" . meow-prev-expand)
|
||||||
|
'("K" . meow-next-expand)
|
||||||
|
'("J" . meow-left-expand)
|
||||||
|
'("L" . meow-right-expand)
|
||||||
|
|
||||||
|
'("u" . meow-back-word)
|
||||||
|
'("U" . meow-back-symbol)
|
||||||
|
'("o" . meow-next-word)
|
||||||
|
'("O" . meow-next-symbol)
|
||||||
|
|
||||||
|
'("a" . meow-mark-word)
|
||||||
|
'("A" . meow-mark-symbol)
|
||||||
|
'("s" . meow-line)
|
||||||
|
'("S" . meow-goto-line)
|
||||||
|
'("w" . meow-block)
|
||||||
|
'("q" . meow-join)
|
||||||
|
'("g" . meow-grab)
|
||||||
|
'("G" . meow-pop-grab)
|
||||||
|
'("m" . meow-swap-grab)
|
||||||
|
'("M" . meow-sync-grab)
|
||||||
|
'("p" . meow-cancel-selection)
|
||||||
|
'("P" . meow-pop-selection)
|
||||||
|
|
||||||
|
'("x" . meow-till)
|
||||||
|
'("z" . meow-find)
|
||||||
|
|
||||||
|
'("," . meow-beginning-of-thing)
|
||||||
|
'("." . meow-end-of-thing)
|
||||||
|
'("<" . meow-inner-of-thing)
|
||||||
|
'(">" . meow-bounds-of-thing)
|
||||||
|
|
||||||
|
;; Editing
|
||||||
|
'("d" . meow-kill)
|
||||||
|
'("f" . meow-change)
|
||||||
|
'("t" . meow-delete)
|
||||||
|
'("c" . meow-save)
|
||||||
|
'("v" . meow-yank)
|
||||||
|
'("V" . meow-yank-pop)
|
||||||
|
|
||||||
|
'("e" . meow-insert)
|
||||||
|
'("E" . meow-open-above)
|
||||||
|
'("r" . meow-append)
|
||||||
|
'("R" . meow-open-below)
|
||||||
|
|
||||||
|
'("h" . undo-only)
|
||||||
|
'("H" . undo-redo)
|
||||||
|
|
||||||
|
'("b" . open-line)
|
||||||
|
'("B" . split-line)
|
||||||
|
|
||||||
|
'("[" . indent-rigidly-left-to-tab-stop)
|
||||||
|
'("]" . indent-rigidly-right-to-tab-stop)
|
||||||
|
|
||||||
|
;; Prefix commands
|
||||||
|
'("nf" . meow-comment)
|
||||||
|
'("nt" . meow-start-kmacro-or-insert-counter)
|
||||||
|
'("nr" . meow-start-kmacro)
|
||||||
|
'("ne" . meow-end-or-call-kmacro)
|
||||||
|
|
||||||
|
'(";f" . save-buffer)
|
||||||
|
'(";F" . save-some-buffers)
|
||||||
|
'(";d" . meow-query-replace-regexp)
|
||||||
|
|
||||||
|
;; Buffer navigation
|
||||||
|
'(";[b" . previous-buffer)
|
||||||
|
'(";]b" . next-buffer)
|
||||||
|
'(";b" . switch-to-buffer)
|
||||||
|
'(";nb" . rename-buffer)
|
||||||
|
'(";B" . revert-buffer)
|
||||||
|
|
||||||
|
'("<escape>" . ignore)))
|
||||||
|
|
||||||
|
:config
|
||||||
|
(meow-ergo-setup)
|
||||||
|
(meow-global-mode 1))
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
** Formatter
|
||||||
|
#+begin_src emacs-lisp
|
||||||
|
(use-package format-all
|
||||||
|
:ensure t
|
||||||
|
:preface
|
||||||
|
(defun refmt ()
|
||||||
|
"Auto-format whole buffer."
|
||||||
|
(interactive)
|
||||||
|
(cond
|
||||||
|
((derived-mode-p 'prolog-mode)
|
||||||
|
(prolog-indent-buffer))
|
||||||
|
((derived-mode-p 'emacs-lisp-mode)
|
||||||
|
(indent-region (point-min) (point-max)))
|
||||||
|
((derived-mode-p 'org-mode)
|
||||||
|
(org-indent-region (point-min) (point-max)))
|
||||||
|
(t
|
||||||
|
(format-all-buffer))))
|
||||||
|
:config
|
||||||
|
(global-set-key (kbd "M-f") #'refmt)
|
||||||
|
(add-hook 'prog-mode-hook #'format-all-ensure-formatter))
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
* PROGRAMMING FEATURES
|
||||||
|
** Syntax highlighting
|
||||||
|
#+begin_src emacs-lisp
|
||||||
|
(use-package treesit-auto
|
||||||
|
:ensure t
|
||||||
|
:custom
|
||||||
|
(treesit-auto-install 'prompt)
|
||||||
|
:config
|
||||||
|
(treesit-auto-add-to-auto-mode-alist 'all)
|
||||||
|
(global-treesit-auto-mode))
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
** LSP
|
||||||
|
#+begin_src emacs-lisp
|
||||||
|
(use-package lsp-mode
|
||||||
|
:ensure t
|
||||||
|
:hook
|
||||||
|
(prog-mode . lsp-deferred)
|
||||||
|
(lsp-mode . lsp-enable-which-key-integration)
|
||||||
|
:commands (lsp lsp-deferred)
|
||||||
|
:init
|
||||||
|
(setq lsp-keymap-prefix "C-c l")
|
||||||
|
:custom
|
||||||
|
(lsp-idle-delay 0.500)
|
||||||
|
(lsp-log-io nil)
|
||||||
|
(lsp-completion-provider :none)
|
||||||
|
(lsp-headerline-breadcrumb-enable nil))
|
||||||
|
|
||||||
|
(use-package flycheck
|
||||||
|
:ensure t
|
||||||
|
:config
|
||||||
|
(global-flycheck-mode +1))
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
** Indentation preferences
|
||||||
|
#+begin_src emacs-lisp
|
||||||
|
(setq-default
|
||||||
|
indent-tabs-mode t
|
||||||
|
tab-width 4
|
||||||
|
standard-indent 4)
|
||||||
|
(setq tab-always-indent 1)
|
||||||
|
|
||||||
|
(use-package dtrt-indent
|
||||||
|
:ensure t
|
||||||
|
:hook (prog-mode . dtrt-indent-mode))
|
||||||
|
|
||||||
|
(use-package whitespace
|
||||||
|
:hook (prog-mode . whitespace-mode)
|
||||||
|
:custom
|
||||||
|
(whitespace-style '(face tabs tab-mark trailing))
|
||||||
|
(whitespace-display-mappings
|
||||||
|
'((tab-mark ?\t [?→ ?\t] [?> ?\t]))))
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
* COMPLETION SYSTEM
|
||||||
|
** Helpful documentation
|
||||||
|
#+begin_src emacs-lisp
|
||||||
|
(use-package helpful
|
||||||
|
:ensure t
|
||||||
|
:bind
|
||||||
|
([remap describe-function] . helpful-callable)
|
||||||
|
([remap describe-variable] . helpful-variable)
|
||||||
|
([remap describe-key] . helpful-key))
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
** Minibuffer completion (Vertico + Marginalia)
|
||||||
|
#+begin_src emacs-lisp
|
||||||
|
(use-package marginalia
|
||||||
|
:ensure t
|
||||||
|
:bind (:map minibuffer-local-map
|
||||||
|
("M-A" . marginalia-cycle))
|
||||||
|
:init
|
||||||
|
(marginalia-mode))
|
||||||
|
|
||||||
|
(use-package vertico
|
||||||
|
:ensure t
|
||||||
|
:custom
|
||||||
|
(vertico-cycle t)
|
||||||
|
:init
|
||||||
|
(vertico-mode))
|
||||||
|
|
||||||
|
(use-package savehist
|
||||||
|
:init
|
||||||
|
(savehist-mode))
|
||||||
|
|
||||||
|
(use-package orderless
|
||||||
|
:ensure t
|
||||||
|
:custom
|
||||||
|
(completion-styles '(orderless basic))
|
||||||
|
(completion-category-defaults nil)
|
||||||
|
(completion-category-overrides '((file (styles partial-completion)))))
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
** Minibuffer settings
|
||||||
|
#+begin_src emacs-lisp
|
||||||
|
(use-package emacs
|
||||||
|
:custom
|
||||||
|
(context-menu-mode t)
|
||||||
|
(enable-recursive-minibuffers t)
|
||||||
|
(read-extended-command-predicate #'command-completion-default-include-p)
|
||||||
|
(text-mode-ispell-word-completion nil)
|
||||||
|
(minibuffer-prompt-properties
|
||||||
|
'(read-only t cursor-intangible t face minibuffer-prompt)))
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
** In-buffer completion (Corfu + Cape)
|
||||||
|
#+begin_src emacs-lisp
|
||||||
|
(use-package corfu
|
||||||
|
:ensure t
|
||||||
|
:custom
|
||||||
|
(corfu-auto t)
|
||||||
|
(corfu-cycle t)
|
||||||
|
(corfu-preselect 'prompt)
|
||||||
|
:init
|
||||||
|
(global-corfu-mode)
|
||||||
|
(corfu-history-mode)
|
||||||
|
(corfu-popupinfo-mode)
|
||||||
|
:bind
|
||||||
|
(:map corfu-map
|
||||||
|
("TAB" . corfu-next)
|
||||||
|
([tab] . corfu-next)
|
||||||
|
("S-TAB" . corfu-previous)
|
||||||
|
([backtab] . corfu-previous)))
|
||||||
|
|
||||||
|
(use-package cape
|
||||||
|
:ensure t
|
||||||
|
:bind ("C-c p" . cape-prefix-map)
|
||||||
|
:hook
|
||||||
|
((completion-at-point-functions . cape-dabbrev)
|
||||||
|
(completion-at-point-functions . cape-file)
|
||||||
|
(completion-at-point-functions . cape-elisp-block)))
|
||||||
|
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
#+RESULTS:
|
||||||
|
: [nil 26870 55996 618175 nil elpaca-process-queues nil nil 712000 nil]
|
||||||
|
|
||||||
|
* VISUAL APPEARANCE
|
||||||
|
** Theme and colors
|
||||||
|
#+begin_src emacs-lisp
|
||||||
|
(use-package doom-themes
|
||||||
|
:ensure t
|
||||||
|
:custom
|
||||||
|
(doom-themes-enable-bold t)
|
||||||
|
(doom-themes-enable-italic t)
|
||||||
|
:config
|
||||||
|
(load-theme 'doom-moonlight t)
|
||||||
|
(doom-themes-visual-bell-config)
|
||||||
|
(doom-themes-org-config)
|
||||||
|
|
||||||
|
(let ((bg "#16191C")
|
||||||
|
(fg "#C5CACE")
|
||||||
|
(bg-alt "#252A2E")
|
||||||
|
(fg-alt "#A3AAAF")
|
||||||
|
(fg-muted "#50555A"))
|
||||||
|
(custom-set-faces
|
||||||
|
`(default ((t (:background ,bg :foreground ,fg))))
|
||||||
|
`(fringe ((t (:background ,bg))))
|
||||||
|
`(hl-line ((t (:background ,bg-alt))))
|
||||||
|
`(mode-line ((t (:background ,bg-alt :foreground ,fg))))
|
||||||
|
`(mode-line-inactive ((t (:background ,bg :foreground ,fg-muted))))
|
||||||
|
`(line-number ((t (:foreground ,fg-muted :background ,bg))))
|
||||||
|
`(line-number-current-line ((t (:foreground ,fg-alt :background ,bg-alt :weight bold))))
|
||||||
|
`(font-lock-comment-face ((t (:foreground ,fg-alt)))))))
|
||||||
|
|
||||||
|
(add-hook 'org-mode-hook
|
||||||
|
(lambda ()
|
||||||
|
(set-face-background 'org-block "#16191C")
|
||||||
|
(set-face-foreground 'org-block "#C5CACE")
|
||||||
|
(set-face-background 'org-block-begin-line "#252A2E")
|
||||||
|
(set-face-foreground 'org-block-begin-line "#A3AAAF")
|
||||||
|
(set-face-background 'org-block-end-line "#252A2E")
|
||||||
|
(set-face-foreground 'org-block-end-line "#A3AAAF")))
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
** Modeline
|
||||||
|
#+begin_src emacs-lisp
|
||||||
|
(use-package doom-modeline
|
||||||
|
:ensure t
|
||||||
|
:init (doom-modeline-mode +1))
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
** Color preview
|
||||||
|
#+begin_src emacs-lisp
|
||||||
|
(use-package colorful-mode
|
||||||
|
:ensure t
|
||||||
|
:custom
|
||||||
|
(colorful-use-prefix t)
|
||||||
|
(colorful-only-strings 'only-prog)
|
||||||
|
(css-fontify-colors nil)
|
||||||
|
:config
|
||||||
|
(global-colorful-mode t)
|
||||||
|
(add-to-list 'global-colorful-modes 'helpful-mode))
|
||||||
|
|
||||||
|
(use-package rainbow-delimiters
|
||||||
|
:ensure t
|
||||||
|
:hook (prog-mode . rainbow-delimiters-mode))
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
#+RESULTS:
|
||||||
|
: [nil 26870 59644 357807 nil elpaca-process-queues nil nil 727000 nil]
|
||||||
|
|
||||||
|
* INTEGRATIONS & UTILITIES
|
||||||
|
** Discord presence
|
||||||
|
#+begin_src emacs-lisp
|
||||||
|
(use-package elcord
|
||||||
|
:ensure t
|
||||||
|
:config
|
||||||
|
(elcord-mode +1))
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
** Project management
|
||||||
|
#+begin_src emacs-lisp
|
||||||
|
(use-package projectile
|
||||||
|
:ensure t
|
||||||
|
:config
|
||||||
|
(projectile-mode +1)
|
||||||
|
(define-key projectile-mode-map (kbd "C-c p") 'projectile-command-map))
|
||||||
|
|
||||||
|
(use-package editorconfig
|
||||||
|
:ensure t
|
||||||
|
:config
|
||||||
|
(editorconfig-mode 1))
|
||||||
|
#+end_src
|
||||||
|
** Dashboard
|
||||||
|
#+begin_src emacs-lisp
|
||||||
|
(use-package page-break-lines
|
||||||
|
:ensure t
|
||||||
|
:config
|
||||||
|
(page-break-lines-mode +1))
|
||||||
|
|
||||||
|
(use-package all-the-icons
|
||||||
|
:ensure t
|
||||||
|
:if (display-graphic-p))
|
||||||
|
|
||||||
|
(use-package dashboard
|
||||||
|
:ensure t
|
||||||
|
:custom
|
||||||
|
(dashboard-banner-logo-title "DMs~ ;)")
|
||||||
|
(dashboard-startup-banner "~/.config/emacs/dash.gif")
|
||||||
|
:config
|
||||||
|
(add-hook 'elpaca-after-init-hook #'dashboard-insert-startupify-lists)
|
||||||
|
(add-hook 'elpaca-after-init-hook #'dashboard-initialize)
|
||||||
|
(dashboard-setup-startup-hook))
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
** File tree
|
||||||
|
#+begin_src emacs-lisp
|
||||||
|
(use-package treemacs
|
||||||
|
:ensure t
|
||||||
|
:bind ("C-c t" . treemacs)
|
||||||
|
:config
|
||||||
|
(setq treemacs-width 30))
|
||||||
|
|
||||||
|
(use-package treemacs-projectile
|
||||||
|
:ensure t
|
||||||
|
:after (treemacs projectile))
|
||||||
|
|
||||||
|
(use-package treemacs-all-the-icons
|
||||||
|
:ensure t
|
||||||
|
:after (treemacs all-the-icons)
|
||||||
|
:config
|
||||||
|
(treemacs-load-theme "all-the-icons"))
|
||||||
|
|
||||||
|
(use-package treemacs-icons-dired
|
||||||
|
:ensure t
|
||||||
|
:hook (dired-mode . treemacs-icons-dired-enable-once))
|
||||||
|
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
#+RESULTS:
|
||||||
|
: [nil 26870 60289 404113 nil elpaca-process-queues nil nil 420000 nil]
|
||||||
BIN
.config/emacs/dash.gif
Normal file
BIN
.config/emacs/dash.gif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 23 KiB |
1
.config/emacs/early-init.el
Normal file
1
.config/emacs/early-init.el
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
(setq package-enable-at-startup nil)
|
||||||
12
.config/emacs/init.el
Normal file
12
.config/emacs/init.el
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
;(add-to-list 'load-path
|
||||||
|
; (expand-file-name
|
||||||
|
; "tao-theme-emacs/"
|
||||||
|
; user-emacs-directory))
|
||||||
|
;
|
||||||
|
;(load "tao-yin-theme.el")
|
||||||
|
;(load-theme 'tao-yin t)
|
||||||
|
|
||||||
|
(org-babel-load-file
|
||||||
|
(expand-file-name
|
||||||
|
"config.org"
|
||||||
|
user-emacs-directory))
|
||||||
44
.config/fastfetch/config.jsonc
Normal file
44
.config/fastfetch/config.jsonc
Normal file
|
|
@ -0,0 +1,44 @@
|
||||||
|
{
|
||||||
|
"$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json",
|
||||||
|
"modules": [
|
||||||
|
"title",
|
||||||
|
"break",
|
||||||
|
{
|
||||||
|
"type": "kernel",
|
||||||
|
"key": "system"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "uptime",
|
||||||
|
"key": "uptime"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "packages",
|
||||||
|
"key": "bloatware"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "wm",
|
||||||
|
"key": "compositor"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "cpu",
|
||||||
|
"key": "cpu"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "gpu",
|
||||||
|
"key": "gpu"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"logo": {
|
||||||
|
"type": "small",
|
||||||
|
"color": {
|
||||||
|
"1": "#9e9b93"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"display": {
|
||||||
|
"separator": " ", // Separator between keys and values
|
||||||
|
"color": {
|
||||||
|
"keys": "#9e9b93", // Key color
|
||||||
|
"title": "#9e9b93" // Title color
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
7
.config/mako/config
Normal file
7
.config/mako/config
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
background-color=#16191C
|
||||||
|
border-color=#252A2E
|
||||||
|
icons=0
|
||||||
|
ignore-timeout=1
|
||||||
|
sort=-time
|
||||||
|
text-color=#A3AAAF
|
||||||
|
margin=4
|
||||||
170
.config/sway/config
Normal file
170
.config/sway/config
Normal file
|
|
@ -0,0 +1,170 @@
|
||||||
|
exec autotiling
|
||||||
|
|
||||||
|
exec systemctl --user import-environment WAYLAND_DISPLAY XDG_CURRENT_DESKTOP
|
||||||
|
exec dbus-update-activation-environment --systemd WAYLAND_DISPLAY XDG_CURRENT_DESKTOP=sway
|
||||||
|
|
||||||
|
### Variables
|
||||||
|
#
|
||||||
|
# Logo key. Use Mod1 for Alt.
|
||||||
|
set $mod Mod4
|
||||||
|
set $left j
|
||||||
|
set $down k
|
||||||
|
set $up i
|
||||||
|
set $right l
|
||||||
|
# Your preferred terminal emulator
|
||||||
|
set $term alacritty
|
||||||
|
# Your preferred application launcher
|
||||||
|
set $menu wmenu-run
|
||||||
|
|
||||||
|
default_border pixel 1
|
||||||
|
client.focused #252a2e #171717 #E9E9E9 #262626 #252a2e
|
||||||
|
client.focused_inactive #252a2e #171717 #E9E9E9 #262626 #262626
|
||||||
|
client.unfocused #252a2e #171717 #E9E9E9 #262626 #262626
|
||||||
|
client.urgent #252a2e #171717 #E9E9E9 #262626 #262626
|
||||||
|
client.placeholder #252a2e #171717 #E9E9E9 #262626 #262626
|
||||||
|
|
||||||
|
gaps inner 2
|
||||||
|
gaps outer 2
|
||||||
|
|
||||||
|
input type:pointer {
|
||||||
|
accel_profile "flat"
|
||||||
|
pointer_accel 0.0
|
||||||
|
}
|
||||||
|
|
||||||
|
output * bg #02060A solid_color
|
||||||
|
|
||||||
|
input type:keyboard {
|
||||||
|
xkb_layout "us"
|
||||||
|
xkb_variant "intl"
|
||||||
|
xkb_options "caps:swapescape"
|
||||||
|
}
|
||||||
|
|
||||||
|
floating_modifier $mod normal
|
||||||
|
|
||||||
|
bindsym $mod+Shift+c reload
|
||||||
|
|
||||||
|
bindsym $mod+Shift+e exec swaynag -t warning -m 'You pressed the exit shortcut. Do you really want to exit sway? This will end your Wayland session.' -B 'Yes, exit sway' 'swaymsg exit'
|
||||||
|
|
||||||
|
#
|
||||||
|
# Workspaces mode:
|
||||||
|
#
|
||||||
|
mode "normal" {
|
||||||
|
# Switch to workspace
|
||||||
|
bindsym 1 workspace number 1; mode "default"
|
||||||
|
bindsym 2 workspace number 2; mode "default"
|
||||||
|
bindsym 3 workspace number 3; mode "default"
|
||||||
|
bindsym 4 workspace number 4; mode "default"
|
||||||
|
bindsym 5 workspace number 5; mode "default"
|
||||||
|
bindsym 6 workspace number 6; mode "default"
|
||||||
|
bindsym 7 workspace number 7; mode "default"
|
||||||
|
bindsym 8 workspace number 8; mode "default"
|
||||||
|
bindsym 9 workspace number 9; mode "default"
|
||||||
|
bindsym 0 workspace number 10; mode "default"
|
||||||
|
|
||||||
|
# Move focused container to workspace
|
||||||
|
bindsym Shift+1 move container to workspace number 1; mode "default"
|
||||||
|
bindsym Shift+2 move container to workspace number 2; mode "default"
|
||||||
|
bindsym Shift+3 move container to workspace number 3; mode "default"
|
||||||
|
bindsym Shift+4 move container to workspace number 4; mode "default"
|
||||||
|
bindsym Shift+5 move container to workspace number 5; mode "default"
|
||||||
|
bindsym Shift+6 move container to workspace number 6; mode "default"
|
||||||
|
bindsym Shift+7 move container to workspace number 7; mode "default"
|
||||||
|
bindsym Shift+8 move container to workspace number 8; mode "default"
|
||||||
|
bindsym Shift+9 move container to workspace number 9; mode "default"
|
||||||
|
bindsym Shift+0 move container to workspace number 10; mode "default"
|
||||||
|
|
||||||
|
#
|
||||||
|
# Moving around:
|
||||||
|
#
|
||||||
|
# Move your focus
|
||||||
|
bindsym left focus left; mode "default"
|
||||||
|
bindsym down focus down; mode "default"
|
||||||
|
bindsym up focus up; mode "default"
|
||||||
|
bindsym right focus right; mode "default"
|
||||||
|
|
||||||
|
# Move the focused window
|
||||||
|
bindsym Shift+left move left; mode "default"
|
||||||
|
bindsym Shift+down move down; mode "default"
|
||||||
|
bindsym Shift+up move up; mode "default"
|
||||||
|
bindsym Shift+right move right; mode "default"
|
||||||
|
|
||||||
|
bindsym Return exec $term; mode "default"
|
||||||
|
bindsym q kill; mode "default"
|
||||||
|
|
||||||
|
#
|
||||||
|
# Layout stuff:
|
||||||
|
#
|
||||||
|
bindsym b splith; mode "default" # horizontal split
|
||||||
|
bindsym v splitv; mode "default" # vertical split
|
||||||
|
bindsym s layout stacking; mode "default"
|
||||||
|
bindsym w layout tabbed; mode "default"
|
||||||
|
bindsym e layout toggle split; mode "default"
|
||||||
|
bindsym f fullscreen; mode "default"
|
||||||
|
bindsym Shift+space floating toggle; mode "default"
|
||||||
|
bindsym space focus mode_toggle; mode "default"
|
||||||
|
bindsym a focus parent; mode "default"
|
||||||
|
|
||||||
|
bindsym d exec $menu; mode "default"
|
||||||
|
|
||||||
|
# Exit mode back to default
|
||||||
|
bindsym Escape mode "default"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Activate workspaces mode with Super+x
|
||||||
|
bindsym $mod+x mode "normal"
|
||||||
|
|
||||||
|
#
|
||||||
|
# Resizing containers:
|
||||||
|
#
|
||||||
|
mode "resize" {
|
||||||
|
# left will shrink the containers width
|
||||||
|
# right will grow the containers width
|
||||||
|
# up will shrink the containers height
|
||||||
|
# down will grow the containers height
|
||||||
|
bindsym $left resize shrink width 10px
|
||||||
|
bindsym $down resize grow height 10px
|
||||||
|
bindsym $up resize shrink height 10px
|
||||||
|
bindsym $right resize grow width 10px
|
||||||
|
|
||||||
|
# Ditto, with arrow keys
|
||||||
|
bindsym Left resize shrink width 10px
|
||||||
|
bindsym Down resize grow height 10px
|
||||||
|
bindsym Up resize shrink height 10px
|
||||||
|
bindsym Right resize grow width 10px
|
||||||
|
|
||||||
|
# Return to default mode
|
||||||
|
bindsym Return mode "default"
|
||||||
|
bindsym Escape mode "default"
|
||||||
|
|
||||||
|
bindsym p exec shotman --capture window
|
||||||
|
bindsym Shift+p exec shotman --capture region
|
||||||
|
bindsym Ctrl+p exec shotman --capture output
|
||||||
|
}
|
||||||
|
bindsym $mod+r mode "resize"
|
||||||
|
#
|
||||||
|
# Utilities:
|
||||||
|
#
|
||||||
|
# Special keys to adjust volume via PulseAudio
|
||||||
|
bindsym --locked XF86AudioMute exec pactl set-sink-mute \@DEFAULT_SINK@ toggle
|
||||||
|
bindsym --locked XF86AudioLowerVolume exec pactl set-sink-volume \@DEFAULT_SINK@ -5%
|
||||||
|
bindsym --locked XF86AudioRaiseVolume exec pactl set-sink-volume \@DEFAULT_SINK@ +5%
|
||||||
|
bindsym --locked XF86AudioMicMute exec pactl set-source-mute \@DEFAULT_SOURCE@ toggle
|
||||||
|
|
||||||
|
# Special key to take a screenshot with grim
|
||||||
|
bindsym $mod+z exec grim -g "$(slurp)"
|
||||||
|
bindsym $mod+y exec grim - | wl-copy
|
||||||
|
|
||||||
|
#
|
||||||
|
# Status Bar:
|
||||||
|
#
|
||||||
|
# Read `man 5 sway-bar` for more information about this section.
|
||||||
|
bar {
|
||||||
|
position top
|
||||||
|
swaybar_command waybar
|
||||||
|
}
|
||||||
|
|
||||||
|
output * {
|
||||||
|
mode 1920x1080@120Hz
|
||||||
|
}
|
||||||
|
|
||||||
|
include /usr/local/etc/sway/config.d/*
|
||||||
87
.config/waybar/config.jsonc
Normal file
87
.config/waybar/config.jsonc
Normal file
|
|
@ -0,0 +1,87 @@
|
||||||
|
// -*- mode: jsonc -*-
|
||||||
|
{
|
||||||
|
// "layer": "top", // Waybar at top layer
|
||||||
|
"position": "top", // Waybar position (top|bottom|left|right)
|
||||||
|
"height": 30, // Waybar height (to be removed for auto height)
|
||||||
|
"spacing": 4, // Gaps between modules (4px)
|
||||||
|
"margin-left": 4,
|
||||||
|
"margin-right": 4,
|
||||||
|
"margin-top": 4,
|
||||||
|
"modules-left": [
|
||||||
|
"sway/workspaces",
|
||||||
|
"sway/mode"
|
||||||
|
],
|
||||||
|
"modules-center": [
|
||||||
|
"custom/media"
|
||||||
|
],
|
||||||
|
"modules-right": [
|
||||||
|
"pulseaudio",
|
||||||
|
"clock",
|
||||||
|
"tray"
|
||||||
|
],
|
||||||
|
// Modules configuration
|
||||||
|
// "sway/workspaces": {
|
||||||
|
// "disable-scroll": true,
|
||||||
|
// "all-outputs": true,
|
||||||
|
// "warp-on-scroll": false,
|
||||||
|
// "format": "{name}: {icon}",
|
||||||
|
// "format-icons": {
|
||||||
|
// "1": "",
|
||||||
|
// "2": "",
|
||||||
|
// "3": "",
|
||||||
|
// "4": "",
|
||||||
|
// "5": "",
|
||||||
|
// "urgent": "",
|
||||||
|
// "focused": "",
|
||||||
|
// "default": ""
|
||||||
|
// }
|
||||||
|
// },
|
||||||
|
"sway/mode": {
|
||||||
|
"format": "{}"
|
||||||
|
},
|
||||||
|
"tray": {
|
||||||
|
// "icon-size": 21,
|
||||||
|
"spacing": 10,
|
||||||
|
// "icons": {
|
||||||
|
// "blueman": "bluetooth",
|
||||||
|
// "TelegramDesktop": "$HOME/.local/share/icons/hicolor/16x16/apps/telegram.png"
|
||||||
|
// }
|
||||||
|
},
|
||||||
|
"clock": {
|
||||||
|
// "timezone": "America/New_York",
|
||||||
|
"format": " {:%H:%M}",
|
||||||
|
"format-alt": "{:%A, %B %d, %Y (%R)}"
|
||||||
|
},
|
||||||
|
"pulseaudio": {
|
||||||
|
// "scroll-step": 1, // %, can be a float
|
||||||
|
"format": "{icon} {volume}%",
|
||||||
|
"format-bluetooth": "{volume}% {icon} {format_source}",
|
||||||
|
"format-bluetooth-muted": " {icon} {format_source}",
|
||||||
|
"format-muted": " 0%",
|
||||||
|
"format-source": "{volume}% ",
|
||||||
|
"format-source-muted": "",
|
||||||
|
"format-icons": {
|
||||||
|
"headphone": "",
|
||||||
|
"hands-free": "",
|
||||||
|
"headset": "",
|
||||||
|
"phone": "",
|
||||||
|
"portable": "",
|
||||||
|
"car": "",
|
||||||
|
"default": ["", "", ""]
|
||||||
|
},
|
||||||
|
"on-click": "pavucontrol"
|
||||||
|
},
|
||||||
|
"custom/media": {
|
||||||
|
"format": "{text}",
|
||||||
|
"return-type": "json",
|
||||||
|
"max-length": 40,
|
||||||
|
"format-icons": {
|
||||||
|
"spotify": "",
|
||||||
|
"default": "🎜"
|
||||||
|
},
|
||||||
|
"escape": true,
|
||||||
|
"exec": "$HOME/.config/waybar/mediaplayer.py 2> /dev/null",
|
||||||
|
"on-click": "playerctl play-pause" // Script in resources folder
|
||||||
|
// "exec": "$HOME/.config/waybar/mediaplayer.py --player spotify 2> /dev/null" // Filter player based on name
|
||||||
|
},
|
||||||
|
}
|
||||||
196
.config/waybar/mediaplayer.py
Executable file
196
.config/waybar/mediaplayer.py
Executable file
|
|
@ -0,0 +1,196 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
import gi
|
||||||
|
gi.require_version("Playerctl", "2.0")
|
||||||
|
from gi.repository import Playerctl, GLib
|
||||||
|
from gi.repository.Playerctl import Player
|
||||||
|
import argparse
|
||||||
|
import logging
|
||||||
|
import sys
|
||||||
|
import signal
|
||||||
|
import gi
|
||||||
|
import json
|
||||||
|
import os
|
||||||
|
from typing import List
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
def signal_handler(sig, frame):
|
||||||
|
logger.info("Received signal to stop, exiting")
|
||||||
|
sys.stdout.write("\n")
|
||||||
|
sys.stdout.flush()
|
||||||
|
# loop.quit()
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
|
|
||||||
|
class PlayerManager:
|
||||||
|
def __init__(self, selected_player=None, excluded_player=[]):
|
||||||
|
self.manager = Playerctl.PlayerManager()
|
||||||
|
self.loop = GLib.MainLoop()
|
||||||
|
self.manager.connect(
|
||||||
|
"name-appeared", lambda *args: self.on_player_appeared(*args))
|
||||||
|
self.manager.connect(
|
||||||
|
"player-vanished", lambda *args: self.on_player_vanished(*args))
|
||||||
|
|
||||||
|
signal.signal(signal.SIGINT, signal_handler)
|
||||||
|
signal.signal(signal.SIGTERM, signal_handler)
|
||||||
|
signal.signal(signal.SIGPIPE, signal.SIG_DFL)
|
||||||
|
self.selected_player = selected_player
|
||||||
|
self.excluded_player = excluded_player.split(',') if excluded_player else []
|
||||||
|
|
||||||
|
self.init_players()
|
||||||
|
|
||||||
|
def init_players(self):
|
||||||
|
for player in self.manager.props.player_names:
|
||||||
|
if player.name in self.excluded_player:
|
||||||
|
continue
|
||||||
|
if self.selected_player is not None and self.selected_player != player.name:
|
||||||
|
logger.debug(f"{player.name} is not the filtered player, skipping it")
|
||||||
|
continue
|
||||||
|
self.init_player(player)
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
logger.info("Starting main loop")
|
||||||
|
self.loop.run()
|
||||||
|
|
||||||
|
def init_player(self, player):
|
||||||
|
logger.info(f"Initialize new player: {player.name}")
|
||||||
|
player = Playerctl.Player.new_from_name(player)
|
||||||
|
player.connect("playback-status",
|
||||||
|
self.on_playback_status_changed, None)
|
||||||
|
player.connect("metadata", self.on_metadata_changed, None)
|
||||||
|
self.manager.manage_player(player)
|
||||||
|
self.on_metadata_changed(player, player.props.metadata)
|
||||||
|
|
||||||
|
def get_players(self) -> List[Player]:
|
||||||
|
return self.manager.props.players
|
||||||
|
|
||||||
|
def write_output(self, text, player):
|
||||||
|
logger.debug(f"Writing output: {text}")
|
||||||
|
|
||||||
|
output = {"text": text,
|
||||||
|
"class": "custom-" + player.props.player_name,
|
||||||
|
"alt": player.props.player_name}
|
||||||
|
|
||||||
|
sys.stdout.write(json.dumps(output) + "\n")
|
||||||
|
sys.stdout.flush()
|
||||||
|
|
||||||
|
def clear_output(self):
|
||||||
|
sys.stdout.write("\n")
|
||||||
|
sys.stdout.flush()
|
||||||
|
|
||||||
|
def on_playback_status_changed(self, player, status, _=None):
|
||||||
|
logger.debug(f"Playback status changed for player {player.props.player_name}: {status}")
|
||||||
|
self.on_metadata_changed(player, player.props.metadata)
|
||||||
|
|
||||||
|
def get_first_playing_player(self):
|
||||||
|
players = self.get_players()
|
||||||
|
logger.debug(f"Getting first playing player from {len(players)} players")
|
||||||
|
if len(players) > 0:
|
||||||
|
# if any are playing, show the first one that is playing
|
||||||
|
# reverse order, so that the most recently added ones are preferred
|
||||||
|
for player in players[::-1]:
|
||||||
|
if player.props.status == "Playing":
|
||||||
|
return player
|
||||||
|
# if none are playing, show the first one
|
||||||
|
return players[0]
|
||||||
|
else:
|
||||||
|
logger.debug("No players found")
|
||||||
|
return None
|
||||||
|
|
||||||
|
def show_most_important_player(self):
|
||||||
|
logger.debug("Showing most important player")
|
||||||
|
# show the currently playing player
|
||||||
|
# or else show the first paused player
|
||||||
|
# or else show nothing
|
||||||
|
current_player = self.get_first_playing_player()
|
||||||
|
if current_player is not None:
|
||||||
|
self.on_metadata_changed(current_player, current_player.props.metadata)
|
||||||
|
else:
|
||||||
|
self.clear_output()
|
||||||
|
|
||||||
|
def on_metadata_changed(self, player, metadata, _=None):
|
||||||
|
logger.debug(f"Metadata changed for player {player.props.player_name}")
|
||||||
|
player_name = player.props.player_name
|
||||||
|
artist = player.get_artist()
|
||||||
|
artist = artist.replace("&", "&")
|
||||||
|
title = player.get_title()
|
||||||
|
title = title.replace("&", "&")
|
||||||
|
|
||||||
|
track_info = ""
|
||||||
|
if player_name == "spotify" and "mpris:trackid" in metadata.keys() and ":ad:" in player.props.metadata["mpris:trackid"]:
|
||||||
|
track_info = "Advertisement"
|
||||||
|
elif artist is not None and title is not None:
|
||||||
|
track_info = f"{artist} - {title}"
|
||||||
|
else:
|
||||||
|
track_info = title
|
||||||
|
|
||||||
|
if track_info:
|
||||||
|
if player.props.status == "Playing":
|
||||||
|
track_info = " " + track_info
|
||||||
|
else:
|
||||||
|
track_info = " " + track_info
|
||||||
|
# only print output if no other player is playing
|
||||||
|
current_playing = self.get_first_playing_player()
|
||||||
|
if current_playing is None or current_playing.props.player_name == player.props.player_name:
|
||||||
|
self.write_output(track_info, player)
|
||||||
|
else:
|
||||||
|
logger.debug(f"Other player {current_playing.props.player_name} is playing, skipping")
|
||||||
|
|
||||||
|
def on_player_appeared(self, _, player):
|
||||||
|
logger.info(f"Player has appeared: {player.name}")
|
||||||
|
if player.name in self.excluded_player:
|
||||||
|
logger.debug(
|
||||||
|
"New player appeared, but it's in exclude player list, skipping")
|
||||||
|
return
|
||||||
|
if player is not None and (self.selected_player is None or player.name == self.selected_player):
|
||||||
|
self.init_player(player)
|
||||||
|
else:
|
||||||
|
logger.debug(
|
||||||
|
"New player appeared, but it's not the selected player, skipping")
|
||||||
|
|
||||||
|
def on_player_vanished(self, _, player):
|
||||||
|
logger.info(f"Player {player.props.player_name} has vanished")
|
||||||
|
self.show_most_important_player()
|
||||||
|
|
||||||
|
def parse_arguments():
|
||||||
|
parser = argparse.ArgumentParser()
|
||||||
|
|
||||||
|
# Increase verbosity with every occurrence of -v
|
||||||
|
parser.add_argument("-v", "--verbose", action="count", default=0)
|
||||||
|
|
||||||
|
parser.add_argument("-x", "--exclude", "- Comma-separated list of excluded player")
|
||||||
|
|
||||||
|
# Define for which player we"re listening
|
||||||
|
parser.add_argument("--player")
|
||||||
|
|
||||||
|
parser.add_argument("--enable-logging", action="store_true")
|
||||||
|
|
||||||
|
return parser.parse_args()
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
arguments = parse_arguments()
|
||||||
|
|
||||||
|
# Initialize logging
|
||||||
|
if arguments.enable_logging:
|
||||||
|
logfile = os.path.join(os.path.dirname(
|
||||||
|
os.path.realpath(__file__)), "media-player.log")
|
||||||
|
logging.basicConfig(filename=logfile, level=logging.DEBUG,
|
||||||
|
format="%(asctime)s %(name)s %(levelname)s:%(lineno)d %(message)s")
|
||||||
|
|
||||||
|
# Logging is set by default to WARN and higher.
|
||||||
|
# With every occurrence of -v it's lowered by one
|
||||||
|
logger.setLevel(max((3 - arguments.verbose) * 10, 0))
|
||||||
|
|
||||||
|
logger.info("Creating player manager")
|
||||||
|
if arguments.player:
|
||||||
|
logger.info(f"Filtering for player: {arguments.player}")
|
||||||
|
if arguments.exclude:
|
||||||
|
logger.info(f"Exclude player {arguments.exclude}")
|
||||||
|
|
||||||
|
player = PlayerManager(arguments.player, arguments.exclude)
|
||||||
|
player.run()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
35
.config/waybar/style.css
Normal file
35
.config/waybar/style.css
Normal file
|
|
@ -0,0 +1,35 @@
|
||||||
|
* {
|
||||||
|
min-height: 0;
|
||||||
|
min-width: 0;
|
||||||
|
font-family: "ShureTechMono Nerd Font";
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
window#waybar {
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
#workspaces,
|
||||||
|
#custom-media,
|
||||||
|
#clock,
|
||||||
|
#pulseaudio,
|
||||||
|
#mode,
|
||||||
|
#tray
|
||||||
|
{
|
||||||
|
padding: 0.5em 1.25em;
|
||||||
|
background-color: #16191C;
|
||||||
|
border: 1px solid #252A2E;
|
||||||
|
color: #A3AAAF;
|
||||||
|
}
|
||||||
|
|
||||||
|
#workspaces button,
|
||||||
|
#mode {
|
||||||
|
color: #50555A;
|
||||||
|
font-weight: 400;
|
||||||
|
}
|
||||||
|
|
||||||
|
#workspaces button.visible {
|
||||||
|
color: #A3AAAF;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue