mirror of
https://github.com/SqrtMinusOne/dotfiles.git
synced 2025-12-11 11:43:03 +03:00
feat(emacs): which-key prefixes, remove dired+, EMMS+MPV & YouTube
This commit is contained in:
parent
9f4a0b1e09
commit
4c544d8508
3 changed files with 419 additions and 214 deletions
228
.emacs.d/init.el
228
.emacs.d/init.el
|
|
@ -202,12 +202,14 @@ then it takes a second \\[keyboard-quit] to abort the minibuffer."
|
||||||
:prefix "SPC"
|
:prefix "SPC"
|
||||||
:states '(normal motion emacs))
|
:states '(normal motion emacs))
|
||||||
|
|
||||||
|
|
||||||
(general-def :states '(normal motion emacs) "SPC" nil)
|
(general-def :states '(normal motion emacs) "SPC" nil)
|
||||||
|
|
||||||
(my-leader-def "?" 'which-key-show-top-level)
|
(my-leader-def "?" 'which-key-show-top-level)
|
||||||
(my-leader-def "E" 'eval-expression)
|
(my-leader-def "E" 'eval-expression)
|
||||||
|
|
||||||
|
(my-leader-def
|
||||||
|
"a" '(:which-key "apps"))
|
||||||
|
|
||||||
(general-def
|
(general-def
|
||||||
:keymaps 'universal-argument-map
|
:keymaps 'universal-argument-map
|
||||||
"M-u" 'universal-argument-more)
|
"M-u" 'universal-argument-more)
|
||||||
|
|
@ -216,9 +218,12 @@ then it takes a second \\[keyboard-quit] to abort the minibuffer."
|
||||||
:states '(normal motion emacs insert visual)
|
:states '(normal motion emacs insert visual)
|
||||||
"M-u" 'universal-argument)
|
"M-u" 'universal-argument)
|
||||||
|
|
||||||
(my-leader-def "Ps" 'profiler-start)
|
(my-leader-def
|
||||||
(my-leader-def "Pe" 'profiler-stop)
|
:infix "P"
|
||||||
(my-leader-def "Pp" 'profiler-report)
|
"" '(:which-key "profiler")
|
||||||
|
"s" 'profiler-start
|
||||||
|
"e" 'profiler-stop
|
||||||
|
"p" 'profiler-report)
|
||||||
|
|
||||||
(general-define-key
|
(general-define-key
|
||||||
:keymaps 'override
|
:keymaps 'override
|
||||||
|
|
@ -237,6 +242,19 @@ then it takes a second \\[keyboard-quit] to abort the minibuffer."
|
||||||
(define-key evil-window-map (kbd "u") 'winner-undo)
|
(define-key evil-window-map (kbd "u") 'winner-undo)
|
||||||
(define-key evil-window-map (kbd "U") 'winner-redo)
|
(define-key evil-window-map (kbd "U") 'winner-redo)
|
||||||
|
|
||||||
|
(my-leader-def
|
||||||
|
:infix "b"
|
||||||
|
"" '(:which-key "buffers")
|
||||||
|
"s" '((lambda () (interactive) (switch-to-buffer (persp-scratch-buffer)))
|
||||||
|
:which-key "*scratch*")
|
||||||
|
"m" '((lambda () (interactive) (persp-switch-to-buffer "*Messages*"))
|
||||||
|
:which-key "*Messages*")
|
||||||
|
"l" 'next-buffer
|
||||||
|
"h" 'previous-buffer
|
||||||
|
"k" 'kill-buffer
|
||||||
|
"b" 'persp-ivy-switch-buffer
|
||||||
|
"u" 'ibuffer)
|
||||||
|
|
||||||
(general-nmap
|
(general-nmap
|
||||||
"gD" 'xref-find-definitions-other-window
|
"gD" 'xref-find-definitions-other-window
|
||||||
"gr" 'xref-find-references)
|
"gr" 'xref-find-references)
|
||||||
|
|
@ -253,16 +271,14 @@ then it takes a second \\[keyboard-quit] to abort the minibuffer."
|
||||||
(interactive)
|
(interactive)
|
||||||
(set-face-attribute 'default nil
|
(set-face-attribute 'default nil
|
||||||
:height
|
:height
|
||||||
(+ (face-attribute 'default :height)
|
(+ (face-attribute 'default :height) 10)))
|
||||||
10)))
|
|
||||||
|
|
||||||
(defun my/zoom-out ()
|
(defun my/zoom-out ()
|
||||||
"Decrease font size by 10 points"
|
"Decrease font size by 10 points"
|
||||||
(interactive)
|
(interactive)
|
||||||
(set-face-attribute 'default nil
|
(set-face-attribute 'default nil
|
||||||
:height
|
:height
|
||||||
(- (face-attribute 'default :height)
|
(- (face-attribute 'default :height) 10)))
|
||||||
10)))
|
|
||||||
|
|
||||||
;; change font size, interactively
|
;; change font size, interactively
|
||||||
(global-set-key (kbd "C-+") 'my/zoom-in)
|
(global-set-key (kbd "C-+") 'my/zoom-in)
|
||||||
|
|
@ -342,6 +358,7 @@ then it takes a second \\[keyboard-quit] to abort the minibuffer."
|
||||||
|
|
||||||
(my-leader-def
|
(my-leader-def
|
||||||
:infix "h"
|
:infix "h"
|
||||||
|
"" '(:which-key "help")
|
||||||
"RET" 'view-order-manuals
|
"RET" 'view-order-manuals
|
||||||
"." 'display-local-help
|
"." 'display-local-help
|
||||||
"?" 'help-for-help
|
"?" 'help-for-help
|
||||||
|
|
@ -444,6 +461,7 @@ then it takes a second \\[keyboard-quit] to abort the minibuffer."
|
||||||
|
|
||||||
(my-leader-def
|
(my-leader-def
|
||||||
:infix "f"
|
:infix "f"
|
||||||
|
"" '(:which-key "various completions")'
|
||||||
;; "b" 'counsel-switch-buffer
|
;; "b" 'counsel-switch-buffer
|
||||||
"b" 'persp-ivy-switch-buffer
|
"b" 'persp-ivy-switch-buffer
|
||||||
"e" 'conda-env-activate
|
"e" 'conda-env-activate
|
||||||
|
|
@ -500,8 +518,10 @@ then it takes a second \\[keyboard-quit] to abort the minibuffer."
|
||||||
:keymaps '(treemacs-mode-map) [mouse-1] #'treemacs-single-click-expand-action)
|
:keymaps '(treemacs-mode-map) [mouse-1] #'treemacs-single-click-expand-action)
|
||||||
|
|
||||||
(my-leader-def
|
(my-leader-def
|
||||||
"tw" 'treemacs-switch-workspace
|
:infix "t"
|
||||||
"te" 'treemacs-edit-workspaces)
|
"" '(:which-key "treemacs")
|
||||||
|
"w" 'treemacs-switch-workspace
|
||||||
|
"e" 'treemacs-edit-workspaces)
|
||||||
|
|
||||||
(defun my/treemacs-open-dired ()
|
(defun my/treemacs-open-dired ()
|
||||||
"Open dired at given treemacs node"
|
"Open dired at given treemacs node"
|
||||||
|
|
@ -540,7 +560,7 @@ then it takes a second \\[keyboard-quit] to abort the minibuffer."
|
||||||
:straight t)
|
:straight t)
|
||||||
|
|
||||||
(my-leader-def
|
(my-leader-def
|
||||||
"p" 'projectile-command-map)
|
"p" '(:keymap projectile-command-map :which-key "projectile"))
|
||||||
|
|
||||||
(general-nmap "C-p" 'counsel-projectile-find-file)
|
(general-nmap "C-p" 'counsel-projectile-find-file)
|
||||||
|
|
||||||
|
|
@ -648,7 +668,7 @@ then it takes a second \\[keyboard-quit] to abort the minibuffer."
|
||||||
(show-paren-mode 1)
|
(show-paren-mode 1)
|
||||||
|
|
||||||
(setq word-wrap 1)
|
(setq word-wrap 1)
|
||||||
(global-visual-line-mode t)
|
(global-visual-line-mode 1)
|
||||||
|
|
||||||
(global-hl-line-mode 1)
|
(global-hl-line-mode 1)
|
||||||
|
|
||||||
|
|
@ -656,8 +676,6 @@ then it takes a second \\[keyboard-quit] to abort the minibuffer."
|
||||||
:straight t
|
:straight t
|
||||||
:if (display-graphic-p)
|
:if (display-graphic-p)
|
||||||
:config
|
:config
|
||||||
(set-face-attribute 'auto-dim-other-buffers-face nil
|
|
||||||
:background "#212533")
|
|
||||||
(auto-dim-other-buffers-mode t))
|
(auto-dim-other-buffers-mode t))
|
||||||
|
|
||||||
(use-package doom-themes
|
(use-package doom-themes
|
||||||
|
|
@ -721,7 +739,7 @@ then it takes a second \\[keyboard-quit] to abort the minibuffer."
|
||||||
(setq persp-sort 'created)
|
(setq persp-sort 'created)
|
||||||
:config
|
:config
|
||||||
(persp-mode)
|
(persp-mode)
|
||||||
(my-leader-def "x" 'perspective-map)
|
(my-leader-def "x" '(:keymap perspective-map :which-key "perspective"))
|
||||||
(general-define-key
|
(general-define-key
|
||||||
:keymaps 'override
|
:keymaps 'override
|
||||||
:states '(normal emacs)
|
:states '(normal emacs)
|
||||||
|
|
@ -917,29 +935,11 @@ then it takes a second \\[keyboard-quit] to abort the minibuffer."
|
||||||
"ad" #'dired
|
"ad" #'dired
|
||||||
"aD" #'my/dired-home)
|
"aD" #'my/dired-home)
|
||||||
|
|
||||||
(use-package dired+
|
(use-package diredfl
|
||||||
:straight t
|
:straight t
|
||||||
:init
|
:after dired
|
||||||
(setq diredp-hide-details-initially-flag nil)
|
|
||||||
:config
|
:config
|
||||||
(defun dired-do-delete (&optional arg)
|
(diredfl-global-mode 1))
|
||||||
"Delete all marked (or next ARG) files.
|
|
||||||
`dired-recursive-deletes' controls whether deletion of
|
|
||||||
non-empty directories is allowed."
|
|
||||||
;; This is more consistent with the file marking feature than
|
|
||||||
;; dired-do-flagged-delete.
|
|
||||||
(interactive "P")
|
|
||||||
(let (markers)
|
|
||||||
(dired-internal-do-deletions
|
|
||||||
(nreverse
|
|
||||||
;; this may move point if ARG is an integer
|
|
||||||
(dired-map-over-marks (cons (dired-get-filename)
|
|
||||||
(let ((m (point-marker)))
|
|
||||||
(push m markers)
|
|
||||||
m))
|
|
||||||
arg))
|
|
||||||
arg t)
|
|
||||||
(dolist (m markers) (set-marker m nil)))))
|
|
||||||
|
|
||||||
(use-package dired-single
|
(use-package dired-single
|
||||||
:after dired
|
:after dired
|
||||||
|
|
@ -968,6 +968,16 @@ then it takes a second \\[keyboard-quit] to abort the minibuffer."
|
||||||
:keymaps 'dired-narrow-map
|
:keymaps 'dired-narrow-map
|
||||||
[escape] 'keyboard-quit))
|
[escape] 'keyboard-quit))
|
||||||
|
|
||||||
|
(use-package dired-git-info
|
||||||
|
:straight t
|
||||||
|
:after dired
|
||||||
|
:if (not my/slow-ssh)
|
||||||
|
:config
|
||||||
|
(general-define-key
|
||||||
|
:keymap 'dired-mode-map
|
||||||
|
:states '(normal emacs)
|
||||||
|
")" 'dired-git-info-mode))
|
||||||
|
|
||||||
(defun my/dired-open-this-subdir ()
|
(defun my/dired-open-this-subdir ()
|
||||||
(interactive)
|
(interactive)
|
||||||
(dired (dired-current-directory)))
|
(dired (dired-current-directory)))
|
||||||
|
|
@ -1263,7 +1273,7 @@ then it takes a second \\[keyboard-quit] to abort the minibuffer."
|
||||||
;; (general-imap :keymaps 'org-mode-map "RET" 'evil-org-return)
|
;; (general-imap :keymaps 'org-mode-map "RET" 'evil-org-return)
|
||||||
(general-nmap :keymaps 'org-mode-map "RET" 'org-ctrl-c-ctrl-c)
|
(general-nmap :keymaps 'org-mode-map "RET" 'org-ctrl-c-ctrl-c)
|
||||||
|
|
||||||
(my-leader-def "aa" 'org-agenda)
|
;; (my-leader-def "aa" 'org-agenda)
|
||||||
(defun my/org-link-copy (&optional arg)
|
(defun my/org-link-copy (&optional arg)
|
||||||
"Extract URL from org-mode link and add it to kill ring."
|
"Extract URL from org-mode link and add it to kill ring."
|
||||||
(interactive "P")
|
(interactive "P")
|
||||||
|
|
@ -1456,8 +1466,11 @@ then it takes a second \\[keyboard-quit] to abort the minibuffer."
|
||||||
"#+end_src")
|
"#+end_src")
|
||||||
(substring data-s drawer-start)))))
|
(substring data-s drawer-start)))))
|
||||||
|
|
||||||
(my-leader-def "oc" 'org-capture)
|
(my-leader-def
|
||||||
(my-leader-def "oa" 'org-agenda)
|
:infix "o"
|
||||||
|
"" '(:which-key "org-mode")
|
||||||
|
"c" 'org-capture
|
||||||
|
"a" 'org-agenda)
|
||||||
|
|
||||||
(setq org-refile-targets
|
(setq org-refile-targets
|
||||||
'(("projects.org" :maxlevel . 2)
|
'(("projects.org" :maxlevel . 2)
|
||||||
|
|
@ -1501,6 +1514,7 @@ then it takes a second \\[keyboard-quit] to abort the minibuffer."
|
||||||
|
|
||||||
(my-leader-def
|
(my-leader-def
|
||||||
:infix "oj"
|
:infix "oj"
|
||||||
|
"" '(:which-key "org-journal")
|
||||||
"j" 'org-journal-new-entry
|
"j" 'org-journal-new-entry
|
||||||
"o" 'org-journal-open-current-journal-file
|
"o" 'org-journal-open-current-journal-file
|
||||||
"s" 'org-journal-search)
|
"s" 'org-journal-search)
|
||||||
|
|
@ -1527,6 +1541,7 @@ then it takes a second \\[keyboard-quit] to abort the minibuffer."
|
||||||
|
|
||||||
(my-leader-def
|
(my-leader-def
|
||||||
:infix "or"
|
:infix "or"
|
||||||
|
"r" '(:which-key "org-roam")
|
||||||
"i" 'org-roam-node-insert
|
"i" 'org-roam-node-insert
|
||||||
"r" 'org-roam-node-find
|
"r" 'org-roam-node-find
|
||||||
"g" 'org-roam-graph
|
"g" 'org-roam-graph
|
||||||
|
|
@ -1544,6 +1559,13 @@ then it takes a second \\[keyboard-quit] to abort the minibuffer."
|
||||||
"C-c i" 'org-id-get-create
|
"C-c i" 'org-id-get-create
|
||||||
"C-c l o" 'org-roam-node-insert))
|
"C-c l o" 'org-roam-node-insert))
|
||||||
|
|
||||||
|
(use-package org-roam-ui
|
||||||
|
:straight (:host github :repo "org-roam/org-roam-ui" :branch "main" :files ("*.el" "out"))
|
||||||
|
:after org-roam
|
||||||
|
;; :hook (org-roam . org-roam-ui-mode)
|
||||||
|
:init
|
||||||
|
(my-leader-def "oru" #'org-roam-ui-mode))
|
||||||
|
|
||||||
(use-package org-ref
|
(use-package org-ref
|
||||||
:straight (:files (:defaults (:exclude "*helm*")))
|
:straight (:files (:defaults (:exclude "*helm*")))
|
||||||
:init
|
:init
|
||||||
|
|
@ -1556,9 +1578,11 @@ then it takes a second \\[keyboard-quit] to abort the minibuffer."
|
||||||
:config
|
:config
|
||||||
(general-define-key
|
(general-define-key
|
||||||
:keymaps 'org-mode-map
|
:keymaps 'org-mode-map
|
||||||
"C-c l l" 'org-ref-ivy-insert-cite-link
|
:infix "C-c l"
|
||||||
"C-c l r" 'org-ref-ivy-insert-ref-link
|
"" '(:which-key "org-ref")
|
||||||
"C-c l h" 'org-ref-cite-hydra/body)
|
"l" 'org-ref-ivy-insert-cite-link
|
||||||
|
"r" 'org-ref-ivy-insert-ref-link
|
||||||
|
"h" 'org-ref-cite-hydra/body)
|
||||||
(general-define-key
|
(general-define-key
|
||||||
:keymaps 'bibtex-mode-map
|
:keymaps 'bibtex-mode-map
|
||||||
"M-RET" 'org-ref-bibtex-hydra/body)
|
"M-RET" 'org-ref-bibtex-hydra/body)
|
||||||
|
|
@ -1839,12 +1863,14 @@ then it takes a second \\[keyboard-quit] to abort the minibuffer."
|
||||||
:commands lsp-treemacs-errors-list)
|
:commands lsp-treemacs-errors-list)
|
||||||
|
|
||||||
(my-leader-def
|
(my-leader-def
|
||||||
"ld" 'lsp-ui-peek-find-definitions
|
:infix "l"
|
||||||
"lr" 'lsp-rename
|
"" '(:which-key "lsp")
|
||||||
"lu" 'lsp-ui-peek-find-references
|
"d" 'lsp-ui-peek-find-definitions
|
||||||
"ls" 'lsp-ui-find-workspace-symbol
|
"r" 'lsp-rename
|
||||||
;; "la" 'helm-lsp-code-actions
|
"u" 'lsp-ui-peek-find-references
|
||||||
"le" 'list-flycheck-errors)
|
"s" 'lsp-ui-find-workspace-symbol
|
||||||
|
;; "a" 'helm-lsp-code-actions
|
||||||
|
"e" 'list-flycheck-errors)
|
||||||
|
|
||||||
(use-package flycheck
|
(use-package flycheck
|
||||||
:straight t
|
:straight t
|
||||||
|
|
@ -2433,6 +2459,7 @@ then it takes a second \\[keyboard-quit] to abort the minibuffer."
|
||||||
|
|
||||||
(my-leader-def
|
(my-leader-def
|
||||||
:infix "L"
|
:infix "L"
|
||||||
|
"" '(:which-key "languagetool")
|
||||||
"c" 'langtool-check
|
"c" 'langtool-check
|
||||||
"s" 'langtool-server-stop
|
"s" 'langtool-server-stop
|
||||||
"d" 'langtool-check-done
|
"d" 'langtool-check-done
|
||||||
|
|
@ -2721,7 +2748,10 @@ then it takes a second \\[keyboard-quit] to abort the minibuffer."
|
||||||
|
|
||||||
(general-define-key "C-c c" 'my/edit-configuration)
|
(general-define-key "C-c c" 'my/edit-configuration)
|
||||||
;; (general-define-key "C-c C" 'my/edit-exwm-configuration)
|
;; (general-define-key "C-c C" 'my/edit-exwm-configuration)
|
||||||
(my-leader-def "cc" 'my/edit-configuration)
|
(my-leader-def
|
||||||
|
:infix "c"
|
||||||
|
"" '(:which-key "configuration")
|
||||||
|
"c" 'my/edit-configuration)
|
||||||
|
|
||||||
(with-eval-after-load 'tramp
|
(with-eval-after-load 'tramp
|
||||||
(add-to-list 'tramp-methods
|
(add-to-list 'tramp-methods
|
||||||
|
|
@ -2804,47 +2834,44 @@ then it takes a second \\[keyboard-quit] to abort the minibuffer."
|
||||||
(when link
|
(when link
|
||||||
(eww link))))
|
(eww link))))
|
||||||
|
|
||||||
(setq my/youtube-dl-quality-list
|
(defun my/get-youtube-url (link)
|
||||||
'("bestvideo[height<=720]+bestaudio/best[height<=720]"
|
(let ((watch-id (cadr
|
||||||
"bestvideo[height<=480]+bestaudio/best[height<=480]"
|
|
||||||
"bestvideo[height<=1080]+bestaudio/best[height<=1080]"))
|
|
||||||
|
|
||||||
(setq my/youtube-dl-quality-default "bestvideo[height<=720]+bestaudio/best[height<=720]")
|
|
||||||
|
|
||||||
(defun my/open-youtube-video (link)
|
|
||||||
"Open Youtube URL with mpv"
|
|
||||||
(interactive "MURL: ")
|
|
||||||
(let ((quality (completing-read "Quality: " my/youtube-dl-quality-list nil t))
|
|
||||||
(watch-id (cadr
|
|
||||||
(assoc "watch?v"
|
(assoc "watch?v"
|
||||||
(url-parse-query-string
|
(url-parse-query-string
|
||||||
(substring
|
(substring
|
||||||
(url-filename
|
(url-filename
|
||||||
(url-generic-parse-url link))
|
(url-generic-parse-url link))
|
||||||
1))))))
|
1))))))
|
||||||
(if (not watch-id)
|
(concat "https://www.youtube.com/watch?v=" watch-id)))
|
||||||
(message "Can't find youtube link")
|
|
||||||
(let ((yt-link (concat "https://www.youtube.com/watch?v=" watch-id))
|
|
||||||
(watch-name (concat "mpv-" watch-id)))
|
|
||||||
(start-process watch-name watch-name "mpv" yt-link
|
|
||||||
(format "--ytdl-format=%s" quality))))))
|
|
||||||
|
|
||||||
(defun my/elfeed-open-mpv ()
|
(with-eval-after-load 'emms
|
||||||
|
(define-emms-source elfeed (entry)
|
||||||
|
(let ((track (emms-track
|
||||||
|
'url (my/get-youtube-url (elfeed-entry-link entry)))))
|
||||||
|
(emms-track-set track 'info-title (elfeed-entry-title entry))
|
||||||
|
(setq my/test track)
|
||||||
|
(emms-playlist-insert-track track))))
|
||||||
|
|
||||||
|
(defun my/elfeed-add-emms-youtube ()
|
||||||
(interactive)
|
(interactive)
|
||||||
"Open MPV for the current entry"
|
(emms-add-elfeed elfeed-show-entry))
|
||||||
(my/open-youtube-video (elfeed-entry-link elfeed-show-entry)))
|
|
||||||
|
|
||||||
(with-eval-after-load 'elfeed
|
(with-eval-after-load 'elfeed
|
||||||
(evil-collection-define-key 'normal 'elfeed-show-mode-map
|
(evil-collection-define-key 'normal 'elfeed-show-mode-map
|
||||||
"gm" #'my/elfeed-open-mpv))
|
"gm" #'my/elfeed-add-emms-youtube))
|
||||||
|
|
||||||
(use-package emms
|
(use-package emms
|
||||||
:straight t
|
:straight t
|
||||||
:commands (emms-smart-browse emms-browser)
|
:commands (emms-smart-browse
|
||||||
|
emms-browser
|
||||||
|
emms-add-url
|
||||||
|
emms-add-file
|
||||||
|
emms-add-find)
|
||||||
:if (not my/is-termux)
|
:if (not my/is-termux)
|
||||||
:init
|
:init
|
||||||
(my-leader-def
|
(my-leader-def
|
||||||
:infix "as"
|
:infix "as"
|
||||||
|
"" '(:which-key "emms")
|
||||||
"s" 'emms-smart-browse
|
"s" 'emms-smart-browse
|
||||||
"b" 'emms-browser
|
"b" 'emms-browser
|
||||||
"p" 'emms-pause
|
"p" 'emms-pause
|
||||||
|
|
@ -2856,6 +2883,7 @@ then it takes a second \\[keyboard-quit] to abort the minibuffer."
|
||||||
:config
|
:config
|
||||||
(require 'emms-setup)
|
(require 'emms-setup)
|
||||||
(require 'emms-player-mpd)
|
(require 'emms-player-mpd)
|
||||||
|
(require 'emms-player-mpv)
|
||||||
(emms-all)
|
(emms-all)
|
||||||
;; MPD setup
|
;; MPD setup
|
||||||
(setq emms-source-file-default-directory (expand-file-name "~/Music/"))
|
(setq emms-source-file-default-directory (expand-file-name "~/Music/"))
|
||||||
|
|
@ -2865,9 +2893,36 @@ then it takes a second \\[keyboard-quit] to abort the minibuffer."
|
||||||
(setq emms-player-mpd-server-port "6600")
|
(setq emms-player-mpd-server-port "6600")
|
||||||
(setq emms-player-mpd-music-directory "~/Music")
|
(setq emms-player-mpd-music-directory "~/Music")
|
||||||
(emms-player-mpd-connect)
|
(emms-player-mpd-connect)
|
||||||
;; Clear MPD playlist on clearing EMMS playlist
|
|
||||||
;; IDK if this is fine for MPD playlists, I don't use them anyhow
|
|
||||||
(add-hook 'emms-playlist-cleared-hook 'emms-player-mpd-clear)
|
(add-hook 'emms-playlist-cleared-hook 'emms-player-mpd-clear)
|
||||||
|
(emms-player-set emms-player-mpd
|
||||||
|
'regex
|
||||||
|
(emms-player-simple-regexp
|
||||||
|
"m3u" "ogg" "flac" "mp3" "wav" "mod" "au" "aiff"))
|
||||||
|
;; MPV setup
|
||||||
|
(add-to-list 'emms-player-list 'emms-player-mpv t)
|
||||||
|
(emms-player-set emms-player-mpv
|
||||||
|
'regex
|
||||||
|
(rx (or (: "https://" (* nonl) "youtube.com" (* nonl))
|
||||||
|
(+ (? (or "https://" "http://"))
|
||||||
|
(* nonl)
|
||||||
|
(regexp (eval (emms-player-simple-regexp
|
||||||
|
"mp4" "mov" "wmv" "webm" "flv" "avi" "mkv")))))))
|
||||||
|
(setq my/youtube-dl-quality-list
|
||||||
|
'("bestvideo[height<=720]+bestaudio/best[height<=720]"
|
||||||
|
"bestvideo[height<=480]+bestaudio/best[height<=480]"
|
||||||
|
"bestvideo[height<=1080]+bestaudio/best[height<=1080]"))
|
||||||
|
|
||||||
|
(setq my/default-emms-player-mpv-parameters
|
||||||
|
'("--quiet" "--really-quiet" "--no-audio-display"))
|
||||||
|
|
||||||
|
(defun my/set-emms-mpd-youtube-quality (quality)
|
||||||
|
(interactive "P")
|
||||||
|
(unless quality
|
||||||
|
(setq quality (completing-read "Quality: " my/youtube-dl-quality-list nil t)))
|
||||||
|
(setq emms-player-mpv-parameters
|
||||||
|
`(,@my/default-emms-player-mpv-parameters ,(format "--ytdl-format=%s" quality))))
|
||||||
|
|
||||||
|
(my/set-emms-mpd-youtube-quality (car my/youtube-dl-quality-list))
|
||||||
;; evil-lion shadows ga bindings
|
;; evil-lion shadows ga bindings
|
||||||
(add-hook 'emms-browser-mode-hook
|
(add-hook 'emms-browser-mode-hook
|
||||||
(lambda () (evil-lion-mode -1)))
|
(lambda () (evil-lion-mode -1)))
|
||||||
|
|
@ -2914,6 +2969,19 @@ then it takes a second \\[keyboard-quit] to abort the minibuffer."
|
||||||
(setq alists (cons alist alists)))
|
(setq alists (cons alist alists)))
|
||||||
alists))))
|
alists))))
|
||||||
|
|
||||||
|
(defun my/emms-cleanup-urls ()
|
||||||
|
(interactive)
|
||||||
|
(let ((keys-to-delete '()))
|
||||||
|
(maphash (lambda (key value)
|
||||||
|
(when (eq (cdr (assoc 'type value)) 'url)
|
||||||
|
(add-to-list 'keys-to-delete key)))
|
||||||
|
emms-cache-db)
|
||||||
|
(dolist (key keys-to-delete)
|
||||||
|
(remhash key emms-cache-db)))
|
||||||
|
(setq emms-cache-dirty t))
|
||||||
|
|
||||||
|
(my-leader-def "asc" #'my/emms-cleanup-urls)
|
||||||
|
|
||||||
(with-eval-after-load 'emms-browser
|
(with-eval-after-load 'emms-browser
|
||||||
(evil-collection-define-key 'normal 'emms-browser-mode-map
|
(evil-collection-define-key 'normal 'emms-browser-mode-map
|
||||||
"q" 'quit-window))
|
"q" 'quit-window))
|
||||||
|
|
@ -2973,11 +3041,13 @@ then it takes a second \\[keyboard-quit] to abort the minibuffer."
|
||||||
("ru" . "en"))))
|
("ru" . "en"))))
|
||||||
|
|
||||||
(my-leader-def
|
(my-leader-def
|
||||||
"atp" 'google-translate-at-point
|
:infix "at"
|
||||||
"atP" 'google-translate-at-point-reverse
|
"" '(:which-key "google translate")
|
||||||
"atq" 'google-translate-query-translate
|
"p" 'google-translate-at-point
|
||||||
"atQ" 'google-translate-query-translate-reverse
|
"P" 'google-translate-at-point-reverse
|
||||||
"att" 'google-translate-smooth-translate)
|
"q" 'google-translate-query-translate
|
||||||
|
"Q" 'google-translate-query-translate-reverse
|
||||||
|
"t" 'google-translate-smooth-translate)
|
||||||
|
|
||||||
(use-package elcord
|
(use-package elcord
|
||||||
:straight t
|
:straight t
|
||||||
|
|
|
||||||
404
Emacs.org
404
Emacs.org
|
|
@ -44,6 +44,7 @@ As with other files in the repo, parts prefixed with (OFF) are not used but kept
|
||||||
- [[#universal-argument][Universal argument]]
|
- [[#universal-argument][Universal argument]]
|
||||||
- [[#profiler][Profiler]]
|
- [[#profiler][Profiler]]
|
||||||
- [[#buffer-switching][Buffer switching]]
|
- [[#buffer-switching][Buffer switching]]
|
||||||
|
- [[#buffer-management][Buffer management]]
|
||||||
- [[#xref][xref]]
|
- [[#xref][xref]]
|
||||||
- [[#folding][Folding]]
|
- [[#folding][Folding]]
|
||||||
- [[#zoom][Zoom]]
|
- [[#zoom][Zoom]]
|
||||||
|
|
@ -71,7 +72,6 @@ As with other files in the repo, parts prefixed with (OFF) are not used but kept
|
||||||
- [[#company][Company]]
|
- [[#company][Company]]
|
||||||
- [[#git--magit][Git & Magit]]
|
- [[#git--magit][Git & Magit]]
|
||||||
- [[#editorconfig][Editorconfig]]
|
- [[#editorconfig][Editorconfig]]
|
||||||
- [[#off-avy][(OFF) Avy]]
|
|
||||||
- [[#snippets][Snippets]]
|
- [[#snippets][Snippets]]
|
||||||
- [[#time-trackers][Time trackers]]
|
- [[#time-trackers][Time trackers]]
|
||||||
- [[#wakatime][WakaTime]]
|
- [[#wakatime][WakaTime]]
|
||||||
|
|
@ -97,7 +97,6 @@ As with other files in the repo, parts prefixed with (OFF) are not used but kept
|
||||||
- [[#dired][Dired]]
|
- [[#dired][Dired]]
|
||||||
- [[#basic-config--keybindings][Basic config & keybindings]]
|
- [[#basic-config--keybindings][Basic config & keybindings]]
|
||||||
- [[#addons][Addons]]
|
- [[#addons][Addons]]
|
||||||
- [[#dired-on-emacs-28][dired+ on Emacs 28]]
|
|
||||||
- [[#subdirectories][Subdirectories]]
|
- [[#subdirectories][Subdirectories]]
|
||||||
- [[#tramp][TRAMP]]
|
- [[#tramp][TRAMP]]
|
||||||
- [[#bookmarks][Bookmarks]]
|
- [[#bookmarks][Bookmarks]]
|
||||||
|
|
@ -125,6 +124,7 @@ As with other files in the repo, parts prefixed with (OFF) are not used but kept
|
||||||
- [[#custom-agendas][Custom agendas]]
|
- [[#custom-agendas][Custom agendas]]
|
||||||
- [[#org-journal][Org Journal]]
|
- [[#org-journal][Org Journal]]
|
||||||
- [[#org-roam][Org Roam]]
|
- [[#org-roam][Org Roam]]
|
||||||
|
- [[#org-roam-ui][org-roam-ui]]
|
||||||
- [[#org-roam-protocol][org-roam-protocol]]
|
- [[#org-roam-protocol][org-roam-protocol]]
|
||||||
- [[#org-ref][org-ref]]
|
- [[#org-ref][org-ref]]
|
||||||
- [[#org-roam-bibtex][org-roam-bibtex]]
|
- [[#org-roam-bibtex][org-roam-bibtex]]
|
||||||
|
|
@ -230,8 +230,11 @@ As with other files in the repo, parts prefixed with (OFF) are not used but kept
|
||||||
- [[#some-additions][Some additions]]
|
- [[#some-additions][Some additions]]
|
||||||
- [[#youtube][YouTube]]
|
- [[#youtube][YouTube]]
|
||||||
- [[#emms][EMMS]]
|
- [[#emms][EMMS]]
|
||||||
|
- [[#mpd][MPD]]
|
||||||
|
- [[#mpv][MPV]]
|
||||||
|
- [[#cache-cleanup][Cache cleanup]]
|
||||||
- [[#some-keybindings][Some keybindings]]
|
- [[#some-keybindings][Some keybindings]]
|
||||||
- [[#fixes][Fixes]]
|
- [[#emms--mpd-fixes][EMMS & mpd Fixes]]
|
||||||
- [[#eww][EWW]]
|
- [[#eww][EWW]]
|
||||||
- [[#erc][ERC]]
|
- [[#erc][ERC]]
|
||||||
- [[#google-translate][Google Translate]]
|
- [[#google-translate][Google Translate]]
|
||||||
|
|
@ -305,16 +308,14 @@ References:
|
||||||
*** Garbage collection
|
*** Garbage collection
|
||||||
Just setting ~gc-cons-treshold~ to a larger value.
|
Just setting ~gc-cons-treshold~ to a larger value.
|
||||||
|
|
||||||
| Note | Type |
|
|
||||||
|-------+---------------------------------------------------|
|
|
||||||
| CHECK | The value may be too large for an interactive use |
|
|
||||||
|
|
||||||
#+begin_src emacs-lisp
|
#+begin_src emacs-lisp
|
||||||
(setq gc-cons-threshold 80000000)
|
(setq gc-cons-threshold 80000000)
|
||||||
(setq read-process-output-max (* 1024 1024))
|
(setq read-process-output-max (* 1024 1024))
|
||||||
#+end_src
|
#+end_src
|
||||||
*** Run garbage collection when Emacs is unfocused
|
*** Run garbage collection when Emacs is unfocused
|
||||||
Run GC when Emacs loses focus. Time will tell if that's a good idea.
|
Run GC when Emacs loses focus. +Time will tell if that's a good idea.+
|
||||||
|
|
||||||
|
Some time has passed, and I still don't know if there is any quantifiable advantage to this, but it doesn't hurt.
|
||||||
|
|
||||||
#+begin_src emacs-lisp
|
#+begin_src emacs-lisp
|
||||||
(add-hook 'emacs-startup-hook
|
(add-hook 'emacs-startup-hook
|
||||||
|
|
@ -332,7 +333,7 @@ The following variable is true when my machine is not powerful enough for some r
|
||||||
(setq my/lowpower (string= (system-name) "azure"))
|
(setq my/lowpower (string= (system-name) "azure"))
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
The following is true if Emacs is meant to be used with TRAMP over slow ssh
|
The following is true if Emacs is meant to be used with TRAMP over slow ssh.
|
||||||
#+begin_src emacs-lisp
|
#+begin_src emacs-lisp
|
||||||
(setq my/slow-ssh (string= (getenv "IS_TRAMP") "true"))
|
(setq my/slow-ssh (string= (getenv "IS_TRAMP") "true"))
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
@ -384,6 +385,8 @@ By default, custom writes stuff to =init.el=, which is somewhat annoying. The fo
|
||||||
(load custom-file 'noerror)
|
(load custom-file 'noerror)
|
||||||
#+end_src
|
#+end_src
|
||||||
** No littering
|
** No littering
|
||||||
|
By default emacs and its packages create a lot files in =.emacs.d= and in other places. [[https://github.com/emacscollective/no-littering][no-littering]] is a collective effort to redirect all of this to two folders in =user-emacs-directory=.
|
||||||
|
|
||||||
#+begin_src emacs-lisp
|
#+begin_src emacs-lisp
|
||||||
(use-package no-littering
|
(use-package no-littering
|
||||||
:straight t)
|
:straight t)
|
||||||
|
|
@ -493,7 +496,7 @@ Basic evil configuration.
|
||||||
"g-" 'evil-numbers/dec-at-pt))
|
"g-" 'evil-numbers/dec-at-pt))
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
[[https://github.com/edkolev/evil-lion][evil-lion]] provides alignment operators.
|
[[https://github.com/edkolev/evil-lion][evil-lion]] provides alignment operators, somewhat similar to vim-easyalign.
|
||||||
#+begin_src emacs-lisp
|
#+begin_src emacs-lisp
|
||||||
(use-package evil-lion
|
(use-package evil-lion
|
||||||
:straight t
|
:straight t
|
||||||
|
|
@ -548,12 +551,12 @@ I don't enable the entire package, just the modes I need.
|
||||||
#+end_src
|
#+end_src
|
||||||
** More keybindigs
|
** More keybindigs
|
||||||
The main keybindigs setup is positioned after evil mode to take the latter into account.
|
The main keybindigs setup is positioned after evil mode to take the latter into account.
|
||||||
|
|
||||||
*** Escape key
|
*** Escape key
|
||||||
Use escape key instead of =C-g= whenever possible.
|
Use escape key instead of =C-g= whenever possible.
|
||||||
|
|
||||||
I must have copied it from somewhere, but as I googled to find out the original source, I discovered quite a number of variations of the following code over time.
|
I must have copied it from somewhere, but as I googled to find out the original source, I discovered quite a number of variations of the following code over time. I wonder if Richard Dawkins was inspired by something like this a few decades ago.
|
||||||
|
|
||||||
I wonder if Richard Dawkins was inspired by something like this a few decades ago.
|
|
||||||
#+begin_src emacs-lisp
|
#+begin_src emacs-lisp
|
||||||
(defun minibuffer-keyboard-quit ()
|
(defun minibuffer-keyboard-quit ()
|
||||||
"Abort recursive edit.
|
"Abort recursive edit.
|
||||||
|
|
@ -584,7 +587,7 @@ then it takes a second \\[keyboard-quit] to abort the minibuffer."
|
||||||
"<end>" 'end-of-line)
|
"<end>" 'end-of-line)
|
||||||
#+end_src
|
#+end_src
|
||||||
*** My leader
|
*** My leader
|
||||||
Using the =SPC= key as a sort of leader key.
|
Using the =SPC= key as a leader key, like in Doom Emacs or Spacemacs.
|
||||||
|
|
||||||
#+begin_src emacs-lisp
|
#+begin_src emacs-lisp
|
||||||
(general-create-definer my-leader-def
|
(general-create-definer my-leader-def
|
||||||
|
|
@ -592,14 +595,20 @@ Using the =SPC= key as a sort of leader key.
|
||||||
:prefix "SPC"
|
:prefix "SPC"
|
||||||
:states '(normal motion emacs))
|
:states '(normal motion emacs))
|
||||||
|
|
||||||
|
|
||||||
(general-def :states '(normal motion emacs) "SPC" nil)
|
(general-def :states '(normal motion emacs) "SPC" nil)
|
||||||
|
|
||||||
(my-leader-def "?" 'which-key-show-top-level)
|
(my-leader-def "?" 'which-key-show-top-level)
|
||||||
(my-leader-def "E" 'eval-expression)
|
(my-leader-def "E" 'eval-expression)
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
|
=general.el= has a nice intergration with which-key, so I use this fact to show more desriptive annotations for certain groups of keybindings (the default one is =prefix=).
|
||||||
|
#+begin_src emacs-lisp
|
||||||
|
(my-leader-def
|
||||||
|
"a" '(:which-key "apps"))
|
||||||
|
#+end_src
|
||||||
*** Universal argument
|
*** Universal argument
|
||||||
Change the universal argument to =M-u=
|
Change the universal argument to =M-u=. I use =C-u= to scroll up, as I'm used to from vim.
|
||||||
|
|
||||||
#+begin_src emacs-lisp
|
#+begin_src emacs-lisp
|
||||||
(general-def
|
(general-def
|
||||||
:keymaps 'universal-argument-map
|
:keymaps 'universal-argument-map
|
||||||
|
|
@ -611,13 +620,18 @@ Change the universal argument to =M-u=
|
||||||
#+end_src
|
#+end_src
|
||||||
*** Profiler
|
*** Profiler
|
||||||
The built-in profiler is a magnificent tool to troubleshoot performance issues.
|
The built-in profiler is a magnificent tool to troubleshoot performance issues.
|
||||||
|
|
||||||
#+begin_src emacs-lisp
|
#+begin_src emacs-lisp
|
||||||
(my-leader-def "Ps" 'profiler-start)
|
(my-leader-def
|
||||||
(my-leader-def "Pe" 'profiler-stop)
|
:infix "P"
|
||||||
(my-leader-def "Pp" 'profiler-report)
|
"" '(:which-key "profiler")
|
||||||
|
"s" 'profiler-start
|
||||||
|
"e" 'profiler-stop
|
||||||
|
"p" 'profiler-report)
|
||||||
#+end_src
|
#+end_src
|
||||||
*** Buffer switching
|
*** Buffer switching
|
||||||
Some keybindings I used in vim to switch buffers and can't let go of.
|
Some keybindings I used in vim to switch buffers and can't let go of.
|
||||||
|
|
||||||
#+begin_src emacs-lisp
|
#+begin_src emacs-lisp
|
||||||
(general-define-key
|
(general-define-key
|
||||||
:keymaps 'override
|
:keymaps 'override
|
||||||
|
|
@ -639,6 +653,21 @@ And winner-mode to keep the history of window states.
|
||||||
(define-key evil-window-map (kbd "u") 'winner-undo)
|
(define-key evil-window-map (kbd "u") 'winner-undo)
|
||||||
(define-key evil-window-map (kbd "U") 'winner-redo)
|
(define-key evil-window-map (kbd "U") 'winner-redo)
|
||||||
#+end_src
|
#+end_src
|
||||||
|
*** Buffer management
|
||||||
|
#+begin_src emacs-lisp
|
||||||
|
(my-leader-def
|
||||||
|
:infix "b"
|
||||||
|
"" '(:which-key "buffers")
|
||||||
|
"s" '((lambda () (interactive) (switch-to-buffer (persp-scratch-buffer)))
|
||||||
|
:which-key "*scratch*")
|
||||||
|
"m" '((lambda () (interactive) (persp-switch-to-buffer "*Messages*"))
|
||||||
|
:which-key "*Messages*")
|
||||||
|
"l" 'next-buffer
|
||||||
|
"h" 'previous-buffer
|
||||||
|
"k" 'kill-buffer
|
||||||
|
"b" 'persp-ivy-switch-buffer
|
||||||
|
"u" 'ibuffer)
|
||||||
|
#+end_src
|
||||||
*** xref
|
*** xref
|
||||||
Some keybindings for xref, Emacs' built-in systems for managing identifiers.
|
Some keybindings for xref, Emacs' built-in systems for managing identifiers.
|
||||||
#+begin_src emacs-lisp
|
#+begin_src emacs-lisp
|
||||||
|
|
@ -650,6 +679,12 @@ Some keybindings for xref, Emacs' built-in systems for managing identifiers.
|
||||||
"fx" 'xref-find-apropos)
|
"fx" 'xref-find-apropos)
|
||||||
#+end_src
|
#+end_src
|
||||||
*** Folding
|
*** Folding
|
||||||
|
There are multiple ways to fold text in Emacs.
|
||||||
|
|
||||||
|
The most versatile is the built-in =hs-minor-mode=, which seems to work out of box for Lisps, C-like languages and Python. =outline-minor-mode= works for org mode, LaTeX and the like. There is 3rd-party solution [[https://github.com/elp-revive/origami.el][origami.el]], but I don't use it at the moment.
|
||||||
|
|
||||||
|
Evil does a pretty good job of uniting these two in the set of vim-like keybindings. I was using =SPC= in vim, but as now this isn't an option, I set =TAB= to toggle folding.
|
||||||
|
|
||||||
#+begin_src emacs-lisp
|
#+begin_src emacs-lisp
|
||||||
(general-nmap :keymaps '(hs-minor-mode-map outline-minor-mode-map)
|
(general-nmap :keymaps '(hs-minor-mode-map outline-minor-mode-map)
|
||||||
"ze" 'hs-hide-level
|
"ze" 'hs-hide-level
|
||||||
|
|
@ -662,16 +697,14 @@ Some keybindings for xref, Emacs' built-in systems for managing identifiers.
|
||||||
(interactive)
|
(interactive)
|
||||||
(set-face-attribute 'default nil
|
(set-face-attribute 'default nil
|
||||||
:height
|
:height
|
||||||
(+ (face-attribute 'default :height)
|
(+ (face-attribute 'default :height) 10)))
|
||||||
10)))
|
|
||||||
|
|
||||||
(defun my/zoom-out ()
|
(defun my/zoom-out ()
|
||||||
"Decrease font size by 10 points"
|
"Decrease font size by 10 points"
|
||||||
(interactive)
|
(interactive)
|
||||||
(set-face-attribute 'default nil
|
(set-face-attribute 'default nil
|
||||||
:height
|
:height
|
||||||
(- (face-attribute 'default :height)
|
(- (face-attribute 'default :height) 10)))
|
||||||
10)))
|
|
||||||
|
|
||||||
;; change font size, interactively
|
;; change font size, interactively
|
||||||
(global-set-key (kbd "C-+") 'my/zoom-in)
|
(global-set-key (kbd "C-+") 'my/zoom-in)
|
||||||
|
|
@ -801,6 +834,7 @@ As I use =C-h= to switch buffers, I moved the help to =SPC-h= with the code belo
|
||||||
#+begin_src emacs-lisp
|
#+begin_src emacs-lisp
|
||||||
(my-leader-def
|
(my-leader-def
|
||||||
:infix "h"
|
:infix "h"
|
||||||
|
"" '(:which-key "help")
|
||||||
"RET" 'view-order-manuals
|
"RET" 'view-order-manuals
|
||||||
"." 'display-local-help
|
"." 'display-local-help
|
||||||
"?" 'help-for-help
|
"?" 'help-for-help
|
||||||
|
|
@ -925,6 +959,7 @@ References:
|
||||||
#+begin_src emacs-lisp
|
#+begin_src emacs-lisp
|
||||||
(my-leader-def
|
(my-leader-def
|
||||||
:infix "f"
|
:infix "f"
|
||||||
|
"" '(:which-key "various completions")'
|
||||||
;; "b" 'counsel-switch-buffer
|
;; "b" 'counsel-switch-buffer
|
||||||
"b" 'persp-ivy-switch-buffer
|
"b" 'persp-ivy-switch-buffer
|
||||||
"e" 'conda-env-activate
|
"e" 'conda-env-activate
|
||||||
|
|
@ -1019,8 +1054,12 @@ Integrates with evil, magit, projectile and perspective. The latter is particula
|
||||||
(setq treemacs-follow-after-init nil)
|
(setq treemacs-follow-after-init nil)
|
||||||
(setq treemacs-space-between-root-nodes nil)
|
(setq treemacs-space-between-root-nodes nil)
|
||||||
(treemacs-git-mode 'extended)
|
(treemacs-git-mode 'extended)
|
||||||
(with-eval-after-load 'treemacs
|
(add-to-list 'treemacs-pre-file-insert-predicates #'treemacs-is-file-git-ignored?)
|
||||||
(add-to-list 'treemacs-pre-file-insert-predicates #'treemacs-is-file-git-ignored?)))
|
(general-define-key
|
||||||
|
:keymaps 'treemacs-mode-map
|
||||||
|
[mouse-1] #'treemacs-single-click-expand-action
|
||||||
|
"M-l" #'treemacs-root-down
|
||||||
|
"M-h" #'treemacs-root-up))
|
||||||
|
|
||||||
(use-package treemacs-evil
|
(use-package treemacs-evil
|
||||||
:after (treemacs evil)
|
:after (treemacs evil)
|
||||||
|
|
@ -1044,8 +1083,10 @@ Integrates with evil, magit, projectile and perspective. The latter is particula
|
||||||
:keymaps '(treemacs-mode-map) [mouse-1] #'treemacs-single-click-expand-action)
|
:keymaps '(treemacs-mode-map) [mouse-1] #'treemacs-single-click-expand-action)
|
||||||
|
|
||||||
(my-leader-def
|
(my-leader-def
|
||||||
"tw" 'treemacs-switch-workspace
|
:infix "t"
|
||||||
"te" 'treemacs-edit-workspaces)
|
"" '(:which-key "treemacs")
|
||||||
|
"w" 'treemacs-switch-workspace
|
||||||
|
"e" 'treemacs-edit-workspaces)
|
||||||
#+end_src
|
#+end_src
|
||||||
*** Helper functions
|
*** Helper functions
|
||||||
Function to open dired and vterm at given nodes.
|
Function to open dired and vterm at given nodes.
|
||||||
|
|
@ -1093,11 +1134,10 @@ Function to open dired and vterm at given nodes.
|
||||||
:straight t)
|
:straight t)
|
||||||
|
|
||||||
(my-leader-def
|
(my-leader-def
|
||||||
"p" 'projectile-command-map)
|
"p" '(:keymap projectile-command-map :which-key "projectile"))
|
||||||
|
|
||||||
(general-nmap "C-p" 'counsel-projectile-find-file)
|
(general-nmap "C-p" 'counsel-projectile-find-file)
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
** Company
|
** Company
|
||||||
A completion framework for Emacs.
|
A completion framework for Emacs.
|
||||||
|
|
||||||
|
|
@ -1176,15 +1216,6 @@ References:
|
||||||
'(emmet-mode emmet-indentation)))
|
'(emmet-mode emmet-indentation)))
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
** OFF (OFF) Avy
|
|
||||||
#+begin_src emacs-lisp :tangle no
|
|
||||||
(use-package avy
|
|
||||||
:straight t)
|
|
||||||
|
|
||||||
(general-nmap "\\w" 'avy-goto-word-0-below)
|
|
||||||
(general-nmap "\\b" 'avy-goto-word-0-above)
|
|
||||||
#+end_src
|
|
||||||
|
|
||||||
** Snippets
|
** Snippets
|
||||||
A snippet system for Emacs and a collection of pre-built snippets.
|
A snippet system for Emacs and a collection of pre-built snippets.
|
||||||
|
|
||||||
|
|
@ -1247,13 +1278,13 @@ Disable GUI elements
|
||||||
(scroll-bar-mode -1))
|
(scroll-bar-mode -1))
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
Transparency
|
Transparency. Not setting it now, as I'm using [[file:Desktop.org::*Picom][picom]].
|
||||||
#+begin_src emacs-lisp
|
#+begin_src emacs-lisp
|
||||||
;; (set-frame-parameter (selected-frame) 'alpha '(90 . 90))
|
;; (set-frame-parameter (selected-frame) 'alpha '(90 . 90))
|
||||||
;; (add-to-list 'default-frame-alist '(alpha . (90 . 90)))
|
;; (add-to-list 'default-frame-alist '(alpha . (90 . 90)))
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
Prettify symbols
|
Prettify symbols. Also not setting it, ligatures seem to be enough for me.
|
||||||
#+begin_src emacs-lisp
|
#+begin_src emacs-lisp
|
||||||
;; (global-prettify-symbols-mode)
|
;; (global-prettify-symbols-mode)
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
@ -1295,13 +1326,17 @@ Show pairs
|
||||||
(show-paren-mode 1)
|
(show-paren-mode 1)
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
Word wrap
|
Word wrapping. These settings aren't too obvious compared to =:set wrap= from vim:
|
||||||
|
- =word-wrap= means just "don't split one word between two lines". So, if there isn't enough place to put a word at the end of line, it will be put on a new one. Run =M-x toggle-word-wrap= to toggle that.
|
||||||
|
- =visual-line-mode= seems to be a superset of =word-wrap=. It also enables some editing commands to work on visual lines instead of logical once, hence the naming.
|
||||||
|
- =auto-fill-mode= does the same as =word-wrap=, except it actually *edits the buffer* to make lines break in appropriate places.
|
||||||
|
- =truncate-lines= truncate long lines instted of continuing them. Run =M-x toggle-truncate-lines= to toggle that. I find that =truncate-lines= behaves strangely when =visual-line-mode= is on, so I use one or another.
|
||||||
#+begin_src emacs-lisp
|
#+begin_src emacs-lisp
|
||||||
(setq word-wrap 1)
|
(setq word-wrap 1)
|
||||||
(global-visual-line-mode t)
|
(global-visual-line-mode 1)
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
Hightlight line
|
Hightlight current line
|
||||||
#+begin_src emacs-lisp
|
#+begin_src emacs-lisp
|
||||||
(global-hl-line-mode 1)
|
(global-hl-line-mode 1)
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
@ -1312,8 +1347,6 @@ Dim inactive buffers.
|
||||||
:straight t
|
:straight t
|
||||||
:if (display-graphic-p)
|
:if (display-graphic-p)
|
||||||
:config
|
:config
|
||||||
(set-face-attribute 'auto-dim-other-buffers-face nil
|
|
||||||
:background "#212533")
|
|
||||||
(auto-dim-other-buffers-mode t))
|
(auto-dim-other-buffers-mode t))
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
|
|
@ -1358,7 +1391,8 @@ Also, a hook allows me to change doom-theme more or less at will, although I do
|
||||||
`(epe-pipeline-host-face ((t (:foreground ,(doom-color 'blue)))))
|
`(epe-pipeline-host-face ((t (:foreground ,(doom-color 'blue)))))
|
||||||
`(epe-pipeline-time-face ((t (:foreground ,(doom-color 'yellow)))))
|
`(epe-pipeline-time-face ((t (:foreground ,(doom-color 'yellow)))))
|
||||||
`(epe-pipeline-user-face ((t (:foreground ,(doom-color 'red)))))
|
`(epe-pipeline-user-face ((t (:foreground ,(doom-color 'red)))))
|
||||||
`(elfeed-search-tag-face ((t (:foreground ,(doom-color 'yellow))))))
|
`(elfeed-search-tag-face ((t (:foreground ,(doom-color 'yellow)))))
|
||||||
|
`(notmuch-wash-cited-text ((t (:foreground ,(doom-color 'yellow))))))
|
||||||
(custom-theme-set-variables
|
(custom-theme-set-variables
|
||||||
'my-theme
|
'my-theme
|
||||||
`(aweshell-invalid-command-color ,(doom-color 'red))
|
`(aweshell-invalid-command-color ,(doom-color 'red))
|
||||||
|
|
@ -1384,6 +1418,8 @@ References:
|
||||||
|
|
||||||
To make the icons work (e.g. in the Doom Modeline), run =M-x all-the-icons-install-fonts=. The package definition is somewhere later in the config.
|
To make the icons work (e.g. in the Doom Modeline), run =M-x all-the-icons-install-fonts=. The package definition is somewhere later in the config.
|
||||||
** Custom frame title
|
** Custom frame title
|
||||||
|
Title format, which looks something like =emacs:project@hostname=.
|
||||||
|
|
||||||
#+begin_src emacs-lisp
|
#+begin_src emacs-lisp
|
||||||
(setq-default frame-title-format
|
(setq-default frame-title-format
|
||||||
'(""
|
'(""
|
||||||
|
|
@ -1409,7 +1445,7 @@ However, I don't like that list of workspaces is displayed inside the modeline r
|
||||||
(setq persp-sort 'created)
|
(setq persp-sort 'created)
|
||||||
:config
|
:config
|
||||||
(persp-mode)
|
(persp-mode)
|
||||||
(my-leader-def "x" 'perspective-map)
|
(my-leader-def "x" '(:keymap perspective-map :which-key "perspective"))
|
||||||
(general-define-key
|
(general-define-key
|
||||||
:keymaps 'override
|
:keymaps 'override
|
||||||
:states '(normal emacs)
|
:states '(normal emacs)
|
||||||
|
|
@ -1677,15 +1713,13 @@ My config mostly follows ranger's and vifm's keybindings which I'm used to.
|
||||||
"aD" #'my/dired-home)
|
"aD" #'my/dired-home)
|
||||||
#+end_src
|
#+end_src
|
||||||
** Addons
|
** Addons
|
||||||
|
I used to use [[https://www.emacswiki.org/emacs/DiredPlus][dired+]], which provides a lot of extensions for dired functionality, but it also creates some new problems, so I opt out of it. Fortunately, the one feature I want from this package - adding more colors to dired buffers - is available as a separate package
|
||||||
[[https://www.emacswiki.org/emacs/DiredPlus][Dired+]] provides a lot of extensions for dired functionality.
|
#+begin_src emacs-lisp
|
||||||
#+begin_src emacs-lisp :noweb yes
|
(use-package diredfl
|
||||||
(use-package dired+
|
|
||||||
:straight t
|
:straight t
|
||||||
:init
|
:after dired
|
||||||
(setq diredp-hide-details-initially-flag nil)
|
|
||||||
:config
|
:config
|
||||||
<<diredp-fixes>>)
|
(diredfl-global-mode 1))
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
Reuse the current dired buffer instead of spamming new ones.
|
Reuse the current dired buffer instead of spamming new ones.
|
||||||
|
|
@ -1731,28 +1765,18 @@ vifm-like filter
|
||||||
:keymaps 'dired-narrow-map
|
:keymaps 'dired-narrow-map
|
||||||
[escape] 'keyboard-quit))
|
[escape] 'keyboard-quit))
|
||||||
#+end_src
|
#+end_src
|
||||||
*** dired+ on Emacs 28
|
|
||||||
It looks like dired+ is not quite compatible with Emacs 28. So I override certain functions for now.
|
|
||||||
|
|
||||||
#+begin_src emacs-lisp :tangle no :noweb-ref diredp-fixes
|
Display git info, such last commit for file and stuff. It's pretty useful, but also slows down Dired a bit, hence I don't turn in out by default.
|
||||||
(defun dired-do-delete (&optional arg)
|
#+begin_src emacs-lisp
|
||||||
"Delete all marked (or next ARG) files.
|
(use-package dired-git-info
|
||||||
`dired-recursive-deletes' controls whether deletion of
|
:straight t
|
||||||
non-empty directories is allowed."
|
:after dired
|
||||||
;; This is more consistent with the file marking feature than
|
:if (not my/slow-ssh)
|
||||||
;; dired-do-flagged-delete.
|
:config
|
||||||
(interactive "P")
|
(general-define-key
|
||||||
(let (markers)
|
:keymap 'dired-mode-map
|
||||||
(dired-internal-do-deletions
|
:states '(normal emacs)
|
||||||
(nreverse
|
")" 'dired-git-info-mode))
|
||||||
;; this may move point if ARG is an integer
|
|
||||||
(dired-map-over-marks (cons (dired-get-filename)
|
|
||||||
(let ((m (point-marker)))
|
|
||||||
(push m markers)
|
|
||||||
m))
|
|
||||||
arg))
|
|
||||||
arg t)
|
|
||||||
(dolist (m markers) (set-marker m nil))))
|
|
||||||
#+end_src
|
#+end_src
|
||||||
** Subdirectories
|
** Subdirectories
|
||||||
Subdirectories are one of the interesting features of Dired. It allows displaying multiple folders on the same window.
|
Subdirectories are one of the interesting features of Dired. It allows displaying multiple folders on the same window.
|
||||||
|
|
@ -2343,8 +2367,11 @@ Used files
|
||||||
|
|
||||||
Hotkeys
|
Hotkeys
|
||||||
#+begin_src emacs-lisp
|
#+begin_src emacs-lisp
|
||||||
(my-leader-def "oc" 'org-capture)
|
(my-leader-def
|
||||||
(my-leader-def "oa" 'org-agenda)
|
:infix "o"
|
||||||
|
"" '(:which-key "org-mode")
|
||||||
|
"c" 'org-capture
|
||||||
|
"a" 'org-agenda)
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
Refile targets
|
Refile targets
|
||||||
|
|
@ -2427,6 +2454,7 @@ Log DONE time
|
||||||
|
|
||||||
(my-leader-def
|
(my-leader-def
|
||||||
:infix "oj"
|
:infix "oj"
|
||||||
|
"" '(:which-key "org-journal")
|
||||||
"j" 'org-journal-new-entry
|
"j" 'org-journal-new-entry
|
||||||
"o" 'org-journal-open-current-journal-file
|
"o" 'org-journal-open-current-journal-file
|
||||||
"s" 'org-journal-search)
|
"s" 'org-journal-search)
|
||||||
|
|
@ -2465,6 +2493,7 @@ References:
|
||||||
|
|
||||||
(my-leader-def
|
(my-leader-def
|
||||||
:infix "or"
|
:infix "or"
|
||||||
|
"r" '(:which-key "org-roam")
|
||||||
"i" 'org-roam-node-insert
|
"i" 'org-roam-node-insert
|
||||||
"r" 'org-roam-node-find
|
"r" 'org-roam-node-find
|
||||||
"g" 'org-roam-graph
|
"g" 'org-roam-graph
|
||||||
|
|
@ -2482,6 +2511,17 @@ References:
|
||||||
"C-c i" 'org-id-get-create
|
"C-c i" 'org-id-get-create
|
||||||
"C-c l o" 'org-roam-node-insert))
|
"C-c l o" 'org-roam-node-insert))
|
||||||
#+end_src
|
#+end_src
|
||||||
|
**** org-roam-ui
|
||||||
|
A browser frontend to visualize a Roam directory in a form of graph.
|
||||||
|
|
||||||
|
#+begin_src emacs-lisp
|
||||||
|
(use-package org-roam-ui
|
||||||
|
:straight (:host github :repo "org-roam/org-roam-ui" :branch "main" :files ("*.el" "out"))
|
||||||
|
:after org-roam
|
||||||
|
;; :hook (org-roam . org-roam-ui-mode)
|
||||||
|
:init
|
||||||
|
(my-leader-def "oru" #'org-roam-ui-mode))
|
||||||
|
#+end_src
|
||||||
**** org-roam-protocol
|
**** org-roam-protocol
|
||||||
Open links such as =org-protocol://= from browser. Run =M-x server-start= for org-protocol to work.
|
Open links such as =org-protocol://= from browser. Run =M-x server-start= for org-protocol to work.
|
||||||
|
|
||||||
|
|
@ -2522,9 +2562,11 @@ As of now, this package loads Helm on start. To avoid this, I have to exclude He
|
||||||
:config
|
:config
|
||||||
(general-define-key
|
(general-define-key
|
||||||
:keymaps 'org-mode-map
|
:keymaps 'org-mode-map
|
||||||
"C-c l l" 'org-ref-ivy-insert-cite-link
|
:infix "C-c l"
|
||||||
"C-c l r" 'org-ref-ivy-insert-ref-link
|
"" '(:which-key "org-ref")
|
||||||
"C-c l h" 'org-ref-cite-hydra/body)
|
"l" 'org-ref-ivy-insert-cite-link
|
||||||
|
"r" 'org-ref-ivy-insert-ref-link
|
||||||
|
"h" 'org-ref-cite-hydra/body)
|
||||||
(general-define-key
|
(general-define-key
|
||||||
:keymaps 'bibtex-mode-map
|
:keymaps 'bibtex-mode-map
|
||||||
"M-RET" 'org-ref-bibtex-hydra/body)
|
"M-RET" 'org-ref-bibtex-hydra/body)
|
||||||
|
|
@ -2725,7 +2767,7 @@ Add a custom LaTeX template without default packages. Packages are indented to b
|
||||||
;; (general-imap :keymaps 'org-mode-map "RET" 'evil-org-return)
|
;; (general-imap :keymaps 'org-mode-map "RET" 'evil-org-return)
|
||||||
(general-nmap :keymaps 'org-mode-map "RET" 'org-ctrl-c-ctrl-c)
|
(general-nmap :keymaps 'org-mode-map "RET" 'org-ctrl-c-ctrl-c)
|
||||||
|
|
||||||
(my-leader-def "aa" 'org-agenda)
|
;; (my-leader-def "aa" 'org-agenda)
|
||||||
#+end_src
|
#+end_src
|
||||||
*** Copy a link
|
*** Copy a link
|
||||||
#+begin_src emacs-lisp :noweb-ref org-keys-setup
|
#+begin_src emacs-lisp :noweb-ref org-keys-setup
|
||||||
|
|
@ -2904,6 +2946,7 @@ A script to run tangle from CLI.
|
||||||
|
|
||||||
#+begin_src emacs-lisp :tangle ~/.config/yadm/hooks/run-tangle.el :noweb yes
|
#+begin_src emacs-lisp :tangle ~/.config/yadm/hooks/run-tangle.el :noweb yes
|
||||||
(require 'org)
|
(require 'org)
|
||||||
|
(require 'password-store)
|
||||||
|
|
||||||
(org-babel-do-load-languages
|
(org-babel-do-load-languages
|
||||||
'org-babel-load-languages
|
'org-babel-load-languages
|
||||||
|
|
@ -3025,12 +3068,14 @@ Origami should've leveraged LSP folding, but it was too unstable at the moment I
|
||||||
**** Keybindings
|
**** Keybindings
|
||||||
#+begin_src emacs-lisp
|
#+begin_src emacs-lisp
|
||||||
(my-leader-def
|
(my-leader-def
|
||||||
"ld" 'lsp-ui-peek-find-definitions
|
:infix "l"
|
||||||
"lr" 'lsp-rename
|
"" '(:which-key "lsp")
|
||||||
"lu" 'lsp-ui-peek-find-references
|
"d" 'lsp-ui-peek-find-definitions
|
||||||
"ls" 'lsp-ui-find-workspace-symbol
|
"r" 'lsp-rename
|
||||||
;; "la" 'helm-lsp-code-actions
|
"u" 'lsp-ui-peek-find-references
|
||||||
"le" 'list-flycheck-errors)
|
"s" 'lsp-ui-find-workspace-symbol
|
||||||
|
;; "a" 'helm-lsp-code-actions
|
||||||
|
"e" 'list-flycheck-errors)
|
||||||
#+end_src
|
#+end_src
|
||||||
*** Flycheck
|
*** Flycheck
|
||||||
A syntax checking extension for Emacs. Integrates with LSP-mode, but can also use various standalone checkers.
|
A syntax checking extension for Emacs. Integrates with LSP-mode, but can also use various standalone checkers.
|
||||||
|
|
@ -3703,6 +3748,7 @@ References:
|
||||||
|
|
||||||
(my-leader-def
|
(my-leader-def
|
||||||
:infix "L"
|
:infix "L"
|
||||||
|
"" '(:which-key "languagetool")
|
||||||
"c" 'langtool-check
|
"c" 'langtool-check
|
||||||
"s" 'langtool-server-stop
|
"s" 'langtool-server-stop
|
||||||
"d" 'langtool-check-done
|
"d" 'langtool-check-done
|
||||||
|
|
@ -4134,7 +4180,10 @@ A bunch of functions for managing dotfiles with yadm.
|
||||||
|
|
||||||
(general-define-key "C-c c" 'my/edit-configuration)
|
(general-define-key "C-c c" 'my/edit-configuration)
|
||||||
;; (general-define-key "C-c C" 'my/edit-exwm-configuration)
|
;; (general-define-key "C-c C" 'my/edit-exwm-configuration)
|
||||||
(my-leader-def "cc" 'my/edit-configuration)
|
(my-leader-def
|
||||||
|
:infix "c"
|
||||||
|
"" '(:which-key "configuration")
|
||||||
|
"c" 'my/edit-configuration)
|
||||||
#+end_src
|
#+end_src
|
||||||
*** Open Magit for yadm
|
*** Open Magit for yadm
|
||||||
Idea:
|
Idea:
|
||||||
|
|
@ -4251,53 +4300,41 @@ Open a URL with eww.
|
||||||
(eww link))))
|
(eww link))))
|
||||||
#+end_src
|
#+end_src
|
||||||
**** YouTube
|
**** YouTube
|
||||||
| Guix dependency |
|
Previously this block was opening MPV with =start-process=, but now I've managed to hook up MPV with EMMS. So there is integration of elfeed with EMMS.
|
||||||
|-----------------|
|
|
||||||
| mpv |
|
|
||||||
| youtube-dl |
|
|
||||||
|
|
||||||
A function to open YouTube link with mpv
|
|
||||||
|
|
||||||
|
The following function converts URLs from Invidious to YouTube.
|
||||||
#+begin_src emacs-lisp
|
#+begin_src emacs-lisp
|
||||||
(setq my/youtube-dl-quality-list
|
(defun my/get-youtube-url (link)
|
||||||
'("bestvideo[height<=720]+bestaudio/best[height<=720]"
|
(let ((watch-id (cadr
|
||||||
"bestvideo[height<=480]+bestaudio/best[height<=480]"
|
|
||||||
"bestvideo[height<=1080]+bestaudio/best[height<=1080]"))
|
|
||||||
|
|
||||||
(setq my/youtube-dl-quality-default "bestvideo[height<=720]+bestaudio/best[height<=720]")
|
|
||||||
|
|
||||||
(defun my/open-youtube-video (link)
|
|
||||||
"Open Youtube URL with mpv"
|
|
||||||
(interactive "MURL: ")
|
|
||||||
(let ((quality (completing-read "Quality: " my/youtube-dl-quality-list nil t))
|
|
||||||
(watch-id (cadr
|
|
||||||
(assoc "watch?v"
|
(assoc "watch?v"
|
||||||
(url-parse-query-string
|
(url-parse-query-string
|
||||||
(substring
|
(substring
|
||||||
(url-filename
|
(url-filename
|
||||||
(url-generic-parse-url link))
|
(url-generic-parse-url link))
|
||||||
1))))))
|
1))))))
|
||||||
(if (not watch-id)
|
(concat "https://www.youtube.com/watch?v=" watch-id)))
|
||||||
(message "Can't find youtube link")
|
|
||||||
(let ((yt-link (concat "https://www.youtube.com/watch?v=" watch-id))
|
|
||||||
(watch-name (concat "mpv-" watch-id)))
|
|
||||||
(start-process watch-name watch-name "mpv" yt-link
|
|
||||||
(format "--ytdl-format=%s" quality))))))
|
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
And a function to open YouTube link from elfeed
|
Now, a function to add YouTube link with metadata from elfeed to EMMS.
|
||||||
#+begin_src emacs-lisp
|
#+begin_src emacs-lisp
|
||||||
(defun my/elfeed-open-mpv ()
|
(with-eval-after-load 'emms
|
||||||
|
(define-emms-source elfeed (entry)
|
||||||
|
(let ((track (emms-track
|
||||||
|
'url (my/get-youtube-url (elfeed-entry-link entry)))))
|
||||||
|
(emms-track-set track 'info-title (elfeed-entry-title entry))
|
||||||
|
(setq my/test track)
|
||||||
|
(emms-playlist-insert-track track))))
|
||||||
|
|
||||||
|
(defun my/elfeed-add-emms-youtube ()
|
||||||
(interactive)
|
(interactive)
|
||||||
"Open MPV for the current entry"
|
(emms-add-elfeed elfeed-show-entry))
|
||||||
(my/open-youtube-video (elfeed-entry-link elfeed-show-entry)))
|
|
||||||
|
|
||||||
(with-eval-after-load 'elfeed
|
(with-eval-after-load 'elfeed
|
||||||
(evil-collection-define-key 'normal 'elfeed-show-mode-map
|
(evil-collection-define-key 'normal 'elfeed-show-mode-map
|
||||||
"gm" #'my/elfeed-open-mpv))
|
"gm" #'my/elfeed-add-emms-youtube))
|
||||||
#+end_src
|
#+end_src
|
||||||
*** EMMS
|
*** EMMS
|
||||||
EMMS is the Emacs Multi-Media System. I am controlling MPD from Emacs with its help.
|
EMMS is the Emacs Multi-Media System. I control MPD from Emacs with its help.
|
||||||
|
|
||||||
References:
|
References:
|
||||||
- [[https://www.gnu.org/software/emms/manual/][EMMS Manual]]
|
- [[https://www.gnu.org/software/emms/manual/][EMMS Manual]]
|
||||||
|
|
@ -4306,11 +4343,16 @@ References:
|
||||||
#+begin_src emacs-lisp :noweb yes
|
#+begin_src emacs-lisp :noweb yes
|
||||||
(use-package emms
|
(use-package emms
|
||||||
:straight t
|
:straight t
|
||||||
:commands (emms-smart-browse emms-browser)
|
:commands (emms-smart-browse
|
||||||
|
emms-browser
|
||||||
|
emms-add-url
|
||||||
|
emms-add-file
|
||||||
|
emms-add-find)
|
||||||
:if (not my/is-termux)
|
:if (not my/is-termux)
|
||||||
:init
|
:init
|
||||||
(my-leader-def
|
(my-leader-def
|
||||||
:infix "as"
|
:infix "as"
|
||||||
|
"" '(:which-key "emms")
|
||||||
"s" 'emms-smart-browse
|
"s" 'emms-smart-browse
|
||||||
"b" 'emms-browser
|
"b" 'emms-browser
|
||||||
"p" 'emms-pause
|
"p" 'emms-pause
|
||||||
|
|
@ -4322,18 +4364,12 @@ References:
|
||||||
:config
|
:config
|
||||||
(require 'emms-setup)
|
(require 'emms-setup)
|
||||||
(require 'emms-player-mpd)
|
(require 'emms-player-mpd)
|
||||||
|
(require 'emms-player-mpv)
|
||||||
(emms-all)
|
(emms-all)
|
||||||
;; MPD setup
|
;; MPD setup
|
||||||
(setq emms-source-file-default-directory (expand-file-name "~/Music/"))
|
<<emms-mpd-setup>>
|
||||||
(add-to-list 'emms-info-functions 'emms-info-mpd)
|
;; MPV setup
|
||||||
(add-to-list 'emms-player-list 'emms-player-mpd)
|
<<emms-mpv-setup>>
|
||||||
(setq emms-player-mpd-server-name "localhost")
|
|
||||||
(setq emms-player-mpd-server-port "6600")
|
|
||||||
(setq emms-player-mpd-music-directory "~/Music")
|
|
||||||
(emms-player-mpd-connect)
|
|
||||||
;; Clear MPD playlist on clearing EMMS playlist
|
|
||||||
;; IDK if this is fine for MPD playlists, I don't use them anyhow
|
|
||||||
(add-hook 'emms-playlist-cleared-hook 'emms-player-mpd-clear)
|
|
||||||
;; evil-lion shadows ga bindings
|
;; evil-lion shadows ga bindings
|
||||||
(add-hook 'emms-browser-mode-hook
|
(add-hook 'emms-browser-mode-hook
|
||||||
(lambda () (evil-lion-mode -1)))
|
(lambda () (evil-lion-mode -1)))
|
||||||
|
|
@ -4342,6 +4378,104 @@ References:
|
||||||
(emms-playing-time-display-mode -1)
|
(emms-playing-time-display-mode -1)
|
||||||
<<emms-fixes>>)
|
<<emms-fixes>>)
|
||||||
#+end_src
|
#+end_src
|
||||||
|
**** MPD
|
||||||
|
:PROPERTIES:
|
||||||
|
:header-args:emacs-lisp: :tangle no :noweb-ref emms-mpd-setup
|
||||||
|
:END:
|
||||||
|
[[https://www.musicpd.org/][mpd]] is server for playing music. It has a couple of first-class clients, including curses-based [[https://github.com/ncmpcpp/ncmpcpp][ncmpcpp]], but of course I want to use Emacs.
|
||||||
|
|
||||||
|
#+begin_src emacs-lisp
|
||||||
|
(setq emms-source-file-default-directory (expand-file-name "~/Music/"))
|
||||||
|
(add-to-list 'emms-info-functions 'emms-info-mpd)
|
||||||
|
(add-to-list 'emms-player-list 'emms-player-mpd)
|
||||||
|
(setq emms-player-mpd-server-name "localhost")
|
||||||
|
(setq emms-player-mpd-server-port "6600")
|
||||||
|
(setq emms-player-mpd-music-directory "~/Music")
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
Connect on setup. For some reason it stops mpd playback whenever it connects, but it is not a big issue.
|
||||||
|
#+begin_src emacs-lisp
|
||||||
|
(emms-player-mpd-connect)
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
Clear MPD playlist on clearing EMMS playlist. IDK if this is fine for MPD playlists, I don't use them anyhow.
|
||||||
|
#+begin_src emacs-lisp
|
||||||
|
(add-hook 'emms-playlist-cleared-hook 'emms-player-mpd-clear)
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
Set a custom regex for MPD. EMMS sets up the default regex from mpd diagnostic output, so that regex opens basically everything, including videos, https links, etc. That is fine is MPD is the only player in EMMS, but as I want to use MPV as well, I override the regex.
|
||||||
|
#+begin_src emacs-lisp
|
||||||
|
(emms-player-set emms-player-mpd
|
||||||
|
'regex
|
||||||
|
(emms-player-simple-regexp
|
||||||
|
"m3u" "ogg" "flac" "mp3" "wav" "mod" "au" "aiff"))
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
Now, after all this is done, run =M-x emms-cache-set-from-mpd-all= to set cache from MPD. If everything is correct, EMMS browser will be populated with MPD database.
|
||||||
|
**** MPV
|
||||||
|
:PROPERTIES:
|
||||||
|
:header-args:emacs-lisp: :tangle no :noweb-ref emms-mpv-setup
|
||||||
|
:END:
|
||||||
|
| Guix dependency |
|
||||||
|
|-----------------|
|
||||||
|
| mpv |
|
||||||
|
| youtube-dl |
|
||||||
|
|
||||||
|
[[https://mpv.io/][mpv]] is a decent media player, which has found a place in this configuration becase it integrates with youtube-dl.
|
||||||
|
|
||||||
|
#+begin_src emacs-lisp
|
||||||
|
(add-to-list 'emms-player-list 'emms-player-mpv t)
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
Also a custom regex. My demands for MPV include running =youtube-dl=, so there is a regex which matches youtube.com or some of the video formats.
|
||||||
|
#+begin_src emacs-lisp
|
||||||
|
(emms-player-set emms-player-mpv
|
||||||
|
'regex
|
||||||
|
(rx (or (: "https://" (* nonl) "youtube.com" (* nonl))
|
||||||
|
(+ (? (or "https://" "http://"))
|
||||||
|
(* nonl)
|
||||||
|
(regexp (eval (emms-player-simple-regexp
|
||||||
|
"mp4" "mov" "wmv" "webm" "flv" "avi" "mkv")))))))
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
By default MPV plays the video in the best possible quality, which may be pretty high, even too high with limited bandwidth. So here is the logic to choose youtube quality.
|
||||||
|
#+begin_src emacs-lisp
|
||||||
|
(setq my/youtube-dl-quality-list
|
||||||
|
'("bestvideo[height<=720]+bestaudio/best[height<=720]"
|
||||||
|
"bestvideo[height<=480]+bestaudio/best[height<=480]"
|
||||||
|
"bestvideo[height<=1080]+bestaudio/best[height<=1080]"))
|
||||||
|
|
||||||
|
(setq my/default-emms-player-mpv-parameters
|
||||||
|
'("--quiet" "--really-quiet" "--no-audio-display"))
|
||||||
|
|
||||||
|
(defun my/set-emms-mpd-youtube-quality (quality)
|
||||||
|
(interactive "P")
|
||||||
|
(unless quality
|
||||||
|
(setq quality (completing-read "Quality: " my/youtube-dl-quality-list nil t)))
|
||||||
|
(setq emms-player-mpv-parameters
|
||||||
|
`(,@my/default-emms-player-mpv-parameters ,(format "--ytdl-format=%s" quality))))
|
||||||
|
|
||||||
|
(my/set-emms-mpd-youtube-quality (car my/youtube-dl-quality-list))
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
Now =emms-add-url= should work on YouTube URLs just fine. Just keep in mind that it will only add the URL to the playlist, not play it right away.
|
||||||
|
**** Cache cleanup
|
||||||
|
Now, all these URLs reside in EMMS cache after being played. I don't want them to stay there for a long time, so here is a handy function to clean it.
|
||||||
|
|
||||||
|
#+begin_src emacs-lisp
|
||||||
|
(defun my/emms-cleanup-urls ()
|
||||||
|
(interactive)
|
||||||
|
(let ((keys-to-delete '()))
|
||||||
|
(maphash (lambda (key value)
|
||||||
|
(when (eq (cdr (assoc 'type value)) 'url)
|
||||||
|
(add-to-list 'keys-to-delete key)))
|
||||||
|
emms-cache-db)
|
||||||
|
(dolist (key keys-to-delete)
|
||||||
|
(remhash key emms-cache-db)))
|
||||||
|
(setq emms-cache-dirty t))
|
||||||
|
|
||||||
|
(my-leader-def "asc" #'my/emms-cleanup-urls)
|
||||||
|
#+end_src
|
||||||
**** Some keybindings
|
**** Some keybindings
|
||||||
#+begin_src emacs-lisp
|
#+begin_src emacs-lisp
|
||||||
(with-eval-after-load 'emms-browser
|
(with-eval-after-load 'emms-browser
|
||||||
|
|
@ -4352,7 +4486,7 @@ References:
|
||||||
(evil-collection-define-key 'normal 'emms-playlist-mode-map
|
(evil-collection-define-key 'normal 'emms-playlist-mode-map
|
||||||
"q" 'quit-window))
|
"q" 'quit-window))
|
||||||
#+end_src
|
#+end_src
|
||||||
**** Fixes
|
**** EMMS & mpd Fixes
|
||||||
Some fixes until I submit a patch.
|
Some fixes until I submit a patch.
|
||||||
|
|
||||||
For some reason EMMS doesn't fetch =albumartist= from MPD. Overriding this function fixes that.
|
For some reason EMMS doesn't fetch =albumartist= from MPD. Overriding this function fixes that.
|
||||||
|
|
@ -4505,11 +4639,13 @@ References:
|
||||||
("ru" . "en"))))
|
("ru" . "en"))))
|
||||||
|
|
||||||
(my-leader-def
|
(my-leader-def
|
||||||
"atp" 'google-translate-at-point
|
:infix "at"
|
||||||
"atP" 'google-translate-at-point-reverse
|
"" '(:which-key "google translate")
|
||||||
"atq" 'google-translate-query-translate
|
"p" 'google-translate-at-point
|
||||||
"atQ" 'google-translate-query-translate-reverse
|
"P" 'google-translate-at-point-reverse
|
||||||
"att" 'google-translate-smooth-translate)
|
"q" 'google-translate-query-translate
|
||||||
|
"Q" 'google-translate-query-translate-reverse
|
||||||
|
"t" 'google-translate-smooth-translate)
|
||||||
#+end_src
|
#+end_src
|
||||||
*** Discord integration
|
*** Discord integration
|
||||||
Integration with Discord. Shows which file is being edited in Emacs.
|
Integration with Discord. Shows which file is being edited in Emacs.
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,6 @@ Some of the notable programs are listed in the table below.
|
||||||
| internet | [[https://newsboat.org/][newsboat]] | terminal RSS reader | archive | - | urls are encrypted |
|
| internet | [[https://newsboat.org/][newsboat]] | terminal RSS reader | archive | - | urls are encrypted |
|
||||||
| internet | [[https://qutebrowser.org/][qutebrowser]] | browser with vim bindings | archive | - | |
|
| internet | [[https://qutebrowser.org/][qutebrowser]] | browser with vim bindings | archive | - | |
|
||||||
| internet | [[https://github.com/jarun/buku][buku]] | bookmarks manager | archive | - | |
|
| internet | [[https://github.com/jarun/buku][buku]] | bookmarks manager | archive | - | |
|
||||||
| internet | [[https://tabliss.io/][tabliss]] | new tab page | *active* | - | runned as server to work with tridactyl |
|
|
||||||
| audio | [[https://www.musicpd.org/][mpd]] | music player daemon | *active* | - | |
|
| audio | [[https://www.musicpd.org/][mpd]] | music player daemon | *active* | - | |
|
||||||
| audio | [[https://github.com/ncmpcpp/ncmpcpp][ncmpcpp]] | MPD frontend | *active* | - | |
|
| audio | [[https://github.com/ncmpcpp/ncmpcpp][ncmpcpp]] | MPD frontend | *active* | - | |
|
||||||
| misc | [[https://yadm.io][yadm]] | dotfiles manager | *active* | - | |
|
| misc | [[https://yadm.io][yadm]] | dotfiles manager | *active* | - | |
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue