Compare commits
101
Commits
07712d1ad4
...
wayland
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1a2c0153c7 | ||
|
|
93c1ef048d | ||
|
|
ae8f793265 | ||
|
|
c62cd37298 | ||
|
|
0757d0ac9d | ||
|
|
ac8ff55089 | ||
|
|
42be3086e2 | ||
|
|
8de971278a | ||
|
|
5ecf4b09e7 | ||
|
|
bc4a34cbce | ||
|
|
ea757b4185 | ||
|
|
9a79b23a52 | ||
|
|
935d6d999b | ||
|
|
855732f3c1 | ||
|
|
a2148c1e19 | ||
|
|
679af71d41 | ||
|
|
7bc3ec6d98 | ||
|
|
4ca12fd342 | ||
|
|
b24521fd4f | ||
|
|
b561e7e2f3 | ||
|
|
b473dbbe74 | ||
|
|
e1700384a8 | ||
|
|
ebc6245ea2 | ||
|
|
5cd3ac24a1 | ||
|
|
7cef694420 | ||
|
|
ccebfdcdd5 | ||
|
|
6e50e217c3 | ||
|
|
f0835c1a06 | ||
|
|
98cf182406 | ||
|
|
16321c0c4f | ||
|
|
9d7b1f5850 | ||
|
|
3c5fbbf581 | ||
|
|
a38b5d1e15 | ||
|
|
f223178f39 | ||
|
|
33f22e6471 | ||
|
|
b21b6d2462 | ||
|
|
795f2aad5b | ||
|
|
cf156ca80b | ||
|
|
a282e01692 | ||
|
|
88f9e2e408 | ||
|
|
a208f458c1 | ||
|
|
d488a323da | ||
|
|
9cc18db3ba | ||
|
|
88dc203b9f | ||
|
|
50d8e3f455 | ||
|
|
5e7058563f | ||
|
|
5bc947db3d | ||
|
|
94f59f5b31 | ||
|
|
484fa668de | ||
|
|
1fb041fffc | ||
|
|
9f5ce80255 | ||
|
|
1068ef9502 | ||
|
|
3b01c0b759 | ||
|
|
11d351f629 | ||
|
|
dbf929c687 | ||
|
|
9461c904cd | ||
|
|
f9459cfe66 | ||
|
|
17cbd91236 | ||
|
|
89607db905 | ||
|
|
2b5aabebfb | ||
|
|
437dd48e51 | ||
|
|
82e5740e22 | ||
|
|
cf417d95b2 | ||
|
|
c3811b7f78 | ||
|
|
3378ba974c | ||
|
|
8904a85694 | ||
|
|
008efd440b | ||
|
|
dcaff77c01 | ||
|
|
b28a885af9 | ||
|
|
3492090285 | ||
|
|
21dc56539f | ||
|
|
847537257e | ||
|
|
81edda78b1 | ||
|
|
b87f56abcf | ||
|
|
82171e6684 | ||
|
|
a4bf47770c | ||
|
|
cd45f7595d | ||
|
|
915690a2c8 | ||
|
|
140c723776 | ||
|
|
68a2c75bbc | ||
|
|
92fa2f52d8 | ||
|
|
9049b130a8 | ||
|
|
4389dce613 | ||
|
|
28c152ba22 | ||
|
|
ffbefa0887 | ||
|
|
de64c467e3 | ||
|
|
d91d412362 | ||
|
|
594c32aa87 | ||
|
|
48b88d0464 | ||
|
|
2bd9ebc4ea | ||
|
|
4c88465f78 | ||
|
|
c116b8f589 | ||
|
|
9697bab8ef | ||
|
|
36631a5372 | ||
|
|
268b9e8dee | ||
|
|
9cdaac7413 | ||
|
|
9a17694bc9 | ||
|
|
e6bddb75c8 | ||
|
|
a36cbbe4eb | ||
|
|
1ae30d54b1 | ||
|
|
62e3d3f5e5 |
@@ -0,0 +1,2 @@
|
||||
[General]
|
||||
theme=KvArcDark
|
||||
@@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<actions>
|
||||
<action>
|
||||
<icon>utilities-terminal</icon>
|
||||
<name>Open Terminal Here</name>
|
||||
<unique-id>1594675818593070-1</unique-id>
|
||||
<description>Open Terminal in the Current Directory</description>
|
||||
|
||||
<!-- >>> session=xorg -->
|
||||
<command>urxvt -cd %f</command>
|
||||
<!-- <<< -->
|
||||
<!-- >>> session=wayland -->
|
||||
<!-- <command>ghostty -e "sh -c 'cd %f && exec $SHELL'"</command> -->
|
||||
<!-- <<< -->
|
||||
|
||||
<patterns>*</patterns>
|
||||
<startup-notify/>
|
||||
<directories/>
|
||||
</action>
|
||||
</actions>
|
||||
@@ -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
|
||||
@@ -0,0 +1,3 @@
|
||||
DP-1 00ffffffffffff00046932290dea00001c170104a5431c783aca95a6554ea1260f5054b7ef00d1c0b30095008180814081c08100714fcd4600a0a0381f4030203a00a11c2100001a000000ff0044374c4d54463035393931370a000000fd00174c18531804110140f838f03c000000fc00415355532050423239380a202001a502032571520102031112130414051f900e0f1d1e2220212309170783010000656e0c0010008c0ad08a20e02d10103e9600a11c21000018011d007251d01e206e285500a11c2100001e011d00bc52d01e20b8285540a11c2100001e8c0ad090204031200c405500a11c21000018000000000000000000000000000000000000cd
|
||||
DP-2 00ffffffffffff004162685096de81022a120104a52e1d7826e525a65444a125145054a56b807100814081809500a900b3000101010121399030621a274068b03600d0221100001c000000fd00384c1e5110000a202020202020000000fc00504b422056495332323257530a000000ff003432303635353538333030380a0087
|
||||
HDMI-2 00ffffffffffff004c2d3a0d00060001011a0103805932780a23ada4544d99260f474abdef80714f81c0810081809500a9c0b300010104740030f2705a80b0588a00501d7400001e023a801871382d40582c4500501d7400001e000000fd00184b0f511e000a202020202020000000fc0053414d53554e470a20202020200129020346f0535f101f041305142021225d5e62636407160312290907071507503d04c083010000e2000fe30503016e030c001000b83c20008001020304e3060d01e50e60616566011d80d0721c1620102c2580501d7400009e662156aa51001e30468f3300501d7400001e000000000000000000000000000000000000000000cd
|
||||
@@ -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
|
||||
@@ -0,0 +1 @@
|
||||
eDP-1 00ffffffffffff0034a9a29600082131ff190104a51d137803ee91a3544c99260f50540000000101010101010101010101010101010180a2b868b1d04070080888001dbe1000001e000000fd002e3c5e7c2a010a202020202020000000fc005656583134503034384d30300a0000001000000000000000000000000000000084
|
||||
@@ -0,0 +1,2 @@
|
||||
[config]
|
||||
skip-options=gamma
|
||||
@@ -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
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,407 +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-bin "/usr/bin/lua-language-server")
|
||||
(setq lsp-clients-lua-language-server-install-dir "/usr/lib/lua-language-server/")
|
||||
(setq lsp-clients-lua-language-server-main-location "/usr/lib/lua-language-server/main.lua")
|
||||
(setq lsp-enable-xref t)
|
||||
(setq lsp-headerline-breadcrumb-enable nil)
|
||||
(setq lsp-intelephense-storage-path (concat dot-cache-dir "/lsp-cache"))
|
||||
(setq lsp-keep-workspace-alive nil)
|
||||
(setq lsp-prefer-flymake nil)
|
||||
(setq lsp-session-file (concat dot-cache-dir "/lsp-session-v1"))
|
||||
|
||||
;; Mark clangd args variable as safe to modify via .dir-locals.el
|
||||
(put 'lsp-clients-clangd-args 'safe-local-variable #'listp)
|
||||
|
||||
;; Enable which-key descriptions
|
||||
(dolist (leader-key (list dot/leader-key dot/leader-alt-key))
|
||||
(let ((lsp-keymap-prefix (concat leader-key " l")))
|
||||
(lsp-enable-which-key-integration)))
|
||||
|
||||
(defun 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
|
||||
@@ -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
|
||||
@@ -1,157 +0,0 @@
|
||||
#+TITLE: Mail Configuration
|
||||
#+OPTIONS: toc:nil
|
||||
#+PROPERTY: header-args:emacs-lisp :shebang ";;; -*- lexical-binding: t; -*-\n"
|
||||
|
||||
** Table of Contents :toc_4:
|
||||
- [[#mail-functions][Mail Functions]]
|
||||
- [[#mail-in-emacs-with-mu4e][Mail in Emacs with mu4e]]
|
||||
- [[#sources][Sources]]
|
||||
|
||||
** Mail Functions
|
||||
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(with-eval-after-load 'auth-source
|
||||
(defun dot/mail-auth-get-field (host prop)
|
||||
"Find PROP in `auth-sources' for HOST entry."
|
||||
(when-let ((source (auth-source-search :max 1 :host host)))
|
||||
(if (eq prop :secret)
|
||||
(funcall (plist-get (car source) prop))
|
||||
(plist-get (flatten-list source) prop)))))
|
||||
#+END_SRC
|
||||
|
||||
** Mail in Emacs with mu4e
|
||||
|
||||
Useful mu4e manual pages:
|
||||
|
||||
- [[https://www.djcbsoftware.nl/code/mu/mu4e/MSGV-Keybindings.html#MSGV-Keybindings][Key bindings]]
|
||||
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(use-package mu4e
|
||||
:ensure nil
|
||||
:load-path "/usr/share/emacs/site-lisp/mu4e"
|
||||
:defer 20
|
||||
:commands mu4e
|
||||
:config
|
||||
(setq auth-sources `(,(concat dot-etc-dir "/authinfo.gpg")))
|
||||
(setq user-full-name (dot/mail-auth-get-field "fullname" :user))
|
||||
(setq user-mail-address (dot/mail-auth-get-field "info" :user))
|
||||
(setq mail-user-agent 'mu4e-user-agent)
|
||||
|
||||
;; Headers
|
||||
(setq mu4e-headers-date-format "%d-%m-%Y")
|
||||
(setq mu4e-headers-time-format "%I:%M %p")
|
||||
(setq mu4e-headers-long-date-format "%d-%m-%Y %I:%M:%S %p")
|
||||
|
||||
;; Syncing
|
||||
(setq mu4e-get-mail-command (concat "mbsync -a -c " (getenv "XDG_CONFIG_HOME") "/isync/mbsyncrc"))
|
||||
(setq mu4e-update-interval (* 15 60)) ; 15 minutes
|
||||
(setq mu4e-maildir "~/mail")
|
||||
(setq mu4e-attachment-dir "~/downloads")
|
||||
|
||||
;; Avoid mail syncing issues when using mbsync
|
||||
(setq mu4e-change-filenames-when-moving t)
|
||||
|
||||
;; Misc
|
||||
(setq mu4e-completing-read-function 'completing-read)
|
||||
(setq mu4e-confirm-quit nil)
|
||||
(setq mu4e-display-update-status-in-modeline t)
|
||||
(setq mu4e-hide-index-messages t)
|
||||
(setq mu4e-sent-messages-behavior 'sent)
|
||||
(setq mu4e-view-show-addresses t)
|
||||
(setq mu4e-view-show-images nil)
|
||||
|
||||
;; Compose
|
||||
(setq mu4e-compose-context-policy 'ask)
|
||||
(setq mu4e-compose-dont-reply-to-self t)
|
||||
(setq mu4e-compose-signature (concat (dot/mail-auth-get-field "fullname" :user) "\nriyyi.com\n"))
|
||||
(setq mu4e-compose-signature-auto-include t)
|
||||
|
||||
;; Contexts
|
||||
(setq mu4e-context-policy 'pick-first)
|
||||
(setq mu4e-contexts
|
||||
`(,(make-mu4e-context
|
||||
:name "info"
|
||||
:match-func (lambda (msg)
|
||||
(when msg
|
||||
(string= (mu4e-message-field msg :maildir) "/info")))
|
||||
:vars `((user-mail-address . ,(dot/mail-auth-get-field "info" :user))
|
||||
(mu4e-drafts-folder . "/info/Drafts")
|
||||
(mu4e-refile-folder . "/info/Archive")
|
||||
(mu4e-sent-folder . "/info/Sent")
|
||||
(mu4e-trash-folder . "/info/Trash")))
|
||||
,(make-mu4e-context
|
||||
:name "private"
|
||||
:match-func (lambda (msg)
|
||||
(when msg
|
||||
(string= (mu4e-message-field msg :maildir) "/private")))
|
||||
:vars `((user-mail-address . ,(dot/mail-auth-get-field "private" :user))
|
||||
(mu4e-drafts-folder . "/private/Drafts")
|
||||
(mu4e-refile-folder . "/private/Archive")
|
||||
(mu4e-sent-folder . "/private/Sent")
|
||||
(mu4e-trash-folder . "/private/Trash")))
|
||||
))
|
||||
|
||||
;; Do not mark messages as IMAP-deleted, just move them to the Trash directory!
|
||||
;; https://github.com/djcb/mu/issues/1136#issuecomment-486177435
|
||||
(setf (alist-get 'trash mu4e-marks)
|
||||
(list :char '("d" . "▼")
|
||||
:prompt "dtrash"
|
||||
:dyn-target (lambda (target msg)
|
||||
(mu4e-get-trash-folder msg))
|
||||
:action (lambda (docid msg target)
|
||||
(mu4e~proc-move docid (mu4e~mark-check-target target) "-N"))))
|
||||
|
||||
;; Start mu4e in the background for mail syncing
|
||||
(mu4e t))
|
||||
#+END_SRC
|
||||
|
||||
Use [[https://github.com/iqbalansari/mu4e-alert][mu4e-alert]] to show new e-mail notifications.
|
||||
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
|
||||
(use-package mu4e-alert
|
||||
:after mu4e
|
||||
:config
|
||||
(setq mu4e-alert-interesting-mail-query "(maildir:/info/Inbox OR maildir:/private/Inbox) AND flag:unread AND NOT flag:trashed")
|
||||
(setq mu4e-alert-notify-repeated-mails nil)
|
||||
|
||||
(mu4e-alert-set-default-style 'libnotify)
|
||||
(mu4e-alert-enable-notifications))
|
||||
#+END_SRC
|
||||
|
||||
Sending mail.
|
||||
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(use-package smtpmail
|
||||
:ensure nil ; built-in
|
||||
:after mu4e
|
||||
:init (setq smtpmail-default-smtp-server "mail.riyyi.com")
|
||||
:config
|
||||
(setq smtpmail-smtp-server "mail.riyyi.com")
|
||||
(setq smtpmail-local-domain "riyyi.com")
|
||||
(setq smtpmail-smtp-service 587)
|
||||
(setq smtpmail-stream-type 'starttls)
|
||||
(setq smtpmail-queue-mail nil))
|
||||
|
||||
(use-package sendmail
|
||||
:ensure nil ; built-in
|
||||
:after mu4e
|
||||
:config (setq send-mail-function 'smtpmail-send-it))
|
||||
|
||||
(use-package message
|
||||
:ensure nil ; built-in
|
||||
:after mu4e
|
||||
:config
|
||||
(setq message-kill-buffer-on-exit t)
|
||||
(setq message-send-mail-function 'smtpmail-send-it))
|
||||
#+END_SRC
|
||||
|
||||
** Sources
|
||||
|
||||
- https://rakhim.org/fastmail-setup-with-emacs-mu4e-and-mbsync-on-macos/
|
||||
- https://wiki.archlinux.org/title/Isync
|
||||
- https://man.archlinux.org/man/community/isync/mbsync.1.en
|
||||
- https://gitlab.com/protesilaos/dotfiles/-/blob/master/mbsync/.mbsyncrc
|
||||
- https://gitlab.com/protesilaos/dotfiles/-/blob/master/emacs/.emacs.d/prot-lisp/prot-mail.el
|
||||
- https://gitlab.com/protesilaos/dotfiles/-/blob/master/emacs/.emacs.d/prot-lisp/prot-mu4e-deprecated-conf.el
|
||||
- https://github.com/daviwil/dotfiles/blob/master/Mail.org
|
||||
@@ -1,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
|
||||
@@ -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
|
||||
@@ -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 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")
|
||||
|
||||
(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 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-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
|
||||
@@ -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
@@ -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
|
||||
@@ -0,0 +1,24 @@
|
||||
;;; dot-core.el --- -*- lexical-binding: t; -*-
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
;; Load configuration core.
|
||||
|
||||
;;; Code:
|
||||
|
||||
;; -----------------------------------------
|
||||
|
||||
(add-to-list 'load-path (locate-user-emacs-file "site-lisp/core"))
|
||||
|
||||
(require 'dot-core-variables)
|
||||
(require 'dot-core-customize)
|
||||
(require 'dot-core-fonts)
|
||||
(require 'dot-core-packages)
|
||||
(require 'dot-core-config)
|
||||
(require 'dot-core-functions)
|
||||
(require 'dot-core-advice)
|
||||
(require 'dot-core-hooks)
|
||||
|
||||
(provide 'dot-core)
|
||||
|
||||
;;; dot-core.el ends here
|
||||
@@ -0,0 +1,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
|
||||
@@ -0,0 +1,62 @@
|
||||
;;; dot-elpaca.el --- -*- lexical-binding: t; -*-
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
;; Elpaca bootstrap
|
||||
|
||||
;;; Code:
|
||||
|
||||
;; -----------------------------------------
|
||||
|
||||
;; Elpaca bootstrap
|
||||
(defvar elpaca-installer-version 0.9)
|
||||
(defvar elpaca-directory (expand-file-name "elpaca/" user-emacs-directory))
|
||||
(defvar elpaca-builds-directory (expand-file-name "builds/" elpaca-directory))
|
||||
(defvar elpaca-repos-directory (expand-file-name "repos/" elpaca-directory))
|
||||
(defvar elpaca-order '(elpaca :repo "https://github.com/progfolio/elpaca.git"
|
||||
:ref nil :depth 1 :inherit ignore
|
||||
:files (:defaults "elpaca-test.el" (:exclude "extensions"))
|
||||
:build (:not elpaca--activate-package)))
|
||||
(let* ((repo (expand-file-name "elpaca/" elpaca-repos-directory))
|
||||
(build (expand-file-name "elpaca/" elpaca-builds-directory))
|
||||
(order (cdr elpaca-order))
|
||||
(default-directory repo))
|
||||
(add-to-list 'load-path (if (file-exists-p build) build repo))
|
||||
(unless (file-exists-p repo)
|
||||
(make-directory repo t)
|
||||
(when (< emacs-major-version 28) (require 'subr-x))
|
||||
(condition-case-unless-debug err
|
||||
(if-let* ((buffer (pop-to-buffer-same-window "*elpaca-bootstrap*"))
|
||||
((zerop (apply #'call-process `("git" nil ,buffer t "clone"
|
||||
,@(when-let* ((depth (plist-get order :depth)))
|
||||
(list (format "--depth=%d" depth) "--no-single-branch"))
|
||||
,(plist-get order :repo) ,repo))))
|
||||
((zerop (call-process "git" nil buffer t "checkout"
|
||||
(or (plist-get order :ref) "--"))))
|
||||
(emacs (concat invocation-directory invocation-name))
|
||||
((zerop (call-process emacs nil buffer nil "-Q" "-L" "." "--batch"
|
||||
"--eval" "(byte-recompile-directory \".\" 0 'force)")))
|
||||
((require 'elpaca))
|
||||
((elpaca-generate-autoloads "elpaca" repo)))
|
||||
(progn (message "%s" (buffer-string)) (kill-buffer buffer))
|
||||
(error "%s" (with-current-buffer buffer (buffer-string))))
|
||||
((error) (warn "%s" err) (delete-directory repo 'recursive))))
|
||||
(unless (require 'elpaca-autoloads nil t)
|
||||
(require 'elpaca)
|
||||
(elpaca-generate-autoloads "elpaca" repo)
|
||||
(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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -0,0 +1,148 @@
|
||||
;;; dot-mail.el --- -*- lexical-binding: t; -*-
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
;; Mail configuration.
|
||||
|
||||
;;; Code:
|
||||
|
||||
;; -----------------------------------------
|
||||
;; Mail Functions
|
||||
|
||||
(with-eval-after-load 'auth-source
|
||||
(defun dot/mail-auth-get-field (host prop)
|
||||
"Find PROP in `auth-sources' for HOST entry."
|
||||
(when-let ((source (auth-source-search :max 1 :host host)))
|
||||
(if (eq prop :secret)
|
||||
(funcall (plist-get (car source) prop))
|
||||
(plist-get (flatten-list source) prop)))))
|
||||
|
||||
;; Mail in Emacs with mu4e
|
||||
|
||||
;; Useful mu4e manual pages:
|
||||
|
||||
;; Key bindings
|
||||
;; [https://www.djcbsoftware.nl/code/mu/mu4e/MSGV-Keybindings.html#MSGV-Keybindings]
|
||||
|
||||
(elpaca-nil (setup mu4e ; loaded from AUR package
|
||||
(add-to-list 'load-path "/usr/share/emacs/site-lisp/mu4e")
|
||||
(:autoload mu4e mu4e-update-index)
|
||||
(:when-loaded
|
||||
(add-to-list 'auth-sources (expand-file-name "authinfo.gpg" dot-etc-dir))
|
||||
(setq user-full-name (dot/mail-auth-get-field "fullname" :user))
|
||||
(setq user-mail-address (dot/mail-auth-get-field "info" :user))
|
||||
(setq mail-user-agent 'mu4e-user-agent)
|
||||
|
||||
;; Headers
|
||||
(setq mu4e-headers-date-format "%d-%m-%Y")
|
||||
(setq mu4e-headers-time-format "%I:%M %p")
|
||||
(setq mu4e-headers-long-date-format "%d-%m-%Y %I:%M:%S %p")
|
||||
|
||||
;; Syncing
|
||||
(setq mu4e-get-mail-command (concat "mbsync -a -c " (expand-file-name "isync/mbsyncrc" (getenv "XDG_CONFIG_HOME"))))
|
||||
(setq mu4e-update-interval (* 15 60)) ; 15 minutes
|
||||
(setq mu4e-maildir "~/mail")
|
||||
(setq mu4e-attachment-dir "~/downloads")
|
||||
|
||||
;; Avoid mail syncing issues when using mbsync
|
||||
(setq mu4e-change-filenames-when-moving t)
|
||||
|
||||
;; Misc
|
||||
(setq mu4e-completing-read-function 'completing-read)
|
||||
(setq mu4e-confirm-quit nil)
|
||||
(setq mu4e-display-update-status-in-modeline t)
|
||||
(setq mu4e-hide-index-messages t)
|
||||
(setq mu4e-sent-messages-behavior 'sent)
|
||||
(setq mu4e-view-show-addresses t)
|
||||
(setq mu4e-view-show-images nil)
|
||||
|
||||
;; Compose
|
||||
(setq mu4e-compose-context-policy 'ask)
|
||||
(setq mu4e-compose-dont-reply-to-self t)
|
||||
(setq mu4e-compose-signature (concat (dot/mail-auth-get-field "fullname" :user) "\nriyyi.com\n"))
|
||||
(setq mu4e-compose-signature-auto-include t)
|
||||
|
||||
;; Contexts
|
||||
(setq mu4e-context-policy 'pick-first)
|
||||
(setq mu4e-contexts
|
||||
`(,(make-mu4e-context
|
||||
:name "info"
|
||||
:match-func (lambda (msg)
|
||||
(when msg
|
||||
(string= (mu4e-message-field msg :maildir) "/info")))
|
||||
:vars `((user-mail-address . ,(dot/mail-auth-get-field "info" :user))
|
||||
(mu4e-drafts-folder . "/info/Drafts")
|
||||
(mu4e-refile-folder . "/info/Archive")
|
||||
(mu4e-sent-folder . "/info/Sent")
|
||||
(mu4e-trash-folder . "/info/Trash")))
|
||||
,(make-mu4e-context
|
||||
:name "private"
|
||||
:match-func (lambda (msg)
|
||||
(when msg
|
||||
(string= (mu4e-message-field msg :maildir) "/private")))
|
||||
:vars `((user-mail-address . ,(dot/mail-auth-get-field "private" :user))
|
||||
(mu4e-drafts-folder . "/private/Drafts")
|
||||
(mu4e-refile-folder . "/private/Archive")
|
||||
(mu4e-sent-folder . "/private/Sent")
|
||||
(mu4e-trash-folder . "/private/Trash")))
|
||||
))
|
||||
|
||||
;; Do not mark messages as IMAP-deleted, just move them to the Trash directory!
|
||||
;; https://github.com/djcb/mu/issues/1136#issuecomment-486177435
|
||||
(setf (alist-get 'trash mu4e-marks)
|
||||
(list :char '("d" . "▼")
|
||||
:prompt "dtrash"
|
||||
:dyn-target (lambda (target msg)
|
||||
(mu4e-get-trash-folder msg))
|
||||
:action (lambda (docid msg target)
|
||||
(mu4e~proc-move docid (mu4e~mark-check-target target) "-N"))))
|
||||
|
||||
;; Start mu4e in the background for mail syncing
|
||||
(mu4e t))))
|
||||
|
||||
;; Use mu4e-alert to show new e-mail notifications.
|
||||
;; https://github.com/iqbalansari/mu4e-alert
|
||||
|
||||
(elpaca-setup mu4e-alert
|
||||
(:defer 20)
|
||||
(:when-loaded
|
||||
(setq mu4e-alert-interesting-mail-query "(maildir:/info/Inbox OR maildir:/private/Inbox) AND flag:unread AND NOT flag:trashed")
|
||||
(setq mu4e-alert-notify-repeated-mails nil)
|
||||
|
||||
(mu4e-alert-set-default-style 'libnotify)
|
||||
(mu4e-alert-enable-notifications)))
|
||||
|
||||
;; Sending mail.
|
||||
|
||||
(elpaca-nil (setup smtpmail ; built-in
|
||||
(setq smtpmail-default-smtp-server "mail.riyyi.com")
|
||||
(:load-after mu4e)
|
||||
(:when-loaded
|
||||
(setq smtpmail-smtp-server "mail.riyyi.com")
|
||||
(setq smtpmail-local-domain "riyyi.com")
|
||||
(setq smtpmail-smtp-service 587)
|
||||
(setq smtpmail-stream-type 'starttls)
|
||||
(setq smtpmail-queue-mail nil))))
|
||||
|
||||
(elpaca-nil (setup sendmail ; built-in
|
||||
(:load-after mu4e)
|
||||
(:when-loaded (setq send-mail-function 'smtpmail-send-it))))
|
||||
|
||||
(elpaca-nil (setup message ; built-in
|
||||
(:load-after mu4e)
|
||||
(:when-loaded
|
||||
(setq message-kill-buffer-on-exit t)
|
||||
(setq message-send-mail-function 'smtpmail-send-it))))
|
||||
|
||||
;; Sources:
|
||||
;; - https://rakhim.org/fastmail-setup-with-emacs-mu4e-and-mbsync-on-macos/
|
||||
;; - https://wiki.archlinux.org/title/Isync
|
||||
;; - https://man.archlinux.org/man/community/isync/mbsync.1.en
|
||||
;; - https://gitlab.com/protesilaos/dotfiles/-/blob/master/mbsync/.mbsyncrc
|
||||
;; - https://gitlab.com/protesilaos/dotfiles/-/blob/master/emacs/.emacs.d/prot-lisp/prot-mail.el
|
||||
;; - https://gitlab.com/protesilaos/dotfiles/-/blob/master/emacs/.emacs.d/prot-lisp/prot-mu4e-deprecated-conf.el
|
||||
;; - https://github.com/daviwil/dotfiles/blob/master/Mail.org
|
||||
|
||||
(provide 'dot-mail)
|
||||
|
||||
;;; dot-mail.el ends here
|
||||
@@ -0,0 +1,352 @@
|
||||
;;; 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
|
||||
(:also-load 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
|
||||
@@ -0,0 +1,29 @@
|
||||
;;; dot-rss.el --- -*- lexical-binding: t; -*-
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
;; RSS.
|
||||
|
||||
;;; Code:
|
||||
|
||||
;; -----------------------------------------
|
||||
|
||||
(elpaca-setup elfeed
|
||||
(:autoload elfeed)
|
||||
(:with-mode dot/hook-disable-line-numbers
|
||||
(:hook-into elfeed-search-mode)
|
||||
(:hook-into elfeed-show-mode))
|
||||
(:when-loaded
|
||||
(setq elfeed-db-directory (expand-file-name "elfeed" dot-cache-dir))
|
||||
(setq elfeed-enclosure-default-dir "~/downloads/")
|
||||
(setq elfeed-search-filter "@6-months-ago +unread")
|
||||
(setq elfeed-search-clipboard-type 'CLIPBOARD)
|
||||
(setq elfeed-search-title-max-width 100)
|
||||
(setq elfeed-search-title-min-width 30)
|
||||
(setq elfeed-search-trailing-width 55)
|
||||
(setq elfeed-show-unique-buffers t)
|
||||
(load (expand-file-name "elfeed-feeds" dot-etc-dir))))
|
||||
|
||||
(provide 'dot-rss)
|
||||
|
||||
;;; dot-rss.el ends here
|
||||
@@ -0,0 +1,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
|
||||
@@ -0,0 +1,107 @@
|
||||
;;; dot-setup.el --- -*- lexical-binding: t; -*-
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
;; Configure SetupEl and keywords.
|
||||
|
||||
;;; Code:
|
||||
|
||||
;; -----------------------------------------
|
||||
;; SetupEl
|
||||
|
||||
;; Install and load SetupEl immediately
|
||||
(elpaca setup (require 'setup)
|
||||
|
||||
;;; Configure custom macros
|
||||
|
||||
(setup-define :load-after
|
||||
(lambda (&rest features)
|
||||
(let ((body `(require ',(setup-get 'feature))))
|
||||
(dolist (feature (nreverse features))
|
||||
(setq body `(with-eval-after-load ',feature ,body)))
|
||||
body))
|
||||
:documentation "Load the current feature after FEATURES.")
|
||||
|
||||
(setup-define :autoload
|
||||
(lambda (func)
|
||||
(let ((fn (if (memq (car-safe func) '(quote function))
|
||||
(cadr func)
|
||||
func)))
|
||||
`(unless (fboundp (quote ,fn))
|
||||
(autoload (function ,fn) ,(symbol-name (setup-get 'feature)) nil t))))
|
||||
:documentation "Autoload COMMAND if not already bound."
|
||||
:repeatable t
|
||||
:signature '(FUNC ...))
|
||||
|
||||
(setup-define :defer
|
||||
(lambda (secs)
|
||||
`(if (numberp ,secs)
|
||||
(run-with-idle-timer ,secs nil (lambda () (require ',(setup-get 'feature))))
|
||||
,(setup-quit)))
|
||||
:documentation "Defer loading of feature for SECS idle seconds.")
|
||||
|
||||
;;; Configure custom macros for evil bindings
|
||||
|
||||
(setup-define :with-evil-state
|
||||
(lambda (states &rest body)
|
||||
(setup-bind body (states states)))
|
||||
:documentation "Change the STATE that BODY will bind to."
|
||||
:indent 1)
|
||||
|
||||
(setup-define :evil-bind-impl
|
||||
(lambda (key command)
|
||||
`(evil-define-key* ',(setup-get 'states) ,(setup-get 'map) ,key ,command))
|
||||
:documentation "Bind KEY to COMMAND in the current map."
|
||||
:after-loaded t
|
||||
:ensure '(kbd func)
|
||||
:repeatable t)
|
||||
|
||||
(setup-define :evil-bind
|
||||
(lambda (states &rest keybinds)
|
||||
`(with-eval-after-load 'evil
|
||||
(:with-evil-state ,states (:evil-bind-impl ,@keybinds))))
|
||||
:documentation "Bind KEYBINDS in STATES in the current map.")
|
||||
|
||||
(setup-define :evil-bind-into
|
||||
(lambda (states feature-or-map &rest keybinds)
|
||||
(if (string-match-p "-map\\'" (symbol-name feature-or-map))
|
||||
`(:with-map ,feature-or-map (:evil-bind ,states ,@keybinds))
|
||||
`(:with-feature ,feature-or-map (:evil-bind ,states ,@keybinds))))
|
||||
:documentation "Bind KEYBINDS in STATE into the map of FEATURE-OR-MAP.
|
||||
The arguments REST are handled as by `:evil-bind'."
|
||||
:indent 1)
|
||||
)
|
||||
|
||||
;;; Add setup.el macro
|
||||
|
||||
;;;###autoload
|
||||
(defmacro elpaca-setup (order &rest body)
|
||||
"Execute BODY in `setup' declaration after ORDER is finished.
|
||||
If the :disabled keyword is present in body, the package is completely ignored.
|
||||
This happens regardless of the value associated with :disabled.
|
||||
The expansion is a string indicating the package has been disabled."
|
||||
(declare (indent 1))
|
||||
(if (memq :disabled body)
|
||||
(format "%S :disabled by elpaca-setup" order)
|
||||
(let ((o order))
|
||||
(when-let ((ensure (cl-position :ensure body)))
|
||||
(setq o (if (null (nth (1+ ensure) body)) nil order)
|
||||
body (append (cl-subseq body 0 ensure)
|
||||
(cl-subseq body (+ ensure 2)))))
|
||||
`(elpaca ,o (setup
|
||||
,(if-let (((memq (car-safe order) '(quote \`)))
|
||||
(feature (flatten-tree order)))
|
||||
(cadr feature)
|
||||
(elpaca--first order))
|
||||
,@body)))))
|
||||
|
||||
;; Startup benchmark
|
||||
(elpaca-setup benchmark-init
|
||||
(:require benchmark-init)
|
||||
(:when-loaded
|
||||
(benchmark-init/activate)
|
||||
(add-hook 'elpaca-after-init-hook #'benchmark-init/deactivate)))
|
||||
|
||||
(provide 'dot-setup-el)
|
||||
|
||||
;;; dot-setup.el ends here
|
||||
@@ -0,0 +1,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
|
||||
@@ -4,6 +4,6 @@
|
||||
# --
|
||||
namespace ${1:Namespace} {
|
||||
|
||||
$0
|
||||
$0
|
||||
|
||||
} // namespace $1
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
[redshift]
|
||||
[general]
|
||||
temp-day=5700
|
||||
|
||||
; >>> hostname=arch-desktop
|
||||
@@ -14,7 +14,13 @@ brightness-day=1.0
|
||||
brightness-night=0.9
|
||||
|
||||
location-provider=manual
|
||||
|
||||
; >>> session=xorg
|
||||
adjustment-method=randr
|
||||
; <<<
|
||||
; >>> session=wayland
|
||||
; adjustment-method=wayland
|
||||
; <<<
|
||||
|
||||
[manual]
|
||||
lat=51.81
|
||||
@@ -0,0 +1,12 @@
|
||||
app-notifications = no-clipboard-copy
|
||||
confirm-close-surface = false
|
||||
copy-on-select = clipboard
|
||||
cursor-style-blink = false
|
||||
font-family = DejaVuSansM Nerd Font Mono
|
||||
font-size = 10
|
||||
link-url = true
|
||||
selection-invert-fg-bg = true
|
||||
term = xterm-256color
|
||||
theme = terminal-sexy
|
||||
window-decoration = false
|
||||
window-inherit-working-directory = true
|
||||
@@ -0,0 +1,21 @@
|
||||
palette = 0=#282a2e
|
||||
palette = 1=#a54242
|
||||
palette = 2=#8c9440
|
||||
palette = 3=#de935f
|
||||
palette = 4=#5f819d
|
||||
palette = 5=#85678f
|
||||
palette = 6=#5e8d87
|
||||
palette = 7=#707880
|
||||
palette = 8=#373b41
|
||||
palette = 9=#cc6666
|
||||
palette = 10=#b5bd68
|
||||
palette = 11=#f0c674
|
||||
palette = 12=#81a2be
|
||||
palette = 13=#b294bb
|
||||
palette = 14=#8abeb7
|
||||
palette = 15=#c5c8c6
|
||||
background = #1c1c1c
|
||||
foreground = #c5c8c6
|
||||
cursor-color = #c5c8c6
|
||||
selection-background = #373b41
|
||||
selection-foreground = #c5c8c6
|
||||
@@ -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,4 +1,4 @@
|
||||
pinentry-program /usr/bin/pinentry
|
||||
pinentry-program /usr/bin/pinentry-gtk
|
||||
|
||||
default-cache-ttl 900
|
||||
max-cache-ttl 7200
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
# DO NOT EDIT! This file will be overwritten by LXAppearance.
|
||||
# DO NOT EDIT! This file will be overwritten by nwg-look.
|
||||
# Any customization should be done in ~/.gtkrc-2.0.mine instead.
|
||||
|
||||
include "/home/rick/.gtkrc-2.0.mine"
|
||||
gtk-theme-name="Arc-Dark"
|
||||
gtk-icon-theme-name="Arc"
|
||||
gtk-font-name="DejaVu Sans 10"
|
||||
|
||||
@@ -14,3 +14,4 @@ gtk-xft-antialias=1
|
||||
gtk-xft-hinting=1
|
||||
gtk-xft-hintstyle=hintslight
|
||||
gtk-xft-rgba=rgb
|
||||
gtk-application-prefer-dark-theme=1
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
general {
|
||||
lock_cmd = pidof hyprlock || hyprlock
|
||||
before_sleep_cmd = loginctl lock-session
|
||||
after_sleep_cmd = hyprctl dispatch dpms on # avoid having to press a key twice to turn on display
|
||||
}
|
||||
|
||||
# Turn the screen off after 30 seconds on the lock-screen
|
||||
listener {
|
||||
timeout = 30
|
||||
on-timeout = pidof hyprlock && hyprctl dispatch dpms off
|
||||
on-resume = hyprctl dispatch dpms on
|
||||
}
|
||||
@@ -0,0 +1,422 @@
|
||||
################
|
||||
### MONITORS ###
|
||||
################
|
||||
|
||||
# See https://wiki.hyprland.org/Configuring/Monitors/
|
||||
|
||||
monitor = desc:Ancor Communications Inc ASUS PB298 D7LMTF059917, preferred, 0x0, auto
|
||||
monitor = desc:Iiyama North America PL2492H 11511037C7430, preferred, 2560x0, auto
|
||||
monitor = , preferred, auto, auto # fallback
|
||||
|
||||
|
||||
###################
|
||||
### MY PROGRAMS ###
|
||||
###################
|
||||
|
||||
# See https://wiki.hyprland.org/Configuring/Keywords/
|
||||
|
||||
# Set programs that you use
|
||||
$terminal = ghostty
|
||||
$fileManager = thunar
|
||||
$menu = rofi -show drun
|
||||
|
||||
|
||||
#################
|
||||
### AUTOSTART ###
|
||||
#################
|
||||
|
||||
# System level
|
||||
exec-once = gammastep
|
||||
exec-once = systemctl --user start hyprpolkitagent
|
||||
exec-once = hyprctl setcursor capitaine-cursors-light 24
|
||||
exec-once = hypridle
|
||||
exec-once = ydotoold
|
||||
|
||||
# Scripts
|
||||
exec-once = ${HOME}/.local/bin/wm/wallpaper.sh
|
||||
exec-once = ${HOME}/.local/bin/panel/waybar.sh
|
||||
|
||||
# Applications
|
||||
exec-once = [workspace 1] firefox
|
||||
exec-once = [workspace 2] $terminal
|
||||
exec-once = [workspace 3] thunar --daemon
|
||||
exec-once = [workspace 3] thunar
|
||||
|
||||
|
||||
#############################
|
||||
### ENVIRONMENT VARIABLES ###
|
||||
#############################
|
||||
|
||||
# See https://wiki.hyprland.org/Configuring/Environment-variables/
|
||||
|
||||
env = XDG_CURRENT_DESKTOP,Hyprland
|
||||
env = XDG_SESSION_TYPE,wayland
|
||||
env = XDG_SESSION_DESKTOP,Hyprland
|
||||
|
||||
env = XCURSOR_SIZE,24
|
||||
env = HYPRCURSOR_SIZE,24
|
||||
|
||||
|
||||
#####################
|
||||
### LOOK AND FEEL ###
|
||||
#####################
|
||||
|
||||
# Refer to https://wiki.hyprland.org/Configuring/Variables/
|
||||
|
||||
# https://wiki.hyprland.org/Configuring/Variables/#general
|
||||
general {
|
||||
gaps_in = 5
|
||||
gaps_out = 10
|
||||
|
||||
border_size = 2
|
||||
|
||||
# https://wiki.hyprland.org/Configuring/Variables/#variable-types for info about colors
|
||||
col.active_border = rgb(404552)
|
||||
col.inactive_border = rgb(2b2e39)
|
||||
|
||||
# Set to true enable resizing windows by clicking and dragging on borders and gaps
|
||||
resize_on_border = false
|
||||
|
||||
# Please see https://wiki.hyprland.org/Configuring/Tearing/ before you turn this on
|
||||
allow_tearing = false
|
||||
|
||||
layout = dwindle
|
||||
}
|
||||
|
||||
# https://wiki.hyprland.org/Configuring/Variables/#decoration
|
||||
decoration {
|
||||
rounding = 0
|
||||
|
||||
# Change transparency of focused and unfocused windows
|
||||
active_opacity = 1.0
|
||||
inactive_opacity = 1.0
|
||||
|
||||
shadow {
|
||||
enabled = false
|
||||
}
|
||||
|
||||
# https://wiki.hyprland.org/Configuring/Variables/#blur
|
||||
blur {
|
||||
enabled = false
|
||||
}
|
||||
}
|
||||
|
||||
# https://wiki.hyprland.org/Configuring/Variables/#animations
|
||||
animations {
|
||||
enabled = true
|
||||
|
||||
# Default animations, see https://wiki.hyprland.org/Configuring/Animations/ for more
|
||||
|
||||
bezier = easeOutQuint,0.23,1,0.32,1
|
||||
bezier = easeInOutCubic,0.65,0.05,0.36,1
|
||||
bezier = linear,0,0,1,1
|
||||
bezier = almostLinear,0.5,0.5,0.75,1.0
|
||||
bezier = quick,0.15,0,0.1,1
|
||||
|
||||
animation = global, 1, 10, default
|
||||
animation = border, 1, 5.39, easeOutQuint
|
||||
animation = windows, 1, 4.79, easeOutQuint
|
||||
animation = windowsIn, 1, 4.1, easeOutQuint, popin 87%
|
||||
animation = windowsOut, 1, 1.49, linear, popin 87%
|
||||
animation = fadeIn, 1, 1.73, almostLinear
|
||||
animation = fadeOut, 1, 1.46, almostLinear
|
||||
animation = fade, 1, 3.03, quick
|
||||
animation = layers, 1, 3.81, easeOutQuint
|
||||
animation = layersIn, 1, 4, easeOutQuint, fade
|
||||
animation = layersOut, 1, 1.5, linear, fade
|
||||
animation = fadeLayersIn, 1, 1.79, almostLinear
|
||||
animation = fadeLayersOut, 1, 1.39, almostLinear
|
||||
animation = workspaces, 1, 1.94, almostLinear, fade
|
||||
animation = workspacesIn, 1, 1.21, almostLinear, fade
|
||||
animation = workspacesOut, 1, 1.94, almostLinear, fade
|
||||
}
|
||||
|
||||
# Ref https://wiki.hyprland.org/Configuring/Workspace-Rules/
|
||||
# "Smart gaps" / "No gaps when only"
|
||||
workspace = w[tv1], gapsout:0, gapsin:0
|
||||
workspace = f[1], gapsout:0, gapsin:0
|
||||
windowrule = border_size 0, match:float 0, match:workspace w[tv1]
|
||||
windowrule = rounding 0, match:float 0, match:workspace w[tv1]
|
||||
windowrule = border_size 0, match:float 0, match:workspace f[1]
|
||||
windowrule = rounding 0, match:float 0, match:workspace f[1]
|
||||
|
||||
# See https://wiki.hyprland.org/Configuring/Dwindle-Layout/ for more
|
||||
dwindle {
|
||||
force_split = 2 # split to the bottom right
|
||||
preserve_split = true
|
||||
pseudotile = false
|
||||
}
|
||||
|
||||
# See https://wiki.hyprland.org/Configuring/Master-Layout/ for more
|
||||
master {
|
||||
new_status = master
|
||||
}
|
||||
|
||||
# https://wiki.hyprland.org/Configuring/Variables/#misc
|
||||
misc {
|
||||
disable_hyprland_logo = true
|
||||
vfr = true # lower amount of sent frames when nothing is happening on-screen
|
||||
}
|
||||
|
||||
|
||||
#############
|
||||
### INPUT ###
|
||||
#############
|
||||
|
||||
# https://wiki.hyprland.org/Configuring/Variables/#input
|
||||
input {
|
||||
kb_layout = us
|
||||
kb_variant =
|
||||
kb_model =
|
||||
kb_options = caps:swapescape
|
||||
kb_rules =
|
||||
|
||||
follow_mouse = 1
|
||||
|
||||
sensitivity = 0 # -1.0 - 1.0, 0 means no modification.
|
||||
|
||||
touchpad {
|
||||
natural_scroll = false
|
||||
}
|
||||
}
|
||||
|
||||
# https://wiki.hyprland.org/Configuring/Variables/#gestures
|
||||
gestures {
|
||||
workspace_swipe_touch = false
|
||||
}
|
||||
|
||||
# Example per-device config
|
||||
# See https://wiki.hyprland.org/Configuring/Keywords/#per-device-input-configs for more
|
||||
device { # hyprctl devices
|
||||
name = logitech-wireless-mouse-pid:4038
|
||||
sensitivity = -0.5
|
||||
accel_profile = flat
|
||||
}
|
||||
|
||||
|
||||
###################
|
||||
### KEYBINDINGS ###
|
||||
###################
|
||||
|
||||
# See https://wiki.hyprland.org/Configuring/Keywords/
|
||||
$mainMod = SUPER # Sets "Windows" key as main modifier
|
||||
|
||||
# Bind docs https://wiki.hyprland.org/Configuring/Binds/
|
||||
|
||||
#--- Control ---#
|
||||
|
||||
# Reload hyprland
|
||||
bind = $mainMod Control_L, r, forcerendererreload
|
||||
|
||||
# Close hyprland
|
||||
bind = $mainMod SHIFT, M, exit,
|
||||
|
||||
#--- Window ---#
|
||||
|
||||
# Close window
|
||||
bind = $mainMod, q, killactive,
|
||||
|
||||
#-- State/flags --#
|
||||
|
||||
# Toggle fullscreen mode
|
||||
bind = $mainMod, f, fullscreen
|
||||
|
||||
# Toggle tiled/floating
|
||||
bind = $mainMod, Space, togglefloating,
|
||||
|
||||
#-- Focus --#
|
||||
|
||||
# Focus window in direction
|
||||
bind = $mainMod, h, movefocus, l
|
||||
bind = $mainMod, j, movefocus, d
|
||||
bind = $mainMod, k, movefocus, u
|
||||
bind = $mainMod, l, movefocus, r
|
||||
bind = $mainMod, left, movefocus, l
|
||||
bind = $mainMod, right, movefocus, r
|
||||
bind = $mainMod, up, movefocus, u
|
||||
bind = $mainMod, down, movefocus, d
|
||||
|
||||
# Focus previous/next window
|
||||
bind = $mainMod, Tab, cyclenext
|
||||
bind = $mainMod SHIFT, Tab, cyclenext, prev
|
||||
|
||||
# Focus workspace
|
||||
bind = $mainMod, 1, workspace, 1
|
||||
bind = $mainMod, 2, workspace, 2
|
||||
bind = $mainMod, 3, workspace, 3
|
||||
bind = $mainMod, 4, workspace, 4
|
||||
bind = $mainMod, 5, workspace, 5
|
||||
bind = $mainMod, 6, workspace, 6
|
||||
bind = $mainMod, 7, workspace, 7
|
||||
bind = $mainMod, 8, workspace, 8
|
||||
bind = $mainMod, 9, workspace, 9
|
||||
bind = $mainMod, 0, workspace, 10
|
||||
|
||||
# Focus previous/next workspace
|
||||
bind = $mainMod, equal, workspace, e+1
|
||||
bind = $mainMod, minus, workspace, e-1
|
||||
|
||||
# Focus last workspace
|
||||
bind = $mainMod, GRAVE, focuscurrentorlast
|
||||
|
||||
# Focus previous/next monitor
|
||||
# TODO
|
||||
|
||||
# Special workspace (scratchpad)
|
||||
bind = $mainMod, T, togglespecialworkspace, magic
|
||||
|
||||
#-- Move --#
|
||||
|
||||
# Send window to workspace
|
||||
bind = $mainMod SHIFT, 1, movetoworkspacesilent, 1
|
||||
bind = $mainMod SHIFT, 2, movetoworkspacesilent, 2
|
||||
bind = $mainMod SHIFT, 3, movetoworkspacesilent, 3
|
||||
bind = $mainMod SHIFT, 4, movetoworkspacesilent, 4
|
||||
bind = $mainMod SHIFT, 5, movetoworkspacesilent, 5
|
||||
bind = $mainMod SHIFT, 6, movetoworkspacesilent, 6
|
||||
bind = $mainMod SHIFT, 7, movetoworkspacesilent, 7
|
||||
bind = $mainMod SHIFT, 8, movetoworkspacesilent, 8
|
||||
bind = $mainMod SHIFT, 9, movetoworkspacesilent, 9
|
||||
bind = $mainMod SHIFT, 0, movetoworkspacesilent, 10
|
||||
|
||||
# Move window to previous/next workspace
|
||||
bind = $mainMod SHIFT, equal, movetoworkspace, e+1
|
||||
bind = $mainMod SHIFT, minus, movetoworkspace, e-1
|
||||
|
||||
# Move window to previous/next monitor
|
||||
# TODO
|
||||
|
||||
# Move floating window
|
||||
bind = Control_L Alt_L, h, moveactive, -30 0
|
||||
bind = Control_L Alt_L, j, moveactive, 0 30
|
||||
bind = Control_L Alt_L, k, moveactive, 0 -30
|
||||
bind = Control_L Alt_L, l, moveactive, 30 0
|
||||
bind = Control_L Alt_L, left, moveactive, -30 0
|
||||
bind = Control_L Alt_L, right, moveactive, 30 0
|
||||
bind = Control_L Alt_L, up, moveactive, 0 -30
|
||||
bind = Control_L Alt_L, down, moveactive, 0 30
|
||||
|
||||
# Flip the tree from the current windows parent
|
||||
bind = $mainMod Alt_L, 5, swapsplit, # dwindle
|
||||
bind = $mainMod Alt_L, 6, togglesplit, # dwindle
|
||||
|
||||
# Special workspace (scratchpad)
|
||||
bind = $mainMod SHIFT, T, movetoworkspace, special:magic
|
||||
|
||||
#-- Resize --#
|
||||
|
||||
# Resize windows
|
||||
bind = $mainMod Alt_L, h, resizeactive, -10 0
|
||||
bind = $mainMod Alt_L, j, resizeactive, 0 10
|
||||
bind = $mainMod Alt_L, k, resizeactive, 0 -10
|
||||
bind = $mainMod Alt_L, l, resizeactive, 10 0
|
||||
bind = $mainMod Alt_L, left, resizeactive, -10 0
|
||||
bind = $mainMod Alt_L, right, resizeactive, 10 0
|
||||
bind = $mainMod Alt_L, up, resizeactive, 0 -10
|
||||
bind = $mainMod Alt_L, down, resizeactive, 0 10
|
||||
|
||||
# Move/resize windows with mainMod + LMB/RMB and dragging
|
||||
bindm = $mainMod, mouse:272, movewindow
|
||||
bindm = $mainMod, mouse:273, resizewindow
|
||||
|
||||
#-- Preselect node --#
|
||||
|
||||
bind = SUPER Control_L, h, layoutmsg, preselect left
|
||||
bind = SUPER Control_L, j, layoutmsg, preselect down
|
||||
bind = SUPER Control_L, k, layoutmsg, preselect up
|
||||
bind = SUPER Control_L, l, layoutmsg, preselect right
|
||||
bind = SUPER Control_L, left, layoutmsg, preselect left
|
||||
bind = SUPER Control_L, right, layoutmsg, preselect right
|
||||
bind = SUPER Control_L, up, layoutmsg, preselect up
|
||||
bind = SUPER Control_L, down, layoutmsg, preselect down
|
||||
|
||||
#--- General ---#
|
||||
|
||||
# Start terminal
|
||||
bind = $mainMod, Return, exec, $terminal
|
||||
|
||||
# Start rofi (program launcher)
|
||||
bind = $mainMod, d, exec, $menu
|
||||
|
||||
# mpv
|
||||
bind = $mainMod, m, exec, play
|
||||
bind = $mainMod SHIFT, m, exec, play queue
|
||||
|
||||
#--- Control, compositor agnostic ---#
|
||||
|
||||
# Reload
|
||||
bind = $mainMod Control_L, r, exec, ${HOME}/.local/bin/panel/waybar.sh
|
||||
|
||||
# System
|
||||
bind = $mainMod SHIFT, s, exec, system
|
||||
|
||||
# Screen brightness
|
||||
bind = $mainMod, F2, exec, brictl dec 10
|
||||
bind = $mainMod, F3, exec, brictl inc 10
|
||||
|
||||
# Screen capture
|
||||
bind = , Print, exec, printscreen
|
||||
bind = Control_L, Print, exec, aliases screencast
|
||||
|
||||
# Laptop multimedia keys
|
||||
bindel = , XF86AudioRaiseVolume, exec, wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%+
|
||||
bindel = , XF86AudioLowerVolume, exec, wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%-
|
||||
bindel = , XF86AudioMute, exec, wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle
|
||||
bindel = , XF86AudioMicMute, exec, wpctl set-mute @DEFAULT_AUDIO_SOURCE@ toggle
|
||||
bindel = , XF86MonBrightnessUp, exec, brictl inc 10
|
||||
bindel = , XF86MonBrightnessDown, exec, brictl dec 10
|
||||
|
||||
bindl = , XF86AudioNext, exec, playerctl next
|
||||
bindl = , XF86AudioPause, exec, playerctl play-pause
|
||||
bindl = , XF86AudioPlay, exec, playerctl play-pause
|
||||
bindl = , XF86AudioPrev, exec, playerctl previous
|
||||
|
||||
bindl = , XF86HomePage, exec, inputctl -d toggle # toggle touchpad
|
||||
bindl = , XF86Search, exec, inputctl -s toggle # toggle touchscreen
|
||||
|
||||
#--- Notification ---#
|
||||
|
||||
# Notifiation
|
||||
bind = Control_L, space, exec, dunstctl close
|
||||
bind = Control_L SHIFT, space, exec, dunstctl close-all
|
||||
bind = Control_L, grave, exec, dunstctl history-pop
|
||||
bind = Control_L SHIFT, period, exec, dunstctl context
|
||||
|
||||
|
||||
##############################
|
||||
### WINDOWS AND WORKSPACES ###
|
||||
##############################
|
||||
|
||||
# See https://wiki.hyprland.org/Configuring/Window-Rules/ for more
|
||||
# See https://wiki.hyprland.org/Configuring/Workspace-Rules/ for workspace rules
|
||||
|
||||
# Ignore maximize requests from apps. You'll probably like this.
|
||||
windowrule = suppress_event maximize, match:class .*
|
||||
|
||||
# Fix some dragging issues with XWayland
|
||||
windowrule = no_focus true, match:class ^$, match:title ^$, match:xwayland true, match:float true, match:fullscreen false, match:pin false
|
||||
|
||||
# Set to floating
|
||||
windowrule = float true, match:class feh # window rule v1 can only do either class or title, not both
|
||||
windowrule = float true, match:class mpv
|
||||
windowrule = float true, match:class org.pulseaudio.pavucontrol
|
||||
windowrule = float true, match:class pinentry-gtk
|
||||
windowrule = float true, match:class xarchiver
|
||||
windowrule = float true, match:class firefox, match:title Library
|
||||
windowrule = float true, match:class firefox, match:title ^About.*
|
||||
windowrule = float true, match:class thunar, match:title File Operation Progress
|
||||
|
||||
# Resize floating windows
|
||||
windowrule = size >50% >70%, match:class org.pulseaudio.pavucontrol
|
||||
|
||||
# Put workspaces on specific monitors
|
||||
workspace = 1, monitor:desc:Ancor Communications Inc ASUS PB298 D7LMTF059917, persistent:true, default:true
|
||||
workspace = 2, monitor:desc:Ancor Communications Inc ASUS PB298 D7LMTF059917, persistent:true
|
||||
workspace = 3, monitor:desc:Ancor Communications Inc ASUS PB298 D7LMTF059917, persistent:true
|
||||
workspace = 4, monitor:desc:Ancor Communications Inc ASUS PB298 D7LMTF059917, persistent:true
|
||||
workspace = 5, monitor:desc:Ancor Communications Inc ASUS PB298 D7LMTF059917, persistent:true
|
||||
workspace = 6, monitor:desc:Ancor Communications Inc ASUS PB298 D7LMTF059917, persistent:true
|
||||
workspace = 7, monitor:desc:Ancor Communications Inc ASUS PB298 D7LMTF059917, persistent:true
|
||||
workspace = 8, monitor:desc:Ancor Communications Inc ASUS PB298 D7LMTF059917, persistent:true
|
||||
workspace = 9, monitor:desc:Iiyama North America PL2492H 11511037C7430, persistent:true, default:true
|
||||
workspace = 10, monitor:desc:Iiyama North America PL2492H 11511037C7430, persistent:true
|
||||
@@ -0,0 +1,73 @@
|
||||
$font_size = 48
|
||||
$font_size_small = 16
|
||||
$image_size = 175
|
||||
|
||||
general {
|
||||
hide_cursor = true
|
||||
ignore_empty_input = true
|
||||
}
|
||||
|
||||
background {
|
||||
monitor =
|
||||
path = screenshot
|
||||
blur_passes = 2
|
||||
blur_size = 2
|
||||
noise = 0
|
||||
}
|
||||
|
||||
label {
|
||||
font_family = DejaVu Sans Serif
|
||||
font_size = $font_size
|
||||
|
||||
text = $TIME12
|
||||
text_align = center
|
||||
|
||||
position = 0, 275
|
||||
halign = center
|
||||
valign = center
|
||||
}
|
||||
|
||||
label {
|
||||
font_family = DejaVu Sans Serif
|
||||
font_size = $font_size_small
|
||||
|
||||
text = cmd[] date "+%A, %B %d"
|
||||
|
||||
position = 0, 200
|
||||
halign = center
|
||||
valign = center
|
||||
}
|
||||
|
||||
image {
|
||||
monitor =
|
||||
path = ~/.local/bin/wm/lock.png
|
||||
size = $image_size
|
||||
rounding = -1
|
||||
border_size = 0
|
||||
|
||||
halign = center
|
||||
valign = center
|
||||
}
|
||||
|
||||
input-field {
|
||||
monitor =
|
||||
size = $image_size, $image_size
|
||||
|
||||
outline_thickness = 10
|
||||
outer_color = rgba(255, 255, 255, 0.0)
|
||||
inner_color = rgba(0, 0, 0, 0.0)
|
||||
check_color = rgba(255, 255, 255, 1.0)
|
||||
fail_color = rgba(255, 0, 0, 1.0)
|
||||
|
||||
font_family = DejaVu Sans Serif
|
||||
font_color = rgba(255, 255, 255, 0.9)
|
||||
placeholder_text =
|
||||
fail_text =
|
||||
|
||||
hide_input = true
|
||||
rounding = -1
|
||||
fade_on_empty = false
|
||||
|
||||
halign = center
|
||||
valign = center
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
splash = false
|
||||
@@ -1,13 +1,22 @@
|
||||
[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
|
||||
terminal = urxvt
|
||||
|
||||
# >>> session=xorg
|
||||
type_library = xdotool
|
||||
# <<<
|
||||
# >>> session=wayland
|
||||
# type_library = ydotool
|
||||
# <<<
|
||||
|
||||
hide_groups = Recycle Bin
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"ignorePatterns": [
|
||||
".git/",
|
||||
"*.md",
|
||||
"manafiles.json",
|
||||
"packages",
|
||||
"README.org",
|
||||
"screenshot.png"
|
||||
],
|
||||
"systemPatterns": [
|
||||
"/boot/",
|
||||
"/etc/",
|
||||
"/usr/lib/",
|
||||
"/usr/share/"
|
||||
]
|
||||
}
|
||||
@@ -31,7 +31,7 @@ sub-auto=fuzzy
|
||||
sub-file-paths=ass:srt:sub:subs:subtitles:Subtitles
|
||||
|
||||
# [SUBTITLES LOOK] (for srt)
|
||||
sub-font="Segoe UI Semibold"
|
||||
sub-font="DejaVu Sans"
|
||||
sub-font-size=48
|
||||
sub-margin-y=36
|
||||
sub-color="#FFFFFFFF"
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
-- when opening a .lua file, this file gets executed
|
||||
vim.opt.expandtab = false
|
||||
@@ -0,0 +1,10 @@
|
||||
require("core")
|
||||
require("packages").setup({
|
||||
require("ui"),
|
||||
require("selection"),
|
||||
require("editor"),
|
||||
require("development"),
|
||||
require("git"),
|
||||
})
|
||||
require("terminal").setup()
|
||||
require("keybinds").setup()
|
||||
@@ -0,0 +1,43 @@
|
||||
{
|
||||
"Comment.nvim": { "branch": "master", "commit": "e30b7f2008e52442154b66f7c519bfd2f1e32acb" },
|
||||
"LuaSnip": { "branch": "master", "commit": "3732756842a2f7e0e76a7b0487e9692072857277" },
|
||||
"auto-save.nvim": { "branch": "main", "commit": "37c82fd548e3f5ffc2d9d020a65dac1044584f44" },
|
||||
"cmp-buffer": { "branch": "main", "commit": "b74fab3656eea9de20a9b8116afa3cfc4ec09657" },
|
||||
"cmp-nvim-lsp": { "branch": "main", "commit": "cbc7b02bb99fae35cb42f514762b89b5126651ef" },
|
||||
"cmp-nvim-lua": { "branch": "main", "commit": "e3a22cb071eb9d6508a156306b102c45cd2d573d" },
|
||||
"cmp-path": { "branch": "main", "commit": "c642487086dbd9a93160e1679a1327be111cbc25" },
|
||||
"cmp_luasnip": { "branch": "master", "commit": "98d9cb5c2c38532bd9bdb481067b20fea8f32e90" },
|
||||
"dashboard-nvim": { "branch": "master", "commit": "0775e567b6c0be96d01a61795f7b64c1758262f6" },
|
||||
"diffview.nvim": { "branch": "main", "commit": "4516612fe98ff56ae0415a259ff6361a89419b0a" },
|
||||
"friendly-snippets": { "branch": "main", "commit": "572f5660cf05f8cd8834e096d7b4c921ba18e175" },
|
||||
"gitsigns.nvim": { "branch": "main", "commit": "5813e4878748805f1518cee7abb50fd7205a3a48" },
|
||||
"lazy.nvim": { "branch": "main", "commit": "85c7ff3711b730b4030d03144f6db6375044ae82" },
|
||||
"lspkind.nvim": { "branch": "master", "commit": "3ddd1b4edefa425fda5a9f95a4f25578727c0bb3" },
|
||||
"lspsaga.nvim": { "branch": "main", "commit": "8efe00d6aed9db6449969f889170f1a7e43101a1" },
|
||||
"lualine.nvim": { "branch": "master", "commit": "47f91c416daef12db467145e16bed5bbfe00add8" },
|
||||
"neodev.nvim": { "branch": "main", "commit": "46aa467dca16cf3dfe27098042402066d2ae242d" },
|
||||
"neogit": { "branch": "master", "commit": "d8bf9102692250193b855acd9025a826f1af2729" },
|
||||
"nvim-base16": { "branch": "master", "commit": "e05bcb99951d8ae4ecbf4ae053922fd2be6263a5" },
|
||||
"nvim-cmp": { "branch": "main", "commit": "d97d85e01339f01b842e6ec1502f639b080cb0fc" },
|
||||
"nvim-colorizer.lua": { "branch": "master", "commit": "a065833f35a3a7cc3ef137ac88b5381da2ba302e" },
|
||||
"nvim-lspconfig": { "branch": "master", "commit": "d696e36d5792daf828f8c8e8d4b9aa90c1a10c2a" },
|
||||
"nvim-treesitter": { "branch": "main", "commit": "42fc28ba918343ebfd5565147a42a26580579482" },
|
||||
"nvim-treesitter-textobjects": { "branch": "master", "commit": "5ca4aaa6efdcc59be46b95a3e876300cfead05ef" },
|
||||
"nvim-web-devicons": { "branch": "master", "commit": "6788013bb9cb784e606ada44206b0e755e4323d7" },
|
||||
"omnisharp-extended-lsp.nvim": { "branch": "main", "commit": "a47388e5417e7f1cfa6962cc441a23c4c5fb2151" },
|
||||
"plenary.nvim": { "branch": "master", "commit": "b9fd5226c2f76c951fc8ed5923d85e4de065e509" },
|
||||
"project.nvim": { "branch": "main", "commit": "8c6bad7d22eef1b71144b401c9f74ed01526a4fb" },
|
||||
"rainbow-delimiters.nvim": { "branch": "master", "commit": "8aafe2cbd89cd4090f573a98cab6b20366576fde" },
|
||||
"sqlite.lua": { "branch": "master", "commit": "50092d60feb242602d7578398c6eb53b4a8ffe7b" },
|
||||
"telescope-all-recent.nvim": { "branch": "main", "commit": "e437f60ea468268e49ffdc0c9ed7c5ba384e63cf" },
|
||||
"telescope-file-browser.nvim": { "branch": "master", "commit": "3610dc7dc91f06aa98b11dca5cc30dfa98626b7e" },
|
||||
"telescope-fzf-native.nvim": { "branch": "main", "commit": "6fea601bd2b694c6f2ae08a6c6fab14930c60e2c" },
|
||||
"telescope-recent-files": { "branch": "main", "commit": "eb190c0baded1cbfa9d8767c817b054377683163" },
|
||||
"telescope.nvim": { "branch": "0.1.x", "commit": "a0bbec21143c7bc5f8bb02e0005fa0b982edc026" },
|
||||
"todo-comments.nvim": { "branch": "main", "commit": "31e3c38ce9b29781e4422fc0322eb0a21f4e8668" },
|
||||
"toggleterm.nvim": { "branch": "main", "commit": "9a88eae817ef395952e08650b3283726786fb5fb" },
|
||||
"trouble.nvim": { "branch": "main", "commit": "bd67efe408d4816e25e8491cc5ad4088e708a69a" },
|
||||
"ultimate-autopair.nvim": { "branch": "development", "commit": "5835876b57901d81ebbeb3cd6ad71aaed66f82d7" },
|
||||
"vim-sleuth": { "branch": "master", "commit": "be69bff86754b1aa5adcbb527d7fcd1635a84080" },
|
||||
"which-key.nvim": { "branch": "main", "commit": "3aab2147e74890957785941f0c1ad87d0a44c15a" }
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
require("core.leader-key")
|
||||
require("core.config")
|
||||
require("core.buffers")
|
||||
require("core.autocommands")
|
||||
require("core.globals")
|
||||
require("core.filetypes")
|
||||
@@ -0,0 +1,59 @@
|
||||
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,
|
||||
})
|
||||
|
||||
vim.api.nvim_create_autocmd("BufWinEnter", {
|
||||
callback = function()
|
||||
-- Buffer tracking
|
||||
require("core.buffers").add_buffer()
|
||||
end,
|
||||
desc = "Track all full window buffers visited",
|
||||
})
|
||||
|
||||
vim.api.nvim_create_autocmd({ "BufDelete", "BufWipeout" }, {
|
||||
callback = function(opts)
|
||||
-- Buffer tracking
|
||||
require("core.buffers").remove_buffer(opts.match)
|
||||
end,
|
||||
desc = "Track all full window buffers killed",
|
||||
})
|
||||
@@ -0,0 +1,347 @@
|
||||
local F = require("core.functions")
|
||||
|
||||
-- Module for managing buffers, these are used for navigation
|
||||
|
||||
local M = {}
|
||||
|
||||
-- Buffers, categorized into groups
|
||||
-- {
|
||||
-- { group = "Project", buffers = { "buffer1", "buffer2" }, active_index = 1 },
|
||||
-- { group = "Other", buffers = { "buffer3", "buffer4" }, 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)
|
||||
|
||||
local index
|
||||
for i, buffer_group in ipairs(M.buffers) do
|
||||
if buffer_group.group == group then index = i end
|
||||
end
|
||||
|
||||
-- Group is new entirely, so we only have 1 buffer
|
||||
if not index then
|
||||
table.insert(M.buffers, { group = group, buffers = { buffer_name }, active_index = 1 })
|
||||
return #M.buffers, 1 -- group index, buffer index
|
||||
end
|
||||
|
||||
-- Buffer previously added, set active
|
||||
for i, buffer in ipairs(M.buffers[index].buffers) do
|
||||
if buffer == buffer_name then
|
||||
M.buffers[index].active_index = i
|
||||
return index, i -- group index, buffer index
|
||||
end
|
||||
end
|
||||
|
||||
-- Buffer is new, add it to the list
|
||||
table.insert(M.buffers[index].buffers, buffer_name)
|
||||
local count = #M.buffers[index].buffers
|
||||
M.buffers[index].active_index = count
|
||||
|
||||
return index, count -- group index, buffer index
|
||||
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 i, buffer_group in ipairs(M.buffers) do
|
||||
for j, buffer in ipairs(buffer_group.buffers) do
|
||||
if buffer == buffer_name then
|
||||
return i, j -- group index, buffer index
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
local focus_buffer = function(new_buffer_name)
|
||||
for _, buffer in ipairs(vim.api.nvim_list_bufs()) do
|
||||
if vim.api.nvim_buf_get_name(buffer) == new_buffer_name then
|
||||
vim.api.nvim_set_current_buf(buffer)
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
M.remove_buffer = function(buffer_name)
|
||||
if not buffer_name or buffer_name == "" then return end
|
||||
|
||||
local group_index, buffer_index = get_group_from_buffer(buffer_name)
|
||||
if not group_index or not buffer_index then return end
|
||||
|
||||
local buffer_group = M.buffers[group_index]
|
||||
|
||||
-- Remove the buffer and decrease active index
|
||||
table.remove(buffer_group.buffers, buffer_index)
|
||||
buffer_group.active_index = math.max(buffer_group.active_index - 1, 1)
|
||||
local new_buffer_name = buffer_group.buffers[buffer_group.active_index]
|
||||
|
||||
-- If there are now no buffers in the group, delete the group
|
||||
if #buffer_group.buffers == 0 then
|
||||
table.remove(M.buffers, group_index)
|
||||
if #M.buffers == 0 then return end
|
||||
if #M.buffers < group_index then group_index = group_index - 1 end
|
||||
new_buffer_name = M.buffers[group_index].buffers[M.buffers[group_index].active_index]
|
||||
end
|
||||
|
||||
-- Make the new index the active buffer
|
||||
focus_buffer(new_buffer_name)
|
||||
end
|
||||
|
||||
local buffer_action_in_active_group = function(action, direction)
|
||||
local buffer_name = get_buffer_name()
|
||||
if not buffer_name then return end
|
||||
|
||||
-- Get active group from the current buffer
|
||||
local group_index, buffer_index = get_group_from_buffer(buffer_name)
|
||||
if not group_index then group_index, buffer_index = M.add_buffer() end
|
||||
|
||||
-- Get buffer set
|
||||
local buffers = M.buffers[group_index].buffers
|
||||
if #buffers < 2 then return end
|
||||
|
||||
-- Determine the other index
|
||||
local other_index = buffer_index + direction
|
||||
if buffer_index == 1 and direction == -1 then
|
||||
other_index = #buffers
|
||||
elseif buffer_index == #buffers and direction == 1 then
|
||||
other_index = 1
|
||||
end
|
||||
|
||||
if action == "move" then
|
||||
for _, buffer in ipairs(vim.api.nvim_list_bufs()) do
|
||||
-- TODO: Probably not needed if the other autocommands are implemented
|
||||
-- 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)
|
||||
M.buffers[group_index].active_index = other_index
|
||||
break
|
||||
end
|
||||
|
||||
::continue::
|
||||
end
|
||||
elseif action == "swap" then
|
||||
local tmp = buffers[other_index]
|
||||
buffers[other_index] = buffers[buffer_index]
|
||||
buffers[buffer_index] = tmp
|
||||
end
|
||||
|
||||
M.buffers[group_index].buffers = 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
|
||||
|
||||
-- Get active group from the current buffer
|
||||
local group_index, _ = get_group_from_buffer(buffer_name)
|
||||
if not group_index then group_index, _ = M.add_buffer() end
|
||||
|
||||
-- Check groups bounds
|
||||
if #M.buffers < 2 then return end
|
||||
|
||||
-- Determine the other index
|
||||
local other_index = group_index + direction
|
||||
if group_index == 1 and direction == -1 then
|
||||
other_index = #M.buffers
|
||||
elseif group_index == #M.buffers and direction == 1 then
|
||||
other_index = 1
|
||||
end
|
||||
|
||||
-- Get active index from other group
|
||||
local other_active_index = M.buffers[other_index].active_index
|
||||
|
||||
-- Make buffer active
|
||||
-- TODO: What do if this buffer no longer exists?
|
||||
local other_buffer = M.buffers[other_index].buffers[other_active_index]
|
||||
focus_buffer(other_buffer)
|
||||
end
|
||||
|
||||
M.buffer_group_move_up = function()
|
||||
buffer_group_move(-1)
|
||||
end
|
||||
|
||||
M.buffer_group_move_down = function()
|
||||
buffer_group_move(1)
|
||||
end
|
||||
|
||||
--------------------------------------------
|
||||
-- Telescope functionss
|
||||
|
||||
local pick = function(title, items, entry_maker, action)
|
||||
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 = title,
|
||||
finder = finders.new_table {
|
||||
results = items,
|
||||
entry_maker = entry_maker,
|
||||
},
|
||||
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()
|
||||
action(selection)
|
||||
end)
|
||||
|
||||
return true
|
||||
end,
|
||||
}):find()
|
||||
end
|
||||
|
||||
M.buffer_pick_buffer = function()
|
||||
local buffer_name = get_buffer_name()
|
||||
if not buffer_name then return end
|
||||
|
||||
-- Get active group from the current buffer
|
||||
local group_index, _ = get_group_from_buffer(buffer_name)
|
||||
if not group_index then group_index, _ = M.add_buffer() end
|
||||
|
||||
-- Get all buffers from the active group
|
||||
local buffers = {}
|
||||
for i, buffer in ipairs(M.buffers[group_index].buffers) do
|
||||
table.insert(buffers, { key = buffer, value = tostring(i) })
|
||||
end
|
||||
|
||||
pick("Group buffers",
|
||||
buffers,
|
||||
function(buffer)
|
||||
-- Only show last part of the path
|
||||
local display = buffer.key:match("^.+/(.+)$") or buffer.key
|
||||
return {
|
||||
display = display, -- shown in the picker
|
||||
ordinal = buffer.value, -- used for sorting/filtering
|
||||
value = buffer.value, -- actual value
|
||||
}
|
||||
end,
|
||||
function(selection)
|
||||
local new_buffer_name = M.buffers[group_index].buffers[tonumber(selection.value)]
|
||||
|
||||
-- Make new buffer active
|
||||
focus_buffer(new_buffer_name)
|
||||
end
|
||||
)
|
||||
end
|
||||
|
||||
M.buffer_pick_group = function()
|
||||
-- Get all groups
|
||||
local groups = {}
|
||||
for i, buffer_group in ipairs(M.buffers) do
|
||||
table.insert(groups, { key = buffer_group.group, value = tostring(i) })
|
||||
end
|
||||
|
||||
pick("Groups",
|
||||
groups,
|
||||
function(group)
|
||||
-- Only show last part of the path
|
||||
local display = group.key:match("^.+/(.+)$") or group.key
|
||||
return {
|
||||
display = display, -- shown in the picker
|
||||
ordinal = group.value, -- used for sorting/filtering
|
||||
value = group.value, -- actual value
|
||||
}
|
||||
end,
|
||||
function(selection)
|
||||
local buffer_group = M.buffers[tonumber(selection.value)]
|
||||
local new_buffer_name = buffer_group.buffers[buffer_group.active_index]
|
||||
|
||||
-- Make new buffer active
|
||||
focus_buffer(new_buffer_name)
|
||||
end
|
||||
)
|
||||
end
|
||||
|
||||
return M
|
||||
@@ -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
|
||||
@@ -0,0 +1,5 @@
|
||||
vim.filetype.add({
|
||||
extension = {
|
||||
flw = "lua",
|
||||
},
|
||||
})
|
||||
@@ -0,0 +1,81 @@
|
||||
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.normalize_path = function(path)
|
||||
if not path then return nil end
|
||||
return IS_WINDOWS() and path:gsub("\\", "/") or path
|
||||
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 M.normalize_path(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 M.normalize_path(vim.fn.fnamemodify(vim.fn.bufname(), ":p"))
|
||||
end
|
||||
|
||||
M.get_current_directory = function()
|
||||
return M.get_file_path() or M.get_netrw_path() or M.normalize_path(vim.fn.getcwd())
|
||||
end
|
||||
|
||||
M.find_project_root = function()
|
||||
local current_directory = M.get_current_directory()
|
||||
if current_directory:match("^term://") then return nil, current_directory end
|
||||
|
||||
local directory = current_directory
|
||||
while directory ~= "/" and not directory:match("^%a:[/\\]?$") do
|
||||
local git_path = vim.loop.fs_stat(directory .. "/.git")
|
||||
if git_path then
|
||||
return M.normalize_path(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 M.normalize_path(directory:gsub("/$", "")) -- remove trailing slash
|
||||
end
|
||||
|
||||
directory = M.normalize_path(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
|
||||
@@ -0,0 +1,23 @@
|
||||
IS_WINDOWS = function()
|
||||
return string.find(vim.loop.os_uname().sysname, "NT")
|
||||
end
|
||||
|
||||
-- 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) }, vim.fn.stdpath("cache") .. "/log", "a")
|
||||
end
|
||||
@@ -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 = " "
|
||||
@@ -0,0 +1,213 @@
|
||||
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'}
|
||||
-- },
|
||||
vue_ls = {},
|
||||
}
|
||||
|
||||
-- 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)
|
||||
if vim.lsp.config then
|
||||
vim.lsp.config(server, opts)
|
||||
vim.lsp.enable(server)
|
||||
else
|
||||
require("lspconfig")[server].setup(opts)
|
||||
end
|
||||
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
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -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",
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
}
|
||||
@@ -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 = {},
|
||||
},
|
||||
|
||||
}
|
||||
@@ -0,0 +1,313 @@
|
||||
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
|
||||
|
||||
M.toggle_term = function()
|
||||
vim.api.nvim_command("ToggleTerm")
|
||||
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
|
||||
@@ -0,0 +1,273 @@
|
||||
local K = vim.keymap.set
|
||||
|
||||
local builtin
|
||||
local bs = require("core.buffers")
|
||||
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())
|
||||
|
||||
-- Navigation
|
||||
K("n", "<M-h>", bs.buffer_move_left)
|
||||
K("n", "<M-j>", bs.buffer_group_move_down)
|
||||
K("n", "<M-k>", bs.buffer_group_move_up)
|
||||
K("n", "<M-l>", bs.buffer_move_right)
|
||||
K("n", "<M-H>", bs.buffer_swap_left)
|
||||
K("n", "<M-L>", bs.buffer_swap_right)
|
||||
|
||||
-- Terminal
|
||||
K("n", "<C-\\>", F.toggle_term)
|
||||
K("t", "<C-\\>", F.toggle_term)
|
||||
|
||||
----------------------------------------
|
||||
--- 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>bB", bs.buffer_pick_buffer, { desc = "Switch tab group 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>t", "tabs/toggle")
|
||||
K("n", "<leader>tg", bs.buffer_pick_group, { desc = "Switch tab group" })
|
||||
|
||||
|
||||
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
|
||||
|
||||
-- Keybindings for toggleterm.nvim
|
||||
M.toggleterm_nvim = function()
|
||||
local keymaps = function()
|
||||
local opts = { buffer = 0 }
|
||||
K("t", "<Esc>", [[<C-\><C-n>]], opts)
|
||||
end
|
||||
|
||||
vim.api.nvim_create_autocmd("TermOpen", {
|
||||
pattern = "term://*toggleterm#*",
|
||||
callback = keymaps,
|
||||
})
|
||||
end
|
||||
|
||||
return M
|
||||
@@ -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
|
||||
@@ -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 = IS_WINDOWS() and "mingw32-make" or "make",
|
||||
cond = function()
|
||||
return vim.fn.executable(IS_WINDOWS() and "mingw32-make" or "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",
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
-- Module for managing popup terminal
|
||||
|
||||
local M = {}
|
||||
|
||||
M.persistent_term = nil
|
||||
|
||||
local create_command = function(name, command)
|
||||
if not name or type(name) ~= "string" then return end
|
||||
|
||||
vim.api.nvim_create_user_command(name, function()
|
||||
local cmd = type(command) == "function" and command() or command
|
||||
M.send_cmd_to_term(cmd)
|
||||
end, {})
|
||||
end
|
||||
|
||||
M.setup = function()
|
||||
-- Setup keybinds
|
||||
require("keybinds").toggleterm_nvim()
|
||||
|
||||
create_command("RunScript", "sleep 2 && ls /")
|
||||
create_command("ScanScript", function()
|
||||
local file_path = vim.fn.expand("%:p")
|
||||
LOG(file_path)
|
||||
|
||||
return "ls"
|
||||
end)
|
||||
end
|
||||
|
||||
M.send_cmd_to_term = function(cmd)
|
||||
local term = require("toggleterm.terminal").Terminal
|
||||
local default = term:new({ id = 1 })
|
||||
if not default:is_open() then default:open() end
|
||||
default:send(cmd)
|
||||
end
|
||||
|
||||
return M
|
||||
@@ -0,0 +1,209 @@
|
||||
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
|
||||
|
||||
-- Popup terminal
|
||||
{
|
||||
"akinsho/toggleterm.nvim",
|
||||
config = function()
|
||||
vim.cmd [[let &shellcmdflag = '-s']] -- required for Windows
|
||||
require("toggleterm").setup({
|
||||
auto_scroll = true,
|
||||
direction = "float",
|
||||
float_opts = {
|
||||
border = "curved",
|
||||
row = function() return vim.o.lines - 4 end,
|
||||
width = function() return vim.o.columns - 6 end,
|
||||
height = 20,
|
||||
winblend = 0,
|
||||
},
|
||||
hide_numbers = true,
|
||||
open_mapping = nil,
|
||||
persist_mode = true,
|
||||
size = 20,
|
||||
start_in_insert = true,
|
||||
})
|
||||
end,
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"export-settings-ini": true,
|
||||
"export-gtkrc-20": true,
|
||||
"export-index-theme": true,
|
||||
"export-xsettingsd": true,
|
||||
"export-gtk4-symlinks": true
|
||||
}
|
||||
@@ -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}
|
||||
|
||||
@@ -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)
|
||||
@@ -3,7 +3,7 @@ color_scheme_path=/usr/share/qt5ct/colors/darker.conf
|
||||
custom_palette=false
|
||||
icon_theme=Arc
|
||||
standard_dialogs=default
|
||||
style=qt5gtk2
|
||||
style=kvantum
|
||||
|
||||
[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)
|
||||
|
||||
@@ -3,11 +3,11 @@ color_scheme_path=/usr/share/qt6ct/colors/darker.conf
|
||||
custom_palette=false
|
||||
icon_theme=Arc
|
||||
standard_dialogs=default
|
||||
style=qt6gtk2
|
||||
style=kvantum
|
||||
|
||||
[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)
|
||||
fixed="DejaVu Sans,10,-1,5,400,0,0,0,0,0,0,0,0,0,0,1"
|
||||
general="DejaVu Sans,10,-1,5,400,0,0,0,0,0,0,0,0,0,0,1"
|
||||
|
||||
[Interface]
|
||||
activate_item_on_single_click=1
|
||||
|
||||
@@ -22,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";
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,146 @@
|
||||
// -*- mode: jsonc -*-
|
||||
{
|
||||
// "layer": "top", // Waybar at top layer
|
||||
"position": "top",
|
||||
"height": 22, // Waybar height (to be removed for auto height)
|
||||
"spacing": 0, // Gaps between modules (4px)
|
||||
// Choose the order of the modules
|
||||
"modules-left": [
|
||||
"hyprland/workspaces",
|
||||
],
|
||||
"modules-center": [
|
||||
"hyprland/window"
|
||||
],
|
||||
"modules-right": [
|
||||
"custom/btc",
|
||||
"pulseaudio",
|
||||
"backlight",
|
||||
"network",
|
||||
"battery",
|
||||
"custom/battery-low",
|
||||
"clock",
|
||||
"tray",
|
||||
"custom/power"
|
||||
],
|
||||
// Modules configuration
|
||||
"hyprland/workspaces": {
|
||||
"disable-scroll": false,
|
||||
"on-scroll-up": "hyprctl dispatch workspace -1",
|
||||
"on-scroll-down": "hyprctl dispatch workspace +1",
|
||||
"all-outputs": false,
|
||||
"warp-on-scroll": false,
|
||||
"format": "{icon}",
|
||||
"format-icons": {
|
||||
"1": "一",
|
||||
"2": "二",
|
||||
"3": "三",
|
||||
"4": "四",
|
||||
"5": "五",
|
||||
"6": "六",
|
||||
"7": "七",
|
||||
"8": "八",
|
||||
"9": "九",
|
||||
"10": "十",
|
||||
"urgent": "",
|
||||
"focused": "",
|
||||
"default": ""
|
||||
}
|
||||
},
|
||||
"custom/btc": {
|
||||
"escape": false,
|
||||
"exec": "$HOME/.local/bin/panel/btc.sh",
|
||||
"interval": 300,
|
||||
"format": " {}",
|
||||
"tooltip": false
|
||||
},
|
||||
"pulseaudio": {
|
||||
"scroll-step": 2, // %, can be a float
|
||||
"format": "{icon} {volume}%",
|
||||
"format-bluetooth": "{icon} {volume}%",
|
||||
"format-bluetooth-muted": " {icon}",
|
||||
"format-muted": " {volume}%",
|
||||
"format-source": "{volume}%",
|
||||
"format-source-muted": "",
|
||||
"format-icons": {
|
||||
"headphone": "",
|
||||
"hands-free": "",
|
||||
"headset": "",
|
||||
"phone": "",
|
||||
"portable": "",
|
||||
"car": "",
|
||||
"default": ["", "", ""]
|
||||
},
|
||||
"on-click": "pavucontrol"
|
||||
},
|
||||
"backlight": {
|
||||
"device": "intel_backlight",
|
||||
"format": "{percent}% {icon}",
|
||||
"format-icons": ["", "", "", "", "", "", "", "", ""]
|
||||
},
|
||||
"network": {
|
||||
"format-wifi": " {signalStrength}%",
|
||||
"format-ethernet": "",
|
||||
"tooltip-format": "{ifname}: {ipaddr}/{cidr}\n via {gwaddr}",
|
||||
"tooltip-format-wifi": "{ifname}: {ipaddr}/{cidr}\n via {gwaddr}\n ssid {essid}",
|
||||
"tooltip-format-disconnected": "Disconnected",
|
||||
"format-linked": " (No IP)",
|
||||
"format-disconnected": "<span color='#676e7d'></span>",
|
||||
"on-click": "$HOME/.local/bin/panel/iface.sh"
|
||||
},
|
||||
"battery": {
|
||||
"bat": "BAT0",
|
||||
"interval": 30,
|
||||
"full-at": 98,
|
||||
"states": {
|
||||
"good": 95,
|
||||
"critical": 20
|
||||
},
|
||||
"format": "{icon} {capacity}% ({time})",
|
||||
"format-time": "{H}:{m}",
|
||||
"format-full": "{icon} {capacity}%",
|
||||
"format-charging": " {capacity}%",
|
||||
"format-plugged": " {capacity}%",
|
||||
"format-icons": ["", "", "", "", ""]
|
||||
},
|
||||
"custom/battery-low": {
|
||||
"exec": "$HOME/.local/bin/panel/battery.sh",
|
||||
"interval": 30,
|
||||
"format": "",
|
||||
"tooltip": false
|
||||
},
|
||||
"clock": {
|
||||
// "timezone": "America/New_York",
|
||||
"tooltip-format": "<tt><small>{calendar}</small></tt>",
|
||||
"calendar": {
|
||||
"mode" : "month",
|
||||
"mode-mon-col" : 3,
|
||||
"weeks-pos" : "right",
|
||||
"format": {
|
||||
"months": "<span color='#b294bb'><b>{}</b></span>",
|
||||
"days": "<span color='#fff'><b>{}</b></span>",
|
||||
"weeks": "<span color='#81a2be'><b>W{}</b></span>",
|
||||
"weekdays": "<span color='#8abeb7'><b>{}</b></span>",
|
||||
"today": "<span color='#f0c674'><b><u>{}</u></b></span>"
|
||||
}
|
||||
},
|
||||
"format": " {:%I:%M %p}",
|
||||
"on-click": "$HOME/.local/bin/panel/date.sh"
|
||||
},
|
||||
"tray": {
|
||||
// "icon-size": 21,
|
||||
"spacing": 10
|
||||
},
|
||||
"custom/power": {
|
||||
"format": "⏻",
|
||||
"tooltip": false,
|
||||
"menu": "on-click",
|
||||
"menu-file": "$HOME/.config/waybar/power_menu.xml", // Menu file in resources folder
|
||||
"menu-actions": {
|
||||
"lock": "hyprlock",
|
||||
"shutdown": "shutdown",
|
||||
"reboot": "reboot",
|
||||
"suspend": "systemctl suspend",
|
||||
"hibernate": "systemctl hibernate"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<object class="GtkMenu" id="menu">
|
||||
<child>
|
||||
<object class="GtkMenuItem" id="lock">
|
||||
<property name="label">Lock</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuItem" id="suspend">
|
||||
<property name="label">Suspend</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuItem" id="hibernate">
|
||||
<property name="label">Hibernate</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuItem" id="shutdown">
|
||||
<property name="label">Shutdown</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSeparatorMenuItem" id="delimiter1"/>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuItem" id="reboot">
|
||||
<property name="label">Reboot</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</interface>
|
||||
@@ -0,0 +1,236 @@
|
||||
@define-color black #000;
|
||||
@define-color red #a54242; /* 1 */
|
||||
@define-color orange #de935f; /* 3 */
|
||||
@define-color blue #5f819d; /* 4 */
|
||||
@define-color green #b5bd68; /* 10 */
|
||||
|
||||
@define-color bgcolor #404552;
|
||||
@define-color bgcolor-inactive #2b2e39;
|
||||
@define-color bgcolor-urgent #dc7a43;
|
||||
@define-color fgcolor #fff;
|
||||
@define-color fgcolor-inactive #676e7d;
|
||||
|
||||
* {
|
||||
/* `otf-font-awesome` is required to be installed for icons */
|
||||
font-family: FontAwesome, DejaVu Sans Serif;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
window#waybar {
|
||||
background-color: @bgcolor-inactive;
|
||||
color: @fgcolor;
|
||||
transition-property: background-color;
|
||||
transition-duration: .5s;
|
||||
}
|
||||
|
||||
window#waybar.hidden {
|
||||
opacity: 0.2;
|
||||
}
|
||||
|
||||
button {
|
||||
/* Use box-shadow instead of border so the text isn't offset */
|
||||
box-shadow: inset 0 -3px transparent;
|
||||
/* Avoid rounded borders under each button name */
|
||||
border: none;
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
/* https://github.com/Alexays/Waybar/wiki/FAQ#the-workspace-buttons-have-a-strange-hover-effect */
|
||||
button:hover {
|
||||
background: inherit;
|
||||
box-shadow: inset 0 -3px @fgcolor;
|
||||
}
|
||||
|
||||
#custom-btc,
|
||||
#pulseaudio,
|
||||
#wireplumber,
|
||||
#custom-media,
|
||||
#backlight,
|
||||
#network,
|
||||
#battery,
|
||||
#clock,
|
||||
#tray,
|
||||
#custom-power {
|
||||
padding: 0 6px;
|
||||
color: @fgcolor;
|
||||
}
|
||||
|
||||
#window,
|
||||
#workspaces {
|
||||
margin: 0 4px;
|
||||
}
|
||||
|
||||
@keyframes blink {
|
||||
to {
|
||||
background-color: @fgcolor;
|
||||
color: @black;
|
||||
}
|
||||
}
|
||||
|
||||
label:focus {
|
||||
background-color: @black;
|
||||
}
|
||||
|
||||
/* -------------------------------------- */
|
||||
/* Workspaces module */
|
||||
|
||||
#workspaces button {
|
||||
padding: 0 5px;
|
||||
background-color: transparent;
|
||||
color: @fgcolor-inactive;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
#workspaces button:hover,
|
||||
#workspaces button.empty:hover {
|
||||
background-color: @bgcolor;
|
||||
color: @fgcolor-inactive;
|
||||
}
|
||||
|
||||
#workspaces button.active,
|
||||
#workspaces button.active.empty {
|
||||
background-color: @bgcolor;
|
||||
box-shadow: inset 0 -3px @blue;
|
||||
color: @fgcolor;
|
||||
}
|
||||
|
||||
#workspaces button.empty {
|
||||
background-color: transparent;
|
||||
color: @bgcolor;
|
||||
}
|
||||
|
||||
#workspaces button.focused {
|
||||
background-color: @bgcolor;
|
||||
}
|
||||
|
||||
#workspaces button.urgent {
|
||||
background-color: @bgcolor-urgent;
|
||||
}
|
||||
|
||||
/* If workspaces is the leftmost module, omit left margin */
|
||||
.modules-left > widget:first-child > #workspaces {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
/* If workspaces is the rightmost module, omit right margin */
|
||||
.modules-right > widget:last-child > #workspaces {
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
/* -------------------------------------- */
|
||||
/* BTC module */
|
||||
|
||||
#custom-btc:hover {
|
||||
background-color: @bgcolor;
|
||||
}
|
||||
|
||||
/* -------------------------------------- */
|
||||
/* Media modules */
|
||||
|
||||
#pulseaudio, #wireplumber {
|
||||
color: @fgcolor;
|
||||
}
|
||||
|
||||
#pulseaudio:hover, #wireplumber:hover {
|
||||
background-color: @bgcolor;
|
||||
}
|
||||
|
||||
#pulseaudio.muted, #wireplumber.muted {
|
||||
color: @fgcolor-inactive
|
||||
}
|
||||
|
||||
#custom-media {
|
||||
color: @green;
|
||||
min-width: 100px;
|
||||
}
|
||||
|
||||
#custom-media.custom-spotify {
|
||||
color: @green;
|
||||
}
|
||||
|
||||
#custom-media.custom-vlc {
|
||||
color: @orange;
|
||||
}
|
||||
|
||||
/* -------------------------------------- */
|
||||
/* Backlight module */
|
||||
|
||||
#backlight:hover {
|
||||
background-color: @bgcolor;
|
||||
}
|
||||
|
||||
/* -------------------------------------- */
|
||||
/* Network module */
|
||||
|
||||
#network:hover {
|
||||
background-color: @bgcolor;
|
||||
}
|
||||
|
||||
#network.disconnected {
|
||||
background-color: @bgcolor-inactive;
|
||||
}
|
||||
|
||||
/* -------------------------------------- */
|
||||
/* Battery module */
|
||||
|
||||
#battery:hover {
|
||||
background-color: @bgcolor;
|
||||
}
|
||||
|
||||
#battery.good {
|
||||
color: @green;
|
||||
}
|
||||
|
||||
/* Using steps() instead of linear as a timing function to limit cpu usage */
|
||||
#battery.critical:not(.charging) {
|
||||
background-color: @bgcolor-urgent;
|
||||
animation-name: blink;
|
||||
animation-duration: 2s;
|
||||
animation-timing-function: steps(3);
|
||||
animation-iteration-count: infinite;
|
||||
animation-direction: alternate;
|
||||
}
|
||||
|
||||
/* -------------------------------------- */
|
||||
/* Clock module */
|
||||
|
||||
#clock:hover {
|
||||
background-color: @bgcolor;
|
||||
}
|
||||
|
||||
/* -------------------------------------- */
|
||||
/* Tray module */
|
||||
|
||||
#tray:hover {
|
||||
background-color: @bgcolor;
|
||||
}
|
||||
|
||||
#tray > .passive {
|
||||
-gtk-icon-effect: dim;
|
||||
}
|
||||
|
||||
#tray > .needs-attention {
|
||||
-gtk-icon-effect: highlight;
|
||||
background-color: @bgcolor-urgent;
|
||||
}
|
||||
|
||||
/* -------------------------------------- */
|
||||
/* Power module */
|
||||
|
||||
#custom-power {
|
||||
color: @red;
|
||||
}
|
||||
|
||||
#custom-power:hover {
|
||||
background-color: @bgcolor;
|
||||
}
|
||||
|
||||
/* If power module is the leftmost module, set left margin */
|
||||
.modules-left > widget:first-child > #custom-power {
|
||||
margin-left: 6px;
|
||||
}
|
||||
|
||||
/* If power module is the rightmost module, set right margin */
|
||||
.modules-right > widget:last-child > #custom-power {
|
||||
margin-right: 6px;
|
||||
}
|
||||
@@ -1,20 +1,20 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<?xml version="1.1" encoding="UTF-8"?>
|
||||
|
||||
<channel name="thunar" version="1.0">
|
||||
<property name="last-view" type="string" value="ThunarDetailsView"/>
|
||||
<property name="last-icon-view-zoom-level" type="string" value="THUNAR_ZOOM_LEVEL_LARGEST"/>
|
||||
<property name="last-window-width" type="int" value="3000"/>
|
||||
<property name="last-window-height" type="int" value="1962"/>
|
||||
<property name="last-window-maximized" type="bool" value="false"/>
|
||||
<property name="last-separator-position" type="int" value="400"/>
|
||||
<property name="last-window-maximized" type="bool" value="true"/>
|
||||
<property name="last-separator-position" type="int" value="209"/>
|
||||
<property name="misc-single-click" type="bool" value="false"/>
|
||||
<property name="misc-volume-management" type="bool" value="true"/>
|
||||
<property name="last-details-view-zoom-level" type="string" value="THUNAR_ZOOM_LEVEL_SMALLEST"/>
|
||||
<property name="last-details-view-column-widths" type="string" value="50,241,50,50,1757,50,50,160,440"/>
|
||||
<property name="last-details-view-column-widths" type="string" value="50,241,136,50,85,352,50,160,744,50,50,63,50,108"/>
|
||||
<property name="last-show-hidden" type="bool" value="true"/>
|
||||
<property name="last-sort-column" type="string" value="THUNAR_COLUMN_NAME"/>
|
||||
<property name="last-sort-order" type="string" value="GTK_SORT_ASCENDING"/>
|
||||
<property name="last-side-pane" type="string" value="ThunarShortcutsPane"/>
|
||||
<property name="last-side-pane" type="string" value="THUNAR_SIDEPANE_TYPE_SHORTCUTS"/>
|
||||
<property name="last-location-bar" type="string" value="ThunarLocationEntry"/>
|
||||
<property name="hidden-bookmarks" type="array">
|
||||
<value type="string" value="network:///"/>
|
||||
|
||||
@@ -3,13 +3,7 @@
|
||||
xrdb "$XDG_CONFIG_HOME/xorg/Xresources"
|
||||
|
||||
# Setup display
|
||||
|
||||
# >>> hostname=arch-desktop
|
||||
monctl primary DP-1 &
|
||||
# <<<
|
||||
# >>> hostname=arch-laptop
|
||||
# monctl auto 3000 2000 48 eDP-1 &
|
||||
# <<<
|
||||
autorandr --change
|
||||
|
||||
# Set default X cursor to arrow
|
||||
xsetroot -cursor_name left_ptr
|
||||
@@ -29,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 &
|
||||
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
Net/ThemeName "Arc-Dark"
|
||||
Net/IconThemeName "Arc"
|
||||
Gtk/CursorThemeName "capitaine-cursors-light"
|
||||
Net/EnableEventSounds 1
|
||||
EnableInputFeedbackSounds 1
|
||||
Xft/Antialias 1
|
||||
Xft/Hinting 1
|
||||
Xft/HintStyle "hintslight"
|
||||
Xft/RGBA "rgb"
|
||||
+5
-1
@@ -1,3 +1,7 @@
|
||||
XORG_USER='rick'
|
||||
|
||||
[ "$USER" = "$XORG_USER" ] && [ "$(tty)" = "/dev/tty1" ] && exec xinit -- vt1 > /dev/null 2>&1
|
||||
if [ "$WAYLAND" = true ]; then
|
||||
[ "$USER" = "$XORG_USER" ] && [ "$(tty)" = "/dev/tty1" ] && exec start-hyprland > /dev/null 2>&1
|
||||
else
|
||||
[ "$USER" = "$XORG_USER" ] && [ "$(tty)" = "/dev/tty1" ] && exec xinit -- vt1 > /dev/null 2>&1
|
||||
fi
|
||||
|
||||
+33
-5
@@ -1,4 +1,4 @@
|
||||
## Settings
|
||||
#--- General ---#
|
||||
|
||||
# Directories
|
||||
export CAPTURE="$HOME/pictures/screen-captures"
|
||||
@@ -20,11 +20,20 @@ export PLATFORMIO_HOME_DIR="$XDG_DATA_HOME/platformio"
|
||||
export R_ENVIRON_USER="$XDG_CONFIG_HOME/R/Renviron"
|
||||
|
||||
# HiDPI screen
|
||||
|
||||
# >>> hostname=arch-laptop
|
||||
# export HIDPI=true
|
||||
# <<<
|
||||
|
||||
# Wayland
|
||||
# >>> system=wayland
|
||||
# export WAYLAND=true
|
||||
# <<<
|
||||
|
||||
#--- Program Specific ---#
|
||||
|
||||
# Android
|
||||
export ANDROID_HOME="$XDG_DATA_HOME/android"
|
||||
|
||||
# GPG
|
||||
export GNUPGHOME="$XDG_CONFIG_HOME/gnupg"
|
||||
|
||||
@@ -67,12 +76,24 @@ 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="qt5gtk2"
|
||||
if [ "$WAYLAND" = true ]; then
|
||||
export QT_QPA_PLATFORM="wayland"
|
||||
fi
|
||||
export QT_QPA_PLATFORMTHEME="qt5ct"
|
||||
export QT_WAYLAND_DISABLE_WINDOWDECORATION="1"
|
||||
export QT_STYLE_OVERRIDE="kvantum"
|
||||
|
||||
# Rust
|
||||
export CARGO_HOME="$XDG_DATA_HOME/cargo"
|
||||
export RUSTUP_HOME="$XDG_DATA_HOME/rustup"
|
||||
|
||||
# Sudo
|
||||
export SUDO_ASKPASS="$HOME/.local/bin/rofipass"
|
||||
@@ -81,7 +102,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"
|
||||
@@ -89,8 +110,15 @@ export BROWSER="firefox"
|
||||
# Wget
|
||||
export WGETRC="$XDG_CONFIG_HOME/wget/wgetrc"
|
||||
|
||||
# Wine
|
||||
export WINEPREFIX="$XDG_DATA_HOME/wine"
|
||||
|
||||
# WM
|
||||
export WM="bspwm"
|
||||
if [ "$WAYLAND" = true ]; then
|
||||
export WM="hyprland"
|
||||
else
|
||||
export WM="bspwm"
|
||||
fi
|
||||
|
||||
# Xorg
|
||||
export XINITRC="$XDG_CONFIG_HOME/xorg/xinitrc"
|
||||
|
||||
+11
-3
@@ -73,12 +73,20 @@ zle -N history-beginning-search-backward-end history-search-end
|
||||
zle -N history-beginning-search-forward-end history-search-end
|
||||
|
||||
bindkey '\eOc' forward-word # ctrl-right
|
||||
bindkey '\e[1;5C' forward-word # ctrl-right
|
||||
bindkey '\eOd' backward-word # ctrl-left
|
||||
bindkey '\e[1;5D' backward-word # ctrl-left
|
||||
bindkey '\e[3~' delete-char # del
|
||||
bindkey '\e[7~' beginning-of-line # home
|
||||
bindkey '\e[H' beginning-of-line # home
|
||||
bindkey '\eOH' beginning-of-line # home
|
||||
bindkey '\e[8~' end-of-line # end
|
||||
bindkey '\e[F' end-of-line # end
|
||||
bindkey '\eOF' end-of-line # end
|
||||
bindkey '\e[A' history-beginning-search-backward-end # up
|
||||
bindkey '\eOA' history-beginning-search-backward-end # up
|
||||
bindkey '\e[B' history-beginning-search-forward-end # down
|
||||
bindkey '\eOB' history-beginning-search-forward-end # down
|
||||
bindkey '\e[Z' reverse-menu-complete # shift-tab
|
||||
bindkey '\eh' kill-whole-line # meta-h
|
||||
bindkey '\ej' history-beginning-search-forward-end # meta-j
|
||||
@@ -169,8 +177,8 @@ alias gd="git diff"
|
||||
alias gdc="git diff --cached"
|
||||
alias gds="git diff --staged"
|
||||
alias gf="git fetch"
|
||||
alias gl="git log --graph --abbrev-commit --decorate --format=format:'%C(bold blue)%h%C(reset) - %C(bold cyan)%ai%C(reset) %C(bold green)(%ar)%C(reset)%C(bold yellow)%d %C(reset)%n'' %C(white)%s%C(reset) %C(dim white)- %an%C(reset)' --all"
|
||||
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 gl="git log --graph --abbrev-commit --decorate --format=format:'%C(bold blue)%h%C(reset) - %C(bold cyan)%ai%C(reset) %C(bold green)(%ar)%C(reset)%C(bold yellow)%d %C(reset)%n'' %C(white)%s%C(reset) %C(dim white)- %an <%cn>%C(reset)' --all"
|
||||
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)%nCommitter: %C(dim white)%cn <%ce>%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 || git push origin $(git branch --show-current)'
|
||||
@@ -178,7 +186,7 @@ alias gpsa='git remote | xargs -I remotes git push remotes $(git branch --show-c
|
||||
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 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)%nCommitter: %C(dim white)%cn <%ce>%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 $(git branch --show-current) .'
|
||||
|
||||
# Scripts
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
# This file is written by nwg-look. Do not edit.
|
||||
[Icon Theme]
|
||||
Name=Default
|
||||
Comment=Default Cursor Theme
|
||||
Inherits=capitaine-cursors-light
|
||||
@@ -99,37 +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"
|
||||
[ "$?" -ne 0 ] && return 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
|
||||
|
||||
+20
-15
@@ -74,24 +74,29 @@ done
|
||||
|
||||
embedAudioThumbnail()
|
||||
{
|
||||
# Get file name
|
||||
fileName="$(youtube-dl --get-filename "$1")"
|
||||
fileName="${fileName%.*}"
|
||||
# Get file names
|
||||
youtube-dl --get-filename "$1" |
|
||||
while IFS= read -r fileName; do
|
||||
fileName="${fileName%.*}"
|
||||
|
||||
# Convert thumbnail to actually be a jpg
|
||||
yes y | ffmpeg -i "${fileName}.webp" "${fileName}_converted.jpg" > /dev/null 2>&1
|
||||
yes y | ffmpeg -i "${fileName}.jpg" "${fileName}_converted.jpg" > /dev/null 2>&1
|
||||
# Skip if no thumbnail
|
||||
[ ! -f "${fileName}.webp" ] && [ ! -f "${fileName}.jpg" ] && continue
|
||||
|
||||
# Embed thumbnail into mp3
|
||||
yes y | ffmpeg -i "${fileName}.mp3" -i "${fileName}_converted.jpg" \
|
||||
-map 0:0 -map 1:0 -c copy -id3v2_version 3 \
|
||||
-metadata:s:v title="Album cover" \
|
||||
-metadata:s:v comment="Cover (front)" \
|
||||
"${fileName}_embed.mp3" > /dev/null 2>&1
|
||||
# Convert thumbnail to actually be a jpg
|
||||
yes y | ffmpeg -i "${fileName}.webp" "${fileName}_converted.jpg" > /dev/null 2>&1
|
||||
yes y | ffmpeg -i "${fileName}.jpg" "${fileName}_converted.jpg" > /dev/null 2>&1
|
||||
|
||||
# Remove left over files
|
||||
rm -f "./${fileName}_converted.jpg" "./${fileName}.jpg" "./${fileName}.mp3"
|
||||
mv "${fileName}_embed.mp3" "${fileName}.mp3"
|
||||
# Embed thumbnail into mp3
|
||||
yes y | ffmpeg -i "${fileName}.mp3" -i "${fileName}_converted.jpg" \
|
||||
-map 0:0 -map 1:0 -c copy -id3v2_version 3 \
|
||||
-metadata:s:v title="Album cover" \
|
||||
-metadata:s:v comment="Cover (front)" \
|
||||
"${fileName}_embed.mp3" > /dev/null 2>&1
|
||||
|
||||
# Remove left over files
|
||||
rm -f "./${fileName}_converted.jpg" "./${fileName}.jpg" "./${fileName}.webp"
|
||||
mv -f "${fileName}_embed.mp3" "${fileName}.mp3"
|
||||
done
|
||||
}
|
||||
|
||||
downloadAudio()
|
||||
|
||||
+13
-4
@@ -1,6 +1,6 @@
|
||||
#!/bin/sh
|
||||
|
||||
file="/tmp/polybar-btc-module"
|
||||
file="/tmp/panel-btc-module"
|
||||
|
||||
# Enable mathematics in POSIX shell
|
||||
calc() { awk "BEGIN { printf(\"%.2f\", $*) }"; }
|
||||
@@ -27,12 +27,21 @@ output() {
|
||||
fi
|
||||
|
||||
# Result
|
||||
# >>> session=xorg
|
||||
echo "%{F$color}$symbol $difference%%{F$COLOR15}"
|
||||
# <<<
|
||||
# >>> session=wayland
|
||||
# echo "<span color='$color'>$symbol $difference%</span>"
|
||||
# <<<
|
||||
}
|
||||
|
||||
# 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)"
|
||||
|
||||
Executable
+7
@@ -0,0 +1,7 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Kill existing panel
|
||||
pkill --exact --signal 9 waybar
|
||||
|
||||
# Start panel
|
||||
setsid -f waybar
|
||||
+223
-61
@@ -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,259 @@ ${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
|
||||
# >>> session=xorg
|
||||
clip="$(xclip -selection clipboard -out)"
|
||||
# <<<
|
||||
# >>> session=wayland
|
||||
# clip="$(wl-paste)"
|
||||
# <<<
|
||||
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
|
||||
# >>> session=xorg
|
||||
play "$(xclip -o)"
|
||||
# <<<
|
||||
# >>> session=wayland
|
||||
# play "$(wl-paste)"
|
||||
# <<<
|
||||
else
|
||||
for url in "$@"; do
|
||||
play "$url"
|
||||
done
|
||||
fi
|
||||
fi
|
||||
|
||||
+13
-2
@@ -1,12 +1,17 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Take a screenshot with the configured program
|
||||
# Depends: scrot / maim, xdotool / magick, xdotool
|
||||
# Depends: rofi and scrot / maim, xdotool / magick, xdotool / grim, slurp, jq
|
||||
|
||||
# User-config---------------------------
|
||||
|
||||
# scrot / maim / magick import
|
||||
# scrot / maim / magick import / grim
|
||||
# >>> session=xorg
|
||||
screenshotter="maim"
|
||||
# <<<
|
||||
# >>> session=wayland
|
||||
# screenshotter="grim"
|
||||
# <<<
|
||||
|
||||
# --------------------------------------
|
||||
|
||||
@@ -25,6 +30,12 @@ elif [ "$screenshotter" = "magick import" ] || [ "$screenshotter" = "import" ];
|
||||
selection=""
|
||||
activeWindow="-window \$(xdotool getactivewindow)"
|
||||
filename="$CAPTURE/$(date '+%Y-%m-%d-%H%M%S')_import.png"
|
||||
elif [ "$screenshotter" = "grim" ]; then
|
||||
screenshotter="" # start of command needs to be overwritten
|
||||
fullscreen="grim"
|
||||
selection="slurp | grim -g -"
|
||||
activeWindow="hyprctl -j activewindow | jq -r '\"\(.at[0]),\(.at[1]) \(.size[0])x\(.size[1])\"' | grim -g -"
|
||||
filename="$CAPTURE/$(date '+%Y-%m-%d-%H%M%S')_grim.png"
|
||||
else
|
||||
echo "Printscreen configuration is invalid"
|
||||
exit 1
|
||||
|
||||
@@ -6,6 +6,8 @@ if [ "$WM" = "bspwm" ]; then
|
||||
logout="bspc quit"
|
||||
elif [ "$WM" = "i3" ]; then
|
||||
logout="i3-msg exit"
|
||||
elif [ "$WM" = "hyprland" ]; then
|
||||
logout="hyprctl dispatch exit"
|
||||
fi
|
||||
|
||||
commands="\
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -2,6 +2,11 @@
|
||||
|
||||
LOCK="$XDG_CACHE_HOME/lock.png"
|
||||
|
||||
if [ "$WM" = "hyprland" ]; then
|
||||
hyprlock
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Cache the lock image
|
||||
if [ ! -f "$LOCK" ]; then
|
||||
touch "$LOCK"
|
||||
@@ -51,6 +56,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
|
||||
|
||||
@@ -1,7 +1,23 @@
|
||||
#!/bin/sh
|
||||
|
||||
WALLPAPER="$HOME/pictures/wallpaper.jpg"
|
||||
|
||||
# Overwrite wallpaper with new image if provided
|
||||
[ -n "$1" ] && cp "$1" "$HOME/pictures/wallpaper.jpg"
|
||||
[ -n "$1" ] && cp "$1" "$WALLPAPER"
|
||||
|
||||
# Set wallpaper
|
||||
feh --no-fehbg --bg-fill "$HOME/pictures/wallpaper.jpg"
|
||||
if [ "$WAYLAND" = true ]; then
|
||||
pkill hyprpaper
|
||||
setsid -f hyprpaper
|
||||
|
||||
# Wait until hyprpaper is available
|
||||
while [ -z "$(find "$XDG_RUNTIME_DIR/hypr" -name ".hyprpaper.sock")" ]; do
|
||||
sleep 0.1
|
||||
done
|
||||
sleep 0.1
|
||||
|
||||
hyprctl hyprpaper preload "$WALLPAPER"
|
||||
hyprctl hyprpaper wallpaper ",$WALLPAPER"
|
||||
else
|
||||
feh --no-fehbg --bg-fill "$WALLPAPER"
|
||||
fi
|
||||
|
||||
@@ -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
|
||||
+28
-27
@@ -26,39 +26,39 @@ Manual interventions needed to setup Firefox.
|
||||
Tree Style Tab style rules.
|
||||
|
||||
#+BEGIN_SRC css
|
||||
#tabbar {
|
||||
background: #2b2e39;
|
||||
}
|
||||
#tabbar {
|
||||
background: #2b2e39;
|
||||
}
|
||||
|
||||
.tab {
|
||||
height: 23px;
|
||||
margin-bottom: 1px;
|
||||
background: #404552;
|
||||
border: 0px;
|
||||
color: #c5c8c6;
|
||||
}
|
||||
.tab {
|
||||
height: 25px;
|
||||
margin-bottom: 1px;
|
||||
background: #404552;
|
||||
border: 0px;
|
||||
color: #c5c8c6;
|
||||
}
|
||||
|
||||
.tab .label {
|
||||
line-height: 1.15;
|
||||
margin-bottom: 1px;
|
||||
margin-left: 0.25em;
|
||||
}
|
||||
.tab .label {
|
||||
line-height: 1.75;
|
||||
margin-bottom: 1px;
|
||||
margin-left: 0.25em;
|
||||
}
|
||||
|
||||
.tab .closebox {
|
||||
display: none;
|
||||
}
|
||||
.tab .closebox {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.tab.active {
|
||||
background: #2b2e39 !important;
|
||||
}
|
||||
.tab.active {
|
||||
background: #2b2e39 !important;
|
||||
}
|
||||
|
||||
.tab:hover {
|
||||
background: #2b2e39;
|
||||
}
|
||||
.tab:hover {
|
||||
background: #2b2e39;
|
||||
}
|
||||
|
||||
.newtab-button-box {
|
||||
display: none;
|
||||
}
|
||||
.newtab-button-box {
|
||||
display: none;
|
||||
}
|
||||
#+END_SRC
|
||||
|
||||
* Ublock Origin Filters
|
||||
@@ -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
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
@-moz-document url(chrome://browser/content/browser.xhtml) {
|
||||
/* Hide Firefox top tab bar */
|
||||
#TabsToolbar {
|
||||
visibility: hidden !important;
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
/* Remove titlebar */
|
||||
@@ -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;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user