Compare commits

..
90 Commits
Author SHA1 Message Date
Riyyi f0835c1a06 Neovim: WIP on navigation workflow 2025-01-18 13:54:36 +01:00
Riyyi 98cf182406 Neovim: Improve file browsing 2024-12-12 22:53:27 +01:00
Riyyi 16321c0c4f Neovim: Update packages 2024-12-10 22:19:29 +01:00
Riyyi 9d7b1f5850 Emacs: Improve buffer group separation for projects 2024-11-25 03:14:05 +01:00
Riyyi 3c5fbbf581 Emacs: Add go-mode, fix :load-after typo in restclient 2024-11-14 22:54:27 +01:00
Riyyi a38b5d1e15 Emacs+Packages: Add Swift-mode, add hunspell packages 2024-11-13 11:44:12 +01:00
Riyyi f223178f39 Config: Fix pinentry 2024-07-16 21:51:03 +02:00
Riyyi 33f22e6471 Firefox: Fix URL bar 2024-07-15 22:15:46 +02:00
Riyyi b21b6d2462 Emacs: Add worklog org-capture templates 2024-07-13 11:25:39 +02:00
Riyyi 795f2aad5b Emacs: Append instead of prepend to startup hook 2024-05-13 21:51:13 +02:00
Riyyi cf156ca80b Emacs: Make solution for removal of (elpaca nil) semantics 2024-05-12 22:56:52 +02:00
Riyyi a282e01692 Neovim: Add rainbow-mode, improve diffview colors 2024-02-25 15:44:57 +01:00
Riyyi 88f9e2e408 Neovim: Disable tabs at the top 2024-02-24 20:41:27 +01:00
Riyyi a208f458c1 Config: Add Neovim as git diff/merge tool 2024-02-24 20:36:17 +01:00
Riyyi d488a323da Neovim: Apply custom Telescope setting to its matching layout 2024-02-24 20:30:44 +01:00
Riyyi 9cc18db3ba Neovim: Add config, switch to it from Vim 2024-02-11 18:11:01 +01:00
Riyyi 88dc203b9f Emacs: Fix YASnippet expansion in insert mode 2023-12-08 23:33:28 +01:00
Riyyi 50d8e3f455 Emacs: Fix YASnippet expansion in insert mode 2023-12-08 23:30:45 +01:00
Riyyi 5e7058563f Emacs: Update Elpaca bootstrap to 0.6 2023-11-27 11:42:17 +01:00
Riyyi 5bc947db3d Scripts: Play video from clipboard 2023-11-27 11:32:03 +01:00
Riyyi 94f59f5b31 Emacs: Update function name 2023-11-02 20:44:47 +01:00
Riyyi 484fa668de Emacs: Fill last modified with timestamp when saving org files 2023-11-02 20:36:45 +01:00
Riyyi 1fb041fffc Emacs: Don't fuzzy search in consult-line 2023-08-12 11:53:51 +02:00
Riyyi 9f5ce80255 Emacs: Add hunspell multi-dictionary spell checking 2023-08-10 22:42:38 +02:00
Riyyi 1068ef9502 Emacs: Fix Elpaca call 2023-07-31 23:03:59 +02:00
Riyyi 3b01c0b759 Emacs: Update config to use version 29 features 2023-07-31 23:00:27 +02:00
Riyyi 11d351f629 Emacs: Read cache directory from ~ if no XDG is set 2023-05-01 10:06:49 +02:00
Riyyi dbf929c687 Emacs: Update Elpaca bootstrap to version 0.3 2023-03-31 21:53:49 +02:00
Riyyi 9461c904cd Emacs: Fix org-roam by adding SQLite dependency 2023-03-12 13:35:11 +01:00
Riyyi f9459cfe66 Emacs: Update to use vertico-prescient, update Elpaca bootstrap 2023-03-10 23:36:30 +01:00
Riyyi 17cbd91236 Emacs: Fix dashboard startup 2023-01-23 13:29:52 +01:00
Riyyi 89607db905 Emacs: Complete restructure of the config
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 vertico
2023-01-01 22:46:55 +01:00
Riyyi 2b5aabebfb Config: Fix YouTube channel videos being hidden accidently 2022-12-07 11:57:17 +01:00
Riyyi 437dd48e51 Emacs: Make evil shift in visual mode prefix compatible 2022-09-04 12:37:57 +02:00
Riyyi 82e5740e22 Emacs: Save state on exit, fix general leader key in *Messages* buffer 2022-09-03 01:53:33 +02:00
Riyyi cf417d95b2 Config: Actually lock the screen before going to sleep, using systemd 2022-09-02 15:52:56 +02:00
Riyyi c3811b7f78 Emacs: Add function to copy C++ function implementation to clipboard 2022-09-02 13:22:38 +02:00
Riyyi 3378ba974c Emacs: Add keybind to select magit repo, using prefix argument 2022-09-02 13:20:25 +02:00
Riyyi 8904a85694 Config: Fix rofi not starting due to duplicate keybinding 2022-09-02 12:51:10 +02:00
Riyyi 008efd440b Emacs: Fix auto-save fix :^) 2022-08-28 22:32:30 +02:00
Riyyi dcaff77c01 Emacs: Don't auto-save when focus switches to lsp-mode's signature view 2022-08-28 21:38:40 +02:00
Riyyi b28a885af9 Emacs: Hide everything thats not a file from centaur-tabs 2022-08-23 13:02:03 +02:00
Riyyi 3492090285 Emacs: Add bindings for function signature preview cycling 2022-08-22 23:59:09 +02:00
Riyyi 21dc56539f Emacs: User winner-mode instead of a custom function to undo windows 2022-08-22 16:39:25 +02:00
Riyyi 847537257e Emacs: Add window maximize toggle 2022-08-22 12:24:15 +02:00
Riyyi 81edda78b1 Emacs: Improve Org mode RET at point function for tables 2022-08-22 02:47:47 +02:00
Riyyi b87f56abcf Emacs: Add spell checker toggle function 2022-08-16 22:52:25 +02:00
Riyyi 82171e6684 Config: Add more XDG base directories 2022-08-12 13:57:00 +02:00
Riyyi a4bf47770c Config: Open terminal in current directory 2022-08-12 13:17:56 +02:00
Riyyi cd45f7595d Config: Add link and CSS property to Firefox 2022-08-11 13:14:04 +02:00
Riyyi 915690a2c8 Scripts: Open mpv window when starting audio_only streams 2022-08-10 16:41:58 +02:00
Riyyi 140c723776 Emacs: Check for .clangd config file, update flycheck to C++20 2022-08-06 12:54:21 +02:00
Riyyi 68a2c75bbc Emacs: Only format C++ buffers in source trees with .clang-format file 2022-08-06 10:48:00 +02:00
Riyyi 92fa2f52d8 Emacs: Format C++ project buffers before saving 2022-08-05 16:22:13 +02:00
Riyyi 9049b130a8 Emacs: Use more of the consult package 2022-07-31 16:06:04 +02:00
Riyyi 4389dce613 Emacs: Change git leader key prefix 2022-07-31 14:56:56 +02:00
Riyyi 28c152ba22 Emacs: Switch package projectile -> project.el 2022-07-31 13:00:41 +02:00
Riyyi ffbefa0887 Emacs: Improve pdflatex minted elisp 2022-07-29 10:54:28 +02:00
Riyyi de64c467e3 Manager: Add config file 2022-07-25 17:33:46 +02:00
Riyyi d91d412362 System: Unbind FiiO USB DAC E17K when going to sleep 2022-07-25 17:31:55 +02:00
Riyyi 594c32aa87 Config: Add day of week to polybar date module 2022-04-29 12:09:06 +02:00
Riyyi 48b88d0464 Emacs: Suppress native-comp warnings buffer 2022-04-28 13:20:46 +02:00
Riyyi 2bd9ebc4ea Emacs+Packages: Switch to native-compilation version 2022-04-24 13:11:21 +02:00
Riyyi 4c88465f78 Config: Add looking-glass.desktop file 2022-03-23 00:25:21 +01:00
Riyyi c116b8f589 Scripts: Fix quality flag for Twitch URLs 2022-03-21 14:11:52 +01:00
Riyyi 9697bab8ef Config: Update autorandr desktop profile 2022-03-18 21:29:39 +01:00
Riyyi 36631a5372 Config: Update xinitc to use autorandr 2022-03-18 14:23:05 +01:00
Riyyi 268b9e8dee Config: Add autorandr profile for laptop 2022-03-18 14:20:47 +01:00
Riyyi 9cdaac7413 Config: Add automatic monitor setup using autorandr program 2022-03-18 13:23:00 +01:00
Riyyi 9a17694bc9 Config: Prevent warning on the first exec of the btc polybar module 2022-03-18 13:13:31 +01:00
Riyyi e6bddb75c8 Config: Decrease journald max logging storage 2022-03-18 11:15:14 +01:00
Riyyi a36cbbe4eb Emacs: Store undo history in the cache directory 2022-03-16 11:46:14 +01:00
Riyyi 1ae30d54b1 Scripts: Move streaming videos to play script, update script arguments 2022-03-15 16:42:07 +01:00
Riyyi 62e3d3f5e5 Scripts: Update play queue to use the --input-ipc-server option 2022-03-14 23:48:51 +01:00
Riyyi 07712d1ad4 Config: Add machine specific configuration to lock.sh ring 2022-03-06 01:02:49 +01:00
Riyyi fbb9f3d8c4 Config: Add support for Qt6 uniform themes 2022-03-04 11:29:06 +01:00
Riyyi 793528bfd5 Config: Add trizen config file 2022-03-03 00:43:42 +01:00
Riyyi cf1190e78d Scripts: Add metadata to downloaded videos 2022-03-02 12:17:30 +01:00
Riyyi 0095a45a1b README: Convert from Markdown .md to Org Mode .org 2022-03-01 17:38:05 +01:00
Riyyi 8c10a9b804 Config: Update vim color theme symlink 2022-03-01 17:36:23 +01:00
Riyyi 81f9372766 README: Convert from Markdown .md to Org Mode .org 2022-03-01 17:08:44 +01:00
Riyyi 50db6c771a Emacs: Fix HiDPI mode lines height 2022-03-01 13:16:25 +01:00
Riyyi c893786fba Manager+README: Remove manager, add archive link to README.md 2022-02-28 17:12:52 +01:00
Riyyi ef203c5063 Config+Packages: Implement machine specific configuration 2022-02-28 16:44:01 +01:00
Riyyi 8d8a21166b Manager: Suppress error output, fix Debian package list 2022-02-28 11:58:39 +01:00
Riyyi 946c896f28 Config: Update git aliases, add 2 aliases, add zsh bracket highlights 2022-02-28 11:55:06 +01:00
Riyyi aee2608d4a Config: Fix 4chan post width in userContent.css 2022-02-28 10:59:51 +01:00
Riyyi bc61433953 Emacs: Fix Lua language server 2022-02-21 22:10:37 +01:00
Riyyi e5bee42ee4 Config: Add hyperlinks to ls output 2022-02-21 11:50:17 +01:00
Riyyi 86f403dd99 Config: Set terminal title in Vim 2022-02-21 10:55:02 +01:00
91 changed files with 6048 additions and 3190 deletions
+13
View File
@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<actions>
<action>
<icon>utilities-terminal</icon>
<name>Open Terminal Here</name>
<unique-id>1594675818593070-1</unique-id>
<command>urxvt -cd %f</command>
<description>Open Terminal in the Current Directory</description>
<patterns>*</patterns>
<startup-notify/>
<directories/>
</action>
</actions>
+36
View File
@@ -0,0 +1,36 @@
output HDMI-1
off
output HDMI-3
off
output DP-1
crtc 0
mode 2560x1080
pos 0x0
primary
rate 59.98
x-prop-audio auto
x-prop-broadcast_rgb Automatic
x-prop-colorspace Default
x-prop-max_bpc 12
x-prop-non_desktop 0
output HDMI-2
crtc 1
mode 1920x1080
pos 4240x0
rate 60.00
x-prop-aspect_ratio Automatic
x-prop-audio auto
x-prop-broadcast_rgb Automatic
x-prop-colorspace Default
x-prop-max_bpc 12
x-prop-non_desktop 0
output DP-2
crtc 2
mode 1680x1050
pos 2560x406
rate 59.95
x-prop-audio auto
x-prop-broadcast_rgb Automatic
x-prop-colorspace Default
x-prop-max_bpc 12
x-prop-non_desktop 0
+3
View File
@@ -0,0 +1,3 @@
DP-1 00ffffffffffff00046932290dea00001c170104a5431c783aca95a6554ea1260f5054b7ef00d1c0b30095008180814081c08100714fcd4600a0a0381f4030203a00a11c2100001a000000ff0044374c4d54463035393931370a000000fd00174c18531804110140f838f03c000000fc00415355532050423239380a202001a502032571520102031112130414051f900e0f1d1e2220212309170783010000656e0c0010008c0ad08a20e02d10103e9600a11c21000018011d007251d01e206e285500a11c2100001e011d00bc52d01e20b8285540a11c2100001e8c0ad090204031200c405500a11c21000018000000000000000000000000000000000000cd
DP-2 00ffffffffffff004162685096de81022a120104a52e1d7826e525a65444a125145054a56b807100814081809500a900b3000101010121399030621a274068b03600d0221100001c000000fd00384c1e5110000a202020202020000000fc00504b422056495332323257530a000000ff003432303635353538333030380a0087
HDMI-2 00ffffffffffff004c2d3a0d00060001011a0103805932780a23ada4544d99260f474abdef80714f81c0810081809500a9c0b300010104740030f2705a80b0588a00501d7400001e023a801871382d40582c4500501d7400001e000000fd00184b0f511e000a202020202020000000fc0053414d53554e470a20202020200129020346f0535f101f041305142021225d5e62636407160312290907071507503d04c083010000e2000fe30503016e030c001000b83c20008001020304e3060d01e50e60616566011d80d0721c1620102c2580501d7400009e662156aa51001e30468f3300501d7400001e000000000000000000000000000000000000000000cd
+17
View File
@@ -0,0 +1,17 @@
output HDMI-1
off
output DP-1
off
output HDMI-2
off
output eDP-1
crtc 0
mode 3000x2000
pos 0x0
primary
rate 59.99
x-prop-broadcast_rgb Automatic
x-prop-colorspace Default
x-prop-max_bpc 12
x-prop-non_desktop 0
x-prop-scaling_mode Full aspect
+1
View File
@@ -0,0 +1 @@
eDP-1 00ffffffffffff0034a9a29600082131ff190104a51d137803ee91a3544c99260f50540000000101010101010101010101010101010180a2b868b1d04070080888001dbe1000001e000000fd002e3c5e7c2a010a202020202020000000fc005656583134503034384d30300a0000001000000000000000000000000000000084
+2
View File
@@ -0,0 +1,2 @@
[config]
skip-options=gamma
+1
View File
@@ -51,6 +51,7 @@ bspc rule -a feh state=floating
bspc rule -a firefox:Browser state=floating
bspc rule -a firefox:Places state=floating
bspc rule -a Inferno state=floating
bspc rule -a looking-glass-client state=fullscreen
bspc rule -a Lxappearance state=floating
bspc rule -a mpv state=floating center=on
bspc rule -a Pavucontrol state=floating
+7 -1
View File
@@ -10,7 +10,13 @@ indicate_hidden = false
padding = 10
shrink = false
frame_width = 3
# >>> hostname=arch-desktop
frame_width = 2
# <<<
# >>> hostname=arch-laptop
# frame_width = 3
# <<<
separator_height = 3
separator_color = frame
File diff suppressed because it is too large Load Diff
-406
View File
@@ -1,406 +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]]
- [[#projectile][Projectile]]
- [[#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")))
(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 70)
(setq magit-completing-read-function #'selectrum-completing-read)
(setq magit-diff-paint-whitespace-lines 'both)
(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]))
#+END_SRC
** Projectile
Project manager.
#+BEGIN_SRC emacs-lisp
(use-package projectile
:defer t
:config
(setq projectile-cache-file (concat dot-cache-dir "/projectile.cache"))
(setq projectile-completion-system 'default)
(setq projectile-enable-caching t)
(setq projectile-indexing-method 'hybrid)
(setq projectile-known-projects-file (concat dot-cache-dir "/projectile-bookmarks.eld"))
(setq projectile-project-search-path '("~"))
(setq projectile-sort-order 'recentf)
(defun dot/find-project-root ()
"Return root of the project, determined by `.git/' and `.projectile',
`default-directory' otherwise."
(let ((search-directory (projectile-project-root)))
(if search-directory
search-directory
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)))
(projectile-mode))
#+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"))
(setq lsp-clients-lua-language-server-install-dir "/usr/share/lua-language-server/")
(setq lsp-clients-lua-language-server-bin "/usr/bin/lua-language-server")
(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 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))))
;; 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++17")
(setq flycheck-gcc-language-standard "c++17"))
;; 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))
#+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
-105
View File
@@ -1,105 +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 (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)
(evil-shift-left (region-beginning) (region-end))
(funcall (evil-visual-restore)))
(defun dot/evil-visual-shift-right ()
"Shift visual selection left, retains the selection.
Vim equivalence: >gv"
(interactive)
(evil-shift-right (region-beginning) (region-end))
(funcall (evil-visual-restore)))
(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
-157
View File
@@ -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
-329
View File
@@ -1,329 +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 'projectile
(defun compile-latex ()
"Compile LaTeX project."
(interactive)
(let ((default-directory (dot/find-project-root)))
(projectile-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"))
;; Append -shell-escape so pdflatex exports minted correctly
(add-to-list 'org-latex-pdf-process (replace-regexp-in-string
"%latex "
"%latex -shell-escape "
(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
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))
(_ (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
-46
View File
@@ -1,46 +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-project-root-function #'dot/find-project-root))
#+END_SRC
-261
View File
@@ -1,261 +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 28 18))
(setq centaur-tabs-modified-marker "")
(setq centaur-tabs-set-icons t)
(setq centaur-tabs-set-modified-marker t)
(setq centaur-tabs-style "slant")
(defun centaur-tabs-buffer-groups ()
"Organize tabs into groups by buffer."
(list
(cond
((string-equal "*" (substring (buffer-name) 0 1)) "Emacs")
((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 "User"))))
(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 does match below blacklist
(string-match-p (concat "\\(CAPTURE-\\)?" (format-time-string "%Y%m%d%H%M%S") "-.*\\.org") name)
(string-match-p
(concat "^ ?\\*\\("
"Agenda Commands\\|"
"e?shell\\|"
"Compile-Log\\|"
"Completions\\|"
;; "clangd\\|" ; lsp c/c++
"dap-mouse\\|"
"dap-ui-\\|"
"Debug\\|"
"Faces\\|"
"Flycheck\\|"
"Help\\|"
"helpful\\|"
"httpd\\|"
"iph\\|" ; lsp php
"org-roam\\|"
"Org tags\\|"
"Org todo"
"\\).*")
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-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 'projectile
(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 20 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-projectile-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
+2 -10
View File
@@ -23,16 +23,8 @@
;; Prefer to `load' the newest elisp file
(setq load-prefer-newer t)
;; Set package install location
(setq package-user-dir (concat user-emacs-directory "elpa"))
;; Set package quickstart location
(setq package-quickstart-file (concat
(getenv "XDG_CACHE_HOME")
"/emacs/package-quickstart.el"))
;; Precompute activation actions to speed up startup
(setq package-quickstart t)
;; Disable package.el
(setq package-enable-at-startup nil)
;; -------------------------------------
+14 -22
View File
@@ -2,31 +2,23 @@
;;; Commentary:
;; Setup package archives and build configuration file.
;; Load modules.
;;; Code:
(require 'package)
;; -----------------------------------------
;; Add the MELPA repository to the package manager
(add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/"))
(add-to-list 'load-path (locate-user-emacs-file "site-lisp"))
;; Install the `use-package' dependency
(unless (package-installed-p 'use-package)
(package-refresh-contents)
(package-install 'use-package))
(require 'dot-elpaca)
(require 'dot-setup-el)
(use-package benchmark-init
:ensure t
:config
;; To disable collection of benchmark data after init is complete
(add-hook 'after-init-hook 'benchmark-init/deactivate))
;; -------------------------------------
;; Tangle and load configuration file
(require 'org)
(when (file-readable-p (concat user-emacs-directory "config.org"))
(org-babel-load-file (concat user-emacs-directory "config.org")))
;;; init.el ends here
(require 'dot-core)
(require 'dot-ui)
(require 'dot-evil)
(require 'dot-development)
(require 'dot-selection)
(require 'dot-org-mode)
(require 'dot-mail)
(require 'dot-rss)
(require 'dot-keybinds)
@@ -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,249 @@
;;; 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)
(setq pixel-scroll-precision-mode t)
;; Parenthesis, set behavior
(setq show-paren-delay 0)
(setq show-paren-style 'mixed)
(setq show-paren-context-when-offscreen t)
;; 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 treesit-extra-load-path `(,(expand-file-name "tree-sitter" dot-cache-dir)))
(setq url-configuration-directory (expand-file-name "url/" dot-cache-dir))
(startup-redirect-eln-cache (expand-file-name "eln-cache" 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
(defvar dot-cache-dir
(expand-file-name "emacs" (if (getenv "XDG_CACHE_HOME") (getenv "XDG_CACHE_HOME") "~/.cache"))
"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
+24
View File
@@ -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
+501
View File
@@ -0,0 +1,501 @@
;;; 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
(let* ((project (file-truename (directory-file-name (project-root (project-current)))))
(parent-dir-full (file-name-directory (directory-file-name project)))
(parent-dir (file-name-nondirectory (substring parent-dir-full 0 -1)))
(filename (file-name-nondirectory project)))
(concat filename "/" parent-dir))
"-")))
(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
go-mode ; gopls
kotlin-mode ; kotlin-language-server
lua-mode ; lua-language-server
latex-mode ; texlab
swift-mode ; swift-bin
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-nil (setup csharp-mode)) ; built-in
;;; 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)
;;; Golang
(elpaca-setup go-mode)
;;; HTML
(elpaca-setup web-mode
(:file-match "\\.ts")
(:file-match "\\.vue"))
;;; 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)
(elpaca-setup restclient-jq
(:load-after 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)))
;;; Swift
(elpaca-setup swift-mode)
(elpaca-setup lsp-sourcekit
(:load-after lsp-mode)
(:when-loaded
(setq lsp-sourcekit-executable "/usr/bin/sourcekit-lsp")))
;;; 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
(elpaca-nil (setup ispell ; built-in
(:when-loaded
(setq ispell-program-name "/usr/bin/hunspell")
(ispell-set-spellchecker-params)
(ispell-hunspell-add-multi-dic "en_US,nl_NL")
(setq ispell-dictionary "en_US,nl_NL"))))
;; 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-expand 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
+62
View File
@@ -0,0 +1,62 @@
;;; dot-elpaca.el --- -*- lexical-binding: t; -*-
;;; Commentary:
;; Elpaca bootstrap
;;; Code:
;; -----------------------------------------
;; Elpaca bootstrap
(defvar elpaca-installer-version 0.8)
(defvar elpaca-directory (expand-file-name "elpaca/" user-emacs-directory))
(defvar elpaca-builds-directory (expand-file-name "builds/" elpaca-directory))
(defvar elpaca-repos-directory (expand-file-name "repos/" elpaca-directory))
(defvar elpaca-order '(elpaca :repo "https://github.com/progfolio/elpaca.git"
:ref nil :depth 1
:files (:defaults "elpaca-test.el" (:exclude "extensions"))
:build (:not elpaca--activate-package)))
(let* ((repo (expand-file-name "elpaca/" elpaca-repos-directory))
(build (expand-file-name "elpaca/" elpaca-builds-directory))
(order (cdr elpaca-order))
(default-directory repo))
(add-to-list 'load-path (if (file-exists-p build) build repo))
(unless (file-exists-p repo)
(make-directory repo t)
(when (< emacs-major-version 28) (require 'subr-x))
(condition-case-unless-debug err
(if-let* ((buffer (pop-to-buffer-same-window "*elpaca-bootstrap*"))
((zerop (apply #'call-process `("git" nil ,buffer t "clone"
,@(when-let* ((depth (plist-get order :depth)))
(list (format "--depth=%d" depth) "--no-single-branch"))
,(plist-get order :repo) ,repo))))
((zerop (call-process "git" nil buffer t "checkout"
(or (plist-get order :ref) "--"))))
(emacs (concat invocation-directory invocation-name))
((zerop (call-process emacs nil buffer nil "-Q" "-L" "." "--batch"
"--eval" "(byte-recompile-directory \".\" 0 'force)")))
((require 'elpaca))
((elpaca-generate-autoloads "elpaca" repo)))
(progn (message "%s" (buffer-string)) (kill-buffer buffer))
(error "%s" (with-current-buffer buffer (buffer-string))))
((error) (warn "%s" err) (delete-directory repo 'recursive))))
(unless (require 'elpaca-autoloads nil t)
(require 'elpaca)
(elpaca-generate-autoloads "elpaca" repo)
(load "./elpaca-autoloads")))
(add-hook 'after-init-hook #'elpaca-process-queues)
(elpaca `(,@elpaca-order))
;;;###autoload
(defmacro elpaca-nil (body)
"Defer execution until all Elpaca queues have been processed."
(declare (indent 1))
`(add-hook 'elpaca-after-init-hook (lambda () (,@body)) 1))
;; Stop coping with startup time, its done loading when its done loading
(elpaca-nil (setq after-init-time (current-time)))
(provide 'dot-elpaca)
;;; dot-elpaca.el ends here
+106
View File
@@ -0,0 +1,106 @@
;;; 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)
(unless (yas-expand)
(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
+673
View File
@@ -0,0 +1,673 @@
;;; 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
"<pinch>" nil ; Do not scale text when pinching touchpad
)))
(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" '(dashboard-refresh-buffer :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")
;; Org
"o" '(:ignore t :which-key "org")
"o i" '(dot/org-clock-in :which-key "Clock in")
"o o" '(dot/org-clock-out :which-key "Clock out")
"o s" '(dot/org-switch-task :which-key "Switch task")
;; 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" '(dot/consult-line-no-fuzzy :which-key "Search buffer")
"s S" '(consult-line-multi :which-key "Search all buffers")
;; 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-merge-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
+148
View File
@@ -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
+351
View File
@@ -0,0 +1,351 @@
;;; 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))
(:with-mode before-save
(:hook dot/org-set-last-modified))
(:when-loaded
(setq org-adapt-indentation nil)
(setq org-ellipsis "")
(setq org-image-actual-width nil)
(setq org-startup-folded nil)
;; Enable structured template completion
(add-to-list 'org-modules 'org-tempo t)
(add-to-list 'org-structure-template-alist
'("el" . "src emacs-lisp"))
(defun dot/org-find-or-create-heading (heading level)
"Find or create heading"
(if (re-search-forward (format org-complex-heading-regexp-format
(regexp-quote heading))
nil t)
(beginning-of-line)
(goto-char (point-max))
(unless (bolp) (insert "\n"))
(insert (concat (make-string level ?*) " ") heading "\n")
(beginning-of-line 0)))
(defun dot/org-find-month-week-day ()
"Find or create the journal tree for the current week under current month"
(unless (derived-mode-p 'org-mode)
(error "Target buffer \"%s\" for dot/find-org-week should be in Org mode"
(current-buffer)))
(org-capture-put-target-region-and-position)
(widen)
(goto-char (point-min))
(dot/org-find-or-create-heading "Worklog" 1)
(org-narrow-to-subtree)
(dot/org-find-or-create-heading (format-time-string "%B") 2) ;; month
(org-narrow-to-subtree)
(dot/org-find-or-create-heading (format-time-string "Week %W") 3)
(org-narrow-to-subtree)
(dot/org-find-or-create-heading (format-time-string "%A") 4) ;; day
(org-end-of-subtree))
;; Capture templates
(setq org-capture-templates
`(("i" "Clock in" plain (file+function ,(expand-file-name "worklog.org" org-directory) dot/org-find-month-week-day)
"| %<%Y-%m-%d> | IN | %<%H:%M> | %^{Location|Office|Home|Office|Visit} |\n===================================%?"
:immediate-finish t)
("o" "Clock out" plain (file+function ,(expand-file-name "worklog.org" org-directory) dot/org-find-month-week-day)
"===================================\n| %<%Y-%m-%d> | OUT | %<%H:%M> |%?"
:immediate-finish t)
("s" "Switch task" plain (file+function ,(expand-file-name "worklog.org" org-directory) dot/org-find-month-week-day)
"| %<%Y-%m-%d> | %<%H:%M> | %^{Item ID} | X | %^{Description|-} |%?"
:immediate-finish t)))
;; Keybind functions
(defun dot/org-clock-in () (interactive) (org-capture nil "i"))
(defun dot/org-clock-out () (interactive) (org-capture nil "o"))
(defun dot/org-switch-task () (interactive) (org-capture nil "s"))
(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))
))))
(defun dot/org-find-file-property (property &optional anywhere)
"Return the position of the file PROPERTY if it exists.
When ANYWHERE is non-nil, search beyond the preamble."
(save-excursion
(goto-char (point-min))
(let ((first-heading
(save-excursion
(re-search-forward org-outline-regexp-bol nil t))))
(when (re-search-forward (format "^#\\+%s:" property)
(if anywhere nil first-heading)
t)
(point)))))
(defun dot/org-set-file-property (property value)
"Set the file PROPERTY in the preamble."
(when-let ((pos (dot/org-find-file-property property)))
(save-excursion
(goto-char pos)
(if (looking-at-p " ")
(forward-char)
(insert " "))
(delete-region (point) (line-end-position))
(insert value))))
(defun dot/org-set-last-modified ()
"Update the LAST_MODIFIED file property in the preamble."
(when (derived-mode-p 'org-mode)
(dot/org-set-file-property "LAST_MODIFIED"
(format-time-string "[%Y-%m-%d %a %H:%M]")))))))
;; 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
;; Requires packages: texlive-bin, texlive-latexextra and python-pygments
(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 emacsql-sqlite-builtin)
(elpaca-setup org-roam
(:autoload org-roam-node-find) ;; TODO, is this enough?
(setq org-roam-v2-ack t)
(setq org-roam-database-connector 'sqlite-builtin)
(: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#+LAST_MODIFIED:\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
+29
View File
@@ -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
+83
View File
@@ -0,0 +1,83 @@
;;; 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-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-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 vertico-prescient
(:load-after vertico prescient)
(:when-loaded
(vertico-prescient-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 "?"))
(defun dot/consult-line-no-fuzzy ()
"Call consult-line without fuzzy matching."
(interactive)
(let ((prescient-filter-method (delete 'fuzzy (copy-tree prescient-filter-method))))
(consult-line)))
(consult-customize
dot/consult-line-no-fuzzy :prompt "Search: "
consult-line-multi :prompt "Search: " :initial nil)))
(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
+107
View File
@@ -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
+238
View File
@@ -0,0 +1,238 @@
;;; 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*") (dashboard-refresh-buffer)))
(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)))
;; 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)
))
;; -----------------------------------------
;; 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
+1 -1
View File
@@ -4,6 +4,6 @@
# --
namespace ${1:Namespace} {
$0
$0
} // namespace $1
+8
View File
@@ -7,3 +7,11 @@
[user]
name = Riyyi
email = riyyi3@gmail.com
[diff]
tool = nvimdiff
[merge]
tool = nvimdiff
conflictstyle = diff3
[mergetool]
prompt = false
keepBackup = false
+1 -1
View File
@@ -1,4 +1,4 @@
pinentry-program /usr/bin/pinentry
pinentry-program /usr/bin/pinentry-gtk
default-cache-ttl 900
max-cache-ttl 7200
+3 -1
View File
@@ -1,10 +1,12 @@
[dmenu]
dmenu_command = /usr/bin/rofi -dmenu -i
pinentry = /usr/bin/pinentry
pinentry = /usr/bin/pinentry-gtk
[database]
database_1 = ~/documents/password.kdbx
keyfile_1 =
pw_cache_period_min = 60
autotype_default = {USERNAME}{TAB}{PASSWORD}{ENTER}
gui_editor = emacsclient
editor = vim
+16
View File
@@ -0,0 +1,16 @@
{
"ignorePatterns": [
".git/",
"*.md",
"manafiles.json",
"packages",
"README.org",
"screenshot.png"
],
"systemPatterns": [
"/boot/",
"/etc/",
"/usr/lib/",
"/usr/share/"
]
}
+2
View File
@@ -0,0 +1,2 @@
-- when opening a .lua file, this file gets executed
vim.opt.expandtab = false
+9
View File
@@ -0,0 +1,9 @@
require("core")
require("packages").setup({
require("ui"),
require("selection"),
require("editor"),
require("development"),
require("git"),
})
require("keybinds").setup()
+42
View File
@@ -0,0 +1,42 @@
{
"Comment.nvim": { "branch": "master", "commit": "e30b7f2008e52442154b66f7c519bfd2f1e32acb" },
"LuaSnip": { "branch": "master", "commit": "33b06d72d220aa56a7ce80a0dd6f06c70cd82b9d" },
"auto-save.nvim": { "branch": "main", "commit": "b58948445c43e6903987a9bb97c82e66fdcc0786" },
"cmp-buffer": { "branch": "main", "commit": "3022dbc9166796b644a841a02de8dd1cc1d311fa" },
"cmp-nvim-lsp": { "branch": "main", "commit": "99290b3ec1322070bcfb9e846450a46f6efa50f0" },
"cmp-nvim-lua": { "branch": "main", "commit": "f12408bdb54c39c23e67cab726264c10db33ada8" },
"cmp-path": { "branch": "main", "commit": "91ff86cd9c29299a64f968ebb45846c485725f23" },
"cmp_luasnip": { "branch": "master", "commit": "98d9cb5c2c38532bd9bdb481067b20fea8f32e90" },
"dashboard-nvim": { "branch": "master", "commit": "ae309606940d26d8c9df8b048a6e136b6bbec478" },
"diffview.nvim": { "branch": "main", "commit": "4516612fe98ff56ae0415a259ff6361a89419b0a" },
"friendly-snippets": { "branch": "main", "commit": "efff286dd74c22f731cdec26a70b46e5b203c619" },
"gitsigns.nvim": { "branch": "main", "commit": "5f808b5e4fef30bd8aca1b803b4e555da07fc412" },
"lazy.nvim": { "branch": "main", "commit": "7c493713bc2cb392706866eeba53aaef6c8e9fc6" },
"lspkind.nvim": { "branch": "master", "commit": "d79a1c3299ad0ef94e255d045bed9fa26025dab6" },
"lspsaga.nvim": { "branch": "main", "commit": "2710a0ad97b5aaff404cd4756c296df454b3f726" },
"lualine.nvim": { "branch": "master", "commit": "2a5bae925481f999263d6f5ed8361baef8df4f83" },
"neodev.nvim": { "branch": "main", "commit": "46aa467dca16cf3dfe27098042402066d2ae242d" },
"neogit": { "branch": "master", "commit": "40038473707c54a846bd11ecaf5933dd45858972" },
"nvim-base16": { "branch": "master", "commit": "6ac181b5733518040a33017dde654059cd771b7c" },
"nvim-cmp": { "branch": "main", "commit": "3403e2e9391ed0a28c3afddd8612701b647c8e26" },
"nvim-colorizer.lua": { "branch": "master", "commit": "a065833f35a3a7cc3ef137ac88b5381da2ba302e" },
"nvim-lspconfig": { "branch": "master", "commit": "5a812abc65d529ea7673059a348814c21d7f87ff" },
"nvim-treesitter": { "branch": "master", "commit": "337b503688eccb3046547661e4c738e674548fcf" },
"nvim-treesitter-textobjects": { "branch": "master", "commit": "ad8f0a472148c3e0ae9851e26a722ee4e29b1595" },
"nvim-web-devicons": { "branch": "master", "commit": "e73d2774d12d0ecf9e05578d692ba1ea50508cf2" },
"omnisharp-extended-lsp.nvim": { "branch": "main", "commit": "4916fa12e5b28d21a1f031f0bdd10aa15a75d85d" },
"plenary.nvim": { "branch": "master", "commit": "2d9b06177a975543726ce5c73fca176cedbffe9d" },
"project.nvim": { "branch": "main", "commit": "8c6bad7d22eef1b71144b401c9f74ed01526a4fb" },
"rainbow-delimiters.nvim": { "branch": "master", "commit": "c7e489756b5455f922ce79ac374a4ede594f4a20" },
"sqlite.lua": { "branch": "master", "commit": "d0ffd703b56d090d213b497ed4eb840495f14a11" },
"telescope-all-recent.nvim": { "branch": "main", "commit": "267e9e5fd13a6e9a4cc6ffe00452d446d040401d" },
"telescope-file-browser.nvim": { "branch": "master", "commit": "626998e5c1b71c130d8bc6cf7abb6709b98287bb" },
"telescope-fzf-native.nvim": { "branch": "main", "commit": "cf48d4dfce44e0b9a2e19a008d6ec6ea6f01a83b" },
"telescope-recent-files": { "branch": "main", "commit": "3a7a1b9c6b52b6ff7938c59f64c87a05e013dff8" },
"telescope.nvim": { "branch": "0.1.x", "commit": "a0bbec21143c7bc5f8bb02e0005fa0b982edc026" },
"todo-comments.nvim": { "branch": "main", "commit": "ae0a2afb47cf7395dc400e5dc4e05274bf4fb9e0" },
"trouble.nvim": { "branch": "main", "commit": "46cf952fc115f4c2b98d4e208ed1e2dce08c9bf6" },
"ultimate-autopair.nvim": { "branch": "development", "commit": "9e3209190c22953566ae4e6436ad2b4ff4dabb95" },
"vim-sleuth": { "branch": "master", "commit": "be69bff86754b1aa5adcbb527d7fcd1635a84080" },
"which-key.nvim": { "branch": "main", "commit": "9b365a6428a9633e3eeb34dbef1b791511c54f70" }
}
+5
View File
@@ -0,0 +1,5 @@
require("core.leader-key")
require("core.config")
require("core.buffers")
require("core.autocommands")
require("core.globals")
+53
View File
@@ -0,0 +1,53 @@
local F = require("core.functions")
--------------------------------------------
--- Commands ---
-- Prevent typo
vim.cmd [[
cnoreabbrev <expr> W (getcmdtype() is# ":" && getcmdline() is# "W") ? ("w") : ("W")
cnoreabbrev <expr> Q (getcmdtype() is# ":" && getcmdline() is# "Q") ? ("q") : ("Q")
cnoreabbrev <expr> WQ (getcmdtype() is# ":" && getcmdline() is# "WQ") ? ("wq") : ("WQ")
cnoreabbrev <expr> Wq (getcmdtype() is# ":" && getcmdline() is# "Wq") ? ("wq") : ("Wq")
]]
--------------------------------------------
--- Autocommands ---
-- Cut off trailing whitespace and trailing blank lines
vim.api.nvim_create_autocmd({ "BufWritePre" }, {
pattern = "*",
callback = F.trim_buffer,
})
-- Highlight on yank
-- See `:help vim.highlight.on_yank()`
local highlight_group = vim.api.nvim_create_augroup("YankHighlight", { clear = true })
vim.api.nvim_create_autocmd("TextYankPost", {
pattern = "*",
group = highlight_group,
callback = function() vim.highlight.on_yank() end,
})
-- Show message when autosaving
local autosave_group = vim.api.nvim_create_augroup("autosave", {})
vim.api.nvim_create_autocmd("User", {
pattern = "AutoSaveWritePost",
group = autosave_group,
callback = function(opts)
if opts.data.saved_buffer ~= nil then
local filename = vim.api.nvim_buf_get_name(opts.data.saved_buffer)
vim.notify("Wrote " .. filename, vim.log.levels.INFO)
end
end,
})
-- Create an autocommand for full window buffers
vim.api.nvim_create_autocmd("BufWinEnter", {
-- callback = require("core.buffers").add_buffer
callback = function()
require("core.buffers").add_buffer()
LOG(require("core.buffers").buffers)
end,
desc = "Track all full window buffers visited",
})
+213
View File
@@ -0,0 +1,213 @@
local F = require("core.functions")
-- Module for managing buffers, these are used for navigation
local M = {}
-- Buffer table structure:
-- {
-- "Group" = { "buffer1", "buffer2", active_index = 1 }
-- }
M.buffers = {}
M.buffer_default_group = "Other"
M.buffer_matcher = {
-- match = truthy, function() -> thruthy, or string matching buffer filename
-- group = string, function() -> string
{ match = F.find_project_root, group = F.find_project_root },
{ match = true, group = "Other" }, -- default
}
--------------------------------------------
local get_buffer_name = function()
local buf = vim.api.nvim_get_current_buf()
local buffer_name = vim.api.nvim_buf_get_name(buf)
if not buffer_name or buffer_name == "" then return nil end
return buffer_name
end
M.add_buffer = function()
local buffer_name = get_buffer_name()
if not buffer_name then return end
-- Evaluate group
local eval_group = function(config_group)
if not config_group then return M.buffer_default_group end
if type(config_group) == "function" then return config_group() end
return config_group
end
-- Add if buffer does not exist yet
local add = function(config_group)
local group = eval_group(config_group)
if not M.buffers[group] then M.buffers[group] = {} end
for i, buffer in ipairs(M.buffers[group]) do
if buffer == buffer_name then
M.buffers[group]["active_index"] = i
return group, i
end
end
table.insert(M.buffers[group], buffer_name)
local count = #M.buffers[group]
M.buffers[group]["active_index"] = count
return group, count
end
-- Walk matcher configuration
local matcher = M.buffer_matcher or {}
if matcher and type(matcher) == "function" then
matcher = matcher()
end
if #matcher == 0 then add(M.buffer_default_group) end
for _, config in ipairs(M.buffer_matcher) do
if type(config.match) == "function" and config.match() then
return add(config.group)
end
-- Match path's filename
if type(config.match) == "string" and config.match == buffer_name:match("([^/]+)$") then
return add(config.group)
end
if type(config.match) == "boolean" and config.match then
return add(config.group)
end
end
return add(M.buffer_default_group)
end
local get_group_from_buffer = function(buffer_name)
for group, buffers in pairs(M.buffers) do
for i, buffer in ipairs(buffers) do
if buffer == buffer_name then return group, i end
end
end
return nil
end
local buffer_action_in_active_group = function(action, direction)
local buffer_name = get_buffer_name()
if not buffer_name then return end
local group, index = get_group_from_buffer(buffer_name)
if not group then group, index = M.add_buffer() end
local buffers = M.buffers[group]
if #buffers < 2 then return end
-- Determine the other index
local other_index = index + direction
if index == 1 and direction == -1 then
other_index = #buffers
elseif index == #buffers and direction == 1 then
other_index = 1
end
if action == "move" then
for _, buffer in ipairs(vim.api.nvim_list_bufs()) do
-- Remove inactive buffers
if not vim.api.nvim_buf_is_loaded(buffer) then
for i, group_buffer in ipairs(buffers) do
if buffer == group_buffer then
table.remove(buffers, i)
if i > 1 and i <= other_index then
other_index = other_index - 1
end
end
end
goto continue
end
-- Make buffer active
if vim.api.nvim_buf_get_name(buffer) == buffers[other_index] then
vim.api.nvim_set_current_buf(buffer)
buffers.active_index = other_index
break
end
::continue::
end
elseif action == "swap" then
local tmp = buffers[other_index]
buffers[other_index] = buffers[index]
buffers[index] = tmp
end
M.buffers[group] = buffers
end
M.buffer_move_left = function()
buffer_action_in_active_group("move", -1)
end
M.buffer_move_right = function()
buffer_action_in_active_group("move", 1)
end
M.buffer_swap_left = function()
buffer_action_in_active_group("swap", -1)
end
M.buffer_swap_right = function()
buffer_action_in_active_group("swap", 1)
end
--------------------------------------------
-- Group move
local buffer_group_move = function(direction)
local buffer_name = get_buffer_name()
if not buffer_name then return end
-- TODO: How to get groups deterministically?
-- Get active group from the current buffer
-- Check groups bounds
-- Change active group
end
M.buffer_group_move_up = function()
buffer_group_move(-1)
end
M.buffer_group_move_down = function()
buffer_group_move(1)
end
-- TODO: functions that can
-- v Navigate buffer left
-- v Navigate buffer right
-- - Navigate group up (use active_index when swapping)
-- - Navigate group down
-- v Move buffer left
-- v Move buffer right
-- - Remove buffer from currently active group (decrease active_index)
return M
-- (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")))))
+50
View File
@@ -0,0 +1,50 @@
--- Behavior ---
-- vim.opt.autochdir = true
vim.opt.clipboard = "unnamedplus"
vim.opt.encoding = "utf-8"
vim.opt.fileencoding = "utf-8"
vim.opt.mouse = "a"
vim.opt.scrolloff = 8
vim.opt.signcolumn = "yes" -- always show gutter/fringe
vim.opt.ttimeoutlen = 0
-- Case-insensitive searching UNLESS \C or capital in search
vim.opt.ignorecase = true
vim.opt.smartcase = true
--- Editing ---
vim.opt.number = true
vim.opt.breakindent = true
vim.opt.backspace = "indent,eol,start"
vim.opt.expandtab = false
vim.opt.shiftround = true
vim.opt.shiftwidth = 4
vim.opt.softtabstop = 4
vim.opt.tabstop = 4
vim.opt.smartindent = true
vim.opt.wrap = false
--- Files
vim.opt.backup = true
vim.opt.backupdir = vim.fn.stdpath("cache") .. "/backup"
vim.opt.swapfile = false
vim.opt.undofile = true
vim.opt.undodir = vim.fn.stdpath("cache") .. "/undodir"
vim.opt.shadafile = vim.fn.stdpath("cache") .. "/netrwhist"
--- UI ---
vim.opt.colorcolumn = "81"
vim.opt.completeopt = "menuone,noselect"
vim.opt.cursorline = true
vim.opt.fillchars = vim.opt.fillchars + "diff:"
vim.opt.showtabline = 0
vim.opt.termguicolors = true
vim.opt.title = true
+75
View File
@@ -0,0 +1,75 @@
local M = {}
M.is_buffer_a_file = function()
local buffer_name = vim.fn.bufname()
return buffer_name ~= "" and vim.fn.filereadable(buffer_name) == 1
end
M.get_file_path = function()
if not M.is_buffer_a_file() then
return nil
end
local file_path = vim.fn.expand("%:p")
return vim.fn.fnamemodify(file_path, ":h") .. "/"
end
M.get_netrw_path = function() -- b:netrw_curdir
if vim.fn.expand("#" .. vim.fn.bufnr()) == "0" then
return nil
end
return vim.fn.fnamemodify(vim.fn.bufname(), ":p")
end
M.get_current_directory = function()
return M.get_file_path() or M.get_netrw_path() or vim.fn.getcwd()
end
M.find_project_root = function()
local current_directory = M.get_current_directory()
local directory = current_directory
while directory ~= "/" do
local git_path = vim.loop.fs_stat(directory .. "/.git")
if git_path then
return directory:gsub("/$", "") -- remove trailing slash
end
local project_file = vim.loop.fs_stat(directory .. "/.project")
if project_file and project_file.type == "file" then
return directory:gsub("/$", "") -- remove trailing slash
end
directory = vim.fn.fnamemodify(directory, ":h")
end
return nil, current_directory
end
-- This will merge tables with index-value pairs and keep the unique values
M.table_merge_unique = function(...)
local result = {}
local seen_values = {}
for _, value in ipairs(vim.tbl_flatten(...)) do
if not seen_values[value] then
seen_values[value] = true
table.insert(result, value)
end
end
return result
end
-- Cut off trailing whitespace and trailing blank lines
-- https://vi.stackexchange.com/questions/37421/how-to-remove-neovim-trailing-white-space
-- https://stackoverflow.com/questions/7495932/how-can-i-trim-blank-lines-at-the-end-of-file-in-vim
M.trim_buffer = function()
local save_cursor = vim.fn.getpos(".")
pcall(function() vim.cmd([[%s/\s\+$//e]]) end)
pcall(function() vim.cmd([[%s#\($\n\s*\)\+\%$##]]) end)
vim.fn.setpos(".", save_cursor)
end
return M
+19
View File
@@ -0,0 +1,19 @@
-- Usage:
-- :lua P("Hello World!")
P = function(v)
print(vim.inspect(v))
return v
end
RELOAD = function(...)
return require("plenary.reload").reload_module(...)
end
R = function(name)
RELOAD(name)
return require(name)
end
LOG = function(v)
vim.fn.writefile({ vim.inspect(v) }, "/tmp/nvim-log", "a")
end
+6
View File
@@ -0,0 +1,6 @@
-- Set <space> as the leader key
-- See `:help mapleader`
-- NOTE: Must happen before plugins are required (otherwise wrong leader will be used)
vim.keymap.set({ "n", "v" }, "<Space>", "<Nop>", { silent = true })
vim.g.mapleader = " "
vim.g.maplocalleader = " "
+207
View File
@@ -0,0 +1,207 @@
return {
-- Autocompletion
{
"hrsh7th/nvim-cmp",
lazy = true, -- defer
dependencies = {
-- Snippet Engine & its associated nvim-cmp source
"L3MON4D3/LuaSnip",
"saadparwaiz1/cmp_luasnip",
-- Adds LSP completion capabilities
"hrsh7th/cmp-nvim-lsp", -- source for neovim"s built-in LSP client
"hrsh7th/cmp-nvim-lua", -- source for neovim"s Lua API
"hrsh7th/cmp-buffer",
"hrsh7th/cmp-path",
-- Adds a number of user-friendly snippets
"rafamadriz/friendly-snippets",
-- Icons in the completion menu
"onsails/lspkind.nvim",
},
config = function()
local luasnip = require("luasnip")
require("luasnip.loaders.from_vscode").lazy_load()
luasnip.config.setup({})
require("cmp").setup({
snippet = {
expand = function(args)
luasnip.lsp_expand(args.body)
end,
},
completion = {
completeopt = "menu,menuone,noinsert",
},
sources = {
{ name = "nvim_lsp" },
{ name = "nvim_lua" },
{ name = "luasnip" },
{ name = "buffer" },
{ name = "path" },
},
formatting = {
fields = { "kind", "abbr", "menu" },
-- https://github.com/hrsh7th/nvim-cmp/wiki/Menu-Appearance#how-to-get-types-on-the-left-and-offset-the-menu
-- https://github.com/onsails/lspkind.nvim#option-2-nvim-cmp
format = function(entry, vim_item)
local kind = require("lspkind").cmp_format({ mode = "symbol_text", maxwidth = 50 })(entry,
vim_item)
local strings = vim.split(kind.kind, "%s", { trimempty = true })
kind.kind = strings[1] or ""
kind.menu = " (" .. (strings[2] or "") .. ")"
return kind
end,
expandable_indicator = true,
},
mapping = require("keybinds").nvim_cmp(),
})
end,
},
-- LSP Configuration & Plugins
{ -- https://github.com/neovim/nvim-lspconfig
"neovim/nvim-lspconfig",
dependencies = {
-- Improve the built-in LSP UI
"nvimdev/lspsaga.nvim",
-- Additional lua configuration, makes Nvim stuff amazing!
"folke/neodev.nvim",
-- C# "Goto Definition" with decompilation support
"Hoffs/omnisharp-extended-lsp.nvim",
},
config = function()
-- Setup neovim Lua configuration
require("lspsaga").setup() -- ?? does this do anything with doc hover
require("neodev").setup()
-- Vim process
local pid = vim.fn.getpid()
-- Setup language servers
-- https://github.com/neovim/nvim-lspconfig/blob/master/doc/server_configurations.md
local servers = {
clangd = {}, -- C/C++
intelephense = {}, -- PHP
lua_ls = { -- Lua, via lua-language-server
settings = {
Lua = {
workspace = { checkThirdParty = false },
telemetry = { enable = false },
diagnostics = {
-- Ignore Lua_LS's noisy `missing-fields` warnings
disable = { "missing-fields" },
-- Ignore Lua_LS's noise `undefined global` warnings
globals = { "vim" },
},
},
},
},
omnisharp = { -- C#, via omnisharp-roslyn-bin
cmd = { "/usr/bin/omnisharp", "--languageserver", "--hostPID", tostring(pid) },
handlers = {
["textDocument/definition"] = require('omnisharp_extended').handler,
},
},
ts_ls = {
init_options = {
plugins = {
{
name = '@vue/typescript-plugin',
location = '/home/rick/.cache/.bun/install/global/node_modules/@vue/language-server',
languages = { 'vue' },
},
},
},
filetypes = { 'javascript', 'javascriptreact', 'javascript.jsx', 'typescript', 'typescriptreact', 'typescript.tsx', 'vue', },
-- filetypes = { 'typescript', 'javascript', 'javascriptreact', 'typescriptreact', 'vue' },
-- requires: bun install -g typescript-language-server
-- TODO: Update which-key config, maybe other packages
-- Sources:
-- https://github.com/vuejs/language-tools?tab=readme-ov-file#hybrid-mode-configuration-requires-vuelanguage-server-version-200
-- https://github.com/neovim/nvim-lspconfig/blob/master/lua/lspconfig/configs/ts_ls.lua#L4
},
volar = {
-- init_options = {
-- vue = {
-- hybridMode = false,
-- },
-- },
},
-- volar = {
-- -- init_options = {
-- -- typescript = {
-- -- serverPath = '/home/rick/.cache/.bun/install/global/node_modules/typescript/lib//tsserverlibrary.js'
-- -- }
-- -- },
-- -- filetypes = {'typescript', 'javascript', 'javascriptreact', 'typescriptreact', 'vue', 'json'}
-- },
}
-- nvim-cmp supports additional completion capabilities, so broadcast that to servers
local capabilities = vim.lsp.protocol.make_client_capabilities()
capabilities = require("cmp_nvim_lsp").default_capabilities(capabilities)
for server, _ in pairs(servers) do
local opts = vim.tbl_extend("keep", servers[server], {
capabilities = capabilities,
on_attach = require("keybinds").lspconfig_on_attach,
})
-- P(server)
-- P(opts)
require("lspconfig")[server].setup(opts)
end
end,
},
-- Project
{
"ahmedkhalf/project.nvim",
opts = {
detection_methods = { "lsp", "pattern" },
patterns = { ".git", ".project" },
datapath = vim.fn.stdpath("cache"),
},
config = function(_, opts)
-- Add syncing between project.nvim and dashboard-nvim project entries.
-- NOTE: Must come before the project.nvim setup(),
-- so the glue's VimLeavePre autocmd is defined before it.
local F = require("core.functions")
vim.api.nvim_create_autocmd("VimLeavePre", {
pattern = "*",
callback = function()
-- Fetch project.nvim projects
local project = require("project_nvim.project")
local history = require("project_nvim.utils.history")
local recent = history.recent_projects or {}
local session = history.session_projects or {}
local recent_plus_session = F.table_merge_unique(recent, session)
-- Fetch dashboard-nvim projects
local utils = require("dashboard.utils")
local path = utils.path_join(vim.fn.stdpath("cache"), "dashboard/cache")
local projects = utils.read_project_cache(path) or {}
-- Add any projects that project.nvim uniquely knows about to dashboard-nvim
local all_projects = F.table_merge_unique(recent_plus_session, projects)
vim.fn.writefile({ "return " .. vim.inspect(all_projects) }, path)
-- Add any projects that dashboard-nvim uniquely knows about to project.nvim
for _, value in ipairs(projects) do
if not vim.tbl_contains(recent_plus_session, value) then
pcall(project.set_pwd, value, "manual") -- skip non-existent directories, dont error
end
end
end,
})
require("project_nvim").setup(opts)
require("telescope").load_extension("projects")
end
}
}
+84
View File
@@ -0,0 +1,84 @@
return {
-- Detect tabstop and shiftwidth automatically
"tpope/vim-sleuth",
-- "gc" to comment visual regions/lines
"numToStr/Comment.nvim",
-- Highlight, edit, and navigate code
{
"nvim-treesitter/nvim-treesitter",
dependencies = {
"nvim-treesitter/nvim-treesitter-textobjects",
},
build = ":TSUpdate",
opts = {
ensure_installed = {
"bash", "c", "cmake", "cpp", "c_sharp", "css", "go",
"haskell", "html", "java", "javascript", "jsdoc", "json",
"latex", "lua", "make", "markdown", "php", "python",
"query", "regex", "rust", "toml", "tsx", "typescript",
"vim", "vimdoc", "yaml",
},
sync_install = false,
auto_install = true,
-- Default install directory is <plugin_path>/parser
-- parser_install_dir
highlight = {
enable = true,
additional_vim_regex_highlighting = false,
},
indent = {
enable = true,
},
}
},
-- Auto-save
{
"okuuva/auto-save.nvim",
cmd = "ASToggle", -- defer, until run command
event = { "InsertLeave", "TextChanged" }, -- defer, until event trigger
opts = {
debounce_delay = 5000, -- delay for `defer_save`, in ms
condition = function(buf)
-- Dont save special-buffers
return vim.fn.getbufvar(buf, "&buftype") == ""
end,
},
config = function(_, opts)
require("auto-save").setup(opts)
-- Cut off trailing whitespace and trailing blank lines
local group = vim.api.nvim_create_augroup("AutoSave", { clear = false })
local core = require("core.functions")
vim.api.nvim_create_autocmd("User", {
pattern = "AutoSaveWritePre",
group = group,
callback = function(event)
if event.data.saved_buffer ~= nil then
core.trim_buffer()
end
end,
})
end,
},
-- Autopair / electric pair
{ -- https://github.com/altermo/ultimate-autopair.nvim
"altermo/ultimate-autopair.nvim",
event = { "InsertEnter", "CmdlineEnter" }, -- defer
branch = "development",
opts = {
bs = { -- See: `:h ultimate-autopair-map-backspace-config`
-- Call the backspace logic from the config, instead of automap
-- https://github.com/altermo/ultimate-autopair.nvim/issues/60
map = "<Plug>ultimate-autopair-BS",
},
},
},
}
+34
View File
@@ -0,0 +1,34 @@
return {
-- Adds git related signs to the gutter/fringe
{
"lewis6991/gitsigns.nvim",
opts = {
-- See `:help gitsigns.txt`
signs = {
add = { text = "" },
change = { text = "" },
delete = { text = "" },
topdelete = { text = "" },
changedelete = { text = "" },
untracked = { text = "" },
},
},
},
-- Magit clone
{
"NeogitOrg/neogit",
cmd = "Neogit", -- defer
lazy = true,
dependencies = {
"nvim-lua/plenary.nvim",
"nvim-telescope/telescope.nvim",
"sindrets/diffview.nvim", -- diff integration
-- { "sindrets/diffview.nvim", opts = { enhanced_diff_hl = true } }, -- diff integration
},
opts = {},
},
}
+309
View File
@@ -0,0 +1,309 @@
local builtin
local telescope
local F = require("core.functions")
local M = {}
M.setup = function()
-- Prevent dependency loop
builtin = require("telescope.builtin")
telescope = require("telescope")
end
-- Set which-key key section description
M.wk = function(keybind, description, bufnr)
require("which-key").add({
{ keybind, group = description, mode = { "n", "v" }, buffer = bufnr },
})
end
M.buffer_close = function()
-- Check if there are more than 2 buffers and alternate file is set
local command = vim.fn.expand("#") ~= "" and #vim.fn.getbufinfo({ buflisted = 1 }) > 1
and "e #|bd #|bwipeout #" -- see `:h c_#`
or "bd"
vim.api.nvim_command(command)
end
M.buffer_dashboard = function()
vim.api.nvim_command("Dashboard")
end
M.file_config = function()
builtin.find_files({
prompt_title = "Nvim Config",
cwd = vim.fn.stdpath("config"),
hidden = true,
no_ignore = true,
-- path_display = { "shorten" },
})
end
M.file_find = function()
telescope.extensions.file_browser.file_browser({
cwd = F.get_current_directory(),
hidden = true,
no_ignore = true,
})
end
M.file_find_home = function()
telescope.extensions.file_browser.file_browser({
cwd = "~",
hidden = true,
no_ignore = true,
})
end
M.file_find_recent = function()
telescope.extensions.recent_files.pick()
end
M.file_save = function()
vim.api.nvim_command("w")
end
M.goto_trouble = function()
vim.api.nvim_command("Trouble")
end
M.goto_todos_telescope = function()
vim.api.nvim_command("TodoTelescope")
end
M.goto_todos_trouble = function()
vim.api.nvim_command("TodoTrouble")
end
-- Smart delete
M.hungry_delete = function()
return function()
local start_line = vim.fn.line(".")
local start_col = vim.fn.col(".")
local start_line_content = vim.fn.getline(start_line)
local line_length = start_line_content:len()
-- Check if there are multiple whitespace characters after the cursor
local is_1_whitespace = start_line_content:sub(start_col, start_col):match("%s")
local is_2_whitespace = start_line_content:sub(start_col + 1, start_col + 1):match("%s")
if (start_col <= line_length - 1 and is_1_whitespace and is_2_whitespace)
or (start_col == line_length and is_1_whitespace)
or start_col - 1 == line_length then -- in insert mode, the column is 1 higher
-- Hungry delete
-- Iterate forwards through each line and character
local last_line = vim.fn.line("$")
for line = start_line, last_line do
local line_content = (line == start_line) and start_line_content or vim.fn.getline(line)
local col = (line == start_line) and start_col or 1
for c = col, #line_content do
local char = line_content:sub(c, c)
-- Look until it hits a non-whitespace character
if not vim.fn.strcharpart(char, 0, 1):match("%s") then
-- Delete empty lines, from the starting line to the current line
vim.api.nvim_buf_set_lines(0, start_line - 1, line - 1, false, {})
-- Keep the content that was before the cursor at the start_line,
-- plus the content from the current column to the end of the current line
vim.fn.setline(start_line,
start_line_content:sub(1, start_col - 1) .. line_content:sub(c))
vim.fn.cursor({ start_line, start_col })
return
end
end
end
-- Delete empty lines, if the end of the buffer was only whitespace
vim.api.nvim_buf_set_lines(0, start_line - 1, last_line, false, {})
-- Keep the content that was before the cursor
vim.fn.setline(start_line, start_line_content:sub(1, start_col - 1))
vim.fn.cursor({ start_line, start_col })
else
-- Normal delete
vim.cmd("normal! x")
end
end
end
-- Smart backspace
M.hungry_delete_backspace = function()
-- Cache some values
local core = require("ultimate-autopair.core")
local keycode = vim.api.nvim_replace_termcodes("<Plug>ultimate-autopair-BS", true, false, true)
local fallback = vim.api.nvim_replace_termcodes("<C-h>", true, false, true) -- <BS> => <C-h>, \b
return function()
local start_line = vim.fn.line(".")
local start_col = vim.fn.col(".")
local start_line_content = vim.fn.getline(start_line)
-- Check if there are multiple whitespace characters before the cursor
local is_1_whitespace = start_line_content:sub(start_col - 1, start_col - 1):match("%s")
local is_2_whitespace = start_line_content:sub(start_col - 2, start_col - 2):match("%s")
if (start_col >= 3 and is_1_whitespace and is_2_whitespace)
or (start_col == 2 and is_1_whitespace)
or start_col == 1 then
-- Hungry delete
-- Iterate backwards through each line and character
for line = start_line, 1, -1 do
local line_content = (line == start_line) and start_line_content or vim.fn.getline(line)
local col = (line == start_line) and (start_col - 1) or #line_content
for c = col, 1, -1 do
local char = line_content:sub(c, c)
-- Look until it hits a non-whitespace character
if not vim.fn.strcharpart(char, 0, 1):match("%s") then
-- Delete empty lines, from the starting line to the current line
vim.api.nvim_buf_set_lines(0, line - 1, start_line - 1, false, {})
-- Keep the content from the start of the current line to the current column,
-- plus the content that was after the cursor at the start_line
vim.fn.setline(line, line_content:sub(1, c) .. (line == start_line
and line_content:sub(start_col) -- found non-whitespace on the same line it started
or start_line_content:sub(start_col))) -- jumped through empty lines
vim.fn.cursor({ line, c + 1 })
return
end
end
end
-- Delete empty lines, if the start of the buffer was only whitespace
vim.api.nvim_buf_set_lines(0, 0, start_line - 1, false, {})
-- Keep the content that was after the cursor
vim.fn.setline(1, "" .. start_line_content:sub(start_col))
else
-- Normal backspace, prevent run_run recursive mapping via fallback to \b
local actions = core.run_run(keycode)
vim.api.nvim_feedkeys(actions ~= keycode and actions or fallback, "n", false) -- equivalent to { expr = true }
end
end
end
M.lsp_format_buffer = function()
vim.lsp.buf.format({
formatting_options = {
tabSize = 4,
insertSpaces = false,
},
})
end
M.project_file = function()
local res, err = F.find_project_root()
if res then
builtin.git_files({ cwd = res })
else -- fall-back to find_files, if current buffer isnt in a project
builtin.find_files({ cwd = err })
end
end
M.project_grep = function()
local res, err = F.find_project_root()
builtin.live_grep({ cwd = res or err })
end
M.project_list = function()
telescope.extensions.projects.projects()
end
M.search_buffer = function()
builtin.current_buffer_fuzzy_find({
previewer = false,
sorting_strategy = "ascending",
})
end
-- TODO: Temporary copy/pasted until project_nvim exposes this function
-- https://github.com/ahmedkhalf/project.nvim/issues/145
-- TODO: Create a Telescope extension out of this, for telescope-all-recent
local function create_finder()
local results = require("project_nvim").get_recent_projects()
local entry_display = require("telescope.pickers.entry_display")
local finders = require("telescope.finders")
-- Reverse results
for i = 1, math.floor(#results / 2) do
results[i], results[#results - i + 1] = results[#results - i + 1], results[i]
end
local displayer = entry_display.create({
separator = " ",
items = {
{
width = 30,
},
{
remaining = true,
},
},
})
local function make_display(entry)
return displayer({ entry.name, { entry.value, "Comment" } })
end
return finders.new_table({
results = results,
entry_maker = function(entry)
local name = vim.fn.fnamemodify(entry, ":t")
return {
display = make_display,
name = name,
value = entry,
ordinal = name .. " " .. entry,
}
end,
})
end
M.vc_select_repo = function()
-- local projects = require("project_nvim").get_recent_projects()
local actions = require("telescope.actions")
local action_state = require("telescope.actions.state")
local conf = require("telescope.config").values
-- local finders = require("telescope.finders")
local pickers = require("telescope.pickers")
pickers.new({}, {
prompt_title = "Select Project",
finder = create_finder(),
-- finder = telescope.extensions.projects.create_finder(),
-- finder = finders.new_table {
-- results = projects,
-- },
previewer = false,
sorter = conf.generic_sorter({}),
attach_mappings = function(prompt_bufnr)
actions.select_default:replace(function()
actions.close(prompt_bufnr)
local selection = action_state.get_selected_entry()
-- require("neogit").open({ cwd = selection[1] })
require("neogit").open({ cwd = selection.value })
end)
return true
end,
}):find()
end
M.vc_status = function()
if F.find_project_root() then
-- Open the repository of the current file
require("neogit").open({ cwd = "%:p:h" })
else
-- Pick a project to open
M.vc_select_repo()
end
end
return M
+242
View File
@@ -0,0 +1,242 @@
local K = vim.keymap.set
local builtin
local wk = require("which-key")
local F = require("keybind-functions")
local M = {}
--------------------------------------------
--- Keybindings ---
M.setup = function()
F.setup()
-- Prevent dependency loop
builtin = require("telescope.builtin")
-- Change default behavior
K("n", "Y", "y$")
K("v", "p", "pgvy")
K("n", "J", "mzJ`z") -- dont move cursor to end of line
K("n", "<C-d>", "<C-d>zz") -- stay in the middle
K("n", "<C-u>", "<C-u>zz")
K("n", "n", "nzzzv")
K("n", "N", "Nzzzv")
K("x", "p", "\"_dP") -- dont overwrite clipboard when pasting visually
-- Remap for dealing with word wrap
K("n", "k", [[v:count == 0 ? "gk" : "k"]], { expr = true, silent = true })
K("n", "j", [[v:count == 0 ? "gj" : "j"]], { expr = true, silent = true })
-- Tab/Shift+Tab functionality
K("n", "<Tab>", ">>_")
K("n", "<S-Tab>", "<<_")
K("i", "<S-Tab>", "<C-D>")
K("v", "<Tab>", ">gv")
K("v", "<S-Tab>", "<gv")
-- Move highlighted blocks
K("v", "J", ":m '>+1<CR>gv=gv")
K("v", "K", ":m '<-2<CR>gv=gv")
-- Switch to previous buffer
K("n", "<M-`>", "<C-6>")
-- Center buffer with Ctrl+L
K("n", "<C-l>", "zz")
-- Close buffer with Alt-w
K("n", "<M-w>", F.buffer_close)
-- Hungry delete
K("i", "<BS>", F.hungry_delete_backspace())
K("i", "<Del>", F.hungry_delete())
----------------------------------------
--- Leader keys ---
K("n", "<leader><space>", builtin.commands, { desc = "Execute command" })
F.wk("<leader>b", "buffer/bookmark")
K("n", "<leader>bb", builtin.buffers, { desc = "Switch buffer" })
K("n", "<leader>bd", F.buffer_dashboard, { desc = "Dashboard" })
F.wk("<leader>c", "comment")
-- numToStr/Comment.nvim
K("n", "<leader>cc", "<Plug>(comment_toggle_linewise_current)", { desc = "Comment toggle linewise" })
K("n", "<leader>cp", "<Plug>(comment_toggle_blockwise_current)", { desc = "Comment toggle blockwise" })
K("x", "<leader>cc", "<Plug>(comment_toggle_linewise_visual)", { desc = "Comment toggle linewise (visual)" })
K("x", "<leader>cp", "<Plug>(comment_toggle_blockwise_visual)", { desc = "Comment toggle blockwise (visual)" })
F.wk("<leader>e", "eval")
K("n", "<leader>eb", ":w<CR>:source %<CR>", { desc = "Evaluate buffer" })
F.wk("<leader>f", "file")
K("n", "<leader>fc", F.file_config, { desc = "Config file" })
K("n", "<leader>ff", F.file_find, { desc = "Find file" })
K("n", "<leader>fh", F.file_find_home, { desc = "Find file in ~" })
K("n", "<leader>fr", F.file_find_recent, { desc = "Find recent file" })
K("n", "<leader>fs", F.file_save, { desc = "Save file" })
F.wk("<leader>h", "help")
K("n", "<leader>hh", builtin.help_tags, { desc = "Describe" })
K("n", "<leader>hk", builtin.keymaps, { desc = "Describe key" })
K("n", "<leader>hm", builtin.man_pages, { desc = "Describe manpage" })
F.wk("<leader>g", "goto")
K("n", "<leader>ge", F.goto_trouble, { desc = "Goto trouble" })
K("n", "<leader>gt", F.goto_todos_telescope, { desc = "Goto todos (Telescope)" })
K("n", "<leader>gT", F.goto_todos_trouble, { desc = "Goto todos (Trouble)" })
F.wk("<leader>p", "project")
K("n", "<leader>pf", F.project_file, { desc = "Find project file" })
K("n", "<leader>pg", F.project_grep, { desc = "Find in project" })
K("n", "<leader>pp", F.project_list, { desc = "List projects" })
F.wk("<leader>s", "search")
K("n", "<leader>ss", F.search_buffer, { desc = "Search buffer" })
K("n", "<leader>sq", ":nohlsearch<CR>", { desc = "Stop search", silent = true })
F.wk("<leader>v", "git") -- version control
K("n", "<leader>vr", F.vc_select_repo, { desc = "Select repo" })
K("n", "<leader>vv", F.vc_status, { desc = "Neogit status" })
K({ "n", "v" }, "<leader>w", "<C-W>", { remap = true }) -- keymap and which-key should *both* be triggered
wk.add({
{
mode = { "n", "v" },
{ "<leader>w", group = "window" },
{ "<leader>w+", desc = "Increase height" },
{ "<leader>w-", desc = "Decrease height" },
{ "<leader>w<", desc = "Decrease width" },
{ "<leader>w=", desc = "Equally high and wide" },
{ "<leader>w>", desc = "Increase width" },
{ "<leader>wT", desc = "Break out into a new tab" },
{ "<leader>w_", desc = "Max out the height" },
{ "<leader>wh", desc = "Go to the left window" },
{ "<leader>wj", desc = "Go to the down window" },
{ "<leader>wk", desc = "Go to the up window" },
{ "<leader>wl", desc = "Go to the right window" },
{ "<leader>wo", desc = "Close all other windows" },
{ "<leader>wq", desc = "Quit a window" },
{ "<leader>ws", desc = "Split window" },
{ "<leader>wv", desc = "Split window vertically" },
{ "<leader>ww", desc = "Switch windows" },
{ "<leader>wx", desc = "Swap current with next" },
{ "<leader>w|", desc = "Max out the width" },
},
})
-- https://github.com/folke/which-key.nvim/issues/270
-- https://github.com/folke/which-key.nvim/blob/main/lua/which-key/plugins/presets/misc.lua
end
--------------------------------------------
--- Plugin specific ---
-- This function gets run when an LSP connects to a particular buffer.
M.lspconfig_on_attach = function(_, bufnr)
local nnoremap = function(keys, func, desc)
vim.keymap.set("n", keys, func, { buffer = bufnr, desc = desc })
end
F.wk("<leader>l", "lsp", bufnr)
nnoremap("<leader>la", vim.lsp.buf.code_action, "Code action")
nnoremap("<leader>lf", F.lsp_format_buffer, "Format buffer")
nnoremap("<leader>lr", vim.lsp.buf.rename, "Rename")
nnoremap("<leader>ld", "<cmd>Lspsaga hover_doc<CR>", "Show documentation")
-- vim.keymap.set("n", "<leader>ld", "<cmd>Lspsaga hover_doc<CR>", { desc = "Show documentation" })
F.wk("<leader>lg", "goto", bufnr)
nnoremap("<leader>lga", builtin.lsp_dynamic_workspace_symbols, "Workspace symbols")
nnoremap("<leader>lgd", vim.lsp.buf.declaration, "Declaration")
nnoremap("<leader>lgg", vim.lsp.buf.definition, "Definition") -- builtin.lsp_definitions
nnoremap("<leader>lgi", builtin.lsp_implementations, "Implementation")
nnoremap("<leader>lgr", builtin.lsp_references, "References")
nnoremap("<leader>lgs", builtin.lsp_document_symbols, "Document symbols")
nnoremap("<leader>lgt", builtin.lsp_type_definitions, "Type definition")
-- See `:help K` for why this keymap
nnoremap("K", vim.lsp.buf.hover, "Hover Documentation")
nnoremap("<C-k>", vim.lsp.buf.signature_help, "Signature Documentation")
end
-- Keybindings for nvim-cmp popup
M.nvim_cmp = function()
local cmp = require("cmp")
local luasnip = require("luasnip")
return cmp.mapping.preset.insert({
["<M-h>"] = cmp.mapping.abort(),
["<M-j>"] = cmp.mapping.select_next_item(),
["<M-k>"] = cmp.mapping.select_prev_item(),
["<M-l>"] = cmp.mapping.confirm({
behavior = cmp.ConfirmBehavior.Replace,
select = true,
}),
["<Esc>"] = cmp.mapping.abort(),
["<CR>"] = cmp.mapping.confirm({
behavior = cmp.ConfirmBehavior.Replace,
select = true,
}),
["<C-Space>"] = cmp.mapping.complete(),
["<Tab>"] = cmp.mapping(function(fallback)
if cmp.visible() then
cmp.select_next_item()
elseif luasnip.expand_or_locally_jumpable() then
luasnip.expand_or_jump()
else
fallback()
end
end, { "i", "s" }),
["<S-Tab>"] = cmp.mapping(function(fallback)
if cmp.visible() then
cmp.select_prev_item()
elseif luasnip.locally_jumpable(-1) then
luasnip.jump(-1)
else
fallback()
end
end, { "i", "s" }),
})
end
-- Telescope picker generic mappings
M.telescope_default_mappings = function()
local actions = require("telescope.actions")
return {
n = {
["<M-h>"] = actions.close,
["<M-j>"] = actions.move_selection_next,
["<M-k>"] = actions.move_selection_previous,
["<M-l>"] = actions.select_default,
},
i = {
["<M-h>"] = actions.close,
["<M-j>"] = actions.move_selection_next,
["<M-k>"] = actions.move_selection_previous,
["<M-l>"] = actions.select_default,
["<Tab>"] = actions.select_default,
}
}
end
return M
+32
View File
@@ -0,0 +1,32 @@
local M = {}
local plugin_path = vim.fn.stdpath("cache") .. "/lazy"
-- Install lazy.nvim plugin manager
-- See `:help lazy.nvim.txt`
M.install = function()
local lazy_path = plugin_path .. "/lazy.nvim"
if not vim.loop.fs_stat(lazy_path) then
vim.fn.system {
"git",
"clone",
"--filter=blob:none",
"https://github.com/folke/lazy.nvim.git",
"--branch=stable", -- latest stable release
lazy_path,
}
end
vim.opt.rtp:prepend(lazy_path)
end
M.setup = function(modules)
M.install()
local options = {
root = plugin_path, -- directory where plugins will be installed
}
require("lazy").setup(modules, options)
end
return M
+132
View File
@@ -0,0 +1,132 @@
return {
-- Fuzzy Finder (files, LSP, etc)
{
"nvim-telescope/telescope.nvim",
branch = "0.1.x",
dependencies = {
"nvim-lua/plenary.nvim",
-- Fuzzy Finder Algorithm which requires local dependencies to be built.
{
"nvim-telescope/telescope-fzf-native.nvim",
build = "make",
cond = function()
return vim.fn.executable "make" == 1
end,
},
-- Extensions
"nvim-telescope/telescope-file-browser.nvim",
"smartpde/telescope-recent-files",
},
extensions = {
"fzf",
},
config = function()
require("telescope").setup({
defaults = {
sorting_strategy = "ascending",
layout_strategy = "config",
layout_config = {
height = 10, -- amount of results
config = { -- apply settings to the "config" layout
search_condensed = true,
}
},
border = true,
history = {
path = vim.fn.stdpath("cache") .. "/telescope_history",
},
mappings = require("keybinds").telescope_default_mappings(),
},
extensions = {
file_browser = {
hide_parent_dir = true, -- hide "../"
prompt_path = true, -- set path as prompt prefix
},
},
})
require("telescope").load_extension("fzf")
require("telescope").load_extension "file_browser"
require("telescope").load_extension("recent_files")
--- ┌──────────────────────────────────────────────────┐
--- │ │
--- │ ┌───────────────────┐ │
--- │ │ │ │
--- │ │ │ │
--- │ │ Preview │ │
--- │ │ │ │
--- │ │ │ │
--- │ └───────────────────┘ │
--- │ │
--- ├──────────────────────────────────────────────────┤
--- │ Prompt │
--- ├──────────────────────────────────────────────────┤
--- │ Results │
--- │ │
--- └──────────────────────────────────────────────────┘
require("telescope.pickers.layout_strategies").config = function(picker, max_columns, max_lines,
layout_config)
local p_window = require "telescope.pickers.window"
local initial_options = p_window.get_initial_window_options(picker)
local results = initial_options.results
local prompt = initial_options.prompt
local preview = initial_options.preview
-- Layout config isnt filled by Telescope automatically
layout_config = require("telescope.config").values.layout_config or {}
results.title = ""
results.borderchars = { "", "", "", "", "", "", "", "" }
local bs = picker.window.border and 2 or 0
local search_condensed = bs ~= 0 and layout_config.config.search_condensed and 2 or 0
-- Height
prompt.height = 1
results.height = layout_config.height or 10
local search_height = (prompt.height + results.height + (bs * 3))
preview.height = math.floor((max_lines - search_height) * 0.8)
-- Width
prompt.width = max_columns - (bs ~= 0 and search_condensed == 0 and bs or 0)
results.width = max_columns - (bs ~= 0 and search_condensed == 0 and bs or 0)
preview.width = math.floor(max_columns * 0.75)
-- Line (position), coordinates start at top-left
prompt.line = max_lines - results.height + search_condensed - bs -- take overlapping border into account
results.line = max_lines - results.height + search_condensed - bs + (bs / 2) + prompt.height
preview.line = math.floor((max_lines - search_height - preview.height + bs) / 2) + 1
return {
preview = picker.previewer and preview.width > 0 and preview,
prompt = prompt,
results = results,
}
end
end,
},
-- Telescope pickers sorted by recency and frequency
{
"prochri/telescope-all-recent.nvim",
dependencies = {
"kkharji/sqlite.lua",
},
opts = {
database = {
folder = vim.fn.stdpath("cache"),
},
pickers = { -- extension_name#extension_method
["projects#projects"] = {
disable = false,
use_cwd = false,
sorting = "frecency",
},
},
}
},
}
+186
View File
@@ -0,0 +1,186 @@
return {
-- Theme
{
"RRethy/nvim-base16",
lazy = false, -- make sure to load this during startup if it is your main colorscheme
priority = 1000,
config = function()
require("base16-colorscheme").with_config({
-- TODO: maybe make Telescope borders visible?
-- telescope = false,
})
vim.cmd.colorscheme "base16-tomorrow-night"
local colors = require("base16-colorscheme").colors
-- local blue_m1 = "#9cc4e6"
local blue = colors.base0D -- #81a2be
-- local blue_p1 = "#5f819d"
local blue_p2 = "#445666"
local blue_p3 = "#2a3640"
local cyan = colors.base0C -- #8abeb7
local fg = colors.base05 -- #c5c8c6
local fg_dark = "#515151"
-- local green = colors.base0B -- #b5bd68
local green_p1 = "#8c9440"
-- local green_p2 = "#5f875f"
local green_bg = "#404324"
-- local orange = colors.base09 -- #de935f
-- local magenta = colors.base0E -- #b294bb
local red = colors.base08 -- #cc6666
local red_bg = "#4e2626"
local yellow = colors.base0A -- #f0c674
-- Cursor
vim.api.nvim_command("highlight CursorLineNr guifg=" .. yellow .. " gui=bold")
-- Diffview
vim.api.nvim_command("highlight DiffviewDiffAdd guibg=" .. green_bg)
vim.api.nvim_command("highlight DiffviewDiffChange guibg=" .. blue_p3) -- Unchanged part on a change line
vim.api.nvim_command("highlight DiffviewDiffDelete guibg=" .. red_bg .. " guifg=" .. fg_dark)
vim.api.nvim_command("highlight DiffviewDiffText guibg=" .. blue_p2) -- Changed part on a change line
-- Git gutter
vim.api.nvim_command("highlight GitSignsAdd guifg=" .. green_p1)
vim.api.nvim_command("highlight GitSignsChange guifg=" .. yellow)
-- Rainbow delimiters
vim.api.nvim_command("highlight RainbowDelimiterBlue guifg=" .. blue)
vim.api.nvim_command("highlight RainbowDelimiterCyan guifg=" .. cyan)
vim.api.nvim_command("highlight RainbowDelimiterGreen guifg=" .. green_p1)
vim.api.nvim_command("highlight RainbowDelimiterOrange guifg=" .. fg)
vim.api.nvim_command("highlight RainbowDelimiterRed guifg=" .. red)
vim.api.nvim_command("highlight RainbowDelimiterYellow guifg=" .. yellow)
end,
},
-- Set lualine as statusline
{
-- See `:help lualine.txt`
"nvim-lualine/lualine.nvim",
opts = {
options = {
icons_enabled = false,
theme = "base16",
component_separators = { left = "", right = "" },
section_separators = { left = "", right = "" },
globalstatus = true,
},
sections = {
lualine_a = { "mode" },
lualine_b = { "encoding", "filename" },
lualine_c = {
{
-- TODO: nvim alternate file stuff and closing files is busted
"project",
fmt = function()
local path = require("core.functions").find_project_root() or ""
return path:match("([^/]+)$")
end,
},
},
lualine_x = { "diagnostics", "fileformat" },
lualine_y = { "filetype" },
lualine_z = { "progress", "location" },
},
},
},
-- Add file type icons to plugins
{ "nvim-tree/nvim-web-devicons", lazy = true },
-- Dashboard
{
"nvimdev/dashboard-nvim",
event = "VimEnter",
opts = {
config = {
header = {
" . . ",
" ';;,. ::' ",
" ,:::;,, :ccc, ",
" ,::c::,,,,. :cccc, ",
" ,cccc:;;;;;. cllll, ",
" ,cccc;.;;;;;, cllll; ",
" :cccc; .;;;;;;. coooo; ",
" ;llll; ,:::::'loooo; ",
" ;llll: ':::::loooo: ",
" :oooo: .::::llodd: ",
" .;ooo: ;cclooo:. ",
" .;oc 'coo;. ",
" .' .,. ",
"",
" _______________________________________________________",
"",
"",
},
shortcut = {
{ desc = "Neovim master race!" },
},
footer = {},
},
}
},
-- Show project errors
{
"folke/trouble.nvim",
cmd = "Trouble", -- defer
opts = {
mode = "lsp_references",
use_diagnostic_signs = true,
},
config = function()
-- Gutter/fringe icons
-- https://github.com/folke/trouble.nvim/issues/52
local signs = {
Error = "»",
Warn = "»",
Hint = "»",
Info = "»",
Other = "»",
}
for type, icon in pairs(signs) do
local hl = "DiagnosticSign" .. type
vim.fn.sign_define(hl, { text = icon, texthl = hl, numhl = hl })
end
end,
},
-- Show project TODOs
{
"folke/todo-comments.nvim",
dependencies = { "nvim-lua/plenary.nvim" },
opts = {},
},
-- Useful plugin to show you pending keybinds.
"folke/which-key.nvim",
-- Rainbow delimiters
{
"HiPhish/rainbow-delimiters.nvim",
opts = {
highlight = {
"RainbowDelimiterOrange", -- white
"RainbowDelimiterCyan",
"RainbowDelimiterYellow",
"RainbowDelimiterGreen",
"RainbowDelimiterBlue",
"RainbowDelimiterOrange", -- white
"RainbowDelimiterCyan",
"RainbowDelimiterYellow",
"RainbowDelimiterGreen",
"RainbowDelimiterBlue",
"RainbowDelimiterRed",
},
},
config = function(_, opts)
require("rainbow-delimiters.setup").setup(opts)
end,
},
-- Rainbow-mode
{ -- https://github.com/norcalli/nvim-colorizer.lua
"norcalli/nvim-colorizer.lua",
opts = {},
}, -- :ColorizerToggle
}
+7 -2
View File
@@ -1,4 +1,9 @@
#!/hint/bash
# Make Flags: use 4 threads
MAKEFLAGS="-j4"
# Amount of threads the use with the make command
# >>> hostname=arch-desktop
MAKEFLAGS="-j8"
# <<<
# >>> hostname=arch-laptop
# MAKEFLAGS="-j4"
# <<<
+1 -1
View File
@@ -150,7 +150,7 @@ format =
type = internal/date
interval = 5
time = %I:%M %p
time = %I:%M %p %a
time-alt =
format = %{A1:$HOME/.local/bin/panel/date.sh:}<label>%{A}
+19
View File
@@ -0,0 +1,19 @@
# -*- python -*-
import os
import atexit
import readline
history = os.path.join(os.environ['XDG_CACHE_HOME'], 'python_history')
try:
readline.read_history_file(history)
except OSError:
pass
def write_history():
try:
readline.write_history_file(history)
except OSError:
pass
atexit.register(write_history)
+7 -3
View File
@@ -2,8 +2,8 @@
color_scheme_path=/usr/share/qt5ct/colors/darker.conf
custom_palette=false
icon_theme=Arc
standard_dialogs=gtk2
style=gtk2
standard_dialogs=default
style=qt5gtk2
[Fonts]
fixed=@Variant(\0\0\0@\0\0\0\x16\0\x44\0\x65\0j\0\x61\0V\0u\0 \0S\0\x61\0n\0s@$\0\0\0\0\0\0\xff\xff\xff\xff\x5\x1\0\x32\x10)
@@ -25,4 +25,8 @@ underline_shortcut=1
wheel_scroll_lines=3
[SettingsWindow]
geometry=@ByteArray(\x1\xd9\xd0\xcb\0\x3\0\0\0\0\x1\x8e\0\0\0\xc0\0\0\x4p\0\0\x3&\0\0\x1\x90\0\0\0\xc2\0\0\x4n\0\0\x3$\0\0\0\0\0\0\0\0\x5\xdc\0\0\x1\x90\0\0\0\xc2\0\0\x4n\0\0\x3$)
geometry=@Invalid()
[Troubleshooting]
force_raster_widgets=0
ignored_applications=@Invalid()
+32
View File
@@ -0,0 +1,32 @@
[Appearance]
color_scheme_path=/usr/share/qt6ct/colors/darker.conf
custom_palette=false
icon_theme=Arc
standard_dialogs=default
style=qt6gtk2
[Fonts]
fixed=@Variant(\0\0\0@\0\0\0\x16\0\x44\0\x65\0j\0\x61\0V\0u\0 \0S\0\x61\0n\0s@$\0\0\0\0\0\0\xff\xff\xff\xff\x5\x1\0\x32\x10)
general=@Variant(\0\0\0@\0\0\0\x16\0\x44\0\x65\0j\0\x61\0V\0u\0 \0S\0\x61\0n\0s@$\0\0\0\0\0\0\xff\xff\xff\xff\x5\x1\0\x32\x10)
[Interface]
activate_item_on_single_click=1
buttonbox_layout=0
cursor_flash_time=1000
dialog_buttons_have_icons=1
double_click_interval=400
gui_effects=@Invalid()
keyboard_scheme=2
menus_have_icons=true
show_shortcuts_in_context_menus=true
stylesheets=@Invalid()
toolbutton_style=4
underline_shortcut=1
wheel_scroll_lines=3
[SettingsWindow]
geometry=@Invalid()
[Troubleshooting]
force_raster_widgets=0
ignored_applications=@Invalid()
+8 -1
View File
@@ -1,6 +1,13 @@
[redshift]
temp-day=5700
temp-night=3000
; >>> hostname=arch-desktop
temp-night=3500
; <<<
; >>> hostname=arch-laptop
; temp-night=3000
; <<<
fade=1
brightness-day=1.0
+5 -1
View File
@@ -11,6 +11,10 @@ configuration {
/* Layout */
font: "DejaVu Sans Mono, Font Awesome 6 Free 12";
/* >>> hostname=arch-laptop */
/* dpi: 192; */
/* <<< */
/* Icons */
icon-theme: "Arc";
show-icons: true;
@@ -18,7 +22,7 @@ configuration {
/* Keybinds */
kb-cancel: "Escape,Control+g,Control+bracketleft,Alt+h";
kb-row-down: "Down,Control+n,Alt+j";
kb-row-up: "Up,Control+p,ISO_Left_Tab,Alt+k";
kb-row-up: "Up,Control+p,Alt+k";
kb-accept-entry: "Control+j,Control+m,Return,KP_Enter,Alt+l";
}
+57
View File
@@ -0,0 +1,57 @@
#!/usr/bin/perl
# trizen configuration file
our $CONFIG = {
ask_for_retry => 1, # bool -- When `makepkg` fails to build a package, offer the option for trying again.
aur_results_last_modified => 1, # bool -- Show the date when the packages were last updated in AUR results.
aur_results_popularity => 1, # bool -- Show the popularity score in AUR results.
aur_results_show_installed => 1, # bool -- Show when a package is installed in AUR results.
aur_results_sort_by => "name", # str -- Sort the AUR results by "name", "votes", "popularity" or "date".
aur_results_sort_order => "ascending", # str -- Sort the AUR results in "ascending" or "descending" order.
aur_results_votes => 1, # bool -- Show the number of votes in AUR results.
clone_dir => "/tmp/trizen-$ENV{USER}", # str -- Absolute path to the directory where to clone and build packages.
color_code_dependencies => 1, # bool -- Display the dependencies of a package in specific colors (green = installed; cyan = in repo; purple = in AUR).
debug => 0, # bool -- Verbose mode.
flip_indices => 0, # bool -- In search+install mode, show the indices of packages in reverse order.
flip_results => 0, # bool -- Show the search results in reverse order.
forcecolors => 0, # bool -- Force output colors even when not writing to STDOUT.
git_clone_depth => 0, # int -- Pass the `--depth int` flag to `git clone`. (0 means no limit)
lwp_env_proxy => 1, # bool -- Use proxy settings defined in `env` (if any).
lwp_show_progress => 0, # bool -- Show the HTTPS requests made by LWP::UserAgent to the AUR servers.
lwp_timeout => 60, # int -- Seconds after which an HTTPS connection is aborted.
makepkg_command => "/usr/bin/makepkg -scf", # str -- The `makepkg` command that is used internally in building a package.
movepkg => 0, # bool -- Move built packages in the directory `movepkg_dir`.
movepkg_dir => "/var/cache/pacman/pkg", # str -- Absolute path to the directory where to move built packages (with `movepkg`).
nocolors => 0, # bool -- Disable output colors for `trizen`.
noedit => 0, # bool -- Do not prompt to edit files when installing an AUR package.
noinfo => 0, # bool -- Do not display package information when installing an AUR package.
noinstall => 0, # bool -- Do not install built packages -- builds only.
nopull => 0, # bool -- Do not `git pull` new changes from the AUR git server.
one_line_edit => 0, # bool -- Select one or more build files to view/edit with one-line prompt.
packages_in_stats => 5, # int -- The number of packages to display in `--stats`
pacman_command => "/usr/bin/pacman", # str -- The `pacman` command that is used internally for pacman operations.
pacman_local_dir => "/var/lib/pacman/local", # str -- Absolute path to the pacman's local directory.
pager_mode => 0, # bool -- Show the build files in pager mode using pager.
recompute_deps => 1, # bool -- Recompute the dependencies of a package (after its build files are inspected / edited).
show_build_files_content => 1, # bool -- Show the content of the build files of a package before building it.
show_comments => 0, # int -- Show the `n` most recent AUR comments for a package before building it. (max: 10)
show_diff_only => 0, # bool -- When the build files of a package already exist locally, show the diff only.
show_inexistent => 1, # bool -- Warn about packages that do not exist in AUR, during -Su.
show_ood => 0, # bool -- Warn about out-of-date marked packages, during -Su.
show_unmaintained => 1, # bool -- Warn about unmaintained packages, during -Su.
skipinteg => 0, # bool -- Pass the `--skipinteg` argument to `makepkg`.
split_packages => 1, # bool -- Ask about installing the other parts of a split package.
ssl_verify_hostname => 1, # bool -- Ensure LWP::UserAgent connects to servers that have a valid certificate.
su_command => "/usr/bin/su -c", # str -- Command used when special permissions are required and `use_sudo` is set to 0.
sudo_autorepeat => 1, # bool -- Automatically repeat `sudo -v` in the background after a `sudo` command was first executed.
sudo_autorepeat_at_runtime => 1, # bool -- Execute `sudo -v` when `trizen` is first executed and apply the behavior of `sudo_autorepeat`.
sudo_autorepeat_interval => 180, # int -- Interval, in seconds, after which `sudo -v` is executed in background (with `sudo_autorepeat`).
sudo_command => "/usr/bin/sudo", # str -- Command used when special permissions are required and `use_sudo` is set to 1.
sudo_remove_timestamp => 0, # bool -- Remove the cached sudo credentials before `makepkg` is executed (`sudo --remove-timestamp`).
syntax_highlighting => 0, # bool -- Syntax highlighting of the build files, using the `highlight` tool from [community].
syntax_highlighting_cmd => "/usr/bin/highlight -O ansi", # str -- The `highlight` command used in highlighting the syntax of the build files (with `syntax_highlighting`).
use_github_api => 1, # bool -- Check GitHub sources for updates using GitHub's API. (during `--devel --needed`)
use_gitlab_api => 1, # bool -- Check GitLab sources for updates using GitLab's API. (during `--devel --needed`)
use_sudo => 1, # bool -- Use the `sudo` command when special permissions are required.
}
+1 -1
View File
@@ -1 +1 @@
/home/rick/.config/vim/pack/plugins/opt/vim-hybrid-material/colors/hybrid_reverse.vim
../pack/plugins/opt/vim-hybrid-material/colors/hybrid_reverse.vim
+1
View File
@@ -61,6 +61,7 @@ set shiftwidth=4
set laststatus=2
set noshowmode
set nowrap
set title
"" Plugin configuration
+17 -3
View File
@@ -49,11 +49,25 @@ WmWorkSpace.ws9: 九
WmWorkSpace.ws0: 十
Xcursor.theme: capitaine-cursors-light
Xcursor.size: 48
! >>> hostname=arch-desktop
Xcursor.size: 24
! <<<
! >>> hostname=arch-laptop
! Xcursor.size: 48
! <<<
! Font config
*dpi: 192
Xft.dpi: 192
! >>> hostname=arch-desktop
*dpi: 96
Xft.dpi: 96
! <<<
! >>> hostname=arch-laptop
! *dpi: 192
! Xft.dpi: 192
! <<<
Xft.autohint: 0
Xft.lcdfilter: lcddefault
Xft.hintstyle: hintslight
+1 -2
View File
@@ -3,7 +3,7 @@
xrdb "$XDG_CONFIG_HOME/xorg/Xresources"
# Setup display
#monctl auto 3000 2000 48 eDP-1 &
autorandr --change
# Set default X cursor to arrow
xsetroot -cursor_name left_ptr
@@ -23,7 +23,6 @@ emacs --daemon &
thunar --daemon &
sxhkd "$XDG_CONFIG_HOME/sxhkd/$WM" &
xss-lock -- "$HOME/.local/bin/wm/lock.sh" &
/usr/lib/polkit-kde-authentication-agent-1 &
+21 -4
View File
@@ -1,4 +1,4 @@
## Settings
#--- General ---#
# Directories
export CAPTURE="$HOME/pictures/screen-captures"
@@ -20,7 +20,14 @@ export PLATFORMIO_HOME_DIR="$XDG_DATA_HOME/platformio"
export R_ENVIRON_USER="$XDG_CONFIG_HOME/R/Renviron"
# HiDPI screen
export HIDPI=true
# >>> hostname=arch-laptop
# export HIDPI=true
# <<<
#--- Program Specific ---#
# Android
export ANDROID_HOME="$XDG_DATA_HOME/android"
# GPG
export GNUPGHOME="$XDG_CONFIG_HOME/gnupg"
@@ -64,12 +71,19 @@ export RANDFILE="$XDG_CACHE_HOME/rnd"
[ "$HIDPI" = true ] && export PANEL_HEIGHT=38 || export PANEL_HEIGHT=22
export PANEL_NAME="polybar_panel"
# Python
export PYTHONSTARTUP="$XDG_CONFIG_HOME/python/pythonrc"
# Qt5
if [ "$HIDPI" = true ]; then
export QT_AUTO_SCREEN_SCALE_FACTOR=0
export QT_SCREEN_SCALE_FACTORS=2
fi
export QT_QPA_PLATFORMTHEME="qt5ct"
export QT_QPA_PLATFORMTHEME="qt5gtk2"
# Rust
export CARGO_HOME="$XDG_DATA_HOME/cargo"
export RUSTUP_HOME="$XDG_DATA_HOME/rustup"
# Sudo
export SUDO_ASKPASS="$HOME/.local/bin/rofipass"
@@ -78,7 +92,7 @@ export SUDO_ASKPASS="$HOME/.local/bin/rofipass"
export TERMINAL="urxvt"
# Vim
export VIMINIT="source $XDG_CONFIG_HOME/vim/vimrc"
export VIMINIT="source $XDG_CONFIG_HOME/nvim/init.lua"
# Web browser
export BROWSER="firefox"
@@ -86,6 +100,9 @@ export BROWSER="firefox"
# Wget
export WGETRC="$XDG_CONFIG_HOME/wget/wgetrc"
# Wine
export WINEPREFIX="$XDG_DATA_HOME/wine"
# WM
export WM="bspwm"
+15 -8
View File
@@ -116,10 +116,10 @@ alias fuck='sudo $(fc -ln -1)'
alias grep="grep --color=always"
alias ip="ip --color"
alias ipb="ip --color --brief a"
alias l.="\ls -lAGh --color --group-directories-first | awk '{ if (\$NF ~ /^(.*m)?\./) print }'"
alias la="\ls -lAGh --color --group-directories-first"
alias l.="\ls -lAGh --color --group-directories-first --hyperlink | awk '{ if (\$NF ~ /^(.*m)?\./) print }'"
alias la="\ls -lAGh --color --group-directories-first --hyperlink"
alias less="less -x 4"
alias ls="ls --color --group-directories-first"
alias ls="ls --color --group-directories-first --hyperlink"
alias mkdir="mkdir -pv"
alias mv='mv -i'
alias pkill="pkill -9"
@@ -173,13 +173,13 @@ alias gl="git log --graph --abbrev-commit --decorate --format=format:'%C(bold bl
alias gle="git log --graph --stat --format=format:'%C(bold blue)commit %H%C(reset)%C(bold yellow)%d %C(reset)%nAuthor: %C(dim white)%an <%ae>%C(reset)%nDate: %C(bold cyan)%ai%C(reset) %C(bold green)(%ar)%C(reset)%n%n%w(64,4,4)%B'"
alias gm="git merge"
alias gp="git pull"
alias gps="git push"
alias gpsa="git remote | xargs -I remotes git push remotes master"
alias gpsaf="git remote | xargs -I remotes git push --force remotes master"
alias gps='git push || git push origin $(git branch --show-current)'
alias gpsa='git remote | xargs -I remotes git push remotes $(git branch --show-current)'
alias gpsaf='git remote | xargs -I remotes git push --force remotes $(git branch --show-current)'
alias gr="git reset"
alias gs="git status"
alias gsh="git show --format=format:'%C(bold blue)commit %H%C(reset) %C(bold yellow)%d %C(reset)%nAuthor: %C(dim white)%an <%ae>%C(reset)%nDate: %C(bold cyan)%ai%C(reset) %C(bold green)(%ar)%C(reset)%n%n%w(64,4,4)%B'"
alias gt='git ls-tree -r --name-only master .'
alias gt='git ls-tree -r --name-only $(git branch --show-current) .'
# Scripts
alias nc="netictl"
@@ -194,14 +194,21 @@ alias length="rofi -dmenu -i -p 'String length' -lines 0 | tr -d '\n' | wc -m"
alias p="aliases pastebin"
alias screencast="aliases screencast"
alias stream="aliases stream"
alias temp="watch -n 2 sensors"
alias u="setsid -f urxvt -cd $PWD"
alias weather="curl -s 'https://wttr.in/dordrecht?q&n&p' | head -n -3"
alias webmconvert="aliases webmconvert"
alias windowname="xprop | grep -e WM_CLASS -e WM_NAME"
alias workbench="GDK_SCALE=1 GDK_DPI_SCALE=1 setsid -f -- mysql-workbench > /dev/null 2>&1"
mkcd() { mkdir -pv -- "$1" && cd -P -- "$1" || exit; }
highlighting="/usr/share/zsh/plugins/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh"
[ -f "$highlighting" ] && source "$highlighting"; unset highlighting
if [ -f "$highlighting" ]; then
source "$highlighting";
ZSH_HIGHLIGHT_HIGHLIGHTERS=(main brackets)
ZSH_HIGHLIGHT_STYLES[path]="fg=12,underline"
fi
unset highlighting
[ -f "$ZDOTDIR/.zshrc_extended" ] && source "$ZDOTDIR/.zshrc_extended"
-29
View File
@@ -99,35 +99,6 @@ shuffle() {
echo "$1" | fold -w 1 | shuf | tr -d '\n'
}
stream() {
channel="$1"
quality="$2"
lowLatency="$3"
if [ -z "$quality" ]; then
streamlink --quiet --config "/dev/null" "https://twitch.tv/$1"
printf "Select stream quality: "
read -r quality
fi
if [ -n "$lowLatency" ]; then
arguments="\
--twitch-low-latency \
--player-args '--cache=yes --demuxer-max-bytes=750k' \
"
fi
echo "Starting stream https://twitch.tv/$channel @ $quality"
command="setsid -f streamlink \
--twitch-disable-hosting \
--twitch-disable-reruns \
--player mpv \
--stream-sorting-excludes '<480p,>=1080p' \
$arguments \
https://twitch.tv/$channel $quality > /dev/null 2>&1"
eval "$command"
}
update_mirrorlist() {
sudo rm /etc/pacman.d/mirrorlist.pacnew
sudo reflector --latest 100 --protocol https --sort rate --save /etc/pacman.d/mirrorlist
+1
View File
@@ -112,6 +112,7 @@ downloadVideo()
[ -z "$videoBest" ] && videoLimit="[height<=?1080]"
youtube-dl --format "bestvideo${videoLimit}+bestaudio/best" \
--add-metadata \
--external-downloader aria2c \
--cookies "$HOME/documents/youtube.com-cookies.txt" "$1"
}
+7 -3
View File
@@ -30,9 +30,13 @@ output() {
echo "%{F$color}$symbol $difference%%{F$COLOR15}"
}
# Only pull if older than 10 seconds
lastModified=$(calc "$(date +%s) - $(date +%s -r $file) >= 10" | cut -c 1)
if [ "$lastModified" -eq 0 ]; then cat "$file"; exit; fi
if [ ! -f "$file" ]; then
touch "$file"
else
# Only pull if older than 10 seconds
lastModified=$(calc "$(date +%s) - $(date +%s -r $file) >= 10" | cut -c 1)
if [ "$lastModified" -eq 0 ]; then cat "$file"; exit; fi
fi
# Get dates
date_last_week_start="$(date --date 'last week' +%s000)"
+213 -61
View File
@@ -1,6 +1,8 @@
#!/bin/sh
PIPE="$XDG_CACHE_HOME/mpv/umpv_fifo"
# Depends: GNU getopt, mpv, socat, streamlink, xclip
SOCK="/tmp/umpv-fifo"
help() {
B=$(tput bold)
@@ -16,99 +18,249 @@ ${B}SYNOPSIS${N}
${B}DESCRIPTION${N}
play is a script to manage different mpv viewing bahavior.
If no ${U}URLS${N} argument is provided, it is read from clipboard instead.
If no ${U}URLS${N} argument is provided, it is read from the clipboard instead.
The queue option starts a mpv window with a playlist, which all videos of
subsequent queue calls get added to.
${B}OPTIONS${N}
${B}help${N}
${B}-h${N}, ${B}--help${N}
Display usage message and exit.
[${B}play${N}] [${U}URLS${N}...] (default)
Plays videos in a new mpv window.
${B}-q${N}, ${B}--quality${N} ${U}QUALITY${N}
Set the video quality, example: ${U}720p60${N}.
${B}shuffle${N} [${U}URLS${N}...]
${B}-f${N}, ${B}--shuffle${N} [${U}URLS${N}...]
Shuffle audio playlist (disables video playback).
${B}queue${N} [${U}URLS${N}...]
${B}-u${N}, ${B}--queue${N} [${U}URLS${N}...]
Add multiple videos to the unique mpv's queue.
${B}-s${N}, ${B}--stream${N} [${U}URLS${N}...]
Play video(s) using streamlink.
${B}-l${N}, ${B}--low-latency${N}
Enable twitch low-latency mode in streamlink.
EOF
}
CLIP="$(xclip -se c -o)"
# --------------------------------------
play() {
MPV="mpv --ytdl-raw-options=external-downloader=aria2c"
if [ -z "$1" ]; then
MPV="$MPV $CLIP"
# Cut off everything after space
LINK="$(echo "$CLIP" | sed -nE 's/^(\S+).*/\1/p')"
else
MPV="$MPV $*"
# Determain which argument holds the urls
[ "$1" = "${1#-}" ] && DISPLAY="$1" || DISPLAY="$2"
# Cut off everything after space
LINK="$(echo "$DISPLAY" | sed -nE 's/^(\S+).*/\1/p')"
qualityFormat() {
url="$1"
# Twitch urls dont support fancy matching
if echo "$url" | grep -q "twitch\.tv"; then
if [ -z "$quality" ]; then
echo "Source"
else
echo "$quality"
fi
return
fi
notify-send -t 2500 "Loading video: $LINK"
# Attempt to load video
[ "$($MPV)" ] && notify-send -u critical -t 4000 "Loading video failed.."
# , separator = download several formats
# + separator = merge several formats into a single file
# / separator = or
if [ -z "$quality" ]; then
echo "bestvideo[height<=?1080]+bestaudio/best"
else
height="$(echo "$quality" | awk -F 'p' '{ print $1 }')"
fps="$(echo "$quality" | awk -F 'p' '{ print $2 }')"
format="bestvideo[height<=?$height]"
if [ -n "$fps" ]; then
format="${format}[fps<=?$fps]"
fi
format="$format+bestaudio/best"
echo "$format"
fi
}
play() {
url="$1"
notify-send -t 2500 "Loading video: $url"
setsid -f mpv --no-terminal \
--ytdl-format="$(qualityFormat "$url")" \
--ytdl-raw-options=add-metadata=,external-downloader=aria2c \
"$url"
}
shuffle() {
# Skip first argument
shift 1
urls="$*"
mpv --no-video --shuffle \
--ytdl-format='bestaudio[ext=m4a]' \
--ytdl-raw-options='external-downloader=aria2c' \
"${@:-$CLIP}"
--ytdl-raw-options=add-metadata=,external-downloader=aria2c \
"$urls"
}
queue() {
OPTIONS="--no-terminal --force-window --input-file=$PIPE --ytdl-raw-options=external-downloader=aria2c"
urls="$*"
options="--no-terminal --force-window --input-ipc-server=$SOCK"
# Create mpv cache directory
DIR="$(dirname "$PIPE")"
[ ! -d "$DIR" ] && mkdir -p "$DIR"
dir="$(dirname "$SOCK")"
[ ! -d "$dir" ] && mkdir -p "$dir"
# Delete named pipe if no umpv is running
if ! pgrep -f "mpv $OPTIONS" > /dev/null; then
rm -f "$PIPE"
# Delete socket if no umpv is running
if ! pgrep -f "mpv $options" > /dev/null; then
rm -f "$SOCK"
fi
# Skip first argument
shift 1
# Set url to argument if provided, clipboard otherwise
URLS="${*:-$CLIP}"
if [ -p "$PIPE" ]; then
if [ -S "$SOCK" ]; then
notify-send -t 2500 "Added video to queue.."
# Add video to named pipe
echo "$URLS" \
| awk -v RS=' ' '{ print "raw loadfile "$1" append" }' > "$PIPE"
echo "$urls" | awk -v RS=' ' '{ print "raw loadfile "$1" append" }' \
| socat UNIX-CONNECT:"$SOCK" -
else
# Create named pipe
mkfifo "$PIPE"
# Play video
play "$OPTIONS" "$URLS"
rm -f "$PIPE"
notify-send -t 2500 "Loading video: $urls"
# shellcheck disable=2086
setsid -f mpv $options \
--ytdl-format="$(qualityFormat $urls)" \
--ytdl-raw-options=add-metadata=,external-downloader=aria2c \
$urls
fi
}
case "$1" in
help)
help
;;
shuffle)
shuffle "$@"
;;
queue)
queue "$@"
;;
*)
play "$@"
;;
esac
stream() {
channel="$1"
quality="$2"
lowLatency="$3"
if [ -z "$quality" ]; then
if ! streamlink --quiet --config /dev/null "$channel"; then
return 1
fi
printf "Select stream quality: "
read -r quality
fi
if [ -z "$lowLatency" ]; then
arguments="\
--player-args '--force-window'"
else
arguments="\
--twitch-low-latency \
--player-args '--force-window --cache=yes --demuxer-max-bytes=750k'"
fi
echo "Starting stream $channel @ $quality"
command="setsid -f streamlink \
--twitch-disable-hosting \
--twitch-disable-reruns \
--player mpv \
--stream-sorting-excludes '<480p,>=1080p' \
$arguments \
$channel $quality > /dev/null 2>&1"
eval "$command"
}
# Option parsing
# --------------------------------------
script="$(basename "$0")"
parsed="$(getopt --options "hslquf" \
--longoptions "help,stream,quality,queue,shuffle" \
-n "$script" -- "$@" 2>&1)"
result="$?"
# Exit if invalid option is provided
if [ "$result" -ne 0 ]; then
echo "$parsed" | head -n 1 >&2
echo "Try './$script --help' for more information." >&2
exit 1
fi
eval set -- "$parsed"
streamOption=0
qualityOption=0
lowLatencyOption=0
queueOption=0
shuffleOption=0
while true; do
case "$1" in
-h | --help)
help
exit
;;
-s | --stream)
streamOption=1
shift
;;
-l | --low-latency)
lowLatencyOption=1
shift
;;
-q | --quality)
qualityOption=1
shift
;;
-u | --queue)
queueOption=1
shift
;;
-f | --shuffle)
shuffleOption=1
shift
;;
--)
shift
break
;;
*)
break
;;
esac
done
# Target parsing
# --------------------------------------
# Incompatible flags
result=$((streamOption + queueOption + shuffleOption))
if [ $result -gt 1 ]; then
echo "Incompatible flags." >&2
echo "Try './$script --help' for more information." >&2
exit 1;
fi
# Get quality
if [ $qualityOption -eq 1 ]; then
quality="$1"
shift
fi
# Set url to clipboard if none provided
clip="$(xclip -selection clipboard -out)"
if [ "$#" -eq 0 ]; then
eval set -- "$clip"
fi
[ $lowLatencyOption -eq 1 ] && lowLatency="1"
# Execute
# --------------------------------------
if [ $streamOption -eq 1 ]; then
for url in "$@"; do
stream "$url" "$quality" "$lowLatency"
done
elif [ $shuffleOption -eq 1 ]; then
shuffle "$*"
elif [ $queueOption -eq 1 ]; then
queue "$*"
else
if [ "$*" = "" ]; then
play "$(xclip -o)"
else
for url in "$@"; do
play "$url"
done
fi
fi
+1
View File
@@ -77,6 +77,7 @@ done
pulseTcp()
{
if test "$2" = "off" || test "$2" = "0"; then
echo "Disabling PulseAudio TCP module"
if pactl list modules short | grep -q module-simple-protocol-tcp; then
pactl unload-module module-simple-protocol-tcp
fi
+13 -3
View File
@@ -24,9 +24,18 @@ revert() {
trap revert HUP INT TERM
xset +dpms dpms 30 30 30
# >>> hostname=arch-desktop
radius=92
ringWidth="10.0"
# <<<
# >>> hostname=arch-laptop
# radius=46
# ringWidth="5.0"
# <<<
i3lock -n -i "$LOCK" -B 6 -S 1 -e \
--radius=47 \
--ring-width=5.0 \
--radius="$radius" \
--ring-width="$ringWidth" \
--verif-color=00000000 \
--wrong-color=00000000 \
--time-color=00000000 \
@@ -42,6 +51,7 @@ i3lock -n -i "$LOCK" -B 6 -S 1 -e \
--time-size=64 --date-size=24 \
--time-str="%I:%M %p" --date-str="%A, %B %e" \
--time-pos="ix:iy-250" --date-pos="ix:iy-200" \
--time-color=FFFFFFC0 --date-color=FFFFFFC0
--time-color=FFFFFFC0 --date-color=FFFFFFC0 \
--no-modkey-text
revert
@@ -0,0 +1,7 @@
[Desktop Entry]
Name=Looking Glass (client)
GenericName=Control a VM with PCI pass-through
Exec=looking-glass-client
Icon=find
Type=Application
Terminal=false
+1
View File
@@ -73,3 +73,4 @@ Block YouTube video player loading
- https://www.4chan-x.net/builds/4chan-X.user.js
- https://greasyfork.org/en/scripts/395257-better-google
- https://greasyfork.org/en/scripts/29420-google-dwimages
@@ -42,8 +42,9 @@
}
/* Url bar color */
#urlbar {
#urlbar-background {
background: #404552 !important;
border-radius: 0;
}
/* Hide ... button in URL bar */
@@ -55,13 +56,6 @@
display: none;
}
/* Unzoom URL bar */
#urlbar[breakout-extend] {
top: calc((var(--urlbar-toolbar-height) - var(--urlbar-height)) / 2) !important;
left: calc((var(--urlbar-toolbar-width) - var(--urlbar-width)) / 2) !important;
width: 100% !important;
}
#urlbar[breakout-extend] #urlbar-input-container {
height: calc(var(--tab-min-height) - 3px) !important;
padding: 0px !important;
@@ -13,6 +13,7 @@
#toggleMsgBtn { display: none; }
.adg-rects.desktop { display: none; }
.middlead.center { display: none !important; }
.replacedSideArrows { display: none; }
form[name=post] { display: none; }
hr.aboveMidAd { display: none; }
hr.abovePostForm { display: none; }
@@ -39,6 +40,8 @@
/* Make posts the full width */
.postContainer.replyContainer .post.reply { width: 100% }
.postContainer.replyContainer.yourPost .post.reply { width: calc(100% - 3px); }
.postContainer.replyContainer.quotesYou .post.reply { width: calc(100% - 3px); }
}
@-moz-document domain("github.com") {
@@ -94,12 +97,7 @@
}
/* Hide homepage recommendations */
ytd-rich-grid-renderer {
display: none !important;
}
/* Hide buttons in the top-right */
#masthead #end #buttons > :nth-child(1) {
ytd-two-column-browse-results-renderer[page-subtype="home"] {
display: none !important;
}
+86 -62
View File
@@ -1,30 +1,36 @@
# Dotfiles
#+TITLE: Dotfiles
#+OPTIONS: toc:nil
This is a collection of dotfiles and scripts for my i3 setup, previewed below:
This is a collection of dotfiles and scripts for my i3/bspwm setup, previewed below:
![Screenshot](screenshot.png)
[[screenshot.png]]
### Software:
[[[https://github.com/Riyyi/dotfiles/blob/8d8a21166b106bdb06a5b3e48724c9cd930a7e4b/dotfiles.sh][Archived]]] dotfiles.sh: script to manage dotfiles.
** Software:
All packages that are manually installed via pacman -S, can be found in the packages file,
dependencies are not included.
** Configuration:
### Configuration:
Below are all the system changes that were made.\\
- ~$~ command @@html:<br>@@
- ~<>~ variable @@html:<br>@@
- ~()~ action
Below are all the system changes that were made.<br>
$ = command<br>
<> = variable<br>
() = action
*** Pre-reboot
Boot defaults:
```
#+BEGIN_SRC shell-script
$ vim /boot/loader/loader.conf
timeout 3
default arch
```
#+END_SRC
Boot config:
```
#+BEGIN_SRC shell-script
<uuid> = $ blkid # from the / 'root' partition
$ vim /boot/loader/entries/arch.conf
title Arch Linux
@@ -32,28 +38,47 @@ linux /vmlinuz-linux
initrd /intel-ucode.img
initrd /initramfs-linux.img
options root=PARTUUID=<uuid> rw
```
#+END_SRC
Predictable network interface names:
```
#+BEGIN_SRC shell-script
$ ln -s /dev/null /etc/systemd/network/99-default.link
```
#+END_SRC
Network:
```sh
#+BEGIN_SRC shell-script
$ systemctl enable netctl-auto@wlan0.service
```
$ wifi-menu
#+END_SRC
Trim:
#+BEGIN_SRC shell-script
$ systemctl enable fstrim.timer
#+END_SRC
Give wheel users sudo permission:
```sh
$ vim /etc/sudoers
#+BEGIN_SRC shell-script
$ sudo EDITOR=vim visudo
(add)Defaults insults
(uncomment)%wheel ALL=(ALL) ALL
```
#+END_SRC
Add user:
```sh
$ useradd -m -G wheel -s /bin/bash <username>
$ passwd <username>
```
#+BEGIN_SRC shell-script
$ useradd -m -G wheel -s /bin/bash <user>
$ passwd <user>
#+END_SRC
Pacman colors:
#+BEGIN_SRC shell-script
$ vim /etc/pacman.conf
(uncomment)Color
#+END_SRC
*** Post-reboot:
Installing AUR helper:
```sh
#+BEGIN_SRC shell-script
$ git clone https://aur.archlinux.org/trizen.git
$ cd trizen
$ makepkg -si
@@ -61,58 +86,57 @@ $ cd ..
$ trizen -S trizen
$ rm -rf trizen
```
#+END_SRC
Switch shell to zsh:
```sh
#+BEGIN_SRC shell-script
$ chsh -s /bin/zsh
```
Pacman colors:
```sh
$ vim /etc/pacman.conf
(uncomment)Color
```
#+END_SRC
Git:
```sh
#+BEGIN_SRC shell-script
$ git config --global user.email "<email address>"
$ git config --global user.name "<name>"
```
Tlp:
```sh
$ systemctl enable tlp.service
$ systemctl enable tlp-sleep.service
#+END_SRC
$ vim /etc/default/tlp
Lock before sleep:
#+BEGIN_SRC shell-script
$ sudo systemctl enable i3lock@<user>
#+END_SRC
Tlp:
#+BEGIN_SRC shell-script
$ systemctl enable tlp.service
$ vim /etc/tlp.conf
(edit)SOUND_POWER_SAVE_ON_BAT=0
```
Trim:
```sh
$ systemctl enable fstrim.timer
```
Clock internet sync:
```sh
$ timedatectl set-ntp true
```
#+END_SRC
Mail gpg:
```sh
#+BEGIN_SRC shell-script
$ gpg --decrypt <backup.pgp> | gpg --import
$ gpg --search-keys <email address>
```
Give permission to /dev/ttyUSB0 for PlatformIO:
```sh
#+END_SRC
Give permission to ~/dev/ttyUSB0~ to PlatformIO:
#+BEGIN_SRC shell-script
$ gpasswd -a <user> uucp
```
Give permisson to change brightness for brightnessctl:
```sh
#+END_SRC
Give permissions to change the brightness to brightnessctl:
#+BEGIN_SRC shell-script
$ gpasswd -a <user> input
$ gpasswd -a <user> video
```
#+END_SRC
Set Firefox as default browser:
```sh
#+BEGIN_SRC shell-script
$ xdg-settings set default-web-browser firefox.desktop
```
Prevent bricking motherboard by mounting efivars read-only:<br>
#+END_SRC
Prevent bricking motherboard by mounting efivars read-only:\\
https://wiki.archlinux.org/index.php/Unified_Extensible_Firmware_Interface#Mount_efivarfs
```sh
#+BEGIN_SRC shell-script
$ vim /etc/fstab
(add)efivarfs /sys/firmware/efi/efivars efivarfs ro,nosuid,nodev,noexec,noatime 0 0
```
#+END_SRC
-455
View File
@@ -1,455 +0,0 @@
#!/bin/sh
# Tracks dotfiles and packages
# Depends: GNU getopt, (pacman, pacman-contrib) / (dpkg, apt)
# User-config
# --------------------------------------
# File which holds all installed packages
packageFile="packages"
# Files that are stored in the repository but shouldn't get copied (regex)
excludeFiles="${0#??}|$packageFile|.*.md$|.*README.org$|.git|screenshot.png"
# Directories that are treated like a system directory (/) (regex)
systemDir='boot|etc|usr/share'
# Arch User Repository helper program name (needs pacman flag compatibility!)
aurHelper="trizen"
# --------------------------------------
b="$(tput bold)"
red="$(tput setf 4)"
n="$(tput sgr0)"
if [ "$(dirname "$0")" != "." ]; then
echo "${b}${red}Error:${n} please run this script from the directory it resides." >&2
exit 1
fi
help()
{
(cat << EOF
.TH DOTFILES.SH 1 "2021-08-22" "dotfiles.sh 0.9" "dotfiles.sh Manual"
.SH NAME
dotfiles.sh \- config file and package tracking utility
.SH SYNOPSIS
.B ./dotfiles.sh
.I OPERATION
.RI [ OPTION ...]\&
.RI [ TARGET ...]
.SH DESCRIPTION
dotfiles.sh is a config file and package tracking utility that tracks installed packages on a Linux system.
It features listing and tracking of config files and packages, and the ability to install the tracked packages.
Currently, package tracking is only supported on APT and Pacman based distributions.
Invoking dotfile.sh involves specifying an operation with any potential options and targets to operate on.
A \fItarget\fR is usually a file name, directory or a package name.
Targets can be provided as command line arguments.
Additionally, if a single hyphen (-) is passed as an argument, targets will be read from stdin.
.SH OPERATIONS
.TP
.BR \-F ", " \-\-file
Operate on config files.
This operation allows you to sync config files between the system and the dotfiles directory.
In the first case, if no file names are provided in the command line, all files will be selected.
See File Options below.
.TP
.BR \-P ", " \-\-package
Operate on packages.
This operation allows you to track installed packages and reinstall them.
In the first case, if no package names are provided in the command line, all packages will be selected.
See Package Options below.
.TP
.BR \-h ", " \-\-help
Display usage message and exit.
.SH FILE OPTIONS (APPLY TO -F)
.TP
.BR \-a ", " \-\-add
Add selected file \fIpaths\fR to the dotfiles directory.
.TP
.BR \-l ", " \-\-pull
Pull every (selected) \fIfile\fR from the system to the dotfiles directory.
.TP
.BR \-s ", " \-\-push
Push every (selected) \fIfile\fR from the dotfiles directory to the system.
.SH PACKAGE OPTIONS (APPLY TO -P)
.TP
.BR \-a ", " \-\-aur-install
Install all AUR packages of the stored list.
.TP
.BR \-i ", " \-\-install
Install all official packages of the stored list.
.TP
.BR \-s ", " \-\-store
Stores a list of all installed packages on the system.
.SH EXAMPLES
Usage examples:
$ \fB./dotfiles.sh\fR -Fa ~/.zshrc /etc/zsh/zshenv
.br
\h'4'Add config files to the dotfiles directory
$ \fB./dotfiles.sh\fR -Pia
.br
\h'4'Install all tracked official and AUR packages
.SH AUTHOR
Riyyi
EOF
) | man -l -
}
# Exit if no option is provided
[ "$#" -eq 0 ] && help && exit 1
# Files
# --------------------------------------
getFileList()
{
fileList="$(find . -type f -o -type l \
| awk -v e="^./($excludeFiles)" '$0 !~ e { print $0 }')"
}
separateFileList()
{
[ -z "$fileList" ] && getFileList
match="^./($systemDir)/"
# Filter system directories and remove leading ./ from filepaths
homeFileList="$(echo "$fileList" \
| awk -v m="$match" '$0 !~ m { print substr($0, 3) }')"
# Filter non-system directories and remove leading ./ from filepaths
systemFileList="$(echo "$fileList" \
| awk -v m="$match" '$0 ~ m { print substr($0, 3) }')"
}
filterFileList()
{
if [ -z "$homeFileList" ] || [ -z "$systemFileList" ]; then
separateFileList
fi
# Filter on provided file name
homeFileListLoop="$(echo "$homeFileList" | grep "^$1")"
systemFileListLoop="$(echo "$systemFileList" | grep "^$1")"
}
fileAdd()
{
[ -z "$1" ] && exit 1
file="$(readlink -f "$(dirname "$1")")/$(basename "$1")"
fileCutHome="$(echo "$file" \
| awk -v m="^$HOME/" '$0 ~ m { print substr($0, length(m)) }')"
# /home/<user>/
if [ -n "$fileCutHome" ]; then
mkdir -p "$(pwd)/$(dirname "$fileCutHome")"
cp -a "$file" "$(pwd)/$(dirname "$fileCutHome")"
# /
else
sudo mkdir -p "$(pwd)/$(dirname "$file")"
sudo cp -a "$file" "$(pwd)/$(dirname "$file")"
fi
}
filePull()
{
filterFileList "$1"
for file in $homeFileListLoop; do
# /home/<user>/<file> -> dotfiles/<file>
cp -a "$HOME/$file" "$(pwd)/$file"
done
for file in $systemFileListLoop; do
# /<file> -> dotfiles/<file>
sudo cp -a "/$file" "$(pwd)/$file"
done
}
filePush()
{
filterFileList "$1"
for file in $homeFileListLoop; do
# dotfiles/<file> -> /home/<user>/<file>
mkdir -p "$(dirname "$HOME/$file")"
cp -a "$(pwd)/$file" "$HOME/$file"
done
for file in $systemFileListLoop; do
# dotfiles/<file> -> /<file>
sudo mkdir -p "$(dirname "/$file")"
sudo cp -a "$(pwd)/$file" "/$file"
done
}
files()
{
if [ "$1" = "list" ] || [ "$1" = "" ]; then
[ -z "$fileList" ] && getFileList
# Remove leading ./ from filepaths
echo "$fileList" | sed 's/^\.\///' | grep "$2"
elif [ "$1" = "add" ]; then
fileAdd "$2"
elif [ "$1" = "pull" ]; then
filePull "$2"
elif [ "$1" = "push" ]; then
filePush "$2"
fi
}
# Packages
# --------------------------------------
osDetect()
{
id="$(sed -nE 's/^ID=(.*)/\1/p' /etc/os-release)"
idLike="$(sed -nE 's/^ID_LIKE=(.*)/\1/p' /etc/os-release)"
if [ "$id" = "arch" ]; then
os="arch"
elif echo "$idLike" | grep -q 'arch'; then
os="arch"
elif [ "$id" = "debian" ] || [ "$id" = "ubuntu" ]; then
os="debian"
elif echo "$idLike" | grep -q 'debian'; then
os="debian"
elif echo "$idLike" | grep -q 'ubuntu'; then
os="debian"
else
echo "${b}${red}Error:${n} unsupported operating system." >&2
exit 1
fi
}
osDependencies()
{
if [ "$os" = "arch" ]; then
binaryDependencyPair="
pacman:pacman
pactree:pacman-contrib
"
elif [ "$os" = "debian" ]; then
binaryDependencyPair="
apt-cache:apt
apt-mark:apt
dpkg-query:dpkg
"
fi
for pair in $binaryDependencyPair; do
binary="$(echo "$pair" | cut -d ':' -f 1)"
if ! command -v "$binary" > /dev/null; then
dependency="$(echo "$pair" | cut -d ':' -f 2)"
echo "${b}${red}Error:${n} required dependency '$dependency' is missing." >&2
exit 1
fi
done
}
getPackageList()
{
if [ "$os" = "arch" ]; then
filterList="$( (pacman -Qqg base base-devel; pactree -u base | tail -n +2) | sort)"
packageList="$(pacman -Qqe | grep -vx "$filterList" | sort)"
elif [ "$os" = "debian" ]; then
installedList="$(dpkg-query --show --showformat='${Package}\t${Priority}\n')"
filterList="$(echo "$installedList" | grep -E 'required|important|standard' | cut -f 1)"
installedList="$(echo "$installedList" | cut -f 1)"
installedManuallyList="$(awk '/Commandline:.* install / && !/APT::/ { print $NF }' /var/log/apt/history.log)"
installedManuallyList="$( (echo "$installedManuallyList"; apt-mark showmanual) | sort -u)"
packageList="$(echo "$installedManuallyList" | grep -x "$installedList" | grep -vx "$filterList")"
fi
}
packageInstall()
{
if [ "$os" = "arch" ]; then
# Grab everything off enabled official repositories that is in the list
repoList="$(pacman -Ssq | grep -xf $packageFile)"
if [ "$1" = "aur-install" ]; then
# Determine which packages in the list are from the AUR
aurList="$(grep -vx "$repoList" < $packageFile)"
# Install AUR packages
echo "$aurList" | xargs --open-tty "$aurHelper" -Sy --needed --noconfirm
elif [ "$1" = "install" ]; then
# Install packages
echo "$repoList" | xargs --open-tty sudo pacman -Sy --needed
fi
elif [ "$os" = "debian" ]; then
# Grab everything off enabled official repositories that is in the list
repoList="$(apt-cache search .* | cut -d ' ' -f 1 | grep -xf $packageFile)"
# Install packages
echo "$repoList" | xargs --open-tty sudo apt install
fi
}
packages()
{
# If unset
if [ -z "$os" ]; then
osDetect
osDependencies
fi
if [ "$1" = "list" ] || [ "$1" = "" ]; then
[ -z "$packageList" ] && getPackageList
echo "$packageList" | grep "$2"
elif [ "$1" = "store" ]; then
[ -z "$packageList" ] && getPackageList
echo "$packageList" > "$packageFile"
elif [ "$1" = "aur-install" ]; then
packageInstall "aur-install"
elif [ "$1" = "install" ]; then
packageInstall "install"
fi
}
# Option parsing
# --------------------------------------
script="$(basename "$0")"
parsed="$(getopt --options "hFPails" \
--longoptions "help,file,package,add,aur-install,install,pull,push,store" \
-n "$script" -- "$@" 2>&1)"
result="$?"
# Exit if invalid option is provided
if [ "$result" -ne 0 ]; then
echo "$parsed" | head -n 1 >&2
echo "Try './$script --help' for more information." >&2
exit 1
fi
eval set -- "$parsed"
while true; do
case "$1" in
-h | --help)
help
exit
;;
-F | --file)
if [ -n "$mode" ]; then
echo "${b}${red}Error:${n} only one operation may be used at a time." >&2
exit 1
fi
mode="file"
shift
;;
-P | --package)
if [ -n "$mode" ]; then
echo "${b}${red}Error:${n} only one operation may be used at a time." >&2
exit 1
fi
mode="package"
shift
;;
-a | --add | --aur-install)
[ "$mode" = "file" ] && options="${options}add "
[ "$mode" = "package" ] && options="${options}aur-install "
shift
;;
-i | --install)
options="${options}install "
shift
;;
-l | --pull)
options="${options}pull "
shift
;;
-s | --push | --store)
[ "$mode" = "file" ] && options="${options}push "
[ "$mode" = "package" ] && options="${options}store "
shift
;;
--)
shift
break
;;
*)
break
;;
esac
done
# Target parsing
# --------------------------------------
targets="$*"
targetsNoHyphen="$(echo "$targets" | sed -E 's/(^-$|\s-|-\s)//g; s/(\s-\s)/ /;')"
# Read targets from stdin
if [ "$targets" != "$targetsNoHyphen" ]; then
if [ -t 0 ]; then
echo "${b}${red}Error:${n} argument '-' specified without input on stdin." >&2
exit 1
fi
eval set -- "$targetsNoHyphen $(cat /dev/stdin)"
fi
# Execute
# --------------------------------------
if [ -z "$mode" ]; then
echo "${b}${red}Error:${n} no operation specified (use -h for help)" >&2
exit 1
fi
if [ "$mode" = "file" ]; then
if [ -z "$options" ]; then
files "list" "$@"
exit
fi
for option in $options; do
if [ -z "$*" ]; then
if [ "$option" = "add" ];then
echo "${b}${red}Error:${n} no files or directories selected to add." >&2
exit 1
fi
files "$option"
continue
fi
for path; do
files "$option" "$path"
done
done
fi
if [ "$mode" = "package" ]; then
if [ -z "$options" ]; then
packages "list" "$@"
exit
fi
for option in $options; do
packages "$option"
done
fi
+47
View File
@@ -0,0 +1,47 @@
# This file is part of systemd.
#
# systemd is free software; you can redistribute it and/or modify it under the
# terms of the GNU Lesser General Public License as published by the Free
# Software Foundation; either version 2.1 of the License, or (at your option)
# any later version.
#
# Entries in this file show the compile time defaults. Local configuration
# should be created by either modifying this file, or by creating "drop-ins" in
# the journald.conf.d/ subdirectory. The latter is generally recommended.
# Defaults can be restored by simply deleting this file and all drop-ins.
#
# Use 'systemd-analyze cat-config systemd/journald.conf' to display the full config.
#
# See journald.conf(5) for details.
[Journal]
#Storage=auto
#Compress=yes
#Seal=yes
#SplitMode=uid
#SyncIntervalSec=5m
#RateLimitIntervalSec=30s
#RateLimitBurst=10000
SystemMaxUse=256M
#SystemKeepFree=
#SystemMaxFileSize=
#SystemMaxFiles=100
#RuntimeMaxUse=
#RuntimeKeepFree=
#RuntimeMaxFileSize=
#RuntimeMaxFiles=100
#MaxRetentionSec=
MaxFileSec=2week
#ForwardToSyslog=no
#ForwardToKMsg=no
#ForwardToConsole=no
#ForwardToWall=yes
#TTYPath=/dev/console
#MaxLevelStore=debug
#MaxLevelSyslog=debug
#MaxLevelKMsg=notice
#MaxLevelConsole=info
#MaxLevelWall=emerg
#LineMax=48K
#ReadKMsg=yes
#Audit=yes
+2 -2
View File
@@ -7,7 +7,7 @@
#
# Entries in this file show the compile time defaults. Local configuration
# should be created by either modifying this file, or by creating "drop-ins" in
# the login.conf.d/ subdirectory. The latter is generally recommended.
# the logind.conf.d/ subdirectory. The latter is generally recommended.
# Defaults can be restored by simply deleting this file and all drop-ins.
#
# Use 'systemd-analyze cat-config systemd/logind.conf' to display the full config.
@@ -39,7 +39,7 @@ HandlePowerKey=ignore
#IdleAction=ignore
#IdleActionSec=30min
#RuntimeDirectorySize=10%
#RuntimeDirectoryInodes=400k
#RuntimeDirectoryInodesMax=400k
#RemoveIPC=yes
#InhibitorsMax=8192
#SessionsMax=8192
+586
View File
@@ -0,0 +1,586 @@
# ------------------------------------------------------------------------------
# /etc/tlp.conf - TLP user configuration (version 1.7.0)
# See full explanation: https://linrunner.de/tlp/settings
#
# Copyright (c) 2024 Thomas Koch <linrunner at gmx.net> and others.
# SPDX-License-Identifier: GPL-2.0-or-later
#
# Settings are read in the following order:
#
# 1. Intrinsic defaults
# 2. /etc/tlp.d/*.conf - Drop-in customization snippets
# 3. /etc/tlp.conf - User configuration (this file)
#
# Notes:
# - In case of identical parameters, the last occurence has precedence
# - This also means, parameters enabled here will override anything else
# - However you may append values to a parameter already defined as intrinsic
# default or in a previously read file: use PARAMETER+="add values"
# - IMPORTANT: all parameters here are disabled; remove the leading '#' if you
# like to enable a feature without default or have a value different from the
# default
# - Default *: intrinsic default that is effective when the parameter is missing
# or disabled by a leading '#'; use PARAM="" to disable an intrinsic default
# - Default <none>: do nothing or use kernel/hardware defaults
# - IMPORTANT: parameters must always be specified pairwise i.e. for
# both AC and BAT. Omitting one of the two makes the set value effective for
# both power sources, since a change only occurs when different values are
# defined.
# ------------------------------------------------------------------------------
# tlp - Parameters for power saving
# Set to 0 to disable, 1 to enable TLP.
# Default: 1
#TLP_ENABLE=1
# Control how warnings about invalid settings are issued:
# 0=disabled,
# 1=background tasks (boot, resume, change of power source) report to syslog,
# 2=shell commands report to the terminal (stderr),
# 3=combination of 1 and 2
# Default: 3
#TLP_WARN_LEVEL=3
# Colorize error, warning, notice and success messages. Colors are specified
# with ANSI codes:
# 1=bold black, 90=grey, 91=red, 92=green, 93=yellow, 94=blue, 95=magenta,
# 96=cyan, 97=white.
# Other colors are possible, refer to:
# https://en.wikipedia.org/wiki/ANSI_escape_code#3-bit_and_4-bit
# Colors must be specified in the order "<error> <warning> <notice> <success>".
# By default, errors are shown in red, warnings in yellow, notices in bold
# and success in green.
# Default: "91 93 1 92"
#TLP_MSG_COLORS="91 93 1 92"
# Operation mode when no power supply can be detected: AC, BAT.
# Concerns some desktop and embedded hardware only.
# Default: <none>
#TLP_DEFAULT_MODE=AC
# Operation mode select: 0=depend on power source, 1=always use TLP_DEFAULT_MODE
# Note: use in conjunction with TLP_DEFAULT_MODE=BAT for BAT settings on AC.
# Default: 0
#TLP_PERSISTENT_DEFAULT=0
# Power supply classes to ignore when determining operation mode: AC, USB, BAT.
# Separate multiple classes with spaces.
# Note: try on laptops where operation mode AC/BAT is incorrectly detected.
# Default: <none>
#TLP_PS_IGNORE="BAT"
# Seconds laptop mode has to wait after the disk goes idle before doing a sync.
# Non-zero value enables, zero disables laptop mode.
# Default: 0 (AC), 2 (BAT)
#DISK_IDLE_SECS_ON_AC=0
#DISK_IDLE_SECS_ON_BAT=2
# Dirty page values (timeouts in secs).
# Default: 15 (AC), 60 (BAT)
#MAX_LOST_WORK_SECS_ON_AC=15
#MAX_LOST_WORK_SECS_ON_BAT=60
# Select a CPU scaling driver operation mode.
# Intel CPU with intel_pstate driver:
# active, passive.
# AMD Zen 2 or newer CPU with amd-pstate driver as of kernel 6.3/6.4(*):
# active, passive, guided(*).
# Default: <none>
#CPU_DRIVER_OPMODE_ON_AC=active
#CPU_DRIVER_OPMODE_ON_BAT=active
# Select a CPU frequency scaling governor.
# Intel CPU with intel_pstate driver or
# AMD CPU with amd-pstate driver in active mode ('amd-pstate-epp'):
# performance, powersave(*).
# Intel CPU with intel_pstate driver in passive mode ('intel_cpufreq') or
# AMD CPU with amd-pstate driver in passive or guided mode ('amd-pstate') or
# Intel, AMD and other CPU brands with acpi-cpufreq driver:
# conservative, ondemand(*), userspace, powersave, performance, schedutil(*).
# Use tlp-stat -p to show the active driver and available governors.
# Important:
# Governors marked (*) above are power efficient for *almost all* workloads
# and therefore kernel and most distributions have chosen them as defaults.
# You should have done your research about advantages/disadvantages *before*
# changing the governor.
# Default: <none>
#CPU_SCALING_GOVERNOR_ON_AC=powersave
#CPU_SCALING_GOVERNOR_ON_BAT=powersave
# Set the min/max frequency available for the scaling governor.
# Possible values depend on your CPU. For available frequencies see
# the output of tlp-stat -p.
# Notes:
# - Min/max frequencies must always be specified for both AC *and* BAT
# - Not recommended for use with the intel_pstate driver, use
# CPU_MIN/MAX_PERF_ON_AC/BAT below instead
# Default: <none>
#CPU_SCALING_MIN_FREQ_ON_AC=0
#CPU_SCALING_MAX_FREQ_ON_AC=0
#CPU_SCALING_MIN_FREQ_ON_BAT=0
#CPU_SCALING_MAX_FREQ_ON_BAT=0
# Set CPU energy/performance policies EPP and EPB:
# performance, balance_performance, default, balance_power, power.
# Values are given in order of increasing power saving.
# Requires:
# * Intel CPU
# EPP: Intel Core i 6th gen. or newer CPU with intel_pstate driver
# EPB: Intel Core i 2nd gen. or newer CPU with intel_pstate driver
# EPP and EPB are mutually exclusive: when EPP is available, Intel CPUs
# will not honor EPB. Only the matching feature will be applied by TLP.
# * AMD Zen 2 or newer CPU
# EPP: amd-pstate driver in active mode ('amd-pstate-epp') as of kernel 6.3
# Default: balance_performance (AC), balance_power (BAT)
#CPU_ENERGY_PERF_POLICY_ON_AC=balance_performance
#CPU_ENERGY_PERF_POLICY_ON_BAT=balance_power
# Set Intel CPU P-state performance: 0..100 (%).
# Limit the max/min P-state to control the power dissipation of the CPU.
# Values are stated as a percentage of the available performance.
# Requires Intel Core i 2nd gen. or newer CPU with intel_pstate driver.
# Default: <none>
#CPU_MIN_PERF_ON_AC=0
#CPU_MAX_PERF_ON_AC=100
#CPU_MIN_PERF_ON_BAT=0
#CPU_MAX_PERF_ON_BAT=30
# Set the CPU "turbo boost" (Intel) or "turbo core" (AMD) feature:
# 0=disable, 1=allow.
# Allows to raise the maximum frequency/P-state of some cores if the
# CPU chip is not fully utilized and below it's intended thermal budget.
# Note: a value of 1 does *not* activate boosting, it just allows it.
# Default: <none>
#CPU_BOOST_ON_AC=1
#CPU_BOOST_ON_BAT=0
# Set CPU dynamic boost feature:
# 0=disable, 1=enable.
# Improve performance by increasing minimum P-state limit dynamically
# whenever a task previously waiting on I/O is selected to run.
# Requires Intel Core i 6th gen. or newer CPU: intel_pstate driver in active mode.
# Note: AMD CPUs currently have no tunable for this.
# Default: <none>
#CPU_HWP_DYN_BOOST_ON_AC=1
#CPU_HWP_DYN_BOOST_ON_BAT=0
# Kernel NMI Watchdog:
# 0=disable (default, saves power), 1=enable (for kernel debugging only).
# Default: 0
#NMI_WATCHDOG=0
# Select platform profile:
# performance, balanced, low-power.
# Controls system operating characteristics around power/performance levels,
# thermal and fan speed. Values are given in order of increasing power saving.
# Note: check the output of tlp-stat -p to determine availability on your
# hardware and additional profiles such as: balanced-performance, quiet, cool.
# Default: <none>
#PLATFORM_PROFILE_ON_AC=performance
#PLATFORM_PROFILE_ON_BAT=low-power
# System suspend mode:
# s2idle: Idle standby - a pure software, light-weight, system sleep state,
# deep: Suspend to RAM - the whole system is put into a low-power state,
# except for memory, usually resulting in higher savings than s2idle.
# CAUTION: changing suspend mode may lead to system instability and even
# data loss. As for the availability of different modes on your system,
# check the output of tlp-stat -s. If unsure, stick with the system default
# by not enabling this.
# Default: <none>
#MEM_SLEEP_ON_AC=s2idle
#MEM_SLEEP_ON_BAT=deep
# Define disk devices on which the following DISK/AHCI_RUNTIME parameters act.
# Separate multiple devices with spaces.
# Devices can be specified by disk ID also (lookup with: tlp diskid).
# Default: "nvme0n1 sda"
#DISK_DEVICES="nvme0n1 sda"
# Disk advanced power management level: 1..254, 255 (max saving, min, off).
# Levels 1..127 may spin down the disk; 255 allowable on most drives.
# Separate values for multiple disks with spaces. Use the special value 'keep'
# to keep the hardware default for the particular disk.
# Default: 254 (AC), 128 (BAT)
#DISK_APM_LEVEL_ON_AC="254 254"
#DISK_APM_LEVEL_ON_BAT="128 128"
# Exclude disk classes from advanced power management (APM):
# sata, ata, usb, ieee1394.
# Separate multiple classes with spaces.
# CAUTION: USB and IEEE1394 disks may fail to mount or data may get corrupted
# with APM enabled. Be careful and make sure you have backups of all affected
# media before removing 'usb' or 'ieee1394' from the denylist!
# Default: "usb ieee1394"
#DISK_APM_CLASS_DENYLIST="usb ieee1394"
# Hard disk spin down timeout:
# 0: spin down disabled
# 1..240: timeouts from 5s to 20min (in units of 5s)
# 241..251: timeouts from 30min to 5.5 hours (in units of 30min)
# See 'man hdparm' for details.
# Separate values for multiple disks with spaces. Use the special value 'keep'
# to keep the hardware default for the particular disk.
# Default: <none>
#DISK_SPINDOWN_TIMEOUT_ON_AC="0 0"
#DISK_SPINDOWN_TIMEOUT_ON_BAT="0 0"
# Select I/O scheduler for the disk devices.
# Multi queue (blk-mq) schedulers:
# mq-deadline(*), none, kyber, bfq
# Single queue schedulers:
# deadline(*), cfq, bfq, noop
# (*) recommended.
# Separate values for multiple disks with spaces. Use the special value 'keep'
# to keep the kernel default scheduler for the particular disk.
# Notes:
# - Multi queue (blk-mq) may need kernel boot option 'scsi_mod.use_blk_mq=1'
# and 'modprobe mq-deadline-iosched|kyber|bfq' on kernels < 5.0
# - Single queue schedulers are legacy now and were removed together with
# the old block layer in kernel 5.0
# Default: keep
#DISK_IOSCHED="mq-deadline mq-deadline"
# AHCI link power management (ALPM) for SATA disks:
# min_power, med_power_with_dipm(*), medium_power, max_performance.
# (*) recommended.
# Multiple values separated with spaces are tried sequentially until success.
# Default: med_power_with_dipm (AC & BAT)
#SATA_LINKPWR_ON_AC="med_power_with_dipm"
#SATA_LINKPWR_ON_BAT="med_power_with_dipm"
# Exclude SATA links from AHCI link power management (ALPM).
# SATA links are specified by their host. Refer to the output of
# tlp-stat -d to determine the host; the format is "hostX".
# Separate multiple hosts with spaces.
# Default: <none>
#SATA_LINKPWR_DENYLIST="host1"
# Runtime Power Management for NVMe, SATA, ATA and USB disks
# as well as SATA ports:
# on=disable, auto=enable.
# Note: SATA controllers are PCIe bus devices and handled by RUNTIME_PM further
# down.
# Default: on (AC), auto (BAT)
#AHCI_RUNTIME_PM_ON_AC=on
#AHCI_RUNTIME_PM_ON_BAT=auto
# Seconds of inactivity before disk is suspended.
# Note: effective only when AHCI_RUNTIME_PM_ON_AC/BAT is activated.
# Default: 15
#AHCI_RUNTIME_PM_TIMEOUT=15
# Power off optical drive in UltraBay/MediaBay: 0=disable, 1=enable.
# Drive can be powered on again by releasing (and reinserting) the eject lever
# or by pressing the disc eject button on newer models.
# Note: an UltraBay/MediaBay hard disk is never powered off.
# Default: 0
#BAY_POWEROFF_ON_AC=0
#BAY_POWEROFF_ON_BAT=0
# Optical drive device to power off
# Default: sr0
#BAY_DEVICE="sr0"
# Set the min/max/turbo frequency for the Intel GPU.
# Possible values depend on your hardware. For available frequencies see
# the output of tlp-stat -g.
# Default: <none>
#INTEL_GPU_MIN_FREQ_ON_AC=0
#INTEL_GPU_MIN_FREQ_ON_BAT=0
#INTEL_GPU_MAX_FREQ_ON_AC=0
#INTEL_GPU_MAX_FREQ_ON_BAT=0
#INTEL_GPU_BOOST_FREQ_ON_AC=0
#INTEL_GPU_BOOST_FREQ_ON_BAT=0
# AMD GPU power management.
# Performance level (DPM): auto, low, high; auto is recommended.
# Note: requires amdgpu or radeon driver.
# Default: auto
#RADEON_DPM_PERF_LEVEL_ON_AC=auto
#RADEON_DPM_PERF_LEVEL_ON_BAT=auto
# Dynamic power management method (DPM): balanced, battery, performance.
# Note: radeon driver only.
# Default: <none>
#RADEON_DPM_STATE_ON_AC=performance
#RADEON_DPM_STATE_ON_BAT=battery
# Graphics clock speed (profile method): low, mid, high, auto, default;
# auto = mid on BAT, high on AC.
# Note: radeon driver on legacy ATI hardware only (where DPM is not available).
# Default: default
#RADEON_POWER_PROFILE_ON_AC=default
#RADEON_POWER_PROFILE_ON_BAT=default
# Display panel adaptive backlight modulation (ABM) level: 0(off), 1..4.
# Values 1..4 control the maximum brightness reduction allowed by the ABM
# algorithm, where 1 represents the least and 4 the most power saving.
# Notes:
# - Requires AMD Vega or newer GPU with amdgpu driver as of kernel 6.9
# - Savings are made at the expense of color balance
# Default: 0 (AC), 1 (BAT)
#AMDGPU_ABM_LEVEL_ON_AC=0
#AMDGPU_ABM_LEVEL_ON_BAT=3
# Wi-Fi power saving mode: on=enable, off=disable.
# Default: off (AC), on (BAT)
#WIFI_PWR_ON_AC=off
#WIFI_PWR_ON_BAT=on
# Disable Wake-on-LAN: Y/N.
# Default: Y
#WOL_DISABLE=Y
# Enable audio power saving for Intel HDA, AC97 devices (timeout in secs).
# A value of 0 disables, >= 1 enables power saving.
# Note: 1 is recommended for Linux desktop environments with PulseAudio,
# systems without PulseAudio may require 10.
# Default: 1
# >>> hostname=arch-desktop
SOUND_POWER_SAVE_ON_AC=1
SOUND_POWER_SAVE_ON_BAT=1
# <<<
# >>> hostname=arch-laptop
# SOUND_POWER_SAVE_ON_AC=0
# SOUND_POWER_SAVE_ON_BAT=0
# <<<
# Disable controller too (HDA only): Y/N.
# Note: effective only when SOUND_POWER_SAVE_ON_AC/BAT is activated.
# Default: Y
#SOUND_POWER_SAVE_CONTROLLER=Y
# PCIe Active State Power Management (ASPM):
# default(*), performance, powersave, powersupersave.
# (*) keeps BIOS ASPM defaults (recommended)
# Default: <none>
#PCIE_ASPM_ON_AC=default
#PCIE_ASPM_ON_BAT=default
# Runtime Power Management for PCIe bus devices: on=disable, auto=enable.
# Default: on (AC), auto (BAT)
#RUNTIME_PM_ON_AC=on
#RUNTIME_PM_ON_BAT=auto
# Exclude listed PCIe device adresses from Runtime PM.
# Note: this preserves the kernel driver default, to force a certain state
# use RUNTIME_PM_ENABLE/DISABLE instead.
# Separate multiple addresses with spaces.
# Use lspci to get the adresses (1st column).
# Default: <none>
#RUNTIME_PM_DENYLIST="11:22.3 44:55.6"
# Exclude PCIe devices assigned to the listed drivers from Runtime PM.
# Note: this preserves the kernel driver default, to force a certain state
# use RUNTIME_PM_ENABLE/DISABLE instead.
# Separate multiple drivers with spaces.
# Default: "mei_me nouveau radeon xhci_hcd", use "" to disable completely.
#RUNTIME_PM_DRIVER_DENYLIST="mei_me nouveau radeon xhci_hcd"
# Permanently enable/disable Runtime PM for listed PCIe device addresses
# (independent of the power source). This has priority over all preceding
# Runtime PM settings. Separate multiple addresses with spaces.
# Use lspci to get the adresses (1st column).
# Default: <none>
#RUNTIME_PM_ENABLE="11:22.3"
#RUNTIME_PM_DISABLE="44:55.6"
# Set to 0 to disable, 1 to enable USB autosuspend feature.
# Default: 1
#USB_AUTOSUSPEND=1
# Exclude listed devices from USB autosuspend (separate with spaces).
# Use lsusb to get the ids.
# Note: input devices (usbhid) and libsane-supported scanners are excluded
# automatically.
# Default: <none>
#USB_DENYLIST="1111:2222 3333:4444"
# Exclude audio devices from USB autosuspend:
# 0=do not exclude, 1=exclude.
# Default: 1
#USB_EXCLUDE_AUDIO=1
# Exclude bluetooth devices from USB autosuspend:
# 0=do not exclude, 1=exclude.
# Default: 0
#USB_EXCLUDE_BTUSB=0
# Exclude phone devices from USB autosuspend:
# 0=do not exclude, 1=exclude (enable charging).
# Default: 0
#USB_EXCLUDE_PHONE=0
# Exclude printers from USB autosuspend:
# 0=do not exclude, 1=exclude.
# Default: 1
#USB_EXCLUDE_PRINTER=1
# Exclude WWAN devices from USB autosuspend:
# 0=do not exclude, 1=exclude.
# Default: 0
#USB_EXCLUDE_WWAN=0
# Allow USB autosuspend for listed devices even if already denylisted or
# excluded above (separate with spaces). Use lsusb to get the ids.
# Default: 0
#USB_ALLOWLIST="1111:2222 3333:4444"
# Restore radio device state (Bluetooth, WiFi, WWAN) from previous shutdown
# on system startup: 0=disable, 1=enable.
# Note: the parameters DEVICES_TO_DISABLE/ENABLE_ON_STARTUP/SHUTDOWN below
# are ignored when this is enabled.
# Default: 0
#RESTORE_DEVICE_STATE_ON_STARTUP=0
# Radio devices to disable on startup: bluetooth, nfc, wifi, wwan.
# Separate multiple devices with spaces.
# Default: <none>
#DEVICES_TO_DISABLE_ON_STARTUP="bluetooth nfc wifi wwan"
# Radio devices to enable on startup: bluetooth, nfc, wifi, wwan.
# Separate multiple devices with spaces.
# Default: <none>
#DEVICES_TO_ENABLE_ON_STARTUP="wifi"
# Radio devices to enable on AC: bluetooth, nfc, wifi, wwan.
# Default: <none>
#DEVICES_TO_ENABLE_ON_AC="bluetooth nfc wifi wwan"
# Radio devices to disable on battery: bluetooth, nfc, wifi, wwan.
# Default: <none>
#DEVICES_TO_DISABLE_ON_BAT="bluetooth nfc wifi wwan"
# Radio devices to disable on battery when not in use (not connected):
# bluetooth, nfc, wifi, wwan.
# Default: <none>
#DEVICES_TO_DISABLE_ON_BAT_NOT_IN_USE="bluetooth nfc wifi wwan"
# Battery Care -- Charge thresholds
# Charging starts when the charger is connected and the charge level
# is below the start threshold. Charging stops when the charge level
# is above the stop threshold.
# Required hardware: Lenovo ThinkPads and select other laptop brands
# are driven via specific plugins
# - Active plugin and support status are shown by tlp-stat -b
# - Vendor specific threshold levels are shown by tlp-stat -b, some
# laptops support only 1 (on)/ 0 (off) instead of a percentage level
# - When your hardware supports a start *and* a stop threshold, you must
# specify both, otherwise TLP will refuse to apply the single threshold
# - When your hardware supports only a stop threshold, set the start
# value to 0
# - Older ThinkPads may require an external kernel module, refer to the
# output of tlp-stat -b
# For further explanation and vendor specific details refer to
# - https://linrunner.de/tlp/settings/battery.html
# - https://linrunner.de/tlp/settings/bc-vendors.html
# BAT0: Primary / Main / Internal battery
# Note: also use for batteries BATC, BATT and CMB0
# Default: <none>
# Battery charge level below which charging will begin.
#START_CHARGE_THRESH_BAT0=75
# Battery charge level above which charging will stop.
#STOP_CHARGE_THRESH_BAT0=80
# BAT1: Secondary / Ultrabay / Slice / Replaceable battery
# Note: primary on some laptops
# Default: <none>
# Battery charge level below which charging will begin.
#START_CHARGE_THRESH_BAT1=75
# Battery charge level above which charging will stop.
#STOP_CHARGE_THRESH_BAT1=80
# Restore charge thresholds when AC is unplugged: 0=disable, 1=enable.
# Default: 0
#RESTORE_THRESHOLDS_ON_BAT=1
# ------------------------------------------------------------------------------
# tlp-rdw - Parameters for the radio device wizard
# Possible devices: bluetooth, wifi, wwan.
# Separate multiple radio devices with spaces.
# Default: <none> (for all parameters below)
# Radio devices to disable on connect.
#DEVICES_TO_DISABLE_ON_LAN_CONNECT="wifi wwan"
#DEVICES_TO_DISABLE_ON_WIFI_CONNECT="wwan"
#DEVICES_TO_DISABLE_ON_WWAN_CONNECT="wifi"
# Radio devices to enable on disconnect.
#DEVICES_TO_ENABLE_ON_LAN_DISCONNECT="wifi wwan"
#DEVICES_TO_ENABLE_ON_WIFI_DISCONNECT=""
#DEVICES_TO_ENABLE_ON_WWAN_DISCONNECT=""
# Radio devices to enable/disable when docked.
#DEVICES_TO_ENABLE_ON_DOCK=""
#DEVICES_TO_DISABLE_ON_DOCK=""
# Radio devices to enable/disable when undocked.
#DEVICES_TO_ENABLE_ON_UNDOCK="wifi"
#DEVICES_TO_DISABLE_ON_UNDOCK=""
+12 -4
View File
@@ -9,6 +9,7 @@ arc-icon-theme
aria2
aspell-en
aspell-nl
autorandr
base
brightnessctl
bspwm
@@ -29,7 +30,7 @@ dunst
ebtables
edk2-ovmf
efibootmgr
emacs
emacs-nativecomp
evtest
exfat-utils
feh
@@ -53,6 +54,9 @@ gvfs-gphoto2
gvfs-mtp
gvim
htop
hunspell
hunspell-en_us
hunspell-nl
i3lock-color-git
imagemagick
inetutils
@@ -90,6 +94,7 @@ lua-language-server-git
lvm2
lxappearance
maim
manafiles-git
man-db
man-pages
mariadb
@@ -106,6 +111,7 @@ ncdu
neofetch
nerd-fonts-dejavu-complete
netctl
nlohmann-json
nodejs-intelephense
ntfs-3g
openssh
@@ -140,10 +146,12 @@ python-zstandard
qbittorrent
qemu
qemu-arch-extra
qt5ct
qt5-serialport
qt5-styleplugins
qt5-tools
qt5ct
qt5gtk2
qt6ct
qt6gtk2
r
redshift
reflector
@@ -154,6 +162,7 @@ rtmpdump
rxvt-unicode
signal-desktop
smartmontools
socat
sqlitebrowser
sshfs
stalonetray
@@ -214,7 +223,6 @@ xorg-xinput
xorg-xprop
xorg-xrandr
xorg-xsetroot
xss-lock
yt-dlp
yt-dlp-drop-in
zathura
+33
View File
@@ -0,0 +1,33 @@
#!/bin/sh
# fiio - systemd suspend/resume hook
#
# Disable FiiO DAC when going to sleep.
# Usb vendor/product ID found using lsusb.
#
# Reference:
# https://bbs.archlinux.org/viewtopic.php?id=242633
id="262a:100e"
file="/tmp/systemd-system-sleep-fiio"
case $1 in
pre)
device=$(tree /sys | grep -i "usb.*$id" | sed -E '1s/.*\/(.*):[0-9]\.[0-9].*/\1/;2,$d')
# Bail if device isnt connected
[ -z "$device" ] && exit 1
echo "Suspending device [FiiO USB DAC E17K] on usb $device"
echo "$device" > "$file"
echo "$device" > /sys/bus/usb/drivers/usb/unbind
;;
post)
# Bail if device isnt connected
[ ! -f "$file" ] && exit 1
echo "Resuming device [FiiO USB DAC E17K] on usb $(cat file)"
cat "$file" > /sys/bus/usb/drivers/usb/bind
rm "$file"
;;
esac
+19
View File
@@ -0,0 +1,19 @@
# -*- conf -*-
[Unit]
Description=Lock the screen with i3lock
Before=sleep.target
[Service]
User=%I
Type=forking
Environment=DISPLAY=:0
Environment=XDG_CACHE_HOME=/home/%I/.cache
ExecStart=/bin/setsid -f /home/%I/.local/bin/wm/lock.sh
ExecStartPost=/bin/sleep 1
[Install]
WantedBy=sleep.target
# Reference:
# https://wiki.archlinux.org/title/Power_management#Sleep_hooks