Browse Source
Changed - Org-mode babel config to separate .el modules - Built-in package manager package.el to Elpaca - Configuration macro use-package to setup.el - Completion framework selectrum to verticomaster
Riyyi
2 years ago
29 changed files with 2880 additions and 2705 deletions
@ -1,471 +0,0 @@ |
|||||||
#+TITLE: Development |
|
||||||
#+OPTIONS: toc:nil |
|
||||||
#+PROPERTY: header-args:emacs-lisp :shebang ";;; -*- lexical-binding: t; -*-\n" |
|
||||||
|
|
||||||
** Table of Contents :toc_4: |
|
||||||
- [[#company][Company]] |
|
||||||
- [[#git][Git]] |
|
||||||
- [[#project][Project]] |
|
||||||
- [[#languages][Languages]] |
|
||||||
- [[#language-server-support][Language Server Support]] |
|
||||||
- [[#debug-adapter-support][Debug Adapter Support]] |
|
||||||
- [[#cc][C/C++]] |
|
||||||
- [[#cmake][CMake]] |
|
||||||
- [[#glsl][GLSL]] |
|
||||||
- [[#html][HTML]] |
|
||||||
- [[#kotlin][Kotlin]] |
|
||||||
- [[#lua][Lua]] |
|
||||||
- [[#php][PHP]] |
|
||||||
- [[#python][Python]] |
|
||||||
- [[#yaml][YAML]] |
|
||||||
- [[#quality-of-life][Quality of Life]] |
|
||||||
- [[#flycheck][Flycheck]] |
|
||||||
- [[#flyspell][Flyspell]] |
|
||||||
- [[#rainbow-delimiters][Rainbow Delimiters]] |
|
||||||
- [[#rainbow-mode][Rainbow Mode]] |
|
||||||
- [[#yasnippet][YASnippet]] |
|
||||||
|
|
||||||
** Company |
|
||||||
|
|
||||||
#+BEGIN_SRC emacs-lisp |
|
||||||
(use-package company |
|
||||||
:hook |
|
||||||
((c-mode-common |
|
||||||
emacs-lisp-mode |
|
||||||
latex-mode |
|
||||||
org-mode |
|
||||||
php-mode |
|
||||||
shell-mode |
|
||||||
shell-script-mode) |
|
||||||
. company-mode) |
|
||||||
:config |
|
||||||
(setq company-idle-delay 0.2) |
|
||||||
(setq company-minimum-prefix-length 2) |
|
||||||
(setq company-show-numbers t) |
|
||||||
(setq company-tooltip-align-annotations 't)) |
|
||||||
#+END_SRC |
|
||||||
|
|
||||||
Sort Company completions. |
|
||||||
|
|
||||||
#+BEGIN_SRC emacs-lisp |
|
||||||
(use-package company-prescient |
|
||||||
:after (company prescient) |
|
||||||
:config (company-prescient-mode)) |
|
||||||
#+END_SRC |
|
||||||
|
|
||||||
Auto-completion for C/C++ headers. |
|
||||||
|
|
||||||
#+BEGIN_SRC emacs-lisp |
|
||||||
(use-package company-c-headers |
|
||||||
:after company |
|
||||||
:config (add-to-list 'company-backends 'company-c-headers)) |
|
||||||
#+END_SRC |
|
||||||
|
|
||||||
GLSL integration with company requires the package: ~glslang~. |
|
||||||
|
|
||||||
#+BEGIN_SRC emacs-lisp |
|
||||||
(when (executable-find "glslangValidator") |
|
||||||
(use-package company-glsl |
|
||||||
:after company |
|
||||||
:config (add-to-list 'company-backends 'company-glsl))) |
|
||||||
#+END_SRC |
|
||||||
|
|
||||||
** Git |
|
||||||
|
|
||||||
#+BEGIN_SRC emacs-lisp |
|
||||||
(use-package diff-hl |
|
||||||
:demand |
|
||||||
:hook (prog-mode . turn-on-diff-hl-mode) |
|
||||||
:hook (prog-mode . dot/diff-hl-enable-flydiff-and-fringe) |
|
||||||
:config |
|
||||||
|
|
||||||
(defun dot/diff-hl-enable-flydiff-and-fringe () |
|
||||||
"Enable on the fly diff checking if file is under version control." |
|
||||||
(let ((buffer buffer-file-name)) |
|
||||||
(when (and buffer (vc-registered buffer)) |
|
||||||
(diff-hl-flydiff-mode) |
|
||||||
(dot/toggle-fringe 1))))) |
|
||||||
|
|
||||||
(use-package transient |
|
||||||
:defer t |
|
||||||
:config |
|
||||||
(setq transient-history-file (concat dot-cache-dir "/transient/history.el")) |
|
||||||
(setq transient-values-file (concat dot-cache-dir "/transient/values.el"))) |
|
||||||
|
|
||||||
(use-package magit |
|
||||||
:after (diff-hl transient) |
|
||||||
:hook (git-commit-setup . git-commit-turn-on-auto-fill) |
|
||||||
:hook (git-commit-setup . git-commit-turn-on-flyspell) |
|
||||||
:hook (magit-pre-refresh . diff-hl-magit-pre-refresh) |
|
||||||
:hook (magit-post-refresh . diff-hl-magit-post-refresh) |
|
||||||
:config |
|
||||||
(setq git-commit-fill-column 72) |
|
||||||
(setq git-commit-summary-max-length 72) |
|
||||||
(setq magit-completing-read-function #'selectrum-completing-read) |
|
||||||
(setq magit-diff-paint-whitespace-lines 'both) |
|
||||||
(setq magit-display-buffer-function #'magit-display-buffer-same-window-except-diff-v1) |
|
||||||
(setq magit-repository-directories '(("~/dotfiles" . 0) |
|
||||||
("~/code" . 3))) |
|
||||||
|
|
||||||
(put 'magit-log-select-pick :advertised-binding [?\M-c]) |
|
||||||
(put 'magit-log-select-quit :advertised-binding [?\M-k]) |
|
||||||
|
|
||||||
(defun dot/magit-select-repo () |
|
||||||
"Select project repo." |
|
||||||
(interactive) |
|
||||||
(let ((current-prefix-arg '(t))) |
|
||||||
(call-interactively #'magit-status)))) |
|
||||||
#+END_SRC |
|
||||||
|
|
||||||
** Project |
|
||||||
|
|
||||||
Project manager. |
|
||||||
|
|
||||||
[[https://michael.stapelberg.ch/posts/2021-04-02-emacs-project-override/][Adding to project.el project directory detection]]. |
|
||||||
|
|
||||||
#+BEGIN_SRC emacs-lisp |
|
||||||
(use-package project |
|
||||||
:defer t |
|
||||||
:init (setq project-list-file (concat dot-cache-dir "/projects")) |
|
||||||
:config |
|
||||||
(defun dot/project-find (dir) |
|
||||||
(let ((root (locate-dominating-file dir ".project"))) |
|
||||||
(and root (cons 'vc root)))) |
|
||||||
(add-hook 'project-find-functions #'dot/project-find) |
|
||||||
|
|
||||||
(defun dot/find-project-root () |
|
||||||
"Return root of the project, determined by `.git/' and `.project', |
|
||||||
`default-directory' otherwise." |
|
||||||
(let ((project (project-current))) |
|
||||||
(if project |
|
||||||
(project-root project) |
|
||||||
default-directory))) |
|
||||||
|
|
||||||
(defun dot/find-file-in-project-root () |
|
||||||
"Find file in project root." |
|
||||||
(interactive) |
|
||||||
(let ((default-directory (dot/find-project-root))) |
|
||||||
(call-interactively 'find-file))) |
|
||||||
|
|
||||||
(defun dot/project-remember-projects-under (dir maxdepth) |
|
||||||
"Index all projects below directory DIR recursively, until MAXDEPTH." |
|
||||||
(let ((files (mapcar 'file-name-directory |
|
||||||
(dot/directory-files-recursively-depth |
|
||||||
dir "\\.git$\\|\\.project$" t maxdepth)))) |
|
||||||
(dolist (path files) |
|
||||||
(project-remember-projects-under path)))) |
|
||||||
|
|
||||||
(unless (file-exists-p project-list-file) |
|
||||||
(project-remember-projects-under "~/dotfiles") |
|
||||||
(dot/project-remember-projects-under "~/code" 4)) |
|
||||||
|
|
||||||
(defun dot/project-project-name () |
|
||||||
"Return project name." |
|
||||||
(let ((project (project-current))) |
|
||||||
(if project |
|
||||||
(file-name-nondirectory (directory-file-name (project-root project))) |
|
||||||
"-"))) |
|
||||||
|
|
||||||
(defun dot/project-save-project-buffers () |
|
||||||
"Save all project buffers." |
|
||||||
(interactive) |
|
||||||
(let ((buffers (cl-remove-if (lambda (buffer) (not (buffer-file-name buffer))) |
|
||||||
(project-buffers (project-current))))) |
|
||||||
(save-some-buffers t (lambda () (member (current-buffer) buffers)))))) |
|
||||||
#+END_SRC |
|
||||||
|
|
||||||
** Languages |
|
||||||
|
|
||||||
*** Language Server Support |
|
||||||
|
|
||||||
Language Server Protocol. |
|
||||||
|
|
||||||
#+BEGIN_SRC emacs-lisp |
|
||||||
(use-package lsp-mode |
|
||||||
:commands lsp |
|
||||||
:after which-key |
|
||||||
:hook |
|
||||||
((c-mode ; clangd |
|
||||||
c++-mode ; clangd |
|
||||||
lua-mode ; lua-language-server |
|
||||||
php-mode ; nodejs-intelephense |
|
||||||
latex-mode ; texlab |
|
||||||
kotlin-mode ; kotlin-language-server |
|
||||||
web-mode) |
|
||||||
. lsp-deferred) |
|
||||||
:config |
|
||||||
(setq lsp-auto-guess-root t) |
|
||||||
(setq lsp-clients-clangd-args '("-j=2" |
|
||||||
"--background-index" |
|
||||||
"--clang-tidy" |
|
||||||
"--compile-commands-dir=build" |
|
||||||
"--log=error" |
|
||||||
"--pch-storage=memory" |
|
||||||
"--enable-config")) |
|
||||||
(setq lsp-clients-lua-language-server-bin "/usr/bin/lua-language-server") |
|
||||||
(setq lsp-clients-lua-language-server-install-dir "/usr/lib/lua-language-server/") |
|
||||||
(setq lsp-clients-lua-language-server-main-location "/usr/lib/lua-language-server/main.lua") |
|
||||||
(setq lsp-enable-xref t) |
|
||||||
(setq lsp-headerline-breadcrumb-enable nil) |
|
||||||
(setq lsp-intelephense-storage-path (concat dot-cache-dir "/lsp-cache")) |
|
||||||
(setq lsp-keep-workspace-alive nil) |
|
||||||
(setq lsp-prefer-flymake nil) |
|
||||||
(setq lsp-session-file (concat dot-cache-dir "/lsp-session-v1")) |
|
||||||
|
|
||||||
;; Mark clangd args variable as safe to modify via .dir-locals.el |
|
||||||
(put 'lsp-clients-clangd-args 'safe-local-variable #'listp) |
|
||||||
|
|
||||||
;; Enable which-key descriptions |
|
||||||
(dolist (leader-key (list dot/leader-key dot/leader-alt-key)) |
|
||||||
(let ((lsp-keymap-prefix (concat leader-key " l"))) |
|
||||||
(lsp-enable-which-key-integration))) |
|
||||||
|
|
||||||
(defun dot/lsp-format-buffer-or-region () |
|
||||||
"Format the selection (or buffer) with LSP." |
|
||||||
(interactive) |
|
||||||
(unless (bound-and-true-p lsp-mode) |
|
||||||
(message "Not in an LSP buffer")) |
|
||||||
(call-interactively |
|
||||||
(if (use-region-p) |
|
||||||
#'lsp-format-region |
|
||||||
#'lsp-format-buffer))) |
|
||||||
|
|
||||||
;; This is cached to prevent unneeded I/O |
|
||||||
(setq lsp-in-cpp-project-cache nil) |
|
||||||
(defun dot/lsp-format-cpp-buffer () |
|
||||||
"Format buffer in C++ projects." |
|
||||||
(unless lsp-in-cpp-project-cache |
|
||||||
(set (make-local-variable 'lsp-in-cpp-project-cache) |
|
||||||
(list |
|
||||||
(if (and (eq major-mode 'c++-mode) |
|
||||||
(bound-and-true-p lsp-mode) |
|
||||||
(or |
|
||||||
(locate-dominating-file "." ".clang-format") |
|
||||||
(locate-dominating-file "." "_clang-format"))) |
|
||||||
t |
|
||||||
nil)))) |
|
||||||
(when (car lsp-in-cpp-project-cache) |
|
||||||
(lsp-format-buffer))) |
|
||||||
(add-hook 'before-save-hook #'dot/lsp-format-cpp-buffer)) |
|
||||||
|
|
||||||
;; TODO: add lsp-signature keybinds |
|
||||||
|
|
||||||
(use-package lsp-ui |
|
||||||
:commands lsp-ui-mode |
|
||||||
:after (flycheck lsp-mode) |
|
||||||
:config |
|
||||||
(setq lsp-ui-doc-border (face-foreground 'default)) |
|
||||||
(setq lsp-ui-doc-delay 0.5) |
|
||||||
(setq lsp-ui-doc-enable t) |
|
||||||
(setq lsp-ui-doc-header t) |
|
||||||
(setq lsp-ui-doc-include-signature t) |
|
||||||
(setq lsp-ui-doc-position 'top) |
|
||||||
(setq lsp-ui-doc-use-childframe t) |
|
||||||
(setq lsp-ui-flycheck-list-position 'right) |
|
||||||
(setq lsp-ui-imenu-enable nil) |
|
||||||
(setq lsp-ui-peek-enable nil) |
|
||||||
(setq lsp-ui-sideline-enable nil)) |
|
||||||
#+END_SRC |
|
||||||
|
|
||||||
*** Debug Adapter Support |
|
||||||
|
|
||||||
Debug Adapter Protocol. |
|
||||||
|
|
||||||
#+BEGIN_SRC emacs-lisp |
|
||||||
(use-package treemacs |
|
||||||
:after all-the-icons |
|
||||||
:hook (treemacs-mode . dot/hook-disable-line-numbers) |
|
||||||
:config (setq treemacs-persist-file (concat dot-cache-dir "/treemacs/persist"))) |
|
||||||
|
|
||||||
(use-package dap-mode |
|
||||||
:after (treemacs lsp-mode) |
|
||||||
:hook (lsp-after-initialize . dot/dap-install-debug-adapters) |
|
||||||
:config |
|
||||||
(setq dap-auto-configure-features '(sessions locals expressions controls tooltip)) |
|
||||||
(setq dap-breakpoints-file (concat dot-cache-dir "/dap/breakpoints")) |
|
||||||
(setq dap-utils-extension-path (concat dot-cache-dir "/dap")) |
|
||||||
|
|
||||||
;; Create dap extension directory |
|
||||||
(unless (file-directory-p dap-utils-extension-path) |
|
||||||
(make-directory dap-utils-extension-path t)) |
|
||||||
|
|
||||||
(defun dot/dap-install-debug-adapters () |
|
||||||
"Install and Load debug adapters." |
|
||||||
(interactive) |
|
||||||
(unless (bound-and-true-p lsp-mode) |
|
||||||
(user-error "Not in an LSP buffer")) |
|
||||||
(when (string-equal major-mode "c++-mode") |
|
||||||
(require 'dap-cpptools) |
|
||||||
(dap-cpptools-setup)))) |
|
||||||
#+END_SRC |
|
||||||
|
|
||||||
*** C/C++ |
|
||||||
|
|
||||||
#+BEGIN_SRC emacs-lisp |
|
||||||
(use-package c-mode |
|
||||||
:ensure nil |
|
||||||
:defer t |
|
||||||
;; C++ // line comment style in c-mode |
|
||||||
:hook (c-mode . (lambda () |
|
||||||
(c-toggle-comment-style -1)))) |
|
||||||
#+END_SRC |
|
||||||
|
|
||||||
*** CMake |
|
||||||
|
|
||||||
#+BEGIN_SRC emacs-lisp |
|
||||||
(use-package cmake-mode |
|
||||||
:config (setq cmake-tab-width 4) |
|
||||||
:defer t) |
|
||||||
#+END_SRC |
|
||||||
|
|
||||||
*** GLSL |
|
||||||
|
|
||||||
#+BEGIN_SRC emacs-lisp |
|
||||||
(use-package glsl-mode |
|
||||||
:defer t) |
|
||||||
#+END_SRC |
|
||||||
|
|
||||||
*** HTML |
|
||||||
|
|
||||||
#+BEGIN_SRC emacs-lisp |
|
||||||
(use-package web-mode |
|
||||||
:defer t) |
|
||||||
#+END_SRC |
|
||||||
|
|
||||||
*** Kotlin |
|
||||||
|
|
||||||
#+BEGIN_SRC emacs-lisp |
|
||||||
(use-package kotlin-mode |
|
||||||
:defer t) |
|
||||||
#+END_SRC |
|
||||||
|
|
||||||
*** Lua |
|
||||||
|
|
||||||
#+BEGIN_SRC emacs-lisp |
|
||||||
(use-package lua-mode |
|
||||||
:defer t |
|
||||||
:config (setq lua-indent-level 4)) |
|
||||||
#+END_SRC |
|
||||||
|
|
||||||
*** PHP |
|
||||||
|
|
||||||
#+BEGIN_SRC emacs-lisp |
|
||||||
(use-package php-mode |
|
||||||
:defer t |
|
||||||
:hook |
|
||||||
(php-mode . (lambda () |
|
||||||
(setq indent-tabs-mode t)))) |
|
||||||
|
|
||||||
(use-package restclient |
|
||||||
:defer t) |
|
||||||
#+END_SRC |
|
||||||
|
|
||||||
*** Python |
|
||||||
|
|
||||||
#+BEGIN_SRC emacs-lisp |
|
||||||
(use-package python-mode |
|
||||||
:ensure nil |
|
||||||
:defer t |
|
||||||
:hook (python-mode . (lambda () |
|
||||||
(setq indent-tabs-mode t) |
|
||||||
(setq python-indent-offset 4) |
|
||||||
(setq tab-width 4)))) |
|
||||||
#+END_SRC |
|
||||||
|
|
||||||
*** YAML |
|
||||||
|
|
||||||
#+BEGIN_SRC emacs-lisp |
|
||||||
(use-package yaml-mode |
|
||||||
:defer t) |
|
||||||
#+END_SRC |
|
||||||
|
|
||||||
** Quality of Life |
|
||||||
|
|
||||||
**** Flycheck |
|
||||||
|
|
||||||
On the fly syntax checking. |
|
||||||
|
|
||||||
#+BEGIN_SRC emacs-lisp |
|
||||||
(use-package flycheck |
|
||||||
:hook |
|
||||||
((c-mode-common |
|
||||||
emacs-lisp-mode |
|
||||||
latex-mode |
|
||||||
org-mode |
|
||||||
php-mode |
|
||||||
sh-mode |
|
||||||
shell-mode |
|
||||||
shell-script-mode) |
|
||||||
. flycheck-mode) |
|
||||||
:config |
|
||||||
(setq flycheck-clang-language-standard "c++20") |
|
||||||
(setq flycheck-gcc-language-standard "c++20")) |
|
||||||
|
|
||||||
;; For .el files which are intended to be packages |
|
||||||
(use-package flycheck-package |
|
||||||
:after flycheck |
|
||||||
:config |
|
||||||
(add-to-list 'flycheck-checkers 'flycheck-emacs-lisp-package) |
|
||||||
(flycheck-package-setup)) |
|
||||||
|
|
||||||
(use-package flycheck-clang-tidy |
|
||||||
:after flycheck |
|
||||||
:hook (flycheck-mode . flycheck-clang-tidy-setup) |
|
||||||
:config (setq flycheck-clang-tidy-extra-options "--format-style=file")) |
|
||||||
#+END_SRC |
|
||||||
|
|
||||||
**** Flyspell |
|
||||||
|
|
||||||
Give Flyspell a selection menu. |
|
||||||
|
|
||||||
#+BEGIN_SRC emacs-lisp |
|
||||||
(use-package flyspell-correct |
|
||||||
:after flyspell |
|
||||||
:demand |
|
||||||
:hook (org-mode . flyspell-mode) |
|
||||||
:config |
|
||||||
(setq flyspell-issue-message-flag nil) |
|
||||||
(setq flyspell-issue-welcome-flag nil) |
|
||||||
|
|
||||||
(defun dot/flyspell-toggle () |
|
||||||
"Toggle Flyspell, prompt for language." |
|
||||||
(interactive) |
|
||||||
(if (symbol-value flyspell-mode) |
|
||||||
(flyspell-mode -1) |
|
||||||
(call-interactively 'ispell-change-dictionary) |
|
||||||
(if (derived-mode-p 'prog-mode) |
|
||||||
(flyspell-prog-mode) |
|
||||||
(flyspell-mode)) |
|
||||||
(flyspell-buffer)))) |
|
||||||
#+END_SRC |
|
||||||
|
|
||||||
**** Rainbow Delimiters |
|
||||||
|
|
||||||
#+BEGIN_SRC emacs-lisp |
|
||||||
(use-package rainbow-delimiters |
|
||||||
:hook (prog-mode . rainbow-delimiters-mode)) |
|
||||||
#+END_SRC |
|
||||||
|
|
||||||
**** Rainbow Mode |
|
||||||
|
|
||||||
#+BEGIN_SRC emacs-lisp |
|
||||||
(use-package rainbow-mode |
|
||||||
:hook (css-mode . rainbow-mode)) |
|
||||||
#+END_SRC |
|
||||||
|
|
||||||
**** YASnippet |
|
||||||
|
|
||||||
#+BEGIN_SRC emacs-lisp |
|
||||||
(use-package yasnippet |
|
||||||
:defer t |
|
||||||
:init |
|
||||||
(setq yas-snippet-dirs (list (concat dot-emacs-dir "/snippets"))) |
|
||||||
(setq yas-prompt-functions '(yas-completing-prompt)) |
|
||||||
:config |
|
||||||
(yas-global-mode)) |
|
||||||
|
|
||||||
(use-package yasnippet-snippets |
|
||||||
:after yasnippet) |
|
||||||
#+END_SRC |
|
||||||
|
|
||||||
https://stackoverflow.com/questions/22735895/configuring-a-yasnippet-for-two-scenarios-1-region-is-active-2-region-is |
|
@ -1,108 +0,0 @@ |
|||||||
#+TITLE: Evil |
|
||||||
#+OPTIONS: toc:nil |
|
||||||
#+PROPERTY: header-args:emacs-lisp :shebang ";;; -*- lexical-binding: t; -*-\n" |
|
||||||
|
|
||||||
** Table of Contents :toc_4: |
|
||||||
- [[#evil][Evil]] |
|
||||||
|
|
||||||
** Evil |
|
||||||
|
|
||||||
Evil mode and related packages. |
|
||||||
|
|
||||||
#+BEGIN_SRC emacs-lisp |
|
||||||
(use-package undo-tree |
|
||||||
:config |
|
||||||
(setq undo-tree-auto-save-history t) |
|
||||||
(setq undo-tree-history-directory-alist `(("." . ,(concat dot-cache-dir "/undo-tree")))) |
|
||||||
(global-undo-tree-mode)) |
|
||||||
|
|
||||||
(use-package goto-chg) |
|
||||||
|
|
||||||
(use-package evil |
|
||||||
:after (undo-tree goto-chg) |
|
||||||
:init |
|
||||||
(setq evil-ex-complete-emacs-commands nil) |
|
||||||
(setq evil-kill-on-visual-paste nil) |
|
||||||
(setq evil-operator-state-cursor 'box) ; Do not set half cursor |
|
||||||
(setq evil-search-module 'evil-search) |
|
||||||
(setq evil-split-window-below t) |
|
||||||
(setq evil-undo-system 'undo-tree) |
|
||||||
(setq evil-vsplit-window-right t) |
|
||||||
(setq evil-want-C-u-scroll t) |
|
||||||
(setq evil-want-Y-yank-to-eol t) |
|
||||||
(setq evil-want-keybinding nil) ; Needed by evil-collection |
|
||||||
:config |
|
||||||
|
|
||||||
(defun dot/evil-normal-sort-paragraph () |
|
||||||
"Sort paragraph cursor is under. |
|
||||||
|
|
||||||
Vim equivalence: vip:sort<CR>" |
|
||||||
(interactive) |
|
||||||
(let ((p (point))) |
|
||||||
(evil-visual-char) |
|
||||||
(call-interactively 'evil-inner-paragraph) |
|
||||||
(evil-ex-sort (region-beginning) (region-end)) |
|
||||||
(goto-char p))) |
|
||||||
|
|
||||||
(defun dot/evil-insert-shift-left () |
|
||||||
"Shift line left, retains cursor position. |
|
||||||
|
|
||||||
Vim equivalence: <C-D>" |
|
||||||
(interactive) |
|
||||||
(evil-shift-left-line 1)) |
|
||||||
|
|
||||||
(defun dot/evil-insert-shift-right () |
|
||||||
"Shift line right, retains cursor position. |
|
||||||
|
|
||||||
Vim equivalence: <Tab>" |
|
||||||
(interactive) |
|
||||||
(insert "\t")) |
|
||||||
|
|
||||||
(defun dot/evil-visual-shift-left () |
|
||||||
"Shift visual selection left, retains the selection. |
|
||||||
|
|
||||||
Vim equivalence: <gv" |
|
||||||
(interactive) |
|
||||||
(call-interactively #'evil-shift-left) |
|
||||||
(setq deactivate-mark nil)) |
|
||||||
|
|
||||||
(defun dot/evil-visual-shift-right () |
|
||||||
"Shift visual selection left, retains the selection. |
|
||||||
|
|
||||||
Vim equivalence: >gv" |
|
||||||
(interactive) |
|
||||||
(call-interactively #'evil-shift-right) |
|
||||||
(setq deactivate-mark nil)) |
|
||||||
|
|
||||||
(evil-mode)) |
|
||||||
#+END_SRC |
|
||||||
|
|
||||||
Evil command aliases. |
|
||||||
|
|
||||||
#+BEGIN_SRC emacs-lisp |
|
||||||
(use-package evil-ex |
|
||||||
:ensure nil ; evil-ex.el is part of evil |
|
||||||
:after evil |
|
||||||
:config |
|
||||||
(evil-ex-define-cmd "W" "w") |
|
||||||
(evil-ex-define-cmd "Q" "q") |
|
||||||
(evil-ex-define-cmd "WQ" "wq") |
|
||||||
(evil-ex-define-cmd "Wq" "wq")) |
|
||||||
#+END_SRC |
|
||||||
|
|
||||||
#+BEGIN_SRC emacs-lisp |
|
||||||
(use-package evil-collection |
|
||||||
:after evil |
|
||||||
:init |
|
||||||
(setq evil-collection-company-use-tng nil) |
|
||||||
(setq evil-collection-key-blacklist (list dot/leader-key dot/localleader-key |
|
||||||
dot/leader-alt-key dot/localleader-alt-key |
|
||||||
"M-h" "M-j" "M-k" "M-l")) |
|
||||||
(setq evil-collection-setup-minibuffer t) |
|
||||||
:config |
|
||||||
(evil-collection-init)) |
|
||||||
|
|
||||||
(use-package evil-nerd-commenter |
|
||||||
:defer t |
|
||||||
:after evil) |
|
||||||
#+END_SRC |
|
@ -1,157 +0,0 @@ |
|||||||
#+TITLE: Mail Configuration |
|
||||||
#+OPTIONS: toc:nil |
|
||||||
#+PROPERTY: header-args:emacs-lisp :shebang ";;; -*- lexical-binding: t; -*-\n" |
|
||||||
|
|
||||||
** Table of Contents :toc_4: |
|
||||||
- [[#mail-functions][Mail Functions]] |
|
||||||
- [[#mail-in-emacs-with-mu4e][Mail in Emacs with mu4e]] |
|
||||||
- [[#sources][Sources]] |
|
||||||
|
|
||||||
** Mail Functions |
|
||||||
|
|
||||||
#+BEGIN_SRC emacs-lisp |
|
||||||
(with-eval-after-load 'auth-source |
|
||||||
(defun dot/mail-auth-get-field (host prop) |
|
||||||
"Find PROP in `auth-sources' for HOST entry." |
|
||||||
(when-let ((source (auth-source-search :max 1 :host host))) |
|
||||||
(if (eq prop :secret) |
|
||||||
(funcall (plist-get (car source) prop)) |
|
||||||
(plist-get (flatten-list source) prop))))) |
|
||||||
#+END_SRC |
|
||||||
|
|
||||||
** Mail in Emacs with mu4e |
|
||||||
|
|
||||||
Useful mu4e manual pages: |
|
||||||
|
|
||||||
- [[https://www.djcbsoftware.nl/code/mu/mu4e/MSGV-Keybindings.html#MSGV-Keybindings][Key bindings]] |
|
||||||
|
|
||||||
#+BEGIN_SRC emacs-lisp |
|
||||||
(use-package mu4e |
|
||||||
:ensure nil |
|
||||||
:load-path "/usr/share/emacs/site-lisp/mu4e" |
|
||||||
:defer 20 |
|
||||||
:commands mu4e |
|
||||||
:config |
|
||||||
(setq auth-sources `(,(concat dot-etc-dir "/authinfo.gpg"))) |
|
||||||
(setq user-full-name (dot/mail-auth-get-field "fullname" :user)) |
|
||||||
(setq user-mail-address (dot/mail-auth-get-field "info" :user)) |
|
||||||
(setq mail-user-agent 'mu4e-user-agent) |
|
||||||
|
|
||||||
;; Headers |
|
||||||
(setq mu4e-headers-date-format "%d-%m-%Y") |
|
||||||
(setq mu4e-headers-time-format "%I:%M %p") |
|
||||||
(setq mu4e-headers-long-date-format "%d-%m-%Y %I:%M:%S %p") |
|
||||||
|
|
||||||
;; Syncing |
|
||||||
(setq mu4e-get-mail-command (concat "mbsync -a -c " (getenv "XDG_CONFIG_HOME") "/isync/mbsyncrc")) |
|
||||||
(setq mu4e-update-interval (* 15 60)) ; 15 minutes |
|
||||||
(setq mu4e-maildir "~/mail") |
|
||||||
(setq mu4e-attachment-dir "~/downloads") |
|
||||||
|
|
||||||
;; Avoid mail syncing issues when using mbsync |
|
||||||
(setq mu4e-change-filenames-when-moving t) |
|
||||||
|
|
||||||
;; Misc |
|
||||||
(setq mu4e-completing-read-function 'completing-read) |
|
||||||
(setq mu4e-confirm-quit nil) |
|
||||||
(setq mu4e-display-update-status-in-modeline t) |
|
||||||
(setq mu4e-hide-index-messages t) |
|
||||||
(setq mu4e-sent-messages-behavior 'sent) |
|
||||||
(setq mu4e-view-show-addresses t) |
|
||||||
(setq mu4e-view-show-images nil) |
|
||||||
|
|
||||||
;; Compose |
|
||||||
(setq mu4e-compose-context-policy 'ask) |
|
||||||
(setq mu4e-compose-dont-reply-to-self t) |
|
||||||
(setq mu4e-compose-signature (concat (dot/mail-auth-get-field "fullname" :user) "\nriyyi.com\n")) |
|
||||||
(setq mu4e-compose-signature-auto-include t) |
|
||||||
|
|
||||||
;; Contexts |
|
||||||
(setq mu4e-context-policy 'pick-first) |
|
||||||
(setq mu4e-contexts |
|
||||||
`(,(make-mu4e-context |
|
||||||
:name "info" |
|
||||||
:match-func (lambda (msg) |
|
||||||
(when msg |
|
||||||
(string= (mu4e-message-field msg :maildir) "/info"))) |
|
||||||
:vars `((user-mail-address . ,(dot/mail-auth-get-field "info" :user)) |
|
||||||
(mu4e-drafts-folder . "/info/Drafts") |
|
||||||
(mu4e-refile-folder . "/info/Archive") |
|
||||||
(mu4e-sent-folder . "/info/Sent") |
|
||||||
(mu4e-trash-folder . "/info/Trash"))) |
|
||||||
,(make-mu4e-context |
|
||||||
:name "private" |
|
||||||
:match-func (lambda (msg) |
|
||||||
(when msg |
|
||||||
(string= (mu4e-message-field msg :maildir) "/private"))) |
|
||||||
:vars `((user-mail-address . ,(dot/mail-auth-get-field "private" :user)) |
|
||||||
(mu4e-drafts-folder . "/private/Drafts") |
|
||||||
(mu4e-refile-folder . "/private/Archive") |
|
||||||
(mu4e-sent-folder . "/private/Sent") |
|
||||||
(mu4e-trash-folder . "/private/Trash"))) |
|
||||||
)) |
|
||||||
|
|
||||||
;; Do not mark messages as IMAP-deleted, just move them to the Trash directory! |
|
||||||
;; https://github.com/djcb/mu/issues/1136#issuecomment-486177435 |
|
||||||
(setf (alist-get 'trash mu4e-marks) |
|
||||||
(list :char '("d" . "▼") |
|
||||||
:prompt "dtrash" |
|
||||||
:dyn-target (lambda (target msg) |
|
||||||
(mu4e-get-trash-folder msg)) |
|
||||||
:action (lambda (docid msg target) |
|
||||||
(mu4e~proc-move docid (mu4e~mark-check-target target) "-N")))) |
|
||||||
|
|
||||||
;; Start mu4e in the background for mail syncing |
|
||||||
(mu4e t)) |
|
||||||
#+END_SRC |
|
||||||
|
|
||||||
Use [[https://github.com/iqbalansari/mu4e-alert][mu4e-alert]] to show new e-mail notifications. |
|
||||||
|
|
||||||
#+BEGIN_SRC emacs-lisp |
|
||||||
|
|
||||||
(use-package mu4e-alert |
|
||||||
:after mu4e |
|
||||||
:config |
|
||||||
(setq mu4e-alert-interesting-mail-query "(maildir:/info/Inbox OR maildir:/private/Inbox) AND flag:unread AND NOT flag:trashed") |
|
||||||
(setq mu4e-alert-notify-repeated-mails nil) |
|
||||||
|
|
||||||
(mu4e-alert-set-default-style 'libnotify) |
|
||||||
(mu4e-alert-enable-notifications)) |
|
||||||
#+END_SRC |
|
||||||
|
|
||||||
Sending mail. |
|
||||||
|
|
||||||
#+BEGIN_SRC emacs-lisp |
|
||||||
(use-package smtpmail |
|
||||||
:ensure nil ; built-in |
|
||||||
:after mu4e |
|
||||||
:init (setq smtpmail-default-smtp-server "mail.riyyi.com") |
|
||||||
:config |
|
||||||
(setq smtpmail-smtp-server "mail.riyyi.com") |
|
||||||
(setq smtpmail-local-domain "riyyi.com") |
|
||||||
(setq smtpmail-smtp-service 587) |
|
||||||
(setq smtpmail-stream-type 'starttls) |
|
||||||
(setq smtpmail-queue-mail nil)) |
|
||||||
|
|
||||||
(use-package sendmail |
|
||||||
:ensure nil ; built-in |
|
||||||
:after mu4e |
|
||||||
:config (setq send-mail-function 'smtpmail-send-it)) |
|
||||||
|
|
||||||
(use-package message |
|
||||||
:ensure nil ; built-in |
|
||||||
:after mu4e |
|
||||||
:config |
|
||||||
(setq message-kill-buffer-on-exit t) |
|
||||||
(setq message-send-mail-function 'smtpmail-send-it)) |
|
||||||
#+END_SRC |
|
||||||
|
|
||||||
** Sources |
|
||||||
|
|
||||||
- https://rakhim.org/fastmail-setup-with-emacs-mu4e-and-mbsync-on-macos/ |
|
||||||
- https://wiki.archlinux.org/title/Isync |
|
||||||
- https://man.archlinux.org/man/community/isync/mbsync.1.en |
|
||||||
- https://gitlab.com/protesilaos/dotfiles/-/blob/master/mbsync/.mbsyncrc |
|
||||||
- https://gitlab.com/protesilaos/dotfiles/-/blob/master/emacs/.emacs.d/prot-lisp/prot-mail.el |
|
||||||
- https://gitlab.com/protesilaos/dotfiles/-/blob/master/emacs/.emacs.d/prot-lisp/prot-mu4e-deprecated-conf.el |
|
||||||
- https://github.com/daviwil/dotfiles/blob/master/Mail.org |
|
@ -1,331 +0,0 @@ |
|||||||
#+TITLE: Org Mode |
|
||||||
#+OPTIONS: toc:nil |
|
||||||
#+PROPERTY: header-args:emacs-lisp :shebang ";;; -*- lexical-binding: t; -*-\n" |
|
||||||
|
|
||||||
** Table of Contents :toc_4: |
|
||||||
- [[#latex-configuration][LaTeX Configuration]] |
|
||||||
- [[#org-configuration][Org Configuration]] |
|
||||||
- [[#org-functions][Org Functions]] |
|
||||||
- [[#org-bullets][Org Bullets]] |
|
||||||
- [[#org-export-packages][Org Export Packages]] |
|
||||||
- [[#org-roam][Org Roam]] |
|
||||||
- [[#org-table-of-contents][Org "Table of Contents"]] |
|
||||||
|
|
||||||
** LaTeX Configuration |
|
||||||
|
|
||||||
#+BEGIN_SRC emacs-lisp |
|
||||||
(use-package tex-mode |
|
||||||
:ensure nil ; built-in |
|
||||||
:defer t |
|
||||||
:hook (latex-mode . (lambda () |
|
||||||
(setq indent-tabs-mode t) |
|
||||||
(setq tab-width 4) |
|
||||||
(setq tex-indent-basic 4))) |
|
||||||
:config |
|
||||||
|
|
||||||
(with-eval-after-load 'project |
|
||||||
(defun compile-latex () |
|
||||||
"Compile LaTeX project." |
|
||||||
(interactive) |
|
||||||
(let ((default-directory (dot/find-project-root))) |
|
||||||
(dot/project-save-project-buffers) |
|
||||||
(shell-command "make"))))) |
|
||||||
#+END_SRC |
|
||||||
|
|
||||||
** Org Configuration |
|
||||||
|
|
||||||
|
|
||||||
Base Org. |
|
||||||
|
|
||||||
#+BEGIN_SRC emacs-lisp |
|
||||||
(use-package org |
|
||||||
:config |
|
||||||
(setq org-adapt-indentation nil) |
|
||||||
(setq org-default-notes-file (expand-file-name "notes.org" org-directory)) |
|
||||||
(setq org-directory (concat (getenv "HOME") "/documents/org")) |
|
||||||
(setq org-ellipsis "⤵") |
|
||||||
(setq org-image-actual-width nil) |
|
||||||
|
|
||||||
;; Enable structured template completion |
|
||||||
(add-to-list 'org-modules 'org-tempo t) |
|
||||||
(add-to-list 'org-structure-template-alist |
|
||||||
'("el" . "src emacs-lisp"))) |
|
||||||
#+END_SRC |
|
||||||
|
|
||||||
Org agenda. |
|
||||||
|
|
||||||
#+BEGIN_SRC emacs-lisp |
|
||||||
(use-package org-agenda |
|
||||||
:ensure nil ; built-in |
|
||||||
:defer t |
|
||||||
:config |
|
||||||
(setq org-agenda-files `(,org-directory ,user-emacs-directory)) |
|
||||||
(setq org-agenda-span 14) |
|
||||||
(setq org-agenda-window-setup 'current-window) |
|
||||||
(evil-set-initial-state 'org-agenda-mode 'motion)) |
|
||||||
#+END_SRC |
|
||||||
|
|
||||||
Org capture. |
|
||||||
|
|
||||||
#+BEGIN_SRC emacs-lisp |
|
||||||
(use-package org-capture |
|
||||||
:ensure nil ; built-in |
|
||||||
;; Org-capture in new tab, rather than split window |
|
||||||
:hook (org-capture-mode . delete-other-windows)) |
|
||||||
#+END_SRC |
|
||||||
|
|
||||||
Org keys. |
|
||||||
|
|
||||||
#+BEGIN_SRC emacs-lisp |
|
||||||
(use-package org-keys |
|
||||||
:ensure nil ; built-in |
|
||||||
:config |
|
||||||
(setq org-return-follows-link t)) |
|
||||||
#+END_SRC |
|
||||||
|
|
||||||
Org links. |
|
||||||
|
|
||||||
#+BEGIN_SRC emacs-lisp |
|
||||||
(use-package ol |
|
||||||
:ensure nil ; built-in |
|
||||||
:config |
|
||||||
;; Do not open links to .org files in a split window |
|
||||||
(add-to-list 'org-link-frame-setup '(file . find-file))) |
|
||||||
#+END_SRC |
|
||||||
|
|
||||||
Org source code blocks. |
|
||||||
|
|
||||||
#+BEGIN_SRC emacs-lisp |
|
||||||
(use-package org-src |
|
||||||
:ensure nil ; built-in |
|
||||||
:config |
|
||||||
(setq org-edit-src-content-indentation 0) |
|
||||||
(setq org-src-fontify-natively t) |
|
||||||
(setq org-src-preserve-indentation t) |
|
||||||
(setq org-src-tab-acts-natively t) |
|
||||||
(setq org-src-window-setup 'current-window)) |
|
||||||
#+END_SRC |
|
||||||
|
|
||||||
Org exporter. |
|
||||||
|
|
||||||
#+BEGIN_SRC emacs-lisp |
|
||||||
(use-package ox |
|
||||||
:ensure nil ; built-in |
|
||||||
:defer t |
|
||||||
:config |
|
||||||
(setq org-export-coding-system 'utf-8-unix)) |
|
||||||
#+END_SRC |
|
||||||
|
|
||||||
Org latex exporter. |
|
||||||
|
|
||||||
#+BEGIN_SRC emacs-lisp |
|
||||||
(use-package ox-latex |
|
||||||
:ensure nil ; built-in |
|
||||||
:defer t |
|
||||||
:config |
|
||||||
;; Define how minted (highlighted src code) is added to src code blocks |
|
||||||
(setq org-latex-listings 'minted) |
|
||||||
(setq org-latex-minted-options '(("frame" "lines") ("linenos=true"))) |
|
||||||
;; Set 'Table of Contents' layout |
|
||||||
(setq org-latex-toc-command "\\newpage \\tableofcontents \\newpage") |
|
||||||
;; Add minted package to every LaTeX header |
|
||||||
(add-to-list 'org-latex-packages-alist '("" "minted")) |
|
||||||
;; Add -shell-escape so pdflatex exports minted correctly |
|
||||||
(setcar org-latex-pdf-process (replace-regexp-in-string |
|
||||||
"-%latex -interaction" |
|
||||||
"-%latex -shell-escape -interaction" |
|
||||||
(car org-latex-pdf-process)))) |
|
||||||
#+END_SRC |
|
||||||
|
|
||||||
** Org Functions |
|
||||||
|
|
||||||
#+BEGIN_SRC emacs-lisp |
|
||||||
(with-eval-after-load 'evil-commands |
|
||||||
(defun dot/org-ret-at-point () |
|
||||||
"Org return key at point. |
|
||||||
|
|
||||||
If point is on: |
|
||||||
checkbox -- toggle it |
|
||||||
link -- follow it |
|
||||||
table -- go to next row |
|
||||||
otherwise -- run the default (evil-ret) expression" |
|
||||||
(interactive) |
|
||||||
(let ((type (org-element-type (org-element-context)))) |
|
||||||
(pcase type |
|
||||||
('link (if org-return-follows-link (org-open-at-point) (evil-ret))) |
|
||||||
((guard (org-at-item-checkbox-p)) (org-toggle-checkbox)) |
|
||||||
('table-cell (org-table-next-row)) |
|
||||||
(_ (evil-ret)) |
|
||||||
)))) |
|
||||||
#+END_SRC |
|
||||||
|
|
||||||
** Org Bullets |
|
||||||
|
|
||||||
#+BEGIN_SRC emacs-lisp |
|
||||||
(use-package org-bullets |
|
||||||
:hook (org-mode . org-bullets-mode)) |
|
||||||
#+END_SRC |
|
||||||
|
|
||||||
** Org Export Packages |
|
||||||
|
|
||||||
HTML exporter. |
|
||||||
|
|
||||||
#+BEGIN_SRC emacs-lisp |
|
||||||
(use-package htmlize |
|
||||||
:defer t |
|
||||||
:config (setq org-export-html-postamble nil)) |
|
||||||
;;org-export-html-postamble-format ; TODO |
|
||||||
#+END_SRC |
|
||||||
|
|
||||||
GitHub flavored Markdown exporter. |
|
||||||
|
|
||||||
#+BEGIN_SRC emacs-lisp |
|
||||||
(use-package ox-gfm |
|
||||||
:defer t) |
|
||||||
#+END_SRC |
|
||||||
|
|
||||||
** Org Roam |
|
||||||
|
|
||||||
Setup =org-roam=. |
|
||||||
|
|
||||||
#+BEGIN_SRC emacs-lisp |
|
||||||
(use-package org-roam |
|
||||||
:defer 1 |
|
||||||
:init |
|
||||||
(setq org-roam-v2-ack t) |
|
||||||
:config |
|
||||||
(setq org-roam-db-location (expand-file-name "org-roam.db" dot-cache-dir)) |
|
||||||
(setq org-roam-directory org-directory) |
|
||||||
;; Exclude Syncthing backup directory |
|
||||||
(setq org-roam-file-exclude-regexp "\\.stversions") |
|
||||||
(setq org-roam-verbose nil) |
|
||||||
|
|
||||||
(setq org-roam-capture-templates |
|
||||||
'(("d" "default" plain |
|
||||||
"%?" |
|
||||||
:target (file+head "%<%Y%m%d%H%M%S>-${slug}.org" "#+TITLE: ${title}\n#+FILETAGS: %^{File tags}\n") |
|
||||||
:unnarrowed t))) |
|
||||||
|
|
||||||
(defun dot/org-roam-node-insert-immediate (arg &rest args) |
|
||||||
(interactive "P") |
|
||||||
(let ((args (push arg args)) |
|
||||||
(org-roam-capture-templates (list (append (car org-roam-capture-templates) |
|
||||||
'(:immediate-finish t))))) |
|
||||||
(apply #'org-roam-node-insert args))) |
|
||||||
|
|
||||||
(cl-defmethod org-roam-node-slug ((node org-roam-node)) |
|
||||||
"Return the slug of NODE, strip out common words." |
|
||||||
(let* ((title (org-roam-node-title node)) |
|
||||||
(words (split-string title " ")) |
|
||||||
(common-words '("a" "an" "and" "as" "at" "by" "is" "it" "of" "the" "to")) |
|
||||||
(title (string-join (seq-remove (lambda (element) (member element common-words)) words) "_")) |
|
||||||
(pairs '(("c\\+\\+" . "cpp") ;; convert c++ -> cpp |
|
||||||
("c#" . "cs") ;; convert c# -> cs |
|
||||||
("[^[:alnum:][:digit:]]" . "_") ;; convert anything not alphanumeric |
|
||||||
("__*" . "_") ;; remove sequential underscores |
|
||||||
("^_" . "") ;; remove starting underscore |
|
||||||
("_$" . "")))) ;; remove ending underscore |
|
||||||
(cl-flet ((cl-replace (title pair) |
|
||||||
(replace-regexp-in-string (car pair) (cdr pair) title))) |
|
||||||
(downcase (-reduce-from #'cl-replace title pairs))))) |
|
||||||
|
|
||||||
;; Right-align org-roam-node-tags in the completion menu without a length limit |
|
||||||
;; Source: https://github.com/org-roam/org-roam/issues/1775#issue-971157225 |
|
||||||
(setq org-roam-node-display-template "${title} ${tags:0}") |
|
||||||
(setq org-roam-node-annotation-function #'dot/org-roam-annotate-tag) |
|
||||||
(defun dot/org-roam-annotate-tag (node) |
|
||||||
(let ((tags (mapconcat 'identity (org-roam-node-tags node) " #"))) |
|
||||||
(unless (string-empty-p tags) |
|
||||||
(concat |
|
||||||
(propertize " " 'display `(space :align-to (- right ,(+ 2 (length tags))))) |
|
||||||
(propertize (concat "#" tags) 'face 'bold))))) |
|
||||||
|
|
||||||
(org-roam-setup)) |
|
||||||
#+END_SRC |
|
||||||
|
|
||||||
Enable [[https://www.orgroam.com/manual.html#Roam-Protocol][Roam Protocol]], needed to process =org-protocol://= links |
|
||||||
|
|
||||||
#+BEGIN_SRC emacs-lisp |
|
||||||
(use-package org-roam-protocol |
|
||||||
:ensure nil ; org-roam-protocol.el is part of org-roam |
|
||||||
:after org-roam |
|
||||||
:config |
|
||||||
|
|
||||||
;; Templates used when creating a new file from a bookmark |
|
||||||
(setq org-roam-capture-ref-templates |
|
||||||
'(("r" "ref" plain |
|
||||||
"%?" |
|
||||||
:target (file+head "${slug}.org" "#+TITLE: ${title}\n \n${body}") |
|
||||||
:unnarrowed t)))) |
|
||||||
#+END_SRC |
|
||||||
|
|
||||||
The roam-ref protocol bookmarks to add: |
|
||||||
|
|
||||||
#+BEGIN_SRC javascript |
|
||||||
javascript:location.href = |
|
||||||
'org-protocol://roam-ref?template=r' |
|
||||||
+ '&ref=' + encodeURIComponent(location.href) |
|
||||||
+ '&title=' + encodeURIComponent(document.title) |
|
||||||
+ '&body=' + encodeURIComponent(window.getSelection()) |
|
||||||
#+END_SRC |
|
||||||
|
|
||||||
Setup =org-roam-ui=, runs at http://127.0.0.1:35901. |
|
||||||
|
|
||||||
#+BEGIN_SRC emacs-lisp |
|
||||||
(use-package org-roam-ui |
|
||||||
:after org-roam |
|
||||||
:config |
|
||||||
(setq org-roam-ui-follow t) |
|
||||||
(setq org-roam-ui-open-on-start t) |
|
||||||
(setq org-roam-ui-sync-theme nil) ;; FIXME: Make this work (org-roam-ui-get-theme) |
|
||||||
(setq org-roam-ui-update-on-save t)) |
|
||||||
#+END_SRC |
|
||||||
|
|
||||||
Easily searchable .org files via Deft. |
|
||||||
|
|
||||||
#+BEGIN_SRC emacs-lisp |
|
||||||
(use-package deft |
|
||||||
:after org |
|
||||||
:hook (deft-mode . dot/hook-disable-line-numbers) |
|
||||||
:config |
|
||||||
(setq deft-auto-save-interval 0) |
|
||||||
(setq deft-default-extension "org") |
|
||||||
(setq deft-directory org-directory) |
|
||||||
(setq deft-file-naming-rules '((noslash . "-") |
|
||||||
(nospace . "-") |
|
||||||
(case-fn . downcase))) |
|
||||||
(setq deft-new-file-format "%Y%m%d%H%M%S-deft") |
|
||||||
(setq deft-recursive t) |
|
||||||
;; Exclude Syncthing backup directory |
|
||||||
(setq deft-recursive-ignore-dir-regexp (concat "\\.stversions\\|" deft-recursive-ignore-dir-regexp)) |
|
||||||
;; Remove file variable -*- .. -*- and Org Mode :PROPERTIES: lines |
|
||||||
(setq deft-strip-summary-regexp (concat "\\(^.*-\\*-.+-\\*-$\\|^:[[:alpha:]_]+:.*$\\)\\|" deft-strip-summary-regexp)) |
|
||||||
(setq deft-use-filename-as-title nil) |
|
||||||
(setq deft-use-filter-string-for-filename t) |
|
||||||
|
|
||||||
(add-to-list 'deft-extensions "tex") |
|
||||||
|
|
||||||
;; Start filtering immediately |
|
||||||
(evil-set-initial-state 'deft-mode 'insert) |
|
||||||
|
|
||||||
(defun deft-parse-title (file contents) |
|
||||||
"Parse the given FILE and CONTENTS and determine the title." |
|
||||||
(org-element-property |
|
||||||
:value |
|
||||||
(car |
|
||||||
(org-element-map |
|
||||||
(with-temp-buffer |
|
||||||
(insert contents) |
|
||||||
(org-element-parse-buffer 'greater-element)) |
|
||||||
'keyword |
|
||||||
(lambda (e) (when (string-match "TITLE" (org-element-property :key e)) e))))))) |
|
||||||
#+END_SRC |
|
||||||
|
|
||||||
** Org "Table of Contents" |
|
||||||
|
|
||||||
Generate table of contents without exporting. |
|
||||||
|
|
||||||
#+BEGIN_SRC emacs-lisp |
|
||||||
(use-package toc-org |
|
||||||
:hook (org-mode . toc-org-mode)) |
|
||||||
#+END_SRC |
|
@ -1,52 +0,0 @@ |
|||||||
#+TITLE: Selection |
|
||||||
#+OPTIONS: toc:nil |
|
||||||
#+PROPERTY: header-args:emacs-lisp :shebang ";;; -*- lexical-binding: t; -*-\n" |
|
||||||
|
|
||||||
** Table of Contents :toc_4: |
|
||||||
- [[#selection][Selection]] |
|
||||||
|
|
||||||
** Selection |
|
||||||
|
|
||||||
#+BEGIN_SRC emacs-lisp |
|
||||||
(use-package selectrum |
|
||||||
:hook (emacs-startup . selectrum-mode) |
|
||||||
:config |
|
||||||
|
|
||||||
(defun dot/selectrum-backspace () |
|
||||||
"In Selectrum file completion, backward kill sexp, delete char otherwise." |
|
||||||
(interactive) |
|
||||||
(if (and selectrum-is-active |
|
||||||
minibuffer-completing-file-name) |
|
||||||
(evil-with-state 'insert |
|
||||||
(move-end-of-line 1) (backward-kill-sexp 1)) |
|
||||||
(evil-delete-backward-char-and-join 1)))) |
|
||||||
|
|
||||||
(use-package prescient |
|
||||||
:after selectrum |
|
||||||
:config |
|
||||||
(setq prescient-filter-method '(literal regexp fuzzy)) |
|
||||||
(setq prescient-save-file (concat dot-cache-dir "/prescient-save.el")) |
|
||||||
(prescient-persist-mode)) |
|
||||||
|
|
||||||
(use-package selectrum-prescient |
|
||||||
:after (selectrum prescient) |
|
||||||
:config |
|
||||||
(selectrum-prescient-mode)) |
|
||||||
|
|
||||||
(use-package marginalia |
|
||||||
:after selectrum |
|
||||||
:config |
|
||||||
(setq marginalia-annotators '(marginalia-annotators-heavy marginalia-annotators-light)) |
|
||||||
(marginalia-mode)) |
|
||||||
|
|
||||||
(use-package consult |
|
||||||
:after selectrum |
|
||||||
:config (setq consult-narrow-key (kbd "?"))) |
|
||||||
|
|
||||||
(use-package consult-flycheck |
|
||||||
:after (consult flycheck)) |
|
||||||
|
|
||||||
(use-package consult-project-extra |
|
||||||
:after (consult project) |
|
||||||
:config (setq project-switch-commands 'consult-project-extra-find)) |
|
||||||
#+END_SRC |
|
@ -1,253 +0,0 @@ |
|||||||
#+TITLE: UI |
|
||||||
#+OPTIONS: toc:nil |
|
||||||
#+PROPERTY: header-args:emacs-lisp :shebang ";;; -*- lexical-binding: t; -*-\n" |
|
||||||
|
|
||||||
** Table of Contents :toc_4: |
|
||||||
- [[#all-the-icons][All the icons]] |
|
||||||
- [[#centaur-tabs][Centaur Tabs]] |
|
||||||
- [[#dashboard][Dashboard]] |
|
||||||
- [[#helpful][Helpful]] |
|
||||||
- [[#neotree][NeoTree]] |
|
||||||
- [[#telephone-line][Telephone Line]] |
|
||||||
- [[#theme][Theme]] |
|
||||||
- [[#which-key][Which-key]] |
|
||||||
|
|
||||||
** All the icons |
|
||||||
|
|
||||||
#+BEGIN_SRC emacs-lisp |
|
||||||
(use-package all-the-icons |
|
||||||
:defer t |
|
||||||
:config |
|
||||||
|
|
||||||
;; Install all-the-icons if font files are not found |
|
||||||
(unless (find-font (font-spec :name "all-the-icons")) |
|
||||||
(all-the-icons-install-fonts t))) |
|
||||||
|
|
||||||
(use-package all-the-icons-dired |
|
||||||
:after all-the-icons |
|
||||||
:hook (dired-mode . all-the-icons-dired-mode) |
|
||||||
:config (setq all-the-icons-dired-monochrome nil)) |
|
||||||
#+END_SRC |
|
||||||
|
|
||||||
** Centaur Tabs |
|
||||||
|
|
||||||
Places buffers as tabs in a bar at the top of the frame. |
|
||||||
|
|
||||||
#+BEGIN_SRC emacs-lisp |
|
||||||
(use-package centaur-tabs |
|
||||||
:after all-the-icons |
|
||||||
:demand |
|
||||||
:hook |
|
||||||
((eshell-mode |
|
||||||
help-mode |
|
||||||
helpful-mode |
|
||||||
mu4e-view-mode |
|
||||||
neotree-mode |
|
||||||
shell-mode) |
|
||||||
. centaur-tabs-local-mode) |
|
||||||
:config |
|
||||||
(setq centaur-tabs-enable-ido-completion nil) |
|
||||||
(setq centaur-tabs-height (if dot/hidpi 38 18)) |
|
||||||
(setq centaur-tabs-modified-marker "•") |
|
||||||
(setq centaur-tabs-set-icons t) |
|
||||||
(setq centaur-tabs-set-modified-marker t) |
|
||||||
(setq centaur-tabs-style "slant") |
|
||||||
|
|
||||||
(setq centaur-tabs-project-buffer-group-calc nil) |
|
||||||
(defun centaur-tabs-buffer-groups () |
|
||||||
"Organize tabs into groups by buffer." |
|
||||||
(unless centaur-tabs-project-buffer-group-calc |
|
||||||
(set (make-local-variable 'centaur-tabs-project-buffer-group-calc) |
|
||||||
(list |
|
||||||
(cond |
|
||||||
((string-equal "*" (substring (buffer-name) 0 1)) "Emacs") |
|
||||||
((or (memq major-mode '(magit-process-mode |
|
||||||
magit-status-mode |
|
||||||
magit-diff-mode |
|
||||||
magit-log-mode |
|
||||||
magit-file-mode |
|
||||||
magit-blob-mode |
|
||||||
magit-blame-mode)) |
|
||||||
(string= (buffer-name) "COMMIT_EDITMSG")) "Magit") |
|
||||||
((project-current) (dot/project-project-name)) |
|
||||||
((memq major-mode '(org-mode |
|
||||||
emacs-lisp-mode)) "Org Mode") |
|
||||||
((derived-mode-p 'dired-mode) "Dired") |
|
||||||
((derived-mode-p 'prog-mode |
|
||||||
'text-mode) "Editing") |
|
||||||
(t "Other"))))) |
|
||||||
(symbol-value 'centaur-tabs-project-buffer-group-calc)) |
|
||||||
|
|
||||||
(defun centaur-tabs-hide-tab (buffer) |
|
||||||
"Hide from the tab bar by BUFFER name." |
|
||||||
|
|
||||||
(let ((name (format "%s" buffer))) |
|
||||||
(or |
|
||||||
;; Current window is dedicated window |
|
||||||
(window-dedicated-p (selected-window)) |
|
||||||
;; Buffer name matches below blacklist |
|
||||||
(string-match-p "^ ?\\*.*\\*" name)))) |
|
||||||
|
|
||||||
(defun dot/centaur-tabs-is-buffer-unimportant (buffer) |
|
||||||
"Return t if BUFFER is unimportant and can be killed without caution." |
|
||||||
(let ((name (format "%s" buffer))) |
|
||||||
(cond |
|
||||||
((centaur-tabs-hide-tab name) t) |
|
||||||
((string-match-p "^magit\\(-[a-z]+\\)*: .*" name) t) |
|
||||||
(t nil)))) |
|
||||||
|
|
||||||
(defun dot/centaur-tabs-buffer-cleanup () |
|
||||||
"Clean up all the hidden buffers." |
|
||||||
(interactive) |
|
||||||
(dolist (buffer (buffer-list)) |
|
||||||
(when (dot/centaur-tabs-is-buffer-unimportant buffer) |
|
||||||
(kill-buffer buffer))) |
|
||||||
(princ "Cleaned buffers")) |
|
||||||
|
|
||||||
(defun dot/centaur-tabs-kill-buffer-or-window () |
|
||||||
"Delete window of the current buffer, also kill if the buffer is hidden." |
|
||||||
(interactive) |
|
||||||
(if (dot/centaur-tabs-is-buffer-unimportant (buffer-name)) |
|
||||||
(kill-buffer-and-window) |
|
||||||
(delete-window))) |
|
||||||
|
|
||||||
(centaur-tabs-headline-match) |
|
||||||
(centaur-tabs-mode)) |
|
||||||
#+END_SRC |
|
||||||
|
|
||||||
** Dashboard |
|
||||||
|
|
||||||
#+BEGIN_SRC emacs-lisp |
|
||||||
(use-package page-break-lines) |
|
||||||
|
|
||||||
(use-package dashboard |
|
||||||
:demand |
|
||||||
:hook (dashboard-mode . dot/hook-disable-line-numbers) |
|
||||||
:config |
|
||||||
(setq initial-buffer-choice (lambda () (get-buffer "*dashboard*"))) |
|
||||||
(setq dashboard-banner-logo-title "GNU Emacs master race!") |
|
||||||
(setq dashboard-center-content t) |
|
||||||
(setq dashboard-page-separator "\n\f\n") |
|
||||||
(setq dashboard-projects-backend 'project-el) |
|
||||||
(setq dashboard-set-file-icons t) |
|
||||||
(setq dashboard-set-footer nil) |
|
||||||
(setq dashboard-set-heading-icons t) |
|
||||||
(setq dashboard-show-shortcuts t) |
|
||||||
(setq dashboard-startup-banner 'logo) |
|
||||||
(setq dashboard-items '((projects . 10) |
|
||||||
(bookmarks . 5) |
|
||||||
(recents . 5))) |
|
||||||
|
|
||||||
(defun dot/dashboard-goto () |
|
||||||
"Go to the *dashboard* buffer, create if non-existing." |
|
||||||
(interactive) |
|
||||||
(let ((buffer "*dashboard*")) |
|
||||||
(unless (get-buffer buffer) |
|
||||||
(generate-new-buffer buffer) |
|
||||||
(dashboard-refresh-buffer)) |
|
||||||
(switch-to-buffer buffer))) |
|
||||||
|
|
||||||
;; Fix keybinds.. |
|
||||||
|
|
||||||
(defun dot/dashboard-goto-bookmarks () |
|
||||||
"Move point to bookmarks." |
|
||||||
(interactive) |
|
||||||
(funcall (local-key-binding "m"))) |
|
||||||
|
|
||||||
(defun dot/dashboard-goto-projects () |
|
||||||
"Move point to projects." |
|
||||||
(interactive) |
|
||||||
(funcall (local-key-binding "p"))) |
|
||||||
|
|
||||||
(defun dot/dashboard-goto-recent-files () |
|
||||||
"Move point to recent files." |
|
||||||
(interactive) |
|
||||||
(funcall (local-key-binding "r"))) |
|
||||||
|
|
||||||
(dashboard-setup-startup-hook)) |
|
||||||
#+END_SRC |
|
||||||
|
|
||||||
** Helpful |
|
||||||
|
|
||||||
A better *help* buffer. |
|
||||||
|
|
||||||
#+BEGIN_SRC emacs-lisp |
|
||||||
(use-package helpful |
|
||||||
:hook (helpful-mode . dot/hook-disable-line-numbers)) |
|
||||||
#+END_SRC |
|
||||||
|
|
||||||
** NeoTree |
|
||||||
|
|
||||||
Provides Emacs with a file tree. |
|
||||||
|
|
||||||
#+BEGIN_SRC emacs-lisp |
|
||||||
(use-package neotree |
|
||||||
:after all-the-icons |
|
||||||
:hook (neotree-mode . dot/hook-disable-line-numbers) |
|
||||||
:hook (neotree-mode . hl-line-mode) |
|
||||||
:init |
|
||||||
|
|
||||||
;; This needs to be in init to actually start loading the package |
|
||||||
(with-eval-after-load 'project |
|
||||||
(defun neotree-toggle-in-project-root () |
|
||||||
"Toggle Neotree in project root." |
|
||||||
(interactive) |
|
||||||
(let ((default-directory (dot/find-project-root))) |
|
||||||
(call-interactively #'neotree-toggle)))) |
|
||||||
|
|
||||||
:config |
|
||||||
(setq neo-theme (if (display-graphic-p) 'icons 'arrow)) |
|
||||||
(setq neo-autorefresh nil) |
|
||||||
(setq neo-mode-line-type 'none) |
|
||||||
(setq neo-show-hidden-files t) |
|
||||||
(setq neo-vc-integration '(face))) |
|
||||||
#+END_SRC |
|
||||||
|
|
||||||
** Telephone Line |
|
||||||
|
|
||||||
Emacs mode line replacement. |
|
||||||
|
|
||||||
#+BEGIN_SRC emacs-lisp |
|
||||||
(use-package telephone-line |
|
||||||
:config |
|
||||||
(setq telephone-line-height (if dot/hidpi 30 15)) |
|
||||||
(setq telephone-line-lhs |
|
||||||
'((evil . (telephone-line-evil-tag-segment)) |
|
||||||
(accent . (telephone-line-erc-modified-channels-segment |
|
||||||
telephone-line-process-segment |
|
||||||
telephone-line-buffer-segment)) |
|
||||||
(nil . (telephone-line-project-segment)))) |
|
||||||
(telephone-line-mode)) |
|
||||||
#+END_SRC |
|
||||||
|
|
||||||
** Theme |
|
||||||
|
|
||||||
#+BEGIN_SRC emacs-lisp |
|
||||||
(use-package hybrid-reverse-theme |
|
||||||
:ensure nil |
|
||||||
:load-path "~/code/elisp/emacs-hybrid-reverse" |
|
||||||
:config (load-theme 'hybrid-reverse t)) |
|
||||||
#+END_SRC |
|
||||||
|
|
||||||
** Which-key |
|
||||||
|
|
||||||
Popup that displays available key bindings. |
|
||||||
|
|
||||||
#+BEGIN_SRC emacs-lisp |
|
||||||
(use-package which-key |
|
||||||
:hook (emacs-startup . which-key-mode) |
|
||||||
:config |
|
||||||
(setq which-key-add-column-padding 1) |
|
||||||
(setq which-key-max-display-columns nil) |
|
||||||
(setq which-key-min-display-lines 6) |
|
||||||
(setq which-key-sort-order #'dot/which-key-prefix-then-key-order-alpha) |
|
||||||
(setq which-key-sort-uppercase-first nil) |
|
||||||
|
|
||||||
(defun dot/which-key-prefix-then-key-order-alpha (acons bcons) |
|
||||||
"Order by prefix, then lexicographical." |
|
||||||
(let ((apref? (which-key--group-p (cdr acons))) |
|
||||||
(bpref? (which-key--group-p (cdr bcons)))) |
|
||||||
(if (not (eq apref? bpref?)) |
|
||||||
(and (not apref?) bpref?) |
|
||||||
(which-key-key-order-alpha acons bcons))))) |
|
||||||
#+END_SRC |
|
@ -0,0 +1,25 @@ |
|||||||
|
;;; dot-core-advice.el --- -*- lexical-binding: t; -*- |
||||||
|
|
||||||
|
;;; Commentary: |
||||||
|
|
||||||
|
;; Advice and Aliases. |
||||||
|
|
||||||
|
;;; Code: |
||||||
|
|
||||||
|
;; ----------------------------------------- |
||||||
|
|
||||||
|
;; Advice |
||||||
|
|
||||||
|
;; Define default terminal option. |
||||||
|
(defun dot/ansi-term (program &optional new-buffer-name) |
||||||
|
(interactive (list dot/shell))) |
||||||
|
(advice-add 'ansi-term :before #'dot/ansi-term) |
||||||
|
|
||||||
|
;; Aliases |
||||||
|
|
||||||
|
;; Make confirm easier, by just pressing y/n. |
||||||
|
(defalias 'yes-or-no-p 'y-or-n-p) |
||||||
|
|
||||||
|
(provide 'dot-core-advice) |
||||||
|
|
||||||
|
;;; dot-core-advice.el ends here |
@ -0,0 +1,244 @@ |
|||||||
|
;;; dot-core-config.el --- -*- lexical-binding: t; -*- |
||||||
|
|
||||||
|
;;; Commentary: |
||||||
|
|
||||||
|
;; ?? |
||||||
|
|
||||||
|
;;; Code: |
||||||
|
|
||||||
|
;; ----------------------------------------- |
||||||
|
;; General |
||||||
|
|
||||||
|
;; Columns start at 1 |
||||||
|
(setq column-number-indicator-zero-based nil) |
||||||
|
;; TODO: Make variable below compatible with telephone-line |
||||||
|
;; (setq mode-line-position-column-format " C%C") |
||||||
|
|
||||||
|
;; Dont confirm on quitting Emacs |
||||||
|
(setq confirm-kill-processes nil) |
||||||
|
|
||||||
|
;; Custom thems, do not ask if safe |
||||||
|
(setq custom-safe-themes t) |
||||||
|
|
||||||
|
;; Dired move to trash |
||||||
|
(setq delete-by-moving-to-trash t) |
||||||
|
|
||||||
|
;; Column indicator character |
||||||
|
(setq display-fill-column-indicator-character ?\N{U+2503}) |
||||||
|
|
||||||
|
;; Scrolling |
||||||
|
(setq scroll-conservatively 1) |
||||||
|
(setq mouse-wheel-scroll-amount '(5)) |
||||||
|
(setq mouse-wheel-progressive-speed nil) |
||||||
|
|
||||||
|
;; Parenthesis, set behavior |
||||||
|
(setq show-paren-delay 0) |
||||||
|
(setq show-paren-style 'mixed) |
||||||
|
|
||||||
|
;; Tramp default protocol |
||||||
|
(setq tramp-default-method "ssh") |
||||||
|
|
||||||
|
;; Set undo limit, measured in bytes |
||||||
|
(setq-default undo-limit 400000) |
||||||
|
(setq-default undo-strong-limit 3000000) |
||||||
|
(setq-default undo-outer-limit 12000000) |
||||||
|
|
||||||
|
;; Enable line numbers |
||||||
|
(global-display-line-numbers-mode) |
||||||
|
|
||||||
|
;; C++ syntax highlighting for .h files |
||||||
|
(add-to-list 'auto-mode-alist '("\\.h\\'" . c++-mode)) |
||||||
|
|
||||||
|
;; Set the frame title |
||||||
|
(setq frame-title-format |
||||||
|
`("%b" |
||||||
|
(:eval |
||||||
|
(if (buffer-file-name) |
||||||
|
(concat |
||||||
|
(if (buffer-modified-p) " •" nil) |
||||||
|
" (" |
||||||
|
(abbreviate-file-name |
||||||
|
(directory-file-name |
||||||
|
(file-name-directory (buffer-file-name)))) |
||||||
|
")") |
||||||
|
nil)) |
||||||
|
,(format " - GNU Emacs %s" emacs-version) |
||||||
|
)) |
||||||
|
(setq icon-title-format frame-title-format) |
||||||
|
|
||||||
|
;; ----------------------------------------- |
||||||
|
;; Buffers |
||||||
|
|
||||||
|
(setq confirm-nonexistent-file-or-buffer nil) |
||||||
|
(setq ibuffer-expert t) |
||||||
|
|
||||||
|
;; ----------------------------------------- |
||||||
|
;; Dired |
||||||
|
|
||||||
|
(setq wdired-allow-to-change-permissions t) |
||||||
|
|
||||||
|
;; ----------------------------------------- |
||||||
|
;; Electric |
||||||
|
|
||||||
|
;; Make return key also do indent of previous line |
||||||
|
(electric-indent-mode 1) |
||||||
|
(setq electric-pair-pairs '( |
||||||
|
(?\( . ?\)) |
||||||
|
(?\[ . ?\]) |
||||||
|
)) |
||||||
|
(electric-pair-mode 1) |
||||||
|
|
||||||
|
;; ----------------------------------------- |
||||||
|
;; File Paths |
||||||
|
|
||||||
|
;; Set file paths for built-in features like: auto-saves, backups, etc. |
||||||
|
|
||||||
|
;; Set Directory locations |
||||||
|
(setq auto-save-list-file-prefix (expand-file-name "auto-save/" dot-cache-dir)) |
||||||
|
(setq auto-save-file-name-transforms `((".*" ,auto-save-list-file-prefix t))) |
||||||
|
(setq backup-directory-alist `((".*" . ,(expand-file-name "backup/" dot-cache-dir)))) |
||||||
|
(setq custom-theme-directory (expand-file-name "themes/" dot-emacs-dir)) |
||||||
|
(setq eshell-directory-name (expand-file-name "eshell/" dot-cache-dir)) |
||||||
|
(setq tramp-auto-save-directory (expand-file-name "tramp-auto-save/" dot-cache-dir)) |
||||||
|
(setq tramp-backup-directory-alist backup-directory-alist) |
||||||
|
(setq url-configuration-directory (expand-file-name "url/" dot-cache-dir)) |
||||||
|
|
||||||
|
;; Set file locations |
||||||
|
(setq bookmark-default-file (expand-file-name "bookmarks" dot-etc-dir)) |
||||||
|
(setq nsm-settings-file (expand-file-name "network-security.data" dot-cache-dir)) |
||||||
|
(setq org-id-locations-file (expand-file-name "org-id-locations" dot-cache-dir)) |
||||||
|
(setq tramp-persistency-file-name (expand-file-name "tramp" dot-cache-dir )) |
||||||
|
|
||||||
|
;; ----------------------------------------- |
||||||
|
;; File Backups Versioning |
||||||
|
|
||||||
|
;; Setup file backups versioning. |
||||||
|
|
||||||
|
(setq backup-by-copying t) ; Don't cobbler symlinks |
||||||
|
(setq create-lockfiles nil) ; Disable lockfiles (.#) |
||||||
|
(setq delete-old-versions t) ; Cleanup backups |
||||||
|
(setq kept-new-versions 5) ; Newest backups to keep |
||||||
|
(setq kept-old-versions 2) ; Oldest backups to keep |
||||||
|
(setq version-control t) ; Use version numbers on backups |
||||||
|
|
||||||
|
;; ----------------------------------------- |
||||||
|
;; Formatting |
||||||
|
|
||||||
|
;; Columnn after line-wrapping happens |
||||||
|
(setq-default fill-column 80) |
||||||
|
|
||||||
|
;; Automatically add newline on save at the end of the file |
||||||
|
(setq require-final-newline t) |
||||||
|
|
||||||
|
;; End sentences with a single space |
||||||
|
(setq sentence-end-double-space nil) |
||||||
|
|
||||||
|
;; `tabify' and `untabify' should only affect indentation |
||||||
|
(setq tabify-regexp "^\t* [ \t]+") |
||||||
|
|
||||||
|
;; Do not wrap lines |
||||||
|
(setq-default truncate-lines t) |
||||||
|
|
||||||
|
;; Wrap lines in the middle of words, gives a \ indicator |
||||||
|
(setq-default word-wrap nil) |
||||||
|
|
||||||
|
;; ----------------------------------------- |
||||||
|
;; Hide Elements |
||||||
|
|
||||||
|
(menu-bar-mode 0) |
||||||
|
(scroll-bar-mode 0) |
||||||
|
(tool-bar-mode 0) |
||||||
|
(tooltip-mode 0) |
||||||
|
(fringe-mode 0) |
||||||
|
(blink-cursor-mode 0) |
||||||
|
|
||||||
|
(setq inhibit-startup-message t) |
||||||
|
(setq initial-scratch-message nil) |
||||||
|
(setq ring-bell-function 'ignore) |
||||||
|
|
||||||
|
;; ----------------------------------------- |
||||||
|
;; Native Compilation |
||||||
|
|
||||||
|
(setq native-comp-async-report-warnings-errors nil) |
||||||
|
|
||||||
|
;; ----------------------------------------- |
||||||
|
;; Recentf |
||||||
|
|
||||||
|
(elpaca nil (setup recentf ; built-in |
||||||
|
(:require recentf) |
||||||
|
(:when-loaded |
||||||
|
(setq recentf-auto-cleanup 'never) |
||||||
|
(setq recentf-exclude '("~$" "/ssh:" "/sudo:")) |
||||||
|
(setq recentf-filename-handlers '(abbreviate-file-name)) |
||||||
|
(setq recentf-max-menu-items 0) |
||||||
|
(setq recentf-max-saved-items 200) |
||||||
|
(setq recentf-save-file (expand-file-name "recentf" dot-cache-dir)) |
||||||
|
(recentf-mode)))) |
||||||
|
|
||||||
|
;; ----------------------------------------- |
||||||
|
;; Tabs |
||||||
|
|
||||||
|
;; Tabs |
||||||
|
(setq-default tab-width 4 |
||||||
|
indent-tabs-mode t |
||||||
|
c-basic-offset 4 |
||||||
|
sgml-basic-offset 4 |
||||||
|
sh-basic-offset 4) |
||||||
|
|
||||||
|
;; C/C++-like languages formatting style |
||||||
|
;; https://www.emacswiki.org/emacs/IndentingC |
||||||
|
;; https://www.gnu.org/software/emacs/manual/html_mono/ccmode.html#Getting-Started |
||||||
|
;; https://www.gnu.org/software/emacs/manual/html_mono/ccmode.html#Adding-Styles |
||||||
|
;; https://www.gnu.org/software/emacs/manual/html_mono/ccmode.html#Sample-Init-File |
||||||
|
(c-add-style "user" `("linux" |
||||||
|
(c-basic-offset . ,(default-value 'tab-width)) |
||||||
|
(c-offsets-alist |
||||||
|
(innamespace . -) |
||||||
|
))) |
||||||
|
(setq-default c-default-style "user") |
||||||
|
|
||||||
|
;; ----------------------------------------- |
||||||
|
;; UTF-8 |
||||||
|
|
||||||
|
;; Set UTF-8 encoding as default. |
||||||
|
|
||||||
|
(prefer-coding-system 'utf-8-unix) |
||||||
|
(setq locale-coding-system 'utf-8-unix) |
||||||
|
;; Default also sets file-name, keyboard and terminal coding system |
||||||
|
(set-default-coding-systems 'utf-8-unix) |
||||||
|
(set-buffer-file-coding-system 'utf-8-unix) |
||||||
|
(set-selection-coding-system 'utf-8-unix) |
||||||
|
|
||||||
|
;; ----------------------------------------- |
||||||
|
;; Window |
||||||
|
|
||||||
|
;; Set `switch-to-buffer' to respect the window rules |
||||||
|
(setq switch-to-buffer-obey-display-actions t) |
||||||
|
|
||||||
|
;; Window rules |
||||||
|
(setq display-buffer-alist |
||||||
|
'( |
||||||
|
;; ^\*(e?shell|(ansi-|v)?term).* |
||||||
|
("^\\*\\(e?shell\\|\\(ansi-\\|v\\)?term\\).*" |
||||||
|
(display-buffer-in-side-window) |
||||||
|
(window-height . 0.25) |
||||||
|
(side . bottom) |
||||||
|
(slot . -1)) |
||||||
|
("\\*Faces\\*" |
||||||
|
(display-buffer-in-side-window) |
||||||
|
(window-height . 0.25) |
||||||
|
(side . bottom) |
||||||
|
(slot . 1)) |
||||||
|
("\\*Help.*" |
||||||
|
(display-buffer-in-side-window) |
||||||
|
(window-height . 0.25) |
||||||
|
(side . bottom) |
||||||
|
(slot . 0)) |
||||||
|
)) |
||||||
|
|
||||||
|
;; Allow 'undo' and 'redo' changes in Window Configuration. |
||||||
|
(winner-mode) |
||||||
|
|
||||||
|
(provide 'dot-core-config) |
||||||
|
|
||||||
|
;;; dot-core-config.el ends here |
@ -0,0 +1,19 @@ |
|||||||
|
;;; dot-core-customize.el --- -*- lexical-binding: t; -*- |
||||||
|
|
||||||
|
;;; Commentary: |
||||||
|
|
||||||
|
;; ?? |
||||||
|
|
||||||
|
;;; Code: |
||||||
|
|
||||||
|
;; ----------------------------------------- |
||||||
|
;; Customizations |
||||||
|
|
||||||
|
;; Store customize file separately, don't freak out when it's not found. |
||||||
|
|
||||||
|
(setq custom-file (expand-file-name "custom.el" dot-etc-dir)) |
||||||
|
(load custom-file 'noerror) |
||||||
|
|
||||||
|
(provide 'dot-core-customize) |
||||||
|
|
||||||
|
;;; dot-core-customize.el ends here |
@ -0,0 +1,17 @@ |
|||||||
|
;;; dot-core-fonts.el --- -*- lexical-binding: t; -*- |
||||||
|
|
||||||
|
;;; Commentary: |
||||||
|
|
||||||
|
;; ?? |
||||||
|
|
||||||
|
;;; Code: |
||||||
|
|
||||||
|
;; ----------------------------------------- |
||||||
|
;; Set fonts |
||||||
|
|
||||||
|
(set-face-attribute 'default nil :height 90 :family "DejaVu Sans Mono") |
||||||
|
(set-face-attribute 'fixed-pitch-serif nil :height 100) |
||||||
|
|
||||||
|
(provide 'dot-core-fonts) |
||||||
|
|
||||||
|
;;; dot-core-fonts.el ends here |
@ -0,0 +1,195 @@ |
|||||||
|
;;; dot-core-functions.el --- -*- lexical-binding: t; -*- |
||||||
|
|
||||||
|
;;; Commentary: |
||||||
|
|
||||||
|
;; Custom elisp functions and macros. |
||||||
|
|
||||||
|
;;; Code: |
||||||
|
|
||||||
|
;; ----------------------------------------- |
||||||
|
;; General Functions |
||||||
|
|
||||||
|
;; Functions that only use built-in Emacs functionality. |
||||||
|
|
||||||
|
(defun display-startup-echo-area-message () |
||||||
|
"Hide default startup message." |
||||||
|
(message nil)) |
||||||
|
|
||||||
|
(defun dot/config-visit () |
||||||
|
"Edit config file." |
||||||
|
(interactive) |
||||||
|
(find-file (expand-file-name "init.el" dot-emacs-dir))) |
||||||
|
|
||||||
|
(defun dot/config-reload () |
||||||
|
"Reload config file." |
||||||
|
(interactive) |
||||||
|
(load (expand-file-name "init.el" dot-emacs-dir))) |
||||||
|
|
||||||
|
(defun dot/copy-cpp-function-implementation () |
||||||
|
"Copy C++ function implementation to clipboard." |
||||||
|
(interactive) |
||||||
|
(save-excursion |
||||||
|
(let ((func (save-excursion |
||||||
|
(re-search-backward "\\b") |
||||||
|
(re-search-forward "\\([^;]+\\);") |
||||||
|
(match-string 1))) |
||||||
|
(type (progn |
||||||
|
(re-search-backward "\\b") |
||||||
|
(push-mark) |
||||||
|
(back-to-indentation) |
||||||
|
(buffer-substring (mark) (point)))) |
||||||
|
(class (progn |
||||||
|
(backward-up-list) |
||||||
|
(backward-sexp) |
||||||
|
(back-to-indentation) |
||||||
|
(forward-to-word 1) |
||||||
|
(current-word)))) |
||||||
|
(kill-new (concat type class "::" func "\n{\n}")))) |
||||||
|
(message "Copied function implementation")) |
||||||
|
|
||||||
|
;; Reference: http://turingmachine.org/bl/2013-05-29-recursively-listing-directories-in-elisp.html |
||||||
|
(defun dot/directory-files-recursively-depth (dir regexp include-directories maxdepth) |
||||||
|
"Depth limited variant of the built-in `directory-files-recursively'." |
||||||
|
(let ((result '()) |
||||||
|
(current-directory-list (directory-files dir t))) |
||||||
|
(dolist (path current-directory-list) |
||||||
|
(cond |
||||||
|
((and (file-regular-p path) |
||||||
|
(file-readable-p path) |
||||||
|
(string-match regexp path)) |
||||||
|
(setq result (cons path result))) |
||||||
|
((and (file-directory-p path) |
||||||
|
(file-readable-p path) |
||||||
|
(not (string-equal "/.." (substring path -3))) |
||||||
|
(not (string-equal "/." (substring path -2)))) |
||||||
|
(when (and include-directories |
||||||
|
(string-match regexp path)) |
||||||
|
(setq result (cons path result))) |
||||||
|
(when (> maxdepth 1) |
||||||
|
(setq result (append (nreverse (dot/directory-files-recursively-depth |
||||||
|
path regexp include-directories (- maxdepth 1))) |
||||||
|
result)))) |
||||||
|
(t))) |
||||||
|
(reverse result))) |
||||||
|
|
||||||
|
(defun dot/dired-find-file () |
||||||
|
"In Dired, visit the file or directory named on this line." |
||||||
|
(interactive) |
||||||
|
(if (file-directory-p (dired-file-name-at-point)) |
||||||
|
(dired-find-alternate-file) |
||||||
|
(dired-find-file))) |
||||||
|
|
||||||
|
(defun dot/dired-up-directory () |
||||||
|
"Run Dired on parent directory of current directory." |
||||||
|
(interactive) |
||||||
|
(find-alternate-file "..")) |
||||||
|
|
||||||
|
(defun dot/find-file-emacsd () |
||||||
|
"Find file under `dot-emacs-dir', recursively." |
||||||
|
(interactive) |
||||||
|
(let ((files (mapcar 'abbreviate-file-name |
||||||
|
(directory-files-recursively dot-emacs-dir "")))) |
||||||
|
(find-file (completing-read "Find file (emacs): " files nil t)))) |
||||||
|
|
||||||
|
(defun dot/indent-buffer () |
||||||
|
"Indent each nonblank line in the buffer." |
||||||
|
(interactive) |
||||||
|
(save-excursion |
||||||
|
(indent-region (point-min) (point-max) nil))) |
||||||
|
|
||||||
|
(defun dot/insert-spaces-until-column (until-column) |
||||||
|
"Insert spaces from point to UNTIL-COLUMN." |
||||||
|
(interactive "nInsert spaces until column: ") |
||||||
|
(let ((current-column (current-column))) |
||||||
|
;; Increment column if the index is 1 based |
||||||
|
(when (not column-number-indicator-zero-based) |
||||||
|
(setq current-column (+ current-column 1))) |
||||||
|
;; Insert spaces |
||||||
|
(let ((diff (- until-column current-column))) |
||||||
|
(if (> diff 0) |
||||||
|
(save-excursion (insert (make-string diff ?\ ))) |
||||||
|
(user-error "Column should be higher than point"))))) |
||||||
|
|
||||||
|
(defun dot/reload-theme () |
||||||
|
"Reload custom theme." |
||||||
|
(interactive) |
||||||
|
(mapc 'load (file-expand-wildcards |
||||||
|
(concat (car custom-theme-load-path) "*.el"))) |
||||||
|
(load-theme (car custom-enabled-themes) t)) |
||||||
|
|
||||||
|
(defun dot/sudo-find-file (filename) |
||||||
|
"Edit file FILENAME as root." |
||||||
|
(interactive "FOpen file (as root): ") |
||||||
|
(find-file (concat "/sudo:root@localhost:" filename))) |
||||||
|
|
||||||
|
(defun dot/sudo-this-file () |
||||||
|
"Edit the current file as root." |
||||||
|
(interactive) |
||||||
|
(if buffer-file-name |
||||||
|
(find-alternate-file (concat "/sudo:root@localhost:" buffer-file-name)) |
||||||
|
(princ "Current buffer isn't a file"))) |
||||||
|
|
||||||
|
(defun dot/toggle-fringe (&optional arg) |
||||||
|
"Toggle left-only fringe, or set state with ARG." |
||||||
|
(interactive) |
||||||
|
(if (or (and (eq fringe-mode 0) (eq arg nil)) |
||||||
|
(eq arg 1)) |
||||||
|
(set-fringe-mode '(nil . 0)) |
||||||
|
(set-fringe-mode 0))) |
||||||
|
|
||||||
|
(defun dot/M-x (command) |
||||||
|
"Prompt and execute COMMAND." |
||||||
|
(interactive "CCommand: ") |
||||||
|
(command-execute command)) |
||||||
|
|
||||||
|
(defun split-follow-horizontally () |
||||||
|
"Split and follow window." |
||||||
|
(interactive) |
||||||
|
(split-window-below) |
||||||
|
(other-window 1)) |
||||||
|
(defun split-follow-vertically () |
||||||
|
"Split and follow window." |
||||||
|
(interactive) |
||||||
|
(split-window-right) |
||||||
|
(other-window 1)) |
||||||
|
|
||||||
|
;; https://emacsredux.com/blog/2013/05/04/rename-file-and-buffer/ |
||||||
|
(defun rename-file-and-buffer () |
||||||
|
"Rename the current buffer and file it is visiting." |
||||||
|
(interactive) |
||||||
|
(let ((filename (buffer-file-name))) |
||||||
|
(if (not (and filename (file-exists-p filename))) |
||||||
|
(message "Buffer is not visiting a file!") |
||||||
|
(let ((new-name (read-file-name "New name: " filename))) |
||||||
|
(cond |
||||||
|
((vc-backend filename) (vc-rename-file filename new-name)) |
||||||
|
(t |
||||||
|
(rename-file filename new-name t) |
||||||
|
(set-visited-file-name new-name t t))))))) |
||||||
|
|
||||||
|
;; ----------------------------------------- |
||||||
|
;; Hook call functions |
||||||
|
|
||||||
|
(defun dot/hook-disable-line-numbers () |
||||||
|
"Disable the line numbers." |
||||||
|
(display-line-numbers-mode 0)) |
||||||
|
|
||||||
|
(defun dot/hook-disable-mode-line () |
||||||
|
"Disable the mode line." |
||||||
|
(setq-local mode-line-format nil)) |
||||||
|
|
||||||
|
(provide 'dot-core-functions) |
||||||
|
|
||||||
|
;; ----------------------------------------- |
||||||
|
;; Macros |
||||||
|
|
||||||
|
;; Reference: https://github.com/arcticicestudio/nord-emacs/issues/59#issuecomment-414882071 |
||||||
|
(defmacro dot/run-after-new-frame (func) |
||||||
|
"Run FUNC once or after every frame creation. |
||||||
|
This is needed for UI initialization when running with the daemon." |
||||||
|
`(if (daemonp) |
||||||
|
(add-hook 'after-make-frame-functions |
||||||
|
(lambda (frame) (with-selected-frame frame ,func))) |
||||||
|
,func)) |
||||||
|
|
||||||
|
;;; dot-core-functions.el ends here |
@ -0,0 +1,32 @@ |
|||||||
|
;;; dot-hooks.el --- -*- lexical-binding: t; -*- |
||||||
|
|
||||||
|
;;; Commentary: |
||||||
|
|
||||||
|
;; Add hooks. |
||||||
|
|
||||||
|
;;; Code: |
||||||
|
|
||||||
|
;; ----------------------------------------- |
||||||
|
|
||||||
|
;; Delete trailing whitespace |
||||||
|
(add-hook 'before-save-hook #'delete-trailing-whitespace) |
||||||
|
|
||||||
|
;; Display fill column indicator |
||||||
|
(add-hook 'prog-mode-hook #'display-fill-column-indicator-mode) |
||||||
|
(add-hook 'text-mode-hook #'display-fill-column-indicator-mode) |
||||||
|
|
||||||
|
;; Highlight parenthesis |
||||||
|
(add-hook 'prog-mode-hook #'show-paren-mode) |
||||||
|
|
||||||
|
;; Disable line numbers |
||||||
|
(add-hook 'Custom-mode-hook #'dot/hook-disable-line-numbers) |
||||||
|
(add-hook 'dired-mode-hook #'dot/hook-disable-line-numbers) |
||||||
|
(add-hook 'Info-mode-hook #'dot/hook-disable-line-numbers) |
||||||
|
(add-hook 'term-mode-hook #'dot/hook-disable-line-numbers) |
||||||
|
|
||||||
|
;; Wrap lines in the middle of words, gives a \ indicator |
||||||
|
(add-hook 'visual-line-mode-hook (lambda () (setq word-wrap nil))) |
||||||
|
|
||||||
|
(provide 'dot-core-hooks) |
||||||
|
|
||||||
|
;;; dot-hooks.el ends here |
@ -0,0 +1,90 @@ |
|||||||
|
;;; dot-core-packages.el --- -*- lexical-binding: t; -*- |
||||||
|
|
||||||
|
;;; Commentary: |
||||||
|
|
||||||
|
;; Install core packages. |
||||||
|
|
||||||
|
;;; Code: |
||||||
|
|
||||||
|
;;; Compile |
||||||
|
|
||||||
|
;; Automatically compile all packages. |
||||||
|
;; https://github.com/emacscollective/auto-compile |
||||||
|
|
||||||
|
(elpaca-setup auto-compile |
||||||
|
(:require auto-compile) |
||||||
|
(:when-loaded |
||||||
|
(auto-compile-on-load-mode) |
||||||
|
(auto-compile-on-save-mode))) |
||||||
|
|
||||||
|
;;; General packages |
||||||
|
|
||||||
|
(elpaca-setup general |
||||||
|
(:load-after evil) |
||||||
|
(:when-loaded |
||||||
|
;; Fix for issue: general #493 and evil #130, #301 |
||||||
|
;; https://github.com/noctuid/evil-guide#why-dont-keys-defined-with-evil-define-key-work-immediately |
||||||
|
(defun dot/general-fix-leader-key () |
||||||
|
"Fix leader key in *Messages* buffer." |
||||||
|
(when-let ((messages-buffer (get-buffer "*Messages*"))) |
||||||
|
(with-current-buffer messages-buffer |
||||||
|
(evil-normalize-keymaps)))) |
||||||
|
(add-hook 'emacs-startup-hook #'dot/general-fix-leader-key))) |
||||||
|
|
||||||
|
(elpaca-setup avy) |
||||||
|
|
||||||
|
(elpaca-setup hungry-delete |
||||||
|
(:require hungry-delete) |
||||||
|
(:when-loaded (global-hungry-delete-mode))) |
||||||
|
|
||||||
|
(elpaca-setup smart-tabs-mode |
||||||
|
;; TODO: how does this get auto-loaded? |
||||||
|
(:when-loaded |
||||||
|
(smart-tabs-add-language-support latex latex-mode-hook |
||||||
|
((latex-indent-line . 4) |
||||||
|
(latex-indent-region . 4))) |
||||||
|
;; FIXME: breaks for Python files |
||||||
|
(smart-tabs-insinuate 'c 'c++ 'java 'python 'latex))) |
||||||
|
|
||||||
|
(elpaca-setup super-save |
||||||
|
(:require super-save) |
||||||
|
(:when-loaded |
||||||
|
(setq super-save-auto-save-when-idle t) |
||||||
|
|
||||||
|
;; Fix for issues: super-save #38 and lsp-mode #1322 |
||||||
|
(defun dot/super-save-disable-advice (orig-fun &rest args) |
||||||
|
"Dont auto-save under these conditions." |
||||||
|
(unless (equal (car args) " *LV*") |
||||||
|
(apply orig-fun args))) |
||||||
|
(advice-add 'super-save-command-advice :around #'dot/super-save-disable-advice) |
||||||
|
|
||||||
|
(super-save-mode))) |
||||||
|
|
||||||
|
(elpaca nil (setup desktop ; built-in |
||||||
|
(:require desktop) |
||||||
|
(:when-loaded |
||||||
|
(setq desktop-base-file-name "state") |
||||||
|
(setq desktop-base-lock-name "state.lock") |
||||||
|
(setq desktop-dirname (expand-file-name "desktop/" dot-cache-dir)) |
||||||
|
(setq desktop-path (list desktop-dirname)) |
||||||
|
(setq desktop-globals-to-save '()) ;; Only need frames and buffers |
||||||
|
|
||||||
|
;; Create directory to store desktop file in |
||||||
|
(unless (file-directory-p desktop-dirname) |
||||||
|
(make-directory desktop-dirname t)) |
||||||
|
|
||||||
|
(defun dot/desktop-save () |
||||||
|
"Save frame state and buffers." |
||||||
|
(interactive) |
||||||
|
(dot/centaur-tabs-buffer-cleanup) |
||||||
|
(desktop-save desktop-dirname t)) |
||||||
|
|
||||||
|
(defun dot/desktop-save-on-exit () |
||||||
|
"Save state of buffers before closing Emacs." |
||||||
|
(dot/desktop-save) |
||||||
|
(desktop-release-lock desktop-dirname)) |
||||||
|
(add-hook 'kill-emacs-hook #'dot/desktop-save-on-exit)))) |
||||||
|
|
||||||
|
(provide 'dot-core-packages) |
||||||
|
|
||||||
|
;;; dot-core-packages.el ends here |
@ -0,0 +1,48 @@ |
|||||||
|
;;; dot-core-variables.el --- -*- lexical-binding: t; -*- |
||||||
|
|
||||||
|
;;; Commentary: |
||||||
|
|
||||||
|
;; Global variables. |
||||||
|
|
||||||
|
;;; Code: |
||||||
|
|
||||||
|
;; ----------------------------------------- |
||||||
|
;; Global Variables |
||||||
|
|
||||||
|
;; Variables for directories, leader keys, etc. |
||||||
|
|
||||||
|
(defvar dot-emacs-dir (directory-file-name (file-truename user-emacs-directory)) |
||||||
|
"Directory base.") ; ~/.config/emacs |
||||||
|
|
||||||
|
(defvar dot-etc-dir (expand-file-name "etc" dot-emacs-dir) |
||||||
|
"Directory for non-volatile storage.") ; ~/.config/emacs/etc |
||||||
|
|
||||||
|
;; TODO: remove "-modules" when switching over |
||||||
|
(defvar dot-cache-dir (expand-file-name "emacs" (getenv "XDG_CACHE_HOME")) |
||||||
|
"Directory for cache data.") ; ~/.cache/emacs |
||||||
|
|
||||||
|
(defvar dot/leader-key "SPC" |
||||||
|
"Leader prefix key.") |
||||||
|
|
||||||
|
(defvar dot/leader-alt-key "M-SPC" |
||||||
|
"Alternative leader prefix key, used for Insert and Emacs states.") |
||||||
|
|
||||||
|
(defvar dot/localleader-key "SPC m" |
||||||
|
"Local leader prefix key, for 'major-mode' specific commands.") |
||||||
|
|
||||||
|
(defvar dot/localleader-alt-key "M-SPC m" |
||||||
|
"Alternative local leader prefix key, used for Insert and Emacs states.") |
||||||
|
|
||||||
|
(defvar dot/shell "/bin/zsh" |
||||||
|
"Command interpreter binary path.") |
||||||
|
|
||||||
|
(defvar dot/hidpi (getenv "HIDPI") |
||||||
|
"Whether the primary screen is HiDPI.") |
||||||
|
|
||||||
|
;; Create cache directory |
||||||
|
(unless (file-directory-p dot-cache-dir) |
||||||
|
(make-directory dot-cache-dir t)) |
||||||
|
|
||||||
|
(provide 'dot-core-variables) |
||||||
|
|
||||||
|
;;; dot-core-variables.el ends here |
@ -0,0 +1,24 @@ |
|||||||
|
;;; dot-core.el --- -*- lexical-binding: t; -*- |
||||||
|
|
||||||
|
;;; Commentary: |
||||||
|
|
||||||
|
;; Load configuration core. |
||||||
|
|
||||||
|
;;; Code: |
||||||
|
|
||||||
|
;; ----------------------------------------- |
||||||
|
|
||||||
|
(add-to-list 'load-path (locate-user-emacs-file "site-lisp/core")) |
||||||
|
|
||||||
|
(require 'dot-core-variables) |
||||||
|
(require 'dot-core-customize) |
||||||
|
(require 'dot-core-fonts) |
||||||
|
(require 'dot-core-packages) |
||||||
|
(require 'dot-core-config) |
||||||
|
(require 'dot-core-functions) |
||||||
|
(require 'dot-core-advice) |
||||||
|
(require 'dot-core-hooks) |
||||||
|
|
||||||
|
(provide 'dot-core) |
||||||
|
|
||||||
|
;;; dot-core.el ends here |
@ -0,0 +1,472 @@ |
|||||||
|
;;; dot-development.el --- -*- lexical-binding: t; -*- |
||||||
|
|
||||||
|
;;; Commentary: |
||||||
|
|
||||||
|
;; Development. |
||||||
|
|
||||||
|
;;; Code: |
||||||
|
|
||||||
|
;; ----------------------------------------- |
||||||
|
;; Company |
||||||
|
|
||||||
|
(elpaca-setup company |
||||||
|
(:require company) |
||||||
|
(:with-mode |
||||||
|
(c-mode-common |
||||||
|
emacs-lisp-mode |
||||||
|
latex-mode |
||||||
|
org-mode |
||||||
|
php-mode |
||||||
|
shell-mode |
||||||
|
shell-script-mode) |
||||||
|
(:hook company-mode)) |
||||||
|
(:when-loaded |
||||||
|
(setq company-idle-delay 0.2) |
||||||
|
(setq company-minimum-prefix-length 2) |
||||||
|
(setq company-show-numbers t) |
||||||
|
(setq company-tooltip-align-annotations 't))) |
||||||
|
|
||||||
|
;; Sort Company completions. |
||||||
|
|
||||||
|
(elpaca-setup company-prescient |
||||||
|
(:load-after company prescient) |
||||||
|
(:when-loaded (company-prescient-mode))) |
||||||
|
|
||||||
|
;; Auto-completion for C/C++ headers. |
||||||
|
|
||||||
|
(elpaca-setup company-c-headers |
||||||
|
(:when-loaded (add-to-list 'company-backends 'company-c-headers))) |
||||||
|
|
||||||
|
;; GLSL integration with company requires the package: ~glslang~. |
||||||
|
|
||||||
|
(when (executable-find "glslangValidator") |
||||||
|
(elpaca-setup company-glsl |
||||||
|
(:when-loaded (add-to-list 'company-backends 'company-glsl)))) |
||||||
|
|
||||||
|
;; ----------------------------------------- |
||||||
|
;; Git |
||||||
|
|
||||||
|
(elpaca-setup diff-hl |
||||||
|
(:require diff-hl) |
||||||
|
(:with-mode prog-mode |
||||||
|
(:hook turn-on-diff-hl-mode) |
||||||
|
(:hook dot/diff-hl-enable-flydiff-and-fringe)) |
||||||
|
(:when-loaded |
||||||
|
|
||||||
|
(defun dot/diff-hl-enable-flydiff-and-fringe () |
||||||
|
"Enable on the fly diff checking if file is under version control." |
||||||
|
(let ((buffer buffer-file-name)) |
||||||
|
(when (and buffer (vc-registered buffer)) |
||||||
|
(diff-hl-flydiff-mode) |
||||||
|
(dot/toggle-fringe 1)))))) |
||||||
|
|
||||||
|
(elpaca-setup transient |
||||||
|
(:when-loaded |
||||||
|
(setq transient-history-file (expand-file-name "transient/history.el" dot-cache-dir)) |
||||||
|
(setq transient-values-file (expand-file-name "transient/values.el" dot-cache-dir)))) |
||||||
|
|
||||||
|
(elpaca-setup magit |
||||||
|
(:autoload magit-status magit-status-here) |
||||||
|
(:with-mode git-commit-setup |
||||||
|
(:hook git-commit-turn-on-auto-fill) |
||||||
|
(:hook git-commit-turn-on-flyspell)) |
||||||
|
(:with-mode magit-pre-refresh (:hook diff-hl-magit-pre-refresh)) |
||||||
|
(:with-mode magit-post-refresh (:hook diff-hl-magit-post-refresh)) |
||||||
|
(:load-after diff-hl transient) |
||||||
|
(:when-loaded |
||||||
|
(setq git-commit-fill-column 72) |
||||||
|
(setq git-commit-summary-max-length 72) |
||||||
|
(setq magit-completing-read-function #'completing-read) |
||||||
|
(setq magit-diff-paint-whitespace-lines 'both) |
||||||
|
(setq magit-display-buffer-function #'magit-display-buffer-same-window-except-diff-v1) |
||||||
|
(setq magit-process-extreme-logging nil) |
||||||
|
(setq magit-repository-directories '(("~/dotfiles" . 0) |
||||||
|
("~/code" . 3))) |
||||||
|
|
||||||
|
(put 'magit-log-select-pick :advertised-binding [?\M-c]) |
||||||
|
(put 'magit-log-select-quit :advertised-binding [?\M-k]) |
||||||
|
|
||||||
|
(defun dot/magit-select-repo () |
||||||
|
"Select project repo." |
||||||
|
(interactive) |
||||||
|
(let ((current-prefix-arg '(t))) |
||||||
|
(call-interactively #'magit-status))))) |
||||||
|
|
||||||
|
(elpaca-setup magit-todos |
||||||
|
(:load-after magit) |
||||||
|
(:when-loaded |
||||||
|
(magit-todos-mode))) |
||||||
|
|
||||||
|
;; ----------------------------------------- |
||||||
|
;; Project |
||||||
|
|
||||||
|
;; Project manager. |
||||||
|
|
||||||
|
;; Adding to project.el project directory detection |
||||||
|
;; https://michael.stapelberg.ch/posts/2021-04-02-emacs-project-override/ |
||||||
|
|
||||||
|
(elpaca nil (setup project ; built-in |
||||||
|
(setq project-list-file (expand-file-name "projects" dot-cache-dir)) |
||||||
|
(:when-loaded |
||||||
|
|
||||||
|
(defun dot/project-find (dir) |
||||||
|
(let ((root (locate-dominating-file dir ".project"))) |
||||||
|
(and root (list 'vc 'Filewise root)))) |
||||||
|
(add-hook 'project-find-functions #'dot/project-find) |
||||||
|
|
||||||
|
(defun dot/find-project-root () |
||||||
|
"Return root of the project, determined by `.git/' and `.project', |
||||||
|
`default-directory' otherwise." |
||||||
|
(let ((project (project-current))) |
||||||
|
(if project |
||||||
|
(project-root project) |
||||||
|
default-directory))) |
||||||
|
|
||||||
|
(defun dot/find-file-in-project-root () |
||||||
|
"Find file in project root." |
||||||
|
(interactive) |
||||||
|
(let ((default-directory (dot/find-project-root))) |
||||||
|
(call-interactively 'find-file))) |
||||||
|
|
||||||
|
(defun dot/project-remember-projects-under (dir maxdepth) |
||||||
|
"Index all projects below directory DIR recursively, until MAXDEPTH." |
||||||
|
(let ((files (mapcar 'file-name-directory |
||||||
|
(dot/directory-files-recursively-depth |
||||||
|
dir "\\.git$\\|\\.project$" t maxdepth)))) |
||||||
|
(dolist (path files) |
||||||
|
(project-remember-projects-under path)))) |
||||||
|
|
||||||
|
(unless (file-exists-p project-list-file) |
||||||
|
(project-remember-projects-under "~/dotfiles") |
||||||
|
(dot/project-remember-projects-under "~/code" 4)) |
||||||
|
|
||||||
|
(defun dot/project-project-name () |
||||||
|
"Return project name." |
||||||
|
(let ((project (project-current))) |
||||||
|
(if project |
||||||
|
(file-name-nondirectory (directory-file-name (project-root project))) |
||||||
|
"-"))) |
||||||
|
|
||||||
|
(defun dot/project-save-project-buffers () |
||||||
|
"Save all project buffers." |
||||||
|
(interactive) |
||||||
|
(let ((buffers (cl-remove-if (lambda (buffer) (not (buffer-file-name buffer))) |
||||||
|
(project-buffers (project-current))))) |
||||||
|
(save-some-buffers t (lambda () (member (current-buffer) buffers)))))))) |
||||||
|
|
||||||
|
;; ----------------------------------------- |
||||||
|
;; Compile |
||||||
|
|
||||||
|
;; Enable color escape codes. |
||||||
|
|
||||||
|
(elpaca nil (setup ansi-color ; built-in |
||||||
|
(:with-mode compilation-filter (:hook ansi-color-compilation-filter)) |
||||||
|
;; :hook (compilation-filter . ansi-color-compilation-filter) |
||||||
|
(:when-loaded (setq ansi-color-bold-is-bright t)))) |
||||||
|
|
||||||
|
(elpaca nil (setup compile ; built-in |
||||||
|
(defun dot/compile-disable-underline () "" |
||||||
|
(face-remap-add-relative 'underline :underline nil)) |
||||||
|
(:with-mode comint-mode (:hook dot/compile-disable-underline)) |
||||||
|
(:when-loaded |
||||||
|
(setq compilation-scroll-output 'first-error) |
||||||
|
|
||||||
|
(defun dot/compile () |
||||||
|
"Compile project." |
||||||
|
(interactive) |
||||||
|
(let ((default-directory (dot/find-project-root))) |
||||||
|
(dot/project-save-project-buffers) |
||||||
|
(let ((current-prefix-arg '(t))) |
||||||
|
(call-interactively 'compile))))))) |
||||||
|
|
||||||
|
;; ----------------------------------------- |
||||||
|
;; Languages |
||||||
|
|
||||||
|
;;; Language Server Protocol |
||||||
|
|
||||||
|
(elpaca-setup lsp-mode |
||||||
|
(:autoload lsp-deferred) |
||||||
|
;; (:require lsp-modeline lsp-mode) |
||||||
|
(:with-mode |
||||||
|
(c-mode ; clangd |
||||||
|
c++-mode ; clangd |
||||||
|
php-mode ; nodejs-intelephense |
||||||
|
csharp-mode ; omnisharp-roslyn-bin |
||||||
|
lua-mode ; lua-language-server |
||||||
|
latex-mode ; texlab |
||||||
|
kotlin-mode ; kotlin-language-server |
||||||
|
web-mode) |
||||||
|
(:hook lsp-deferred)) |
||||||
|
(:when-loaded |
||||||
|
(setq lsp-auto-guess-root t) |
||||||
|
(setq lsp-clients-clangd-args '("-j=2" |
||||||
|
"--background-index" |
||||||
|
"--clang-tidy" |
||||||
|
"--compile-commands-dir=build" |
||||||
|
"--log=error" |
||||||
|
"--header-insertion-decorators=0" |
||||||
|
"--pch-storage=memory" |
||||||
|
"--enable-config")) |
||||||
|
(setq lsp-csharp-omnisharp-roslyn-binary-path "/usr/bin/omnisharp") |
||||||
|
(setq lsp-csharp-server-install-dir "/usr/lib/omnisharp/") |
||||||
|
(setq lsp-clients-lua-language-server-bin "/usr/bin/lua-language-server") |
||||||
|
(setq lsp-clients-lua-language-server-install-dir "/usr/lib/lua-language-server/") |
||||||
|
(setq lsp-clients-lua-language-server-main-location "/usr/lib/lua-language-server/main.lua") |
||||||
|
(setq lsp-enable-xref t) |
||||||
|
(setq lsp-headerline-breadcrumb-enable nil) |
||||||
|
(setq lsp-intelephense-storage-path (expand-file-name "lsp-cache" dot-cache-dir)) |
||||||
|
(setq lsp-keep-workspace-alive nil) |
||||||
|
;; (setq lsp-modeline-code-actions-enable nil) |
||||||
|
;; (setq lsp-modeline-diagnostics-enable nil) |
||||||
|
;; (setq lsp-modeline-workspace-status-enable nil) |
||||||
|
(setq lsp-prefer-flymake nil) |
||||||
|
(setq lsp-session-file (expand-file-name "lsp-session-v1" dot-cache-dir)) |
||||||
|
|
||||||
|
;; Mark clangd args variable as safe to modify via .dir-locals.el |
||||||
|
(put 'lsp-clients-clangd-args 'safe-local-variable #'listp) |
||||||
|
|
||||||
|
;; Enable which-key descriptions |
||||||
|
(dolist (leader-key (list dot/leader-key dot/leader-alt-key)) |
||||||
|
(let ((lsp-keymap-prefix (concat leader-key " l"))) |
||||||
|
(lsp-enable-which-key-integration))) |
||||||
|
|
||||||
|
(defun dot/lsp-format-buffer-or-region () |
||||||
|
"Format the selection (or buffer) with LSP." |
||||||
|
(interactive) |
||||||
|
(unless (bound-and-true-p lsp-mode) |
||||||
|
(message "Not in an LSP buffer")) |
||||||
|
(call-interactively |
||||||
|
(if (use-region-p) |
||||||
|
#'lsp-format-region |
||||||
|
#'lsp-format-buffer))) |
||||||
|
|
||||||
|
;; This is cached to prevent unneeded I/O |
||||||
|
(setq lsp-in-cpp-project-cache nil) |
||||||
|
(defun dot/lsp-format-cpp-buffer () |
||||||
|
"Format buffer in C++ projects." |
||||||
|
(unless lsp-in-cpp-project-cache |
||||||
|
(set (make-local-variable 'lsp-in-cpp-project-cache) |
||||||
|
(list |
||||||
|
(if (and (eq major-mode 'c++-mode) |
||||||
|
(bound-and-true-p lsp-mode) |
||||||
|
(or |
||||||
|
(locate-dominating-file "." ".clang-format") |
||||||
|
(locate-dominating-file "." "_clang-format"))) |
||||||
|
t |
||||||
|
nil)))) |
||||||
|
(when (car lsp-in-cpp-project-cache) |
||||||
|
(lsp-format-buffer))) |
||||||
|
(add-hook 'before-save-hook #'dot/lsp-format-cpp-buffer))) |
||||||
|
|
||||||
|
(elpaca-setup lsp-ui |
||||||
|
(:autoload lsp-ui-mode) |
||||||
|
(:load-after flycheck lsp-mode) |
||||||
|
(:when-loaded |
||||||
|
(setq lsp-ui-doc-border (face-foreground 'default)) |
||||||
|
(setq lsp-ui-doc-delay 0.5) |
||||||
|
(setq lsp-ui-doc-enable t) |
||||||
|
(setq lsp-ui-doc-header t) |
||||||
|
(setq lsp-ui-doc-include-signature t) |
||||||
|
(setq lsp-ui-doc-position 'top) |
||||||
|
(setq lsp-ui-doc-use-childframe t) |
||||||
|
(setq lsp-ui-flycheck-list-position 'right) |
||||||
|
(setq lsp-ui-imenu-enable nil) |
||||||
|
(setq lsp-ui-peek-enable nil) |
||||||
|
(setq lsp-ui-sideline-enable nil))) |
||||||
|
|
||||||
|
;;; Debug Adapter Protocol |
||||||
|
|
||||||
|
(elpaca-setup treemacs |
||||||
|
(:hook dot/hook-disable-line-numbers) |
||||||
|
(:when-loaded (setq treemacs-persist-file (expand-file-name "treemacs/persist" dot-cache-dir)))) |
||||||
|
|
||||||
|
(elpaca-setup lsp-treemacs |
||||||
|
(:load-after treemacs) |
||||||
|
(:when-loaded (setq lsp-treemacs-error-list-current-project-only t))) |
||||||
|
|
||||||
|
(elpaca-setup dap-mode |
||||||
|
(:with-mode lsp-after-initialize (:hook dot/dap-install-debug-adapters)) |
||||||
|
(:load-after lsp-treemacs lsp-mode) |
||||||
|
(:when-loaded |
||||||
|
(setq dap-auto-configure-features '(sessions locals expressions controls tooltip)) |
||||||
|
(setq dap-breakpoints-file (expand-file-name "dap/breakpoints" dot-cache-dir)) |
||||||
|
(setq dap-utils-extension-path (expand-file-name "dap" dot-cache-dir)) |
||||||
|
|
||||||
|
;; Create dap extension directory |
||||||
|
(unless (file-directory-p dap-utils-extension-path) |
||||||
|
(make-directory dap-utils-extension-path t)) |
||||||
|
|
||||||
|
(defun dot/dap-install-debug-adapters () |
||||||
|
"Install and Load debug adapters." |
||||||
|
(interactive) |
||||||
|
(unless (bound-and-true-p lsp-mode) |
||||||
|
(user-error "Not in an LSP buffer")) |
||||||
|
(when (string-equal major-mode "c++-mode") |
||||||
|
(require 'dap-cpptools) |
||||||
|
(dap-cpptools-setup))))) |
||||||
|
|
||||||
|
;;; C/C++ |
||||||
|
|
||||||
|
(elpaca nil (setup c-mode ; built-in |
||||||
|
;; C++ // line comment style in c-mode |
||||||
|
(defun dot/c-mode-comment-style () "" |
||||||
|
(c-toggle-comment-style -1)) |
||||||
|
(:hook dot/c-mode-comment-style))) |
||||||
|
|
||||||
|
;;; C# |
||||||
|
|
||||||
|
;; Packages: |
||||||
|
;; - dotnet-host |
||||||
|
;; - dotnet-runtime-6.0 |
||||||
|
;; - dotnet-sdk-6.0 |
||||||
|
;; - dotnet-targeting-pack-6.0 |
||||||
|
;; - omnisharp-roslyn-bin |
||||||
|
;; - netcoredbg (edit PKGBUILD to detect dotnet -6.0 dependencies) |
||||||
|
|
||||||
|
(elpaca-setup csharp-mode) |
||||||
|
|
||||||
|
;;; CMake |
||||||
|
|
||||||
|
(elpaca-setup cmake-mode |
||||||
|
(:defer 2) |
||||||
|
(:when-loaded (setq cmake-tab-width (default-value 'tab-width)))) |
||||||
|
|
||||||
|
;;; Emacs Lisp |
||||||
|
|
||||||
|
(elpaca nil (setup emacs-lisp ; built-in |
||||||
|
(defun dot/elisp-init () "" |
||||||
|
(setq-local indent-tabs-mode nil)) |
||||||
|
(:hook dot/elisp-init))) |
||||||
|
|
||||||
|
;;; GLSL |
||||||
|
|
||||||
|
(elpaca-setup glsl-mode) |
||||||
|
|
||||||
|
;;; HTML |
||||||
|
|
||||||
|
(elpaca-setup web-mode) |
||||||
|
|
||||||
|
;;; Kotlin |
||||||
|
|
||||||
|
(elpaca-setup kotlin-mode) |
||||||
|
|
||||||
|
;;; Lua |
||||||
|
|
||||||
|
(elpaca-setup lua-mode |
||||||
|
(:when-loaded (setq lua-indent-level (default-value 'tab-width)))) |
||||||
|
|
||||||
|
;;; PHP |
||||||
|
|
||||||
|
(elpaca-setup php-mode |
||||||
|
(defun dot/php-mode-init () "" |
||||||
|
(setq-local indent-tabs-mode t)) |
||||||
|
(:hook dot/php-mode-init)) |
||||||
|
|
||||||
|
(elpaca-setup restclient) |
||||||
|
|
||||||
|
;;; Python |
||||||
|
|
||||||
|
(elpaca nil (setup python-mode ; built-in |
||||||
|
(defun dot/python-mode-init () "" |
||||||
|
(setq-local indent-tabs-mode t) |
||||||
|
(setq-local tab-width (default-value 'tab-width)) |
||||||
|
(setq python-indent-offset (default-value 'tab-width))) |
||||||
|
(:hook dot/python-mode-init))) |
||||||
|
|
||||||
|
;;; YAML |
||||||
|
|
||||||
|
(elpaca-setup yaml-mode) |
||||||
|
;; :defer t) |
||||||
|
|
||||||
|
;; ----------------------------------------- |
||||||
|
;; Syntax Highlighting |
||||||
|
|
||||||
|
;; (elpaca-setup tree-sitter-langs)) |
||||||
|
|
||||||
|
;; (elpaca-setup tree-sitter) |
||||||
|
;; (:also-load tree-sitter-langs) |
||||||
|
;; (:when-loaded |
||||||
|
;; (global-tree-sitter-mode) |
||||||
|
;; (add-hook 'tree-sitter-after-on-hook #'tree-sitter-hl-mode))) |
||||||
|
|
||||||
|
;; ----------------------------------------- |
||||||
|
;; Quality of Life |
||||||
|
|
||||||
|
;;; Flycheck, on the fly syntax checking |
||||||
|
|
||||||
|
(elpaca-setup flycheck |
||||||
|
(:autoload flycheck-mode) |
||||||
|
(:with-mode |
||||||
|
(c-mode-common |
||||||
|
emacs-lisp-mode |
||||||
|
latex-mode |
||||||
|
org-mode |
||||||
|
php-mode |
||||||
|
sh-mode |
||||||
|
shell-mode |
||||||
|
shell-script-mode) |
||||||
|
(:hook flycheck-mode)) |
||||||
|
(:when-loaded |
||||||
|
(setq flycheck-clang-language-standard "c++20") |
||||||
|
(setq flycheck-gcc-language-standard "c++20"))) |
||||||
|
|
||||||
|
;; For .el files which are intended to be packages |
||||||
|
(elpaca-setup flycheck-package |
||||||
|
(:load-after flycheck) |
||||||
|
(:when-loaded |
||||||
|
(add-to-list 'flycheck-checkers 'flycheck-emacs-lisp-package) |
||||||
|
(flycheck-package-setup))) |
||||||
|
|
||||||
|
(elpaca-setup flycheck-clang-tidy |
||||||
|
(:load-after flycheck) |
||||||
|
(:with-mode flycheck-mode (:hook flycheck-clang-tidy-setup)) |
||||||
|
(:when-loaded (setq flycheck-clang-tidy-extra-options "--format-style=file"))) |
||||||
|
|
||||||
|
;;; Flyspell |
||||||
|
|
||||||
|
;; Give Flyspell a selection menu. |
||||||
|
(elpaca-setup flyspell-correct |
||||||
|
(:load-after flyspell) |
||||||
|
(:with-mode org-mode (:hook flyspell-mode)) |
||||||
|
(:when-loaded |
||||||
|
(setq flyspell-issue-message-flag nil) |
||||||
|
(setq flyspell-issue-welcome-flag nil)) |
||||||
|
|
||||||
|
(defun dot/flyspell-toggle () |
||||||
|
"Toggle Flyspell, prompt for language." |
||||||
|
(interactive) |
||||||
|
(if (symbol-value flyspell-mode) |
||||||
|
(flyspell-mode -1) |
||||||
|
(call-interactively 'ispell-change-dictionary) |
||||||
|
(if (derived-mode-p 'prog-mode) |
||||||
|
(flyspell-prog-mode) |
||||||
|
(flyspell-mode)) |
||||||
|
(flyspell-buffer)))) |
||||||
|
|
||||||
|
;;; Rainbow Delimiters |
||||||
|
|
||||||
|
(elpaca-setup rainbow-delimiters |
||||||
|
(:hook-into prog-mode)) |
||||||
|
|
||||||
|
;;; Rainbow Mode |
||||||
|
|
||||||
|
(elpaca-setup rainbow-mode |
||||||
|
(:hook-into css-mode)) |
||||||
|
|
||||||
|
;;; YASnippet |
||||||
|
|
||||||
|
(elpaca-setup yasnippet |
||||||
|
(:autoload yas-insert-snippet) |
||||||
|
(setq yas-snippet-dirs (list (expand-file-name "snippets" dot-emacs-dir))) |
||||||
|
(setq yas-prompt-functions '(yas-completing-prompt)) |
||||||
|
(:when-loaded |
||||||
|
(yas-global-mode))) |
||||||
|
|
||||||
|
(elpaca-setup yasnippet-snippets |
||||||
|
(:load-after yasnippet)) |
||||||
|
|
||||||
|
;; https://stackoverflow.com/questions/22735895/configuring-a-yasnippet-for-two-scenarios-1-region-is-active-2-region-is |
||||||
|
|
||||||
|
(provide 'dot-development) |
||||||
|
|
||||||
|
;;; dot-org-mode.el ends here |
@ -0,0 +1,48 @@ |
|||||||
|
;;; dot-elpaca.el --- -*- lexical-binding: t; -*- |
||||||
|
|
||||||
|
;;; Commentary: |
||||||
|
|
||||||
|
;; Elpaca bootstrap |
||||||
|
|
||||||
|
;;; Code: |
||||||
|
|
||||||
|
;; ----------------------------------------- |
||||||
|
|
||||||
|
;; Elpaca bootstrap |
||||||
|
(defvar elpaca-directory (expand-file-name "elpaca/" user-emacs-directory)) |
||||||
|
(defvar elpaca-builds-directory (expand-file-name "builds/" elpaca-directory)) |
||||||
|
(defvar elpaca-order '(elpaca :repo "https://github.com/progfolio/elpaca.git" |
||||||
|
:ref nil |
||||||
|
:build (:not elpaca--activate-package))) |
||||||
|
(when-let ((repo (expand-file-name "repos/elpaca/" elpaca-directory)) |
||||||
|
(build (expand-file-name "elpaca/" elpaca-builds-directory)) |
||||||
|
(order (cdr elpaca-order)) |
||||||
|
((add-to-list 'load-path (if (file-exists-p build) build repo))) |
||||||
|
((not (file-exists-p repo)))) |
||||||
|
(condition-case-unless-debug err |
||||||
|
(if-let ((buffer (pop-to-buffer-same-window "*elpaca-bootstrap*")) |
||||||
|
((zerop (call-process "git" nil buffer t "clone" |
||||||
|
(plist-get order :repo) repo))) |
||||||
|
(default-directory repo) |
||||||
|
((zerop (call-process "git" nil buffer t "checkout" |
||||||
|
(or (plist-get order :ref) "--"))))) |
||||||
|
(progn |
||||||
|
(byte-recompile-directory repo 0 'force) |
||||||
|
(require 'elpaca) |
||||||
|
(and (fboundp 'elpaca-generate-autoloads) |
||||||
|
(elpaca-generate-autoloads "elpaca" repo)) |
||||||
|
(kill-buffer buffer)) |
||||||
|
(error "%s" (with-current-buffer buffer (buffer-string)))) |
||||||
|
((error) |
||||||
|
(warn "%s" err) |
||||||
|
(delete-directory repo 'recursive)))) |
||||||
|
(require 'elpaca-autoloads) |
||||||
|
(add-hook 'after-init-hook #'elpaca-process-queues) |
||||||
|
(elpaca `(,@elpaca-order)) |
||||||
|
|
||||||
|
;; Stop coping with startup time, its done loading when its done loading |
||||||
|
(add-hook 'emacs-startup-hook (lambda () (setq after-init-time (current-time)))) |
||||||
|
|
||||||
|
(provide 'dot-elpaca) |
||||||
|
|
||||||
|
;;; dot-elpaca.el ends here |
@ -0,0 +1,104 @@ |
|||||||
|
;;; dot-evil.el --- -*- lexical-binding: t; -*- |
||||||
|
|
||||||
|
;;; Commentary: |
||||||
|
|
||||||
|
;; Setup Evil and related packages. |
||||||
|
|
||||||
|
;;; Code: |
||||||
|
|
||||||
|
;; ----------------------------------------- |
||||||
|
|
||||||
|
(elpaca-setup undo-tree |
||||||
|
(:when-loaded |
||||||
|
(setq undo-tree-auto-save-history t) |
||||||
|
(setq undo-tree-history-directory-alist `(("." . ,(expand-file-name "undo-tree" dot-cache-dir)))) |
||||||
|
(global-undo-tree-mode))) |
||||||
|
|
||||||
|
(elpaca-setup goto-chg) |
||||||
|
|
||||||
|
(elpaca-setup evil |
||||||
|
(:also-load undo-tree goto-chg) |
||||||
|
(setq evil-ex-complete-emacs-commands nil) |
||||||
|
(setq evil-kill-on-visual-paste nil) |
||||||
|
(setq evil-operator-state-cursor 'box) ; Do not set half cursor |
||||||
|
(setq evil-search-module 'evil-search) |
||||||
|
(setq evil-split-window-below t) |
||||||
|
(setq evil-undo-system 'undo-tree) |
||||||
|
(setq evil-vsplit-window-right t) |
||||||
|
(setq evil-want-C-u-scroll t) |
||||||
|
(setq evil-want-Y-yank-to-eol t) |
||||||
|
(setq evil-want-integration t) |
||||||
|
(setq evil-want-keybinding nil) ; Needed by evil-collection |
||||||
|
(:require evil) |
||||||
|
(:when-loaded |
||||||
|
|
||||||
|
;; Put search results in the center of the window |
||||||
|
(defun dot/evil-scroll-center (&rest _) |
||||||
|
"Scroll cursor to center of the window." |
||||||
|
(evil-scroll-line-to-center nil)) |
||||||
|
(advice-add 'evil-ex-search :after #'dot/evil-scroll-center) |
||||||
|
(advice-add 'evil-match :after #'dot/evil-scroll-center) |
||||||
|
|
||||||
|
(defun dot/evil-normal-sort-paragraph () |
||||||
|
"Sort paragraph cursor is under. |
||||||
|
Vim equivalence: vip:sort<CR>" |
||||||
|
(interactive) |
||||||
|
(let ((p (point))) |
||||||
|
(evil-visual-char) |
||||||
|
(call-interactively 'evil-inner-paragraph) |
||||||
|
(evil-ex-sort (region-beginning) (region-end)) |
||||||
|
(goto-char p))) |
||||||
|
|
||||||
|
(defun dot/evil-insert-shift-left () |
||||||
|
"Shift line left, retains cursor position. |
||||||
|
Vim equivalence: <C-D>" |
||||||
|
(interactive) |
||||||
|
(evil-shift-left-line 1)) |
||||||
|
|
||||||
|
(defun dot/evil-insert-shift-right () |
||||||
|
"Shift line right, retains cursor position. |
||||||
|
Vim equivalence: <Tab>" |
||||||
|
(interactive) |
||||||
|
(insert "\t")) |
||||||
|
|
||||||
|
(defun dot/evil-visual-shift-left () |
||||||
|
"Shift visual selection left, retains the selection. |
||||||
|
Vim equivalence: <gv" |
||||||
|
(interactive) |
||||||
|
(call-interactively #'evil-shift-left) |
||||||
|
(setq deactivate-mark nil)) |
||||||
|
|
||||||
|
(defun dot/evil-visual-shift-right () |
||||||
|
"Shift visual selection left, retains the selection. |
||||||
|
Vim equivalence: >gv" |
||||||
|
(interactive) |
||||||
|
(call-interactively #'evil-shift-right) |
||||||
|
(setq deactivate-mark nil)) |
||||||
|
|
||||||
|
(evil-mode))) |
||||||
|
|
||||||
|
;; Evil command aliases. |
||||||
|
|
||||||
|
(elpaca nil (setup evil-ex ; evil-ex.el is part of evil |
||||||
|
(:when-loaded |
||||||
|
(evil-ex-define-cmd "W" "w") |
||||||
|
(evil-ex-define-cmd "Q" "q") |
||||||
|
(evil-ex-define-cmd "WQ" "wq") |
||||||
|
(evil-ex-define-cmd "Wq" "wq")))) |
||||||
|
|
||||||
|
(elpaca-setup evil-collection |
||||||
|
(setq evil-collection-company-use-tng nil) |
||||||
|
(setq evil-collection-key-blacklist (list dot/leader-key dot/localleader-key |
||||||
|
dot/leader-alt-key dot/localleader-alt-key |
||||||
|
"M-h" "M-j" "M-k" "M-l")) |
||||||
|
(setq evil-collection-setup-minibuffer t) |
||||||
|
(:load-after evil) |
||||||
|
(:when-loaded |
||||||
|
(evil-collection-init))) |
||||||
|
|
||||||
|
(elpaca-setup evil-nerd-commenter |
||||||
|
(:load-after evil)) |
||||||
|
|
||||||
|
(provide 'dot-evil) |
||||||
|
|
||||||
|
;;; dot-evil.el ends here |
@ -0,0 +1,665 @@ |
|||||||
|
;;; dot-keybinds.el --- -*- lexical-binding: t; -*- |
||||||
|
|
||||||
|
;;; Commentary: |
||||||
|
|
||||||
|
;; All keybinds. |
||||||
|
|
||||||
|
;;; Code: |
||||||
|
|
||||||
|
;; ----------------------------------------- |
||||||
|
;; Useful links |
||||||
|
|
||||||
|
;; Mastering Emacs key bindings |
||||||
|
;; https://www.masteringemacs.org/article/mastering-key-bindings-emacs |
||||||
|
|
||||||
|
;; use-package bind key |
||||||
|
;; https://github.com/jwiegley/use-package/blob/master/bind-key.el |
||||||
|
|
||||||
|
;; GNU remapping commands |
||||||
|
;; https://www.gnu.org/software/emacs/manual/html_node/elisp/Remapping-Commands.html |
||||||
|
|
||||||
|
;; GNU binding combinations of modifiers |
||||||
|
;; https://www.gnu.org/software/emacs/manual/html_node/efaq/Binding-combinations-of-modifiers-and-function-keys.html |
||||||
|
|
||||||
|
;; Doom Emacs bindings |
||||||
|
;; https://github.com/hlissner/doom-emacs/blob/develop/modules/config/default/+evil-bindings.el |
||||||
|
|
||||||
|
;; Keybindings and States |
||||||
|
;; https://github.com/noctuid/evil-guide#keybindings-and-states |
||||||
|
|
||||||
|
;; General.el |
||||||
|
;; https://github.com/noctuid/general.el |
||||||
|
|
||||||
|
;; ----------------------------------------- |
||||||
|
;; Disable Native |
||||||
|
|
||||||
|
;; Disable keybinds of native modes that clash with other custom keybinds. |
||||||
|
|
||||||
|
(elpaca nil (setup emacs |
||||||
|
(:global |
||||||
|
"M-h" nil |
||||||
|
"M-j" nil |
||||||
|
"M-k" nil |
||||||
|
"M-l" nil |
||||||
|
))) |
||||||
|
|
||||||
|
(elpaca nil (setup org |
||||||
|
(:bind "M-h" nil |
||||||
|
"C-M-h" nil |
||||||
|
))) |
||||||
|
|
||||||
|
(elpaca nil (setup cc-mode |
||||||
|
(:bind-into c-mode-base-map |
||||||
|
"M-j" nil |
||||||
|
"C-M-h" nil |
||||||
|
))) |
||||||
|
|
||||||
|
(elpaca nil (setup nxml-mode |
||||||
|
(:bind "M-h" nil |
||||||
|
))) |
||||||
|
|
||||||
|
;; ----------------------------------------- |
||||||
|
;; Disable Package |
||||||
|
|
||||||
|
;; Disable keybinds of installed packages that clash with other custom keybinds. |
||||||
|
|
||||||
|
(elpaca nil (setup evil-states |
||||||
|
(:bind-into evil-motion-state-map dot/leader-key nil |
||||||
|
))) |
||||||
|
|
||||||
|
(elpaca nil (setup magit |
||||||
|
(:evil-bind normal |
||||||
|
;; Do not close magit when pressing escape |
||||||
|
"<escape>" nil))) |
||||||
|
|
||||||
|
(elpaca nil (setup php-mode |
||||||
|
(:bind "M-j" nil |
||||||
|
"C-M-h" nil |
||||||
|
))) |
||||||
|
|
||||||
|
;; ----------------------------------------- |
||||||
|
;; Set Native |
||||||
|
|
||||||
|
;; Set keybinds to native functionality. |
||||||
|
|
||||||
|
;;; Set Native Global Keybinds |
||||||
|
|
||||||
|
(elpaca nil (setup emacs |
||||||
|
(:global |
||||||
|
;; Buffers |
||||||
|
"C-x C-b" ibuffer |
||||||
|
"M-w" kill-buffer-and-window |
||||||
|
|
||||||
|
;; Config edit/reload |
||||||
|
"C-c r" dot/config-reload |
||||||
|
"C-c v" dot/config-visit |
||||||
|
|
||||||
|
;; Find file |
||||||
|
"C-x C-f" dot/find-file-in-project-root |
||||||
|
|
||||||
|
;; Split and follow window |
||||||
|
"C-x 2" split-follow-horizontally |
||||||
|
"C-x 3" split-follow-vertically |
||||||
|
|
||||||
|
;; Terminal |
||||||
|
"<s-backspace>" ansi-term |
||||||
|
|
||||||
|
;; Universal prefix argument |
||||||
|
"C-M-u" universal-argument |
||||||
|
))) |
||||||
|
|
||||||
|
;;; Set Native Mode Keybinds |
||||||
|
|
||||||
|
;; Dired |
||||||
|
(elpaca nil (setup dired |
||||||
|
(:bind |
||||||
|
[remap dired-find-file] dot/dired-find-file |
||||||
|
[remap dired-up-directory] dot/dired-up-directory |
||||||
|
))) |
||||||
|
|
||||||
|
;; Org |
||||||
|
(elpaca nil (setup org |
||||||
|
(:bind "M-c" org-edit-special |
||||||
|
))) |
||||||
|
(elpaca nil (setup org-src |
||||||
|
(:bind "M-c" org-edit-src-exit |
||||||
|
"M-k" org-edit-src-abort |
||||||
|
))) |
||||||
|
(elpaca nil (setup org-capture |
||||||
|
(:bind "M-c" org-capture-finalize |
||||||
|
"M-w" org-capture-refile |
||||||
|
"M-k" org-capture-kill |
||||||
|
))) |
||||||
|
|
||||||
|
;; ----------------------------------------- |
||||||
|
;; Set Package |
||||||
|
|
||||||
|
;; Set keybinds to functionality of installed packages. |
||||||
|
|
||||||
|
(elpaca nil (setup emacs |
||||||
|
(:global |
||||||
|
;; Buffers |
||||||
|
"M-h" centaur-tabs-backward-tab |
||||||
|
"M-j" centaur-tabs-forward-group |
||||||
|
"M-k" centaur-tabs-backward-group |
||||||
|
"M-l" centaur-tabs-forward-tab |
||||||
|
"M-H" centaur-tabs-move-current-tab-to-left |
||||||
|
"M-L" centaur-tabs-move-current-tab-to-right |
||||||
|
"M-\`" evil-switch-to-windows-last-buffer |
||||||
|
;; Other |
||||||
|
"M-s" avy-goto-char-timer |
||||||
|
"M-x" dot/M-x |
||||||
|
))) |
||||||
|
|
||||||
|
(elpaca nil (setup company |
||||||
|
(:bind-into company-active-map |
||||||
|
;; Company completion selection |
||||||
|
"M-n" nil |
||||||
|
"M-p" nil |
||||||
|
"M-h" company-abort |
||||||
|
"M-j" company-select-next |
||||||
|
"M-k" company-select-previous |
||||||
|
"M-l" company-complete-selection |
||||||
|
"<escape>" company-abort |
||||||
|
))) |
||||||
|
|
||||||
|
(elpaca nil (setup evil-ex |
||||||
|
(:bind-into evil-ex-completion-map |
||||||
|
;; Evil command history selection |
||||||
|
"M-h" abort-recursive-edit |
||||||
|
"M-j" next-complete-history-element |
||||||
|
"M-k" previous-complete-history-element |
||||||
|
"M-l" exit-minibuffer |
||||||
|
))) |
||||||
|
|
||||||
|
(elpaca nil (setup emacs |
||||||
|
(:global |
||||||
|
;; flyspell-correct |
||||||
|
[remap ispell-word] flyspell-correct-at-point ; z= |
||||||
|
|
||||||
|
;; Helpful overwrite default help functions |
||||||
|
[remap describe-command] helpful-command |
||||||
|
[remap describe-function] helpful-callable |
||||||
|
[remap describe-key] helpful-key |
||||||
|
[remap describe-symbol] helpful-at-point |
||||||
|
[remap describe-variable] helpful-variable |
||||||
|
) |
||||||
|
(setup which-key |
||||||
|
(:when-loaded |
||||||
|
(which-key-add-key-based-replacements "C-h o" "describe-symbol-at-point"))))) |
||||||
|
|
||||||
|
;; LSP |
||||||
|
(elpaca nil (setup lsp-mode |
||||||
|
(:bind-into lsp-signature-mode-map |
||||||
|
"M-j" lsp-signature-next |
||||||
|
"M-k" lsp-signature-previous |
||||||
|
))) |
||||||
|
|
||||||
|
;; Magit |
||||||
|
(elpaca nil (setup magit |
||||||
|
(:bind-into magit-log-select-mode-map |
||||||
|
"M-c" magit-log-select-pick |
||||||
|
"M-k" magit-log-select-quit |
||||||
|
))) |
||||||
|
|
||||||
|
;; Org-roam |
||||||
|
(elpaca nil (setup org-roam |
||||||
|
(:bind [down-mouse-1] org-roam-visit-thing |
||||||
|
))) |
||||||
|
|
||||||
|
;; Minibuffer completion selection |
||||||
|
(elpaca nil (setup minibuffer |
||||||
|
(:bind-into minibuffer-local-map |
||||||
|
"M-J" next-history-element |
||||||
|
"M-K" previous-history-element |
||||||
|
"M-h" abort-recursive-edit |
||||||
|
"M-i" vertico-quick-insert |
||||||
|
"M-j" vertico-next |
||||||
|
"M-k" vertico-previous |
||||||
|
"M-l" vertico-exit |
||||||
|
"M-m" vertico-quick-exit |
||||||
|
"<backspace>" dot/vertico-backspace |
||||||
|
"<S-backspace>" evil-delete-backward-char-and-join |
||||||
|
))) |
||||||
|
|
||||||
|
;; with-editor |
||||||
|
(elpaca nil (setup with-editor |
||||||
|
(:bind |
||||||
|
"M-c" with-editor-finish |
||||||
|
"M-k" with-editor-cancel |
||||||
|
))) |
||||||
|
|
||||||
|
;;; Global evil keymap |
||||||
|
|
||||||
|
(elpaca nil (setup evil |
||||||
|
(:bind-into evil-normal-state-map |
||||||
|
"C-n" neotree-toggle-in-project-root |
||||||
|
"C-S-p" evil-paste-pop-next |
||||||
|
"S-<up>" scroll-down-line |
||||||
|
"S-<down>" scroll-up-line |
||||||
|
) |
||||||
|
|
||||||
|
(:bind-into evil-insert-state-map |
||||||
|
"<backtab>" dot/evil-insert-shift-left ; <S-Tab> |
||||||
|
"TAB" dot/evil-insert-shift-right ; <Tab> |
||||||
|
) |
||||||
|
|
||||||
|
(:bind-into evil-visual-state-map |
||||||
|
"<" dot/evil-visual-shift-left ; <gv |
||||||
|
">" dot/evil-visual-shift-right ; >gv |
||||||
|
) |
||||||
|
|
||||||
|
(:bind-into evil-ex-map |
||||||
|
"e" dot/find-file-in-project-root |
||||||
|
))) |
||||||
|
|
||||||
|
;;; Other evil state-related keybinds |
||||||
|
|
||||||
|
;; Custom (M-x customize) |
||||||
|
(elpaca nil (setup cus-edit |
||||||
|
(:evil-bind-into normal custom-mode-map |
||||||
|
[down-mouse-1] widget-button-click |
||||||
|
))) |
||||||
|
|
||||||
|
;; Dashboard |
||||||
|
(elpaca nil (setup dashboard |
||||||
|
(:evil-bind normal |
||||||
|
[down-mouse-1] widget-button-click |
||||||
|
"g" dashboard-refresh-buffer |
||||||
|
"m" dot/dashboard-goto-bookmarks |
||||||
|
"p" dot/dashboard-goto-projects |
||||||
|
"r" dot/dashboard-goto-recent-files |
||||||
|
))) |
||||||
|
|
||||||
|
;; Dap |
||||||
|
(elpaca nil (setup dap-ui |
||||||
|
(:evil-bind-into normal dap-ui-session-mode-map |
||||||
|
"D" dap-ui-delete-session |
||||||
|
))) |
||||||
|
|
||||||
|
;; Deft |
||||||
|
(elpaca nil (setup deft |
||||||
|
(:evil-bind normal |
||||||
|
[down-mouse-1] widget-button-click |
||||||
|
"+" deft-new-file-named |
||||||
|
"-" deft-new-file |
||||||
|
"a" deft-archive-file |
||||||
|
"c" deft-filter-clear |
||||||
|
"d" deft-delete-file |
||||||
|
"f" deft-find-file |
||||||
|
"g" deft-refresh |
||||||
|
"q" kill-this-buffer |
||||||
|
"R" deft-rename-file |
||||||
|
"s" deft-filter |
||||||
|
"ts" '("Toggle search" . deft-toggle-incremental-search) ; which-key |
||||||
|
"tt" '("Toggle sort" . deft-toggle-sort-method) ; custom string |
||||||
|
))) |
||||||
|
|
||||||
|
;; Elfeed |
||||||
|
(elpaca nil (setup elfeed |
||||||
|
(:evil-bind-into normal elfeed-search-mode-map |
||||||
|
"b" elfeed-search-browse-url |
||||||
|
"c" elfeed-search-clear-filter |
||||||
|
"gr" '("Refresh buffer" . elfeed-search-update--force) |
||||||
|
"gR" '("Update feeds" . elfeed-search-fetch) |
||||||
|
"q" elfeed-search-quit-window |
||||||
|
"u" elfeed-search-tag-all-unread |
||||||
|
"U" nil |
||||||
|
"r" elfeed-search-untag-all-unread |
||||||
|
) |
||||||
|
(:evil-bind-into normal elfeed-show-mode-map |
||||||
|
"b" elfeed-show-visit |
||||||
|
"g" elfeed-show-refresh |
||||||
|
"q" elfeed-kill-buffer |
||||||
|
"u" elfeed-show-tag--unread |
||||||
|
"y" elfeed-show-yank |
||||||
|
))) |
||||||
|
|
||||||
|
;; Magit |
||||||
|
(elpaca nil (setup magit |
||||||
|
(:evil-bind (normal visual) |
||||||
|
"{" magit-section-backward-sibling |
||||||
|
"}" magit-section-forward-sibling |
||||||
|
))) |
||||||
|
|
||||||
|
;; Minibuffer |
||||||
|
(elpaca nil (setup minibuffer |
||||||
|
(:evil-bind-into normal minibuffer-local-map |
||||||
|
"TAB" vertico-insert |
||||||
|
"j" vertico-next |
||||||
|
"k" vertico-previous |
||||||
|
"<up>" vertico-previous |
||||||
|
"<down>" vertico-next |
||||||
|
) |
||||||
|
(:evil-bind-into insert minibuffer-local-map |
||||||
|
"TAB" vertico-insert |
||||||
|
))) |
||||||
|
|
||||||
|
;; Mu4e |
||||||
|
(elpaca nil (setup mu4e |
||||||
|
(:evil-bind-into normal mu4e-compose-mode-map |
||||||
|
"q" mu4e-message-kill-buffer |
||||||
|
"M-c" message-send-and-exit |
||||||
|
"M-k" mu4e-message-kill-buffer |
||||||
|
))) |
||||||
|
|
||||||
|
;; Neotree |
||||||
|
(elpaca nil (setup neotree |
||||||
|
(:evil-bind normal |
||||||
|
"RET" neotree-enter |
||||||
|
"<backtab>" neotree-collapse-all ; <S-tab> |
||||||
|
"c" neotree-create-node |
||||||
|
"r" neotree-rename-node |
||||||
|
"d" neotree-delete-node |
||||||
|
"h" neotree-select-previous-sibling-node |
||||||
|
"g" neotree-refresh |
||||||
|
"j" neotree-next-line |
||||||
|
"k" neotree-previous-line |
||||||
|
"l" neotree-enter |
||||||
|
"C" neotree-change-root |
||||||
|
"H" neotree-hidden-file-toggle |
||||||
|
"q" neotree-hide |
||||||
|
))) |
||||||
|
|
||||||
|
;; Org |
||||||
|
(elpaca nil (setup org |
||||||
|
(:evil-bind normal |
||||||
|
"RET" dot/org-ret-at-point |
||||||
|
) |
||||||
|
(:evil-bind insert |
||||||
|
"RET" evil-ret |
||||||
|
) |
||||||
|
(:evil-bind-into motion org-agenda-mode-map |
||||||
|
"RET" org-agenda-switch-to |
||||||
|
))) |
||||||
|
|
||||||
|
;; Wdired |
||||||
|
(elpaca nil (setup wdired |
||||||
|
(:evil-bind (normal insert) |
||||||
|
"M-c" wdired-finish-edit |
||||||
|
"M-k" wdired-abort-changes |
||||||
|
))) |
||||||
|
|
||||||
|
;; ----------------------------------------- |
||||||
|
;; Set leader key |
||||||
|
|
||||||
|
;; General.el ~leader key binds. |
||||||
|
|
||||||
|
;;; Global Leader |
||||||
|
|
||||||
|
(elpaca nil (setup general |
||||||
|
(:when-loaded |
||||||
|
(general-create-definer space-leader |
||||||
|
:prefix dot/leader-key |
||||||
|
:non-normal-prefix dot/leader-alt-key |
||||||
|
:global-prefix dot/leader-alt-key |
||||||
|
:states '(normal visual insert motion emacs) |
||||||
|
:keymaps 'override) ; prevent leader keybindings from ever being overridden |
||||||
|
|
||||||
|
(space-leader |
||||||
|
"SPC" '(dot/M-x :which-key "Execute command") |
||||||
|
"RET" '(consult-bookmark :which-key "Go to bookmark") |
||||||
|
|
||||||
|
;; Apps |
||||||
|
"a" '(:ignore t :which-key "apps") |
||||||
|
"a d" '(deft :which-key "Deft") |
||||||
|
"a e" '(elfeed :which-key "Elfeed") |
||||||
|
|
||||||
|
;; Buffer / bookmark |
||||||
|
"b" '(:ignore t :which-key "buffer/bookmark") |
||||||
|
"b a" '(auto-revert-mode :which-key "Auto revert buffer") |
||||||
|
"b b" '(consult-buffer :which-key "Switch buffer") |
||||||
|
"b d" '(dot/dashboard-goto :which-key "Dashboard") |
||||||
|
"b k" '(kill-current-buffer :which-key "Kill buffer") |
||||||
|
"b m" '(bookmark-set :which-key "Make bookmark") |
||||||
|
"b n" '(evil-buffer-new :which-key "New empty buffer") |
||||||
|
"b r" '(revert-buffer :which-key "Revert buffer") |
||||||
|
"b s" '(basic-save-buffer :which-key "Save buffer") |
||||||
|
"b B" '(ibuffer :which-key "List buffers") |
||||||
|
"b C" '(dot/centaur-tabs-buffer-cleanup :which-key "Cleanup buffers") |
||||||
|
"b M" '(bookmark-delete :which-key "Delete bookmark") |
||||||
|
"b S" '(evil-write-all :which-key "Save all buffers") |
||||||
|
"b <left>" '(previous-buffer :which-key "Previous buffer") |
||||||
|
"b <right>" '(next-buffer :which-key "Next buffer") |
||||||
|
|
||||||
|
;; Comments |
||||||
|
"c" '(:ignore t :which-key "comment/config") |
||||||
|
"c c" '(evilnc-comment-or-uncomment-lines :which-key "Toggle comment") |
||||||
|
"c p" '(evilnc-comment-or-uncomment-paragraphs :which-key "Toggle comment paragraph") |
||||||
|
"c y" '(evilnc-comment-and-kill-ring-save :which-key "Comment and copy") |
||||||
|
|
||||||
|
;; Elisp |
||||||
|
"e" '(:ignore t :which-key "elisp") |
||||||
|
"e ;" '(eval-expression :which-key "Evaluate expression") |
||||||
|
"e b" '(eval-buffer :which-key "Evaluate buffer") |
||||||
|
"e e" '(eval-last-sexp :which-key "Evaluate last sexp") |
||||||
|
"e r" '(eval-region :which-key "Evaluate region") |
||||||
|
"e t" '(dot/reload-theme :which-key "Reload theme") |
||||||
|
|
||||||
|
;; File |
||||||
|
"f" '(:ignore t :which-key "file") |
||||||
|
"f d" '(dired :which-key "Find directory") |
||||||
|
"f f" '(dot/find-file-in-project-root :which-key "Find file") |
||||||
|
"f o" '(ff-find-other-file :which-key "Find header/source file") |
||||||
|
"f r" '(consult-recent-file :which-key "Find recent file") |
||||||
|
"f R" '(rename-file-and-buffer :which-key "Rename file") |
||||||
|
"f s" '(basic-save-buffer :which-key "Save file") |
||||||
|
"f S" '(write-file :which-key "Save file as...") |
||||||
|
"f u" '(dot/sudo-find-file :which-key "Sudo find file") |
||||||
|
"f U" '(dot/sudo-this-file :which-key "Sudo this file") |
||||||
|
"f e" '(:ignore t :which-key "emacs") |
||||||
|
"f e c" '(dot/config-visit :which-key "Config visit") |
||||||
|
"f e f" '(dot/find-file-emacsd :which-key "Find emacs file") |
||||||
|
"f e r" '(dot/config-reload :which-key "Config reload") |
||||||
|
|
||||||
|
;; Go to |
||||||
|
"g" '(:ignore t :which-key "goto") |
||||||
|
"g b" '(consult-bookmark :which-key "Go to bookmark") |
||||||
|
"g f" '(consult-flycheck :which-key "Go to flycheck error") |
||||||
|
"g m" '(consult-mark :which-key "Go to marker") |
||||||
|
|
||||||
|
;; Help |
||||||
|
"h" '(:keymap help-map :which-key "help") |
||||||
|
"h o" '(:ignore t :which-key "describe-symbol-at-point") |
||||||
|
|
||||||
|
;; Insert |
||||||
|
"i" '(:ignore t :which-key "insert") |
||||||
|
"i b" '(dot/indent-buffer :which-key "Indent buffer") |
||||||
|
"i f" '(fill-region :which-key "Reflow region") |
||||||
|
"i F" '(fill-paragraph :which-key "Reflow paragraph") |
||||||
|
"i r" '(indent-region :which-key "Indent region") |
||||||
|
"i s" '(dot/evil-normal-sort-paragraph :which-key "Sort paragraph") |
||||||
|
"i S" '(dot/insert-spaces-until-column :which-key "Insert spaces") |
||||||
|
"i y" '(yas-insert-snippet :which-key "Insert yasnippet") |
||||||
|
|
||||||
|
;; Notes |
||||||
|
"n" '(:ignore t :which-key "notes") |
||||||
|
"n a" '(org-agenda :which-key "Org agenda") |
||||||
|
"n r" '(:ignore t :which-key "org-roam") |
||||||
|
"n r c" '(org-roam-capture :which-key "Capture") |
||||||
|
"n r C" '(org-roam-db-sync :which-key "Build cache") |
||||||
|
"n r f" '(org-roam-node-find :which-key "Find node") |
||||||
|
"n r g" '(org-roam-graph :which-key "Show graph") |
||||||
|
"n r i" '(org-roam-node-insert :which-key "Insert") |
||||||
|
"n r I" '(dot/org-roam-node-insert-immediate :which-key "Insert (without capture)") |
||||||
|
"n r r" '(org-roam-buffer-toggle :which-key "Toggle buffer") |
||||||
|
"n r s" '(org-roam-ui-mode :which-key "Toggle server") |
||||||
|
|
||||||
|
;; Project |
||||||
|
"p" '(:keymap project-prefix-map :which-key "project") |
||||||
|
"p b" '(consult-project-buffer :which-key "project-switch-buffer") |
||||||
|
"p f" '(consult-project-extra-find :which-key "project-find-file") |
||||||
|
"p g" '(consult-grep :which-key "project-find-regexp") |
||||||
|
|
||||||
|
;; Quit |
||||||
|
"q" '(:ignore t :which-key "quit") |
||||||
|
"q q" '(save-buffers-kill-terminal :which-key "Quit Emacs") |
||||||
|
"q Q" '(save-buffers-kill-emacs :which-key "Quit Emacs (and daemon)") |
||||||
|
"q f" '(delete-frame :which-key "Close frame") |
||||||
|
"q o" '(delete-other-frames :which-key "Close other frames") |
||||||
|
|
||||||
|
;; Search |
||||||
|
"s" '(:ignore t :which-key "search") |
||||||
|
"s a" '(avy-goto-char-timer :which-key "Avy goto char") |
||||||
|
"s f" '(consult-find :which-key "Search file") |
||||||
|
"s l" '(avy-goto-line :which-key "Avy goto line") |
||||||
|
"s p" '(consult-grep :which-key "Search project") |
||||||
|
"s q" '(evil-ex-nohighlight :which-key "Stop search") |
||||||
|
"s s" '(consult-line :which-key "Search buffer") |
||||||
|
|
||||||
|
;; Tabs / toggle |
||||||
|
"t" '(:ignore t :which-key "tabs/toggle") |
||||||
|
"t f" '(dot/toggle-fringe :which-key "Toggle fringe") |
||||||
|
"t g" '(centaur-tabs-switch-group :which-key "Switch tab group") |
||||||
|
"t h" '(centaur-tabs-backward-group :which-key "Tab backward group") |
||||||
|
"t j" '(centaur-tabs-select-end-tab :which-key "Tab select first") |
||||||
|
"t k" '(centaur-tabs-select-beg-tab :which-key "Tab select last") |
||||||
|
"t l" '(centaur-tabs-forward-group :which-key "Tab forward group") |
||||||
|
"t n" '(neotree-toggle-in-project-root :which-key "Toggle Neotree") |
||||||
|
"t s" '(dot/flyspell-toggle :which-key "Toggle spell checker") |
||||||
|
"t w" '(visual-line-mode :which-key "Toggle line wrapping") |
||||||
|
|
||||||
|
;; Update packages |
||||||
|
"U" '(elpaca-update-all :which-key "Update packages") |
||||||
|
|
||||||
|
;; Version control |
||||||
|
"v" '(:ignore t :which-key "git") |
||||||
|
"v b" '(magit-branch-checkout :which-key "Magit switch branch") |
||||||
|
"v B" '(magit-blame-addition :which-key "Magit blame") |
||||||
|
"v C" '(magit-clone :which-key "Magit clone") |
||||||
|
"v F" '(magit-fetch :which-key "Magit fetch") |
||||||
|
"v L" '(magit-log :which-key "Magit log") |
||||||
|
"v s" '(magit-show-commit :which-key "Magit show commit") |
||||||
|
"v S" '(magit-stage-file :which-key "Stage file") |
||||||
|
"v U" '(magit-unstage-file :which-key "Unstage file") |
||||||
|
"v v" '(magit-status :which-key "Magit status") |
||||||
|
"v V" '(magit-status-here :which-key "Magit status here") |
||||||
|
"v c" '(:ignore t :which-key "create") |
||||||
|
"v c c" '(magit-commit-create :which-key "Commit") |
||||||
|
"v c b" '(magit-branch-and-checkout :which-key "Branch") |
||||||
|
"v c r" '(magit-init :which-key "Initialize repo") |
||||||
|
"v f" '(:ignore t :which-key "file") |
||||||
|
"v f c" '(magit-find-git-config-file :which-key "Find gitconfig file") |
||||||
|
"v f D" '(magit-file-delete :which-key "Delete file") |
||||||
|
"v f f" '(magit-find-file :which-key "Find file") |
||||||
|
"v f R" '(magit-file-rename :which-key "Rename file") |
||||||
|
"v l" '(:ignore t :which-key "list") |
||||||
|
"v l r" '(magit-list-repositories :which-key "List repositories") |
||||||
|
"v l s" '(magit-list-submodules :which-key "List submodules") |
||||||
|
"v r" '(dot/magit-select-repo :which-key "Select repo") |
||||||
|
|
||||||
|
;; Window |
||||||
|
"w" '(:ignore t :which-key "window") |
||||||
|
"w +" '(evil-window-increase-height :which-key "Increase window height") |
||||||
|
"w -" '(evil-window-decrease-height :which-key "Decrease window height") |
||||||
|
"w <" '(evil-window-decrease-width :which-key "Decrease window width") |
||||||
|
"w =" '(balance-windows :which-key "Balance windows") |
||||||
|
"w >" '(evil-window-increase-width :which-key "Increase window width") |
||||||
|
"w _" '(evil-window-set-height :which-key "Maximize window height") |
||||||
|
"w h" '(windmove-left :which-key "Focus window left") |
||||||
|
"w j" '(windmove-down :which-key "Focus window down") |
||||||
|
"w k" '(windmove-up :which-key "Focus window up") |
||||||
|
"w l" '(windmove-right :which-key "Focus window right") |
||||||
|
"w o" '(delete-other-windows :which-key "Close other windows") |
||||||
|
"w s" '(split-follow-horizontally :which-key "Split horizontal") |
||||||
|
"w v" '(split-follow-vertically :which-key "Split vertical") |
||||||
|
"w w" '(other-window :which-key "Focus other window") |
||||||
|
"w q" '(dot/centaur-tabs-kill-buffer-or-window :which-key "Close window") |
||||||
|
"w r" '(winner-redo :which-key "Redo window configuration") |
||||||
|
"w u" '(winner-undo :which-key "Undo window configuration") |
||||||
|
"w <left>" '(windmove-left :which-key "Focus window left") |
||||||
|
"w <right>" '(windmove-right :which-key "Focus window right") |
||||||
|
"w <up>" '(windmove-up :which-key "Focus window up") |
||||||
|
"w <down>" '(windmove-down :which-key "Focus window down") |
||||||
|
) |
||||||
|
|
||||||
|
;; Evaluated keybinds. |
||||||
|
|
||||||
|
(with-eval-after-load 'lsp-mode |
||||||
|
(space-leader lsp-mode-map |
||||||
|
"l" lsp-command-map |
||||||
|
"l = f" '(dot/lsp-format-buffer-or-region :which-key "format buffer or region") |
||||||
|
)) |
||||||
|
|
||||||
|
(with-eval-after-load 'dap-mode |
||||||
|
(space-leader lsp-mode-map |
||||||
|
"l d" '(dap-hydra :which-key "DAP hydra") |
||||||
|
))))) |
||||||
|
|
||||||
|
;; Source: |
||||||
|
;; https://github.com/redguardtoo/emacs.d/blob/master/lisp/init-evil.el#L712 |
||||||
|
;; https://github.com/suyashbire1/emacs.d/blob/master/init.el |
||||||
|
|
||||||
|
;;; Local Leader |
||||||
|
|
||||||
|
(elpaca nil (setup general |
||||||
|
(:when-loaded |
||||||
|
(general-create-definer local-leader |
||||||
|
:prefix dot/localleader-key |
||||||
|
:non-normal-prefix dot/localleader-alt-key |
||||||
|
:global-prefix dot/localleader-alt-key |
||||||
|
:states '(normal visual insert motion emacs) |
||||||
|
:keymaps 'override ; prevent leader keybindings from ever being overridden |
||||||
|
"" '(:ignore t :which-key "<localleader>") |
||||||
|
) |
||||||
|
|
||||||
|
(local-leader c++-mode-map |
||||||
|
"i" '(:ignore t :which-key "insert") |
||||||
|
"i i" '(dot/copy-cpp-function-implementation :which-key "Copy function implementation") |
||||||
|
) |
||||||
|
|
||||||
|
(local-leader org-mode-map |
||||||
|
"'" '(org-edit-special :which-key "Org edit") |
||||||
|
"e" '(org-export-dispatch :which-key "Org export") |
||||||
|
"o" '(org-open-at-point :which-key "Org open at point") |
||||||
|
"q" '(org-set-tags-command :which-key "Org tags") |
||||||
|
|
||||||
|
"g" '(:ignore t :which-key "goto") |
||||||
|
"g o" '(consult-outline :which-key "Org go to heading") |
||||||
|
|
||||||
|
"i" '(:ignore t :which-key "insert") |
||||||
|
"i c" '(org-table-insert-column :which-key "Insert table column") |
||||||
|
"i h" '(org-table-insert-hline :which-key "Insert table hline") |
||||||
|
"i H" '(org-table-hline-and-move :which-key "Insert table hline and move") |
||||||
|
"i r" '(org-table-insert-row :which-key "Insert table row") |
||||||
|
"i t" '(org-insert-structure-template :which-key "Insert template") |
||||||
|
|
||||||
|
"l" '(:ignore t :which-key "links") |
||||||
|
"l i" '(org-id-store-link :which-key "Store ID link") |
||||||
|
"l l" '(org-insert-link :which-key "Insert link") |
||||||
|
"l s" '(org-store-link :which-key "Store link") |
||||||
|
"l S" '(org-insert-last-stored-link :which-key "Insert stored link") |
||||||
|
|
||||||
|
"s" '(:ignore t :which-key "tree/subtree") |
||||||
|
"s h" '(org-promote-subtree :which-key "Org promote subtree") |
||||||
|
"s j" '(org-metadown :which-key "Org move subtree down") |
||||||
|
"s k" '(org-metaup :which-key "Org move subtree up") |
||||||
|
"s l" '(org-demote-subtree :which-key "Org demote subtree") |
||||||
|
"s <left>" '(org-promote-subtree :which-key "Org promote subtree") |
||||||
|
"s <right>" '(org-demote-subtree :which-key "Org demote subtree") |
||||||
|
"s <up>" '(org-move-subree-up :which-key "Org move subtree up") |
||||||
|
"s <down>" '(org-move-subtree-down :which-key "Org move subtree down") |
||||||
|
|
||||||
|
"t" '(:ignore t :which-key "toggle") |
||||||
|
"t t" '(org-todo :which-key "Org todo state") |
||||||
|
"t l" '(org-toggle-link-display :which-key "Org link display") |
||||||
|
) |
||||||
|
|
||||||
|
(local-leader org-src-mode-map |
||||||
|
"k" '(org-edit-src-abort :which-key "Org Edit abort")) |
||||||
|
|
||||||
|
(local-leader elfeed-search-mode-map |
||||||
|
"g" '(elfeed-search-update--force :which-key "Elfeed refresh buffer") |
||||||
|
"G" '(elfeed-search-fetch :which-key "Elfeed update feeds") |
||||||
|
) |
||||||
|
|
||||||
|
(local-leader elfeed-show-mode-map |
||||||
|
"g" '(elfeed-show-refresh :which-key "Elfeed refresh buffer") |
||||||
|
)))) |
||||||
|
|
||||||
|
;; c-fill-paragraph Reflow comment |
||||||
|
;; https://youtu.be/hbmV1bnQ-i0?t=1910 |
||||||
|
|
||||||
|
(provide 'dot-keybinds) |
||||||
|
|
||||||
|
;;; dot-keybinds.el ends here |
@ -0,0 +1,148 @@ |
|||||||
|
;;; dot-mail.el --- -*- lexical-binding: t; -*- |
||||||
|
|
||||||
|
;;; Commentary: |
||||||
|
|
||||||
|
;; Mail configuration. |
||||||
|
|
||||||
|
;;; Code: |
||||||
|
|
||||||
|
;; ----------------------------------------- |
||||||
|
;; Mail Functions |
||||||
|
|
||||||
|
(with-eval-after-load 'auth-source |
||||||
|
(defun dot/mail-auth-get-field (host prop) |
||||||
|
"Find PROP in `auth-sources' for HOST entry." |
||||||
|
(when-let ((source (auth-source-search :max 1 :host host))) |
||||||
|
(if (eq prop :secret) |
||||||
|
(funcall (plist-get (car source) prop)) |
||||||
|
(plist-get (flatten-list source) prop))))) |
||||||
|
|
||||||
|
;; Mail in Emacs with mu4e |
||||||
|
|
||||||
|
;; Useful mu4e manual pages: |
||||||
|
|
||||||
|
;; Key bindings |
||||||
|
;; [https://www.djcbsoftware.nl/code/mu/mu4e/MSGV-Keybindings.html#MSGV-Keybindings] |
||||||
|
|
||||||
|
(elpaca nil (setup mu4e ; loaded from AUR package |
||||||
|
(add-to-list 'load-path "/usr/share/emacs/site-lisp/mu4e") |
||||||
|
(:autoload mu4e mu4e-update-index) |
||||||
|
(:when-loaded |
||||||
|
(add-to-list 'auth-sources (expand-file-name "authinfo.gpg" dot-etc-dir)) |
||||||
|
(setq user-full-name (dot/mail-auth-get-field "fullname" :user)) |
||||||
|
(setq user-mail-address (dot/mail-auth-get-field "info" :user)) |
||||||
|
(setq mail-user-agent 'mu4e-user-agent) |
||||||
|
|
||||||
|
;; Headers |
||||||
|
(setq mu4e-headers-date-format "%d-%m-%Y") |
||||||
|
(setq mu4e-headers-time-format "%I:%M %p") |
||||||
|
(setq mu4e-headers-long-date-format "%d-%m-%Y %I:%M:%S %p") |
||||||
|
|
||||||
|
;; Syncing |
||||||
|
(setq mu4e-get-mail-command (concat "mbsync -a -c " (expand-file-name "isync/mbsyncrc" (getenv "XDG_CONFIG_HOME")))) |
||||||
|
(setq mu4e-update-interval (* 15 60)) ; 15 minutes |
||||||
|
(setq mu4e-maildir "~/mail") |
||||||
|
(setq mu4e-attachment-dir "~/downloads") |
||||||
|
|
||||||
|
;; Avoid mail syncing issues when using mbsync |
||||||
|
(setq mu4e-change-filenames-when-moving t) |
||||||
|
|
||||||
|
;; Misc |
||||||
|
(setq mu4e-completing-read-function 'completing-read) |
||||||
|
(setq mu4e-confirm-quit nil) |
||||||
|
(setq mu4e-display-update-status-in-modeline t) |
||||||
|
(setq mu4e-hide-index-messages t) |
||||||
|
(setq mu4e-sent-messages-behavior 'sent) |
||||||
|
(setq mu4e-view-show-addresses t) |
||||||
|
(setq mu4e-view-show-images nil) |
||||||
|
|
||||||
|
;; Compose |
||||||
|
(setq mu4e-compose-context-policy 'ask) |
||||||
|
(setq mu4e-compose-dont-reply-to-self t) |
||||||
|
(setq mu4e-compose-signature (concat (dot/mail-auth-get-field "fullname" :user) "\nriyyi.com\n")) |
||||||
|
(setq mu4e-compose-signature-auto-include t) |
||||||
|
|
||||||
|
;; Contexts |
||||||
|
(setq mu4e-context-policy 'pick-first) |
||||||
|
(setq mu4e-contexts |
||||||
|
`(,(make-mu4e-context |
||||||
|
:name "info" |
||||||
|
:match-func (lambda (msg) |
||||||
|
(when msg |
||||||
|
(string= (mu4e-message-field msg :maildir) "/info"))) |
||||||
|
:vars `((user-mail-address . ,(dot/mail-auth-get-field "info" :user)) |
||||||
|
(mu4e-drafts-folder . "/info/Drafts") |
||||||
|
(mu4e-refile-folder . "/info/Archive") |
||||||
|
(mu4e-sent-folder . "/info/Sent") |
||||||
|
(mu4e-trash-folder . "/info/Trash"))) |
||||||
|
,(make-mu4e-context |
||||||
|
:name "private" |
||||||
|
:match-func (lambda (msg) |
||||||
|
(when msg |
||||||
|
(string= (mu4e-message-field msg :maildir) "/private"))) |
||||||
|
:vars `((user-mail-address . ,(dot/mail-auth-get-field "private" :user)) |
||||||
|
(mu4e-drafts-folder . "/private/Drafts") |
||||||
|
(mu4e-refile-folder . "/private/Archive") |
||||||
|
(mu4e-sent-folder . "/private/Sent") |
||||||
|
(mu4e-trash-folder . "/private/Trash"))) |
||||||
|
)) |
||||||
|
|
||||||
|
;; Do not mark messages as IMAP-deleted, just move them to the Trash directory! |
||||||
|
;; https://github.com/djcb/mu/issues/1136#issuecomment-486177435 |
||||||
|
(setf (alist-get 'trash mu4e-marks) |
||||||
|
(list :char '("d" . "▼") |
||||||
|
:prompt "dtrash" |
||||||
|
:dyn-target (lambda (target msg) |
||||||
|
(mu4e-get-trash-folder msg)) |
||||||
|
:action (lambda (docid msg target) |
||||||
|
(mu4e~proc-move docid (mu4e~mark-check-target target) "-N")))) |
||||||
|
|
||||||
|
;; Start mu4e in the background for mail syncing |
||||||
|
(mu4e t)))) |
||||||
|
|
||||||
|
;; Use mu4e-alert to show new e-mail notifications. |
||||||
|
;; https://github.com/iqbalansari/mu4e-alert |
||||||
|
|
||||||
|
(elpaca-setup mu4e-alert |
||||||
|
(:defer 20) |
||||||
|
(:when-loaded |
||||||
|
(setq mu4e-alert-interesting-mail-query "(maildir:/info/Inbox OR maildir:/private/Inbox) AND flag:unread AND NOT flag:trashed") |
||||||
|
(setq mu4e-alert-notify-repeated-mails nil) |
||||||
|
|
||||||
|
(mu4e-alert-set-default-style 'libnotify) |
||||||
|
(mu4e-alert-enable-notifications))) |
||||||
|
|
||||||
|
;; Sending mail. |
||||||
|
|
||||||
|
(elpaca nil (setup smtpmail ; built-in |
||||||
|
(setq smtpmail-default-smtp-server "mail.riyyi.com") |
||||||
|
(:load-after mu4e) |
||||||
|
(:when-loaded |
||||||
|
(setq smtpmail-smtp-server "mail.riyyi.com") |
||||||
|
(setq smtpmail-local-domain "riyyi.com") |
||||||
|
(setq smtpmail-smtp-service 587) |
||||||
|
(setq smtpmail-stream-type 'starttls) |
||||||
|
(setq smtpmail-queue-mail nil)))) |
||||||
|
|
||||||
|
(elpaca nil (setup sendmail ; built-in |
||||||
|
(:load-after mu4e) |
||||||
|
(:when-loaded (setq send-mail-function 'smtpmail-send-it)))) |
||||||
|
|
||||||
|
(elpaca nil (setup message ; built-in |
||||||
|
(:load-after mu4e) |
||||||
|
(:when-loaded |
||||||
|
(setq message-kill-buffer-on-exit t) |
||||||
|
(setq message-send-mail-function 'smtpmail-send-it)))) |
||||||
|
|
||||||
|
;; Sources: |
||||||
|
;; - https://rakhim.org/fastmail-setup-with-emacs-mu4e-and-mbsync-on-macos/ |
||||||
|
;; - https://wiki.archlinux.org/title/Isync |
||||||
|
;; - https://man.archlinux.org/man/community/isync/mbsync.1.en |
||||||
|
;; - https://gitlab.com/protesilaos/dotfiles/-/blob/master/mbsync/.mbsyncrc |
||||||
|
;; - https://gitlab.com/protesilaos/dotfiles/-/blob/master/emacs/.emacs.d/prot-lisp/prot-mail.el |
||||||
|
;; - https://gitlab.com/protesilaos/dotfiles/-/blob/master/emacs/.emacs.d/prot-lisp/prot-mu4e-deprecated-conf.el |
||||||
|
;; - https://github.com/daviwil/dotfiles/blob/master/Mail.org |
||||||
|
|
||||||
|
(provide 'dot-mail) |
||||||
|
|
||||||
|
;;; dot-mail.el ends here |
@ -0,0 +1,268 @@ |
|||||||
|
;;; dot-org-mode.el --- -*- lexical-binding: t; -*- |
||||||
|
|
||||||
|
;;; Commentary: |
||||||
|
|
||||||
|
;; Load org-mode modules. |
||||||
|
|
||||||
|
;;; Code: |
||||||
|
|
||||||
|
;; ----------------------------------------- |
||||||
|
;; LaTeX Configuration |
||||||
|
|
||||||
|
(elpaca nil (setup tex-mode ; built-in |
||||||
|
(:when-loaded |
||||||
|
(defun dot/tex-mode-init () "" |
||||||
|
(setq indent-tabs-mode t) |
||||||
|
(setq tab-width 4) |
||||||
|
(setq tex-indent-basic 4)) |
||||||
|
(:hook dot/tex-mode-init) |
||||||
|
|
||||||
|
(with-eval-after-load 'project |
||||||
|
(defun compile-latex () |
||||||
|
"Compile LaTeX project." |
||||||
|
(interactive) |
||||||
|
(let ((default-directory (dot/find-project-root))) |
||||||
|
(dot/project-save-project-buffers) |
||||||
|
(shell-command "make"))))))) |
||||||
|
|
||||||
|
;; ----------------------------------------- |
||||||
|
;; Org Configuration |
||||||
|
|
||||||
|
;; Base Org. |
||||||
|
|
||||||
|
(elpaca nil (setup org ; built-in |
||||||
|
(setq org-directory (expand-file-name "documents/org" (getenv "HOME"))) |
||||||
|
(setq org-default-notes-file (expand-file-name "notes.org" org-directory)) |
||||||
|
(:when-loaded |
||||||
|
(setq org-adapt-indentation nil) |
||||||
|
(setq org-ellipsis "⤵") |
||||||
|
(setq org-image-actual-width nil) |
||||||
|
|
||||||
|
;; Enable structured template completion |
||||||
|
(add-to-list 'org-modules 'org-tempo t) |
||||||
|
(add-to-list 'org-structure-template-alist |
||||||
|
'("el" . "src emacs-lisp")) |
||||||
|
|
||||||
|
(with-eval-after-load 'evil-commands |
||||||
|
(defun dot/org-ret-at-point () |
||||||
|
"Org return key at point. |
||||||
|
|
||||||
|
If point is on: |
||||||
|
checkbox -- toggle it |
||||||
|
link -- follow it |
||||||
|
table -- go to next row |
||||||
|
otherwise -- run the default (evil-ret) expression" |
||||||
|
(interactive) |
||||||
|
(let ((type (org-element-type (org-element-context)))) |
||||||
|
(pcase type |
||||||
|
('link (if org-return-follows-link (org-open-at-point) (evil-ret))) |
||||||
|
((guard (org-at-item-checkbox-p)) (org-toggle-checkbox)) |
||||||
|
('table-cell (org-table-next-row)) |
||||||
|
(_ (evil-ret)) |
||||||
|
))))))) |
||||||
|
|
||||||
|
;; Org agenda. |
||||||
|
|
||||||
|
(elpaca nil (setup org-agenda ; built-in |
||||||
|
(:load-after evil org) |
||||||
|
(:when-loaded |
||||||
|
(setq org-agenda-files `(,org-directory ,user-emacs-directory)) |
||||||
|
(setq org-agenda-span 14) |
||||||
|
(setq org-agenda-window-setup 'current-window) |
||||||
|
(evil-set-initial-state 'org-agenda-mode 'motion)))) |
||||||
|
|
||||||
|
;; Org capture. |
||||||
|
|
||||||
|
(elpaca nil (setup org-capture ; built-in |
||||||
|
;; Org-capture in new tab, rather than split window |
||||||
|
(:hook delete-other-windows))) |
||||||
|
|
||||||
|
;; Org keys. |
||||||
|
|
||||||
|
(elpaca nil (setup org-keys ; built-in |
||||||
|
(:when-loaded |
||||||
|
(setq org-return-follows-link t)))) |
||||||
|
|
||||||
|
;; Org links. |
||||||
|
|
||||||
|
(elpaca nil (setup ol ; built-in |
||||||
|
(:when-loaded |
||||||
|
;; Do not open links to .org files in a split window |
||||||
|
(add-to-list 'org-link-frame-setup '(file . find-file))))) |
||||||
|
|
||||||
|
;; Org source code blocks. |
||||||
|
|
||||||
|
(elpaca nil (setup org-src ; built-in |
||||||
|
(:when-loaded |
||||||
|
(setq org-edit-src-content-indentation 0) |
||||||
|
(setq org-src-fontify-natively t) |
||||||
|
(setq org-src-preserve-indentation t) |
||||||
|
(setq org-src-tab-acts-natively t) |
||||||
|
(setq org-src-window-setup 'current-window)))) |
||||||
|
|
||||||
|
;; Org exporter. |
||||||
|
|
||||||
|
(elpaca nil (setup ox ; built-in |
||||||
|
(:when-loaded |
||||||
|
(setq org-export-coding-system 'utf-8-unix)))) |
||||||
|
|
||||||
|
;; Org latex exporter. |
||||||
|
|
||||||
|
(elpaca nil (setup ox-latex ; built-in |
||||||
|
(:when-loaded |
||||||
|
;; Define how minted (highlighted src code) is added to src code blocks |
||||||
|
(setq org-latex-listings 'minted) |
||||||
|
(setq org-latex-minted-options '(("frame" "lines") ("linenos=true"))) |
||||||
|
;; Set 'Table of Contents' layout |
||||||
|
(setq org-latex-toc-command "\\newpage \\tableofcontents \\newpage") |
||||||
|
;; Add minted package to every LaTeX header |
||||||
|
(add-to-list 'org-latex-packages-alist '("" "minted")) |
||||||
|
;; Add -shell-escape so pdflatex exports minted correctly |
||||||
|
(setcar org-latex-pdf-process (replace-regexp-in-string |
||||||
|
"-%latex -interaction" |
||||||
|
"-%latex -shell-escape -interaction" |
||||||
|
(car org-latex-pdf-process)))))) |
||||||
|
|
||||||
|
;;; Org Bullets |
||||||
|
|
||||||
|
(elpaca-setup org-bullets |
||||||
|
(:hook-into org-mode)) |
||||||
|
|
||||||
|
;;; Org Export Packages |
||||||
|
|
||||||
|
;; HTML exporter. |
||||||
|
|
||||||
|
(elpaca-setup htmlize |
||||||
|
(:when-loaded (setq org-export-html-postamble nil))) |
||||||
|
;;org-export-html-postamble-format ; TODO |
||||||
|
|
||||||
|
;; GitHub flavored Markdown exporter. |
||||||
|
|
||||||
|
(elpaca-setup ox-gfm) |
||||||
|
|
||||||
|
;;; Org Roam |
||||||
|
|
||||||
|
(elpaca-setup org-roam |
||||||
|
(:autoload org-roam-node-find) ;; TODO, is this enough? |
||||||
|
(setq org-roam-v2-ack t) |
||||||
|
(:when-loaded |
||||||
|
(setq org-roam-db-location (expand-file-name "org-roam.db" dot-cache-dir)) |
||||||
|
(setq org-roam-directory org-directory) |
||||||
|
;; Exclude Syncthing backup directory |
||||||
|
(setq org-roam-file-exclude-regexp "\\.stversions") |
||||||
|
(setq org-roam-verbose nil) |
||||||
|
|
||||||
|
(setq org-roam-capture-templates |
||||||
|
'(("d" "default" plain |
||||||
|
"%?" |
||||||
|
:target (file+head "%<%Y%m%d%H%M%S>-${slug}.org" "#+TITLE: ${title}\n#+FILETAGS: %^{File tags||:structure:}\n") |
||||||
|
:unnarrowed t))) |
||||||
|
|
||||||
|
(defun dot/org-roam-node-insert-immediate (arg &rest args) |
||||||
|
(interactive "P") |
||||||
|
(let ((args (push arg args)) |
||||||
|
(org-roam-capture-templates (list (append (car org-roam-capture-templates) |
||||||
|
'(:immediate-finish t))))) |
||||||
|
(apply #'org-roam-node-insert args))) |
||||||
|
|
||||||
|
(cl-defmethod org-roam-node-slug ((node org-roam-node)) |
||||||
|
"Return the slug of NODE, strip out common words." |
||||||
|
(let* ((title (org-roam-node-title node)) |
||||||
|
(words (split-string title " ")) |
||||||
|
(common-words '("a" "an" "and" "as" "at" "by" "is" "it" "of" "the" "to")) |
||||||
|
(title (string-join (seq-remove (lambda (element) (member element common-words)) words) "_")) |
||||||
|
(pairs '(("c\\+\\+" . "cpp") ;; convert c++ -> cpp |
||||||
|
("c#" . "cs") ;; convert c# -> cs |
||||||
|
("[^[:alnum:][:digit:]]" . "_") ;; convert anything not alphanumeric |
||||||
|
("__*" . "_") ;; remove sequential underscores |
||||||
|
("^_" . "") ;; remove starting underscore |
||||||
|
("_$" . "")))) ;; remove ending underscore |
||||||
|
(cl-flet ((cl-replace (title pair) |
||||||
|
(replace-regexp-in-string (car pair) (cdr pair) title))) |
||||||
|
(downcase (-reduce-from #'cl-replace title pairs))))) |
||||||
|
|
||||||
|
;; Right-align org-roam-node-tags in the completion menu without a length limit |
||||||
|
;; Source: https://github.com/org-roam/org-roam/issues/1775#issue-971157225 |
||||||
|
(setq org-roam-node-display-template "${title} ${tags:0}") |
||||||
|
(setq org-roam-node-annotation-function #'dot/org-roam-annotate-tag) |
||||||
|
(defun dot/org-roam-annotate-tag (node) |
||||||
|
(let ((tags (mapconcat 'identity (org-roam-node-tags node) " #"))) |
||||||
|
(unless (string-empty-p tags) |
||||||
|
(concat |
||||||
|
(propertize " " 'display `(space :align-to (- right ,(+ 2 (length tags))))) |
||||||
|
(propertize (concat "#" tags) 'face 'bold))))) |
||||||
|
|
||||||
|
(org-roam-setup))) |
||||||
|
|
||||||
|
;; Enable https://www.orgroam.com/manual.html#org_002droam_002dprotocol, needed to process org-protocol:// links |
||||||
|
|
||||||
|
(elpaca nil (setup org-roam-protocol ; org-roam-protocol.el is part of org-roam |
||||||
|
(:load-after org-roam) |
||||||
|
(:when-loaded |
||||||
|
|
||||||
|
;; Templates used when creating a new file from a bookmark |
||||||
|
(setq org-roam-capture-ref-templates |
||||||
|
'(("r" "ref" plain |
||||||
|
"%?" |
||||||
|
:target (file+head "${slug}.org" "#+TITLE: ${title}\n \n${body}") |
||||||
|
:unnarrowed t)))))) |
||||||
|
|
||||||
|
;; The roam-ref protocol bookmarks to add: |
||||||
|
|
||||||
|
;; javascript:location.href = |
||||||
|
;; 'org-protocol://roam-ref?template=r' |
||||||
|
;; + '&ref=' + encodeURIComponent(location.href) |
||||||
|
;; + '&title=' + encodeURIComponent(document.title) |
||||||
|
;; + '&body=' + encodeURIComponent(window.getSelection()) |
||||||
|
|
||||||
|
;; Setup org-roam-ui, runs at http://127.0.0.1:35901. |
||||||
|
|
||||||
|
(elpaca-setup org-roam-ui |
||||||
|
(:load-after org-roam) |
||||||
|
(:when-loaded |
||||||
|
(setq org-roam-ui-follow t) |
||||||
|
(setq org-roam-ui-open-on-start t) |
||||||
|
(setq org-roam-ui-sync-theme nil) ;; FIXME: Make this work (org-roam-ui-get-theme) |
||||||
|
(setq org-roam-ui-update-on-save t))) |
||||||
|
|
||||||
|
;; Easily searchable .org files via Deft. |
||||||
|
|
||||||
|
(elpaca-setup deft |
||||||
|
(:hook dot/hook-disable-line-numbers) |
||||||
|
(:when-loaded |
||||||
|
(setq deft-auto-save-interval 0) |
||||||
|
(setq deft-default-extension "org") |
||||||
|
(setq deft-directory org-directory) |
||||||
|
(setq deft-file-naming-rules '((noslash . "-") |
||||||
|
(nospace . "-") |
||||||
|
(case-fn . downcase))) |
||||||
|
(setq deft-new-file-format "%Y%m%d%H%M%S-deft") |
||||||
|
(setq deft-recursive t) |
||||||
|
;; Exclude Syncthing backup directory |
||||||
|
(setq deft-recursive-ignore-dir-regexp (concat "\\.stversions\\|" deft-recursive-ignore-dir-regexp)) |
||||||
|
;; Remove file variable -*- .. -*- and Org Mode :PROPERTIES: lines |
||||||
|
(setq deft-strip-summary-regexp (concat "\\(^.*-\\*-.+-\\*-$\\|^:[[:alpha:]_]+:.*$\\)\\|" deft-strip-summary-regexp)) |
||||||
|
(setq deft-use-filename-as-title nil) |
||||||
|
(setq deft-use-filter-string-for-filename t) |
||||||
|
|
||||||
|
(add-to-list 'deft-extensions "tex") |
||||||
|
|
||||||
|
;; Start filtering immediately |
||||||
|
(with-eval-after-load 'evil |
||||||
|
(evil-set-initial-state 'deft-mode 'insert)) |
||||||
|
|
||||||
|
(defun deft-parse-title (file contents) |
||||||
|
"Parse the given FILE and CONTENTS and determine the title." |
||||||
|
(if (string-match "#\\+\\(TITLE\\|title\\):\s*\\(.*\\)$" contents) |
||||||
|
(match-string 2 contents) |
||||||
|
(deft-base-filename file))))) |
||||||
|
|
||||||
|
;;; Org "Table of Contents" |
||||||
|
|
||||||
|
;; Generate table of contents without exporting. |
||||||
|
(elpaca-setup toc-org |
||||||
|
(:hook-into org-mode)) |
||||||
|
|
||||||
|
(provide 'dot-org-mode) |
||||||
|
|
||||||
|
;;; dot-org-mode.el ends here |
@ -0,0 +1,29 @@ |
|||||||
|
;;; dot-rss.el --- -*- lexical-binding: t; -*- |
||||||
|
|
||||||
|
;;; Commentary: |
||||||
|
|
||||||
|
;; RSS. |
||||||
|
|
||||||
|
;;; Code: |
||||||
|
|
||||||
|
;; ----------------------------------------- |
||||||
|
|
||||||
|
(elpaca-setup elfeed |
||||||
|
(:autoload elfeed) |
||||||
|
(:with-mode dot/hook-disable-line-numbers |
||||||
|
(:hook-into elfeed-search-mode) |
||||||
|
(:hook-into elfeed-show-mode)) |
||||||
|
(:when-loaded |
||||||
|
(setq elfeed-db-directory (expand-file-name "elfeed" dot-cache-dir)) |
||||||
|
(setq elfeed-enclosure-default-dir "~/downloads/") |
||||||
|
(setq elfeed-search-filter "@6-months-ago +unread") |
||||||
|
(setq elfeed-search-clipboard-type 'CLIPBOARD) |
||||||
|
(setq elfeed-search-title-max-width 100) |
||||||
|
(setq elfeed-search-title-min-width 30) |
||||||
|
(setq elfeed-search-trailing-width 55) |
||||||
|
(setq elfeed-show-unique-buffers t) |
||||||
|
(load (expand-file-name "elfeed-feeds" dot-etc-dir)))) |
||||||
|
|
||||||
|
(provide 'dot-rss) |
||||||
|
|
||||||
|
;;; dot-rss.el ends here |
@ -0,0 +1,79 @@ |
|||||||
|
;;; dot-selection.el --- -*- lexical-binding: t; -*- |
||||||
|
|
||||||
|
;;; Commentary: |
||||||
|
|
||||||
|
;; Incremental narrowing in Emacs. |
||||||
|
|
||||||
|
;;; Code: |
||||||
|
|
||||||
|
(elpaca-setup prescient |
||||||
|
(:require prescient) |
||||||
|
(:when-loaded |
||||||
|
(setq completion-styles '(prescient basic)) |
||||||
|
(setq prescient-completion-enable-sort nil) |
||||||
|
(setq prescient-filter-method '(literal regexp fuzzy)) |
||||||
|
(setq prescient-save-file (expand-file-name "prescient-save.el" dot-cache-dir)) |
||||||
|
(prescient-persist-mode))) |
||||||
|
|
||||||
|
(elpaca-setup (vertico :files (:defaults "extensions/*")) |
||||||
|
(:load-after prescient) |
||||||
|
(:when-loaded |
||||||
|
(setq vertico-sort-function #'prescient-completion-sort) |
||||||
|
(setq vertico-sort-override-function #'prescient-completion-sort) |
||||||
|
|
||||||
|
(defun dot/vertico-prescient-remember () |
||||||
|
"Remember the chosen candidate with Prescient." |
||||||
|
(when (>= vertico--index 0) |
||||||
|
(prescient-remember |
||||||
|
(substring-no-properties |
||||||
|
(nth vertico--index vertico--candidates))))) |
||||||
|
(advice-add #'vertico-insert :after #'dot/vertico-prescient-remember) |
||||||
|
|
||||||
|
(setq vertico-previous-directory nil) |
||||||
|
(defun dot/vertico-backspace () |
||||||
|
"In Vertico file completion, backward kill sexp, delete char otherwise." |
||||||
|
(interactive) |
||||||
|
(if (not (and (active-minibuffer-window) |
||||||
|
minibuffer-completing-file-name)) |
||||||
|
(backward-delete-char 1) |
||||||
|
(setq vertico-previous-directory |
||||||
|
(concat (file-name-nondirectory (directory-file-name (minibuffer-contents))) |
||||||
|
"/")) |
||||||
|
(vertico-directory-delete-word 1))) |
||||||
|
|
||||||
|
(vertico-mode)) |
||||||
|
|
||||||
|
(defun dot/vertico-dired-goto-last-visited (&rest _) |
||||||
|
"Go to directory candidate that was last visited." |
||||||
|
(when minibuffer-completing-file-name |
||||||
|
(setq vertico--index (or (seq-position vertico--candidates vertico-previous-directory) |
||||||
|
(when (string= vertico-previous-directory "~/") |
||||||
|
(seq-position vertico--candidates (concat user-login-name "/"))) |
||||||
|
(if (= vertico--total 0) -1 0))) |
||||||
|
(setq vertico-previous-directory nil))) |
||||||
|
(advice-add 'vertico--update-candidates :after #'dot/vertico-dired-goto-last-visited)) |
||||||
|
|
||||||
|
(elpaca nil (setup vertico-mouse ; vertico-mouse.el is part of vertico |
||||||
|
(:load-after vertico) |
||||||
|
(:when-loaded (vertico-mouse-mode)))) |
||||||
|
|
||||||
|
(elpaca-setup marginalia |
||||||
|
(:load-after vertico) |
||||||
|
(:when-loaded |
||||||
|
(setq marginalia-annotators '(marginalia-annotators-heavy marginalia-annotators-light)) |
||||||
|
(marginalia-mode))) |
||||||
|
|
||||||
|
(elpaca-setup consult |
||||||
|
(:load-after vertico) |
||||||
|
(:when-loaded (setq consult-narrow-key (kbd "?")))) |
||||||
|
|
||||||
|
(elpaca-setup consult-flycheck |
||||||
|
(:load-after consult flycheck)) |
||||||
|
|
||||||
|
(elpaca-setup consult-project-extra |
||||||
|
(:load-after consult project) |
||||||
|
(:when-loaded (setq project-switch-commands 'consult-project-extra-find))) |
||||||
|
|
||||||
|
(provide 'dot-selection) |
||||||
|
|
||||||
|
;;; dot-selection.el ends here |
@ -0,0 +1,107 @@ |
|||||||
|
;;; dot-setup.el --- -*- lexical-binding: t; -*- |
||||||
|
|
||||||
|
;;; Commentary: |
||||||
|
|
||||||
|
;; Configure SetupEl and keywords. |
||||||
|
|
||||||
|
;;; Code: |
||||||
|
|
||||||
|
;; ----------------------------------------- |
||||||
|
;; SetupEl |
||||||
|
|
||||||
|
;; Install and load SetupEl immediately |
||||||
|
(elpaca setup (require 'setup) |
||||||
|
|
||||||
|
;;; Configure custom macros |
||||||
|
|
||||||
|
(setup-define :load-after |
||||||
|
(lambda (&rest features) |
||||||
|
(let ((body `(require ',(setup-get 'feature)))) |
||||||
|
(dolist (feature (nreverse features)) |
||||||
|
(setq body `(with-eval-after-load ',feature ,body))) |
||||||
|
body)) |
||||||
|
:documentation "Load the current feature after FEATURES.") |
||||||
|
|
||||||
|
(setup-define :autoload |
||||||
|
(lambda (func) |
||||||
|
(let ((fn (if (memq (car-safe func) '(quote function)) |
||||||
|
(cadr func) |
||||||
|
func))) |
||||||
|
`(unless (fboundp (quote ,fn)) |
||||||
|
(autoload (function ,fn) ,(symbol-name (setup-get 'feature)) nil t)))) |
||||||
|
:documentation "Autoload COMMAND if not already bound." |
||||||
|
:repeatable t |
||||||
|
:signature '(FUNC ...)) |
||||||
|
|
||||||
|
(setup-define :defer |
||||||
|
(lambda (secs) |
||||||
|
`(if (numberp ,secs) |
||||||
|
(run-with-idle-timer ,secs nil (lambda () (require ',(setup-get 'feature)))) |
||||||
|
,(setup-quit))) |
||||||
|
:documentation "Defer loading of feature for SECS idle seconds.") |
||||||
|
|
||||||
|
;;; Configure custom macros for evil bindings |
||||||
|
|
||||||
|
(setup-define :with-evil-state |
||||||
|
(lambda (states &rest body) |
||||||
|
(setup-bind body (states states))) |
||||||
|
:documentation "Change the STATE that BODY will bind to." |
||||||
|
:indent 1) |
||||||
|
|
||||||
|
(setup-define :evil-bind-impl |
||||||
|
(lambda (key command) |
||||||
|
`(evil-define-key* ',(setup-get 'states) ,(setup-get 'map) ,key ,command)) |
||||||
|
:documentation "Bind KEY to COMMAND in the current map." |
||||||
|
:after-loaded t |
||||||
|
:ensure '(kbd func) |
||||||
|
:repeatable t) |
||||||
|
|
||||||
|
(setup-define :evil-bind |
||||||
|
(lambda (states &rest keybinds) |
||||||
|
`(with-eval-after-load 'evil |
||||||
|
(:with-evil-state ,states (:evil-bind-impl ,@keybinds)))) |
||||||
|
:documentation "Bind KEYBINDS in STATES in the current map.") |
||||||
|
|
||||||
|
(setup-define :evil-bind-into |
||||||
|
(lambda (states feature-or-map &rest keybinds) |
||||||
|
(if (string-match-p "-map\\'" (symbol-name feature-or-map)) |
||||||
|
`(:with-map ,feature-or-map (:evil-bind ,states ,@keybinds)) |
||||||
|
`(:with-feature ,feature-or-map (:evil-bind ,states ,@keybinds)))) |
||||||
|
:documentation "Bind KEYBINDS in STATE into the map of FEATURE-OR-MAP. |
||||||
|
The arguments REST are handled as by `:evil-bind'." |
||||||
|
:indent 1) |
||||||
|
) |
||||||
|
|
||||||
|
;;; Add setup.el macro |
||||||
|
|
||||||
|
;;;###autoload |
||||||
|
(defmacro elpaca-setup (order &rest body) |
||||||
|
"Execute BODY in `setup' declaration after ORDER is finished. |
||||||
|
If the :disabled keyword is present in body, the package is completely ignored. |
||||||
|
This happens regardless of the value associated with :disabled. |
||||||
|
The expansion is a string indicating the package has been disabled." |
||||||
|
(declare (indent 1)) |
||||||
|
(if (memq :disabled body) |
||||||
|
(format "%S :disabled by elpaca-setup" order) |
||||||
|
(let ((o order)) |
||||||
|
(when-let ((ensure (cl-position :ensure body))) |
||||||
|
(setq o (if (null (nth (1+ ensure) body)) nil order) |
||||||
|
body (append (cl-subseq body 0 ensure) |
||||||
|
(cl-subseq body (+ ensure 2))))) |
||||||
|
`(elpaca ,o (setup |
||||||
|
,(if-let (((memq (car-safe order) '(quote \`))) |
||||||
|
(feature (flatten-tree order))) |
||||||
|
(cadr feature) |
||||||
|
(elpaca--first order)) |
||||||
|
,@body))))) |
||||||
|
|
||||||
|
;; Startup benchmark |
||||||
|
(elpaca-setup benchmark-init |
||||||
|
(:require benchmark-init) |
||||||
|
(:when-loaded |
||||||
|
(benchmark-init/activate) |
||||||
|
(add-hook 'elpaca-after-init-hook #'benchmark-init/deactivate))) |
||||||
|
|
||||||
|
(provide 'dot-setup-el) |
||||||
|
|
||||||
|
;;; dot-setup.el ends here |
@ -0,0 +1,249 @@ |
|||||||
|
;;; dot-ui.el --- -*- lexical-binding: t; -*- |
||||||
|
|
||||||
|
;;; Commentary: |
||||||
|
|
||||||
|
;; Setup UI packages. |
||||||
|
|
||||||
|
;;; Code: |
||||||
|
|
||||||
|
;; ----------------------------------------- |
||||||
|
;; All the icons |
||||||
|
|
||||||
|
(elpaca-setup all-the-icons |
||||||
|
(:require all-the-icons) |
||||||
|
(:when-loaded |
||||||
|
|
||||||
|
;; Install all-the-icons if font files are not found |
||||||
|
(dot/run-after-new-frame |
||||||
|
(unless (find-font (font-spec :name "all-the-icons")) |
||||||
|
(all-the-icons-install-fonts t))))) |
||||||
|
|
||||||
|
(elpaca-setup all-the-icons-dired |
||||||
|
(:hook-into dired-mode) |
||||||
|
(:load-after all-the-icons) |
||||||
|
(:when-loaded (setq all-the-icons-dired-monochrome nil))) |
||||||
|
|
||||||
|
;; ----------------------------------------- |
||||||
|
;; Centaur tabs |
||||||
|
|
||||||
|
;; Places buffers as tabs in a bar at the top of the frame. |
||||||
|
|
||||||
|
(elpaca-setup centaur-tabs |
||||||
|
(:load-after all-the-icons) |
||||||
|
(:with-mode |
||||||
|
(eshell-mode |
||||||
|
help-mode |
||||||
|
helpful-mode |
||||||
|
mu4e-view-mode |
||||||
|
neotree-mode |
||||||
|
shell-mode) |
||||||
|
(:hook centaur-tabs-local-mode)) |
||||||
|
(:when-loaded |
||||||
|
(setq centaur-tabs-enable-ido-completion nil) |
||||||
|
(setq centaur-tabs-height (if dot/hidpi 38 18)) |
||||||
|
(setq centaur-tabs-modified-marker "•") |
||||||
|
(setq centaur-tabs-set-icons t) |
||||||
|
(setq centaur-tabs-set-modified-marker t) |
||||||
|
(setq centaur-tabs-style "slant") |
||||||
|
|
||||||
|
(setq centaur-tabs-project-buffer-group-calc nil) |
||||||
|
(defun centaur-tabs-buffer-groups () |
||||||
|
"Organize tabs into groups by buffer." |
||||||
|
(unless centaur-tabs-project-buffer-group-calc |
||||||
|
(set (make-local-variable 'centaur-tabs-project-buffer-group-calc) |
||||||
|
(list |
||||||
|
(cond |
||||||
|
((string-equal "*" (substring (buffer-name) 0 1)) "Emacs") |
||||||
|
((or (memq major-mode '(magit-process-mode |
||||||
|
magit-status-mode |
||||||
|
magit-diff-mode |
||||||
|
magit-log-mode |
||||||
|
magit-file-mode |
||||||
|
magit-blob-mode |
||||||
|
magit-blame-mode)) |
||||||
|
(string= (buffer-name) "COMMIT_EDITMSG")) "Magit") |
||||||
|
((project-current) (dot/project-project-name)) |
||||||
|
((memq major-mode '(org-mode |
||||||
|
emacs-lisp-mode)) "Org Mode") |
||||||
|
((derived-mode-p 'dired-mode) "Dired") |
||||||
|
((derived-mode-p 'prog-mode |
||||||
|
'text-mode) "Editing") |
||||||
|
(t "Other"))))) |
||||||
|
(symbol-value 'centaur-tabs-project-buffer-group-calc)) |
||||||
|
|
||||||
|
(defun centaur-tabs-hide-tab (buffer) |
||||||
|
"Hide from the tab bar by BUFFER name." |
||||||
|
|
||||||
|
(let ((name (format "%s" buffer))) |
||||||
|
(or |
||||||
|
;; Current window is dedicated window |
||||||
|
(window-dedicated-p (selected-window)) |
||||||
|
;; Buffer name matches below blacklist |
||||||
|
(string-match-p "^ ?\\*.*\\*" name)))) |
||||||
|
|
||||||
|
(defun dot/centaur-tabs-is-buffer-unimportant (buffer) |
||||||
|
"Return t if BUFFER is unimportant and can be killed without caution." |
||||||
|
(let ((name (format "%s" buffer))) |
||||||
|
(cond |
||||||
|
((centaur-tabs-hide-tab name) t) |
||||||
|
((string-match-p "^magit\\(-[a-z]+\\)*: .*" name) t) |
||||||
|
(t nil)))) |
||||||
|
|
||||||
|
(defun dot/centaur-tabs-buffer-cleanup () |
||||||
|
"Clean up all the hidden buffers." |
||||||
|
(interactive) |
||||||
|
(dolist (buffer (buffer-list)) |
||||||
|
(when (dot/centaur-tabs-is-buffer-unimportant buffer) |
||||||
|
(kill-buffer buffer))) |
||||||
|
(princ "Cleaned buffers")) |
||||||
|
|
||||||
|
(defun dot/centaur-tabs-kill-buffer-or-window () |
||||||
|
"Delete window of the current buffer, also kill if the buffer is hidden." |
||||||
|
(interactive) |
||||||
|
(if (dot/centaur-tabs-is-buffer-unimportant (buffer-name)) |
||||||
|
(kill-buffer-and-window) |
||||||
|
(delete-window))) |
||||||
|
|
||||||
|
(centaur-tabs-headline-match) |
||||||
|
(centaur-tabs-mode))) |
||||||
|
|
||||||
|
;; ----------------------------------------- |
||||||
|
;; Dashboard |
||||||
|
|
||||||
|
(elpaca-setup page-break-lines |
||||||
|
(:require page-break-lines)) |
||||||
|
|
||||||
|
(elpaca-setup dashboard |
||||||
|
(:require dashboard) |
||||||
|
(:hook dot/hook-disable-line-numbers) |
||||||
|
(:when-loaded |
||||||
|
(setq initial-buffer-choice (lambda () (get-buffer-create "*dashboard*"))) |
||||||
|
(setq dashboard-banner-logo-title "GNU Emacs master race!") |
||||||
|
(setq dashboard-center-content t) |
||||||
|
(setq dashboard-page-separator "\n\f\n") |
||||||
|
(setq dashboard-projects-backend 'project-el) |
||||||
|
(setq dashboard-set-file-icons t) |
||||||
|
(setq dashboard-set-footer nil) |
||||||
|
(setq dashboard-set-heading-icons t) |
||||||
|
(setq dashboard-show-shortcuts t) |
||||||
|
(setq dashboard-startup-banner 'logo) |
||||||
|
(setq dashboard-items '((projects . 10) |
||||||
|
(bookmarks . 5) |
||||||
|
(recents . 5))) |
||||||
|
|
||||||
|
(defun dot/dashboard-goto () |
||||||
|
"Go to the *dashboard* buffer, create if non-existing." |
||||||
|
(interactive) |
||||||
|
(let ((buffer "*dashboard*")) |
||||||
|
(unless (get-buffer buffer) |
||||||
|
(generate-new-buffer buffer) |
||||||
|
(dashboard-refresh-buffer)) |
||||||
|
(switch-to-buffer buffer))) |
||||||
|
|
||||||
|
;; Fix keybinds.. |
||||||
|
|
||||||
|
(defun dot/dashboard-goto-bookmarks () |
||||||
|
"Move point to bookmarks." |
||||||
|
(interactive) |
||||||
|
(funcall (local-key-binding "m"))) |
||||||
|
|
||||||
|
(defun dot/dashboard-goto-projects () |
||||||
|
"Move point to projects." |
||||||
|
(interactive) |
||||||
|
(funcall (local-key-binding "p"))) |
||||||
|
|
||||||
|
(defun dot/dashboard-goto-recent-files () |
||||||
|
"Move point to recent files." |
||||||
|
(interactive) |
||||||
|
(funcall (local-key-binding "r"))) |
||||||
|
|
||||||
|
(let ((command-line-args '("emacs"))) ;; TODO: Remove this when switching over |
||||||
|
(dashboard-setup-startup-hook) |
||||||
|
) |
||||||
|
)) |
||||||
|
|
||||||
|
;; ----------------------------------------- |
||||||
|
;; Helpful |
||||||
|
|
||||||
|
;; A better *help* buffer. |
||||||
|
|
||||||
|
(elpaca-setup helpful |
||||||
|
(:require helpful) |
||||||
|
(:hook dot/hook-disable-line-numbers)) |
||||||
|
|
||||||
|
;; ----------------------------------------- |
||||||
|
;; Neotree |
||||||
|
|
||||||
|
;; Provides Emacs with a file tree. |
||||||
|
|
||||||
|
(elpaca-setup neotree |
||||||
|
(:autoload neotree-toggle) |
||||||
|
(:hook dot/hook-disable-line-numbers) |
||||||
|
(:hook hl-line-mode) |
||||||
|
|
||||||
|
;; This needs to be in init to actually start loading the package |
||||||
|
(with-eval-after-load 'project |
||||||
|
(defun neotree-toggle-in-project-root () |
||||||
|
"Toggle Neotree in project root." |
||||||
|
(interactive) |
||||||
|
(let ((default-directory (dot/find-project-root))) |
||||||
|
(call-interactively #'neotree-toggle)))) |
||||||
|
|
||||||
|
(:when-loaded |
||||||
|
(setq neo-theme (if (display-graphic-p) 'icons 'arrow)) |
||||||
|
(setq neo-autorefresh nil) |
||||||
|
(setq neo-mode-line-type 'none) |
||||||
|
(setq neo-show-hidden-files t) |
||||||
|
(setq neo-vc-integration '(face)))) |
||||||
|
|
||||||
|
;; ----------------------------------------- |
||||||
|
;; Telephone Line |
||||||
|
|
||||||
|
;; Emacs mode line replacement. |
||||||
|
|
||||||
|
(elpaca-setup telephone-line |
||||||
|
(:require telephone-line) |
||||||
|
(:when-loaded |
||||||
|
(setq telephone-line-height (if dot/hidpi 30 15)) |
||||||
|
(setq telephone-line-lhs |
||||||
|
'((evil . (telephone-line-evil-tag-segment)) |
||||||
|
(accent . (telephone-line-erc-modified-channels-segment |
||||||
|
telephone-line-process-segment |
||||||
|
telephone-line-buffer-segment)) |
||||||
|
(nil . (telephone-line-project-segment)))) |
||||||
|
(telephone-line-mode))) |
||||||
|
|
||||||
|
;; ----------------------------------------- |
||||||
|
;; Theme |
||||||
|
|
||||||
|
(elpaca-setup hybrid-reverse-theme |
||||||
|
(:require hybrid-reverse-theme) |
||||||
|
(:when-loaded |
||||||
|
(dot/run-after-new-frame |
||||||
|
(load-theme 'hybrid-reverse t)))) |
||||||
|
|
||||||
|
;; ----------------------------------------- |
||||||
|
;; Which-key |
||||||
|
|
||||||
|
;; Popup that displays available key bindings. |
||||||
|
|
||||||
|
(elpaca-setup which-key |
||||||
|
(:hook-into elpaca-after-init) |
||||||
|
(:when-loaded |
||||||
|
(setq which-key-add-column-padding 1) |
||||||
|
(setq which-key-max-display-columns nil) |
||||||
|
(setq which-key-min-display-lines 6) |
||||||
|
(setq which-key-sort-order #'dot/which-key-prefix-then-key-order-alpha) |
||||||
|
(setq which-key-sort-uppercase-first nil) |
||||||
|
|
||||||
|
(defun dot/which-key-prefix-then-key-order-alpha (acons bcons) |
||||||
|
"Order by prefix, then lexicographical." |
||||||
|
(let ((apref? (which-key--group-p (cdr acons))) |
||||||
|
(bpref? (which-key--group-p (cdr bcons)))) |
||||||
|
(if (not (eq apref? bpref?)) |
||||||
|
(and (not apref?) bpref?) |
||||||
|
(which-key-key-order-alpha acons bcons)))))) |
||||||
|
|
||||||
|
(provide 'dot-ui) |
||||||
|
|
||||||
|
;;; dot-ui.el ends here |
Loading…
Reference in new issue