From b8a5c62b112859f463a53ac97b43f7f8cdc544a9 Mon Sep 17 00:00:00 2001 From: spl3g Date: Sun, 31 Dec 2023 15:08:06 +0300 Subject: uhm --- .../general/programs/alacritty/default.nix | 23 + home-manager/general/programs/default.nix | 7 + home-manager/general/programs/emacs/#init.el# | 735 +++++++++++++++++ home-manager/general/programs/emacs/config.org | 866 +++++++++++++++++++++ home-manager/general/programs/emacs/default.nix | 118 +++ home-manager/general/programs/emacs/early-init.el | 4 + home-manager/general/programs/emacs/init.el | 675 ++++++++++++++++ home-manager/general/programs/emacs/init.old.el | 592 ++++++++++++++ home-manager/general/programs/emacs/tmpWCGTRZ | 735 +++++++++++++++++ home-manager/general/programs/firefox/default.nix | 109 +++ home-manager/general/programs/firefox/user.js | 262 +++++++ .../general/programs/firefox/userChrome.css | 98 +++ home-manager/general/programs/fish/default.nix | 46 ++ home-manager/general/programs/ranger/commands.py | 183 +++++ home-manager/general/programs/ranger/default.nix | 11 + home-manager/general/programs/ranger/default.nix~ | 7 + .../general/programs/ranger/plugins/__init__.py | 0 .../plugins/__pycache__/__init__.cpython-310.pyc | Bin 0 -> 139 bytes .../plugins/__pycache__/__init__.cpython-311.pyc | Bin 0 -> 155 bytes .../ranger/plugins/__pycache__/fd.cpython-311.pyc | Bin 0 -> 6322 bytes .../plugins/__pycache__/quit_cd_wd.cpython-310.pyc | Bin 0 -> 1682 bytes .../plugins/__pycache__/quit_cd_wd.cpython-311.pyc | Bin 0 -> 3030 bytes .../general/programs/ranger/plugins/quit_cd_wd.py | 38 + .../ranger/plugins/ranger_fzf_filter/.gitignore | 132 ++++ .../ranger/plugins/ranger_fzf_filter/LICENSE | 21 + .../ranger/plugins/ranger_fzf_filter/README.md | 47 ++ .../ranger/plugins/ranger_fzf_filter/__init__.py | 35 + .../ranger/plugins/ranger_fzf_filter/command.py | 59 ++ .../ranger/plugins/ranger_fzf_filter/filter.py | 84 ++ home-manager/general/programs/ranger/rc.conf | 12 + home-manager/general/programs/ranger/rifle.conf | 284 +++++++ home-manager/general/programs/ranger/scope.sh | 351 +++++++++ 32 files changed, 5534 insertions(+) create mode 100644 home-manager/general/programs/alacritty/default.nix create mode 100644 home-manager/general/programs/default.nix create mode 100644 home-manager/general/programs/emacs/#init.el# create mode 100644 home-manager/general/programs/emacs/config.org create mode 100644 home-manager/general/programs/emacs/default.nix create mode 100644 home-manager/general/programs/emacs/early-init.el create mode 100644 home-manager/general/programs/emacs/init.el create mode 100644 home-manager/general/programs/emacs/init.old.el create mode 100644 home-manager/general/programs/emacs/tmpWCGTRZ create mode 100644 home-manager/general/programs/firefox/default.nix create mode 100644 home-manager/general/programs/firefox/user.js create mode 100644 home-manager/general/programs/firefox/userChrome.css create mode 100644 home-manager/general/programs/fish/default.nix create mode 100644 home-manager/general/programs/ranger/commands.py create mode 100644 home-manager/general/programs/ranger/default.nix create mode 100644 home-manager/general/programs/ranger/default.nix~ create mode 100644 home-manager/general/programs/ranger/plugins/__init__.py create mode 100644 home-manager/general/programs/ranger/plugins/__pycache__/__init__.cpython-310.pyc create mode 100644 home-manager/general/programs/ranger/plugins/__pycache__/__init__.cpython-311.pyc create mode 100644 home-manager/general/programs/ranger/plugins/__pycache__/fd.cpython-311.pyc create mode 100644 home-manager/general/programs/ranger/plugins/__pycache__/quit_cd_wd.cpython-310.pyc create mode 100644 home-manager/general/programs/ranger/plugins/__pycache__/quit_cd_wd.cpython-311.pyc create mode 100644 home-manager/general/programs/ranger/plugins/quit_cd_wd.py create mode 100644 home-manager/general/programs/ranger/plugins/ranger_fzf_filter/.gitignore create mode 100644 home-manager/general/programs/ranger/plugins/ranger_fzf_filter/LICENSE create mode 100644 home-manager/general/programs/ranger/plugins/ranger_fzf_filter/README.md create mode 100644 home-manager/general/programs/ranger/plugins/ranger_fzf_filter/__init__.py create mode 100644 home-manager/general/programs/ranger/plugins/ranger_fzf_filter/command.py create mode 100644 home-manager/general/programs/ranger/plugins/ranger_fzf_filter/filter.py create mode 100644 home-manager/general/programs/ranger/rc.conf create mode 100644 home-manager/general/programs/ranger/rifle.conf create mode 100755 home-manager/general/programs/ranger/scope.sh (limited to 'home-manager/general/programs') diff --git a/home-manager/general/programs/alacritty/default.nix b/home-manager/general/programs/alacritty/default.nix new file mode 100644 index 0000000..930952d --- /dev/null +++ b/home-manager/general/programs/alacritty/default.nix @@ -0,0 +1,23 @@ +{ pkgs, ... }: + +{ + home.packages = [ pkgs.alacritty-theme ]; + programs.alacritty = { + enable = true; + settings = { + import = [ "${pkgs.alacritty-theme}/catppuccin_macchiato.yaml" ]; + font = { + normal = { + family = "Source Code Pro"; + style = "Medium"; + }; + size = 11.5; + }; + window.opacity = 0.7; + cursor = { + style = "Beam"; + thickness = 0.27; + }; + }; + }; +} diff --git a/home-manager/general/programs/default.nix b/home-manager/general/programs/default.nix new file mode 100644 index 0000000..cf86795 --- /dev/null +++ b/home-manager/general/programs/default.nix @@ -0,0 +1,7 @@ +[ + ./fish + ./firefox + ./emacs + ./ranger + ./alacritty +] diff --git a/home-manager/general/programs/emacs/#init.el# b/home-manager/general/programs/emacs/#init.el# new file mode 100644 index 0000000..b17a54b --- /dev/null +++ b/home-manager/general/programs/emacs/#init.el# @@ -0,0 +1,735 @@ +(setq gc-cons-threshold (* 50 1000 1000)) + +(require 'use-package) +(eval-and-compile + (setq use-package-always-ensure t + use-package-expand-minimally t)) + +(use-package savehist + :init + (setq savehist-file "~/.config/emacs/var/savehist.el") + :config + (setq history-length 500) + (setq savehist-additional-variables '(kill-ring search-ring)) + (savehist-mode t)) + +(use-package meow + :config + (defun meow-setup () + (setq meow-cheatsheet-layout meow-cheatsheet-layout-qwerty) + (meow-motion-overwrite-define-key + '("j" . meow-next) + '("k" . meow-prev) + '("" . ignore)) + (meow-leader-define-key + ;; SPC j/k will run the original command in MOTION state. + '("j" . "H-j") + '("k" . "H-k") + ;; Use SPC (0-9) for digit arguments. + '("1" . meow-digit-argument) + '("2" . meow-digit-argument) + '("3" . meow-digit-argument) + '("4" . meow-digit-argument) + '("5" . meow-digit-argument) + '("6" . meow-digit-argument) + '("7" . meow-digit-argument) + '("8" . meow-digit-argument) + '("9" . meow-digit-argument) + '("0" . meow-digit-argument) + '("/" . meow-keypad-describe-key) + '("?" . meow-cheatsheet) + '("bk" . kill-this-buffer)) + (meow-normal-define-key + '("0" . meow-expand-0) + '("9" . meow-expand-9) + '("8" . meow-expand-8) + '("7" . meow-expand-7) + '("6" . meow-expand-6) + '("5" . meow-expand-5) + '("4" . meow-expand-4) + '("3" . meow-expand-3) + '("2" . meow-expand-2) + '("1" . meow-expand-1) + '("-" . negative-argument) + '(";" . meow-reverse) + '("," . meow-inner-of-thing) + '("." . meow-bounds-of-thing) + '("[" . meow-beginning-of-thing) + '("]" . meow-end-of-thing) + '("a" . meow-append) + '("A" . meow-open-below) + '("b" . meow-back-word) + '("B" . meow-back-symbol) + '("c" . meow-change) + '("d" . meow-delete) + '("D" . meow-backward-delete) + '("e" . meow-next-word) + '("E" . meow-next-symbol) + '("f" . meow-find) + '("g" . meow-cancel-selection) + '("G" . meow-grab) + '("h" . meow-left) + '("H" . meow-left-expand) + '("i" . meow-insert) + '("I" . meow-open-above) + '("j" . meow-next) + '("J" . meow-next-expand) + '("k" . meow-prev) + '("K" . meow-prev-expand) + '("l" . meow-right) + '("L" . meow-right-expand) + '("m" . meow-join) + '("n" . meow-search) + '("o" . meow-block) + '("O" . meow-to-block) + '("p" . meow-yank) + '("q" . meow-quit) + '("Q" . meow-goto-line) + '("r" . meow-replace) + '("R" . meow-swap-grab) + '("s" . meow-kill) + '("t" . meow-till) + '("u" . meow-undo) + '("U" . meow-undo-in-selection) + '("v" . meow-visit) + '("w" . meow-mark-word) + '("W" . meow-mark-symbol) + '("x" . meow-line) + '("X" . meow-goto-line) + '("y" . meow-save) + '("Y" . meow-sync-grab) + '("z" . meow-pop-selection) + '("'" . repeat) + '("" . ignore))) + (setq meow-use-enhanced-selection-effect t) + (meow-setup)) + ;; (meow-global-mode 1)) + +(use-package kakoune + ;; Having a non-chord way to escape is important, since key-chords don't work in macros + :bind ("C-z" . ryo-modal-mode) + :hook (after-init . my/kakoune-setup) + :config + (defun ryo-enter () "Enter normal mode" (interactive) (ryo-modal-mode 1)) + (defun my/kakoune-setup () + "Call kakoune-setup-keybinds and then add some personal config." + (kakoune-setup-keybinds) + (setq ryo-modal-cursor-type 'box) + (add-hook 'prog-mode-hook #'ryo-enter) + (define-key ryo-modal-mode-map (kbd "SPC h") 'help-command) + ;; Access all C-x bindings easily + (define-key ryo-modal-mode-map (kbd "z") ctl-x-map) + (ryo-modal-keys + ("," save-buffer) + ("P" counsel-yank-pop) + ("m" mc/mark-next-like-this) + ("M" mc/skip-to-next-like-this) + ("n" mc/mark-previous-like-this) + ("N" mc/skip-to-previous-like-this) + ("M-m" mc/edit-lines) + ("*" mc/mark-all-like-this) + ("v" er/expand-region) + ("C-v" set-rectangular-region-anchor) + ("M-s" mc/split-region) + (";" (("q" delete-window) + ("v" split-window-horizontally) + ("s" split-window-vertically))) + ("C-h" windmove-left) + ("C-j" windmove-down) + ("C-k" windmove-up) + ("C-l" windmove-right) + ("C-u" scroll-down-command :first '(deactivate-mark)) + ("C-d" scroll-up-command :first '(deactivate-mark))))) + +;; This overrides the default mark-in-region with a prettier-looking one, +;; and provides a couple extra commands +(use-package visual-regexp + :ryo + ("s" vr/mc-mark) + ("?" vr/replace) + ("M-/" vr/query-replace)) + +;; Emacs incremental search doesn't work with multiple cursors, but this fixes that +(use-package phi-search + :bind (("C-s" . phi-search) + ("C-r" . phi-search-backward))) + +;; Probably the first thing you'd miss is undo and redo, which requires an extra package +;; to work like it does in kakoune (and almost every other editor). +(use-package undo-tree + :config + (global-undo-tree-mode) + :ryo + ("u" undo-tree-undo) + ("U" undo-tree-redo) + ("SPC u" undo-tree-visualize) + :bind (:map undo-tree-visualizer-mode-map + ("h" . undo-tree-visualize-switch-branch-left) + ("j" . undo-tree-visualize-redo) + ("k" . undo-tree-visualize-undo) + ("l" . undo-tree-visualize-switch-branch-right))) + + +(use-package general + :config + ;; SPC as the global leader key + (general-create-definer spl3g/leader-keys + :prefix "C-c") + + (spl3g/leader-keys + ;; Buffers + "b" '(:ignore t :wk "Buffer") + "bi" '(ibuffer :wk "ibuffer") + "bk" '(kill-this-buffer :wk "Kill this buffer") + "bn" '(next-buffer :wk "Next buffer") + "bp" '(previous-buffer :wk "Previous buffer") + "br" '(revert-buffer :wk "Reload buffer") + "." '(find-file :wk "Find file") + ;; Splits + "w" '(:ignore t :wk "Splits") + "wv" '(split-window-right :wk "Split vertical") + "ws" '(split-window-below :wk "Split") + "ww" '(other-window :wk "Cycle throug windows") + "wc" '(delete-window :wk "Close window") + "wd" '(delete-window :wk "Close window") + "wl" '(evil-window-right :wk "") + "wj" '(evil-window-down :wk "") + "wk" '(evil-window-up :wk "") + "wh" '(evil-window-left :wk "") + "wo" '(delete-other-windows :wk "") + ;; Files + "f" '(:ignore t :wk "Files") + "fc" '((lambda () (interactive) (find-file "~/nixfiles/home-manager/programs/emacs/config.org")) :wk "Edit emacs config") + "fu" '(crux-sudo-edit :wk "Sudo edit file") + ;; Compilation + "c" '(:ignore t :wk "Compilation") + "cc" '(compile :wk "Compile") + "cr" '(recompile :wk "Recompile") + )) + +(defun spl3g/disable-scroll-bars (frame) + (modify-frame-parameters frame + '((vertical-scroll-bars . nil) + (horizontal-scroll-bars . nil)))) +(add-hook 'after-make-frame-functions 'spl3g/disable-scroll-bars) + +(setq default-frame-alist '((font . "Source Code Pro"))) +(set-face-attribute 'default nil + :font "Source Code Pro" + :height 110 + :weight 'medium) +(set-face-attribute 'fixed-pitch nil + :font "Source Code Pro" + :height 110 + :weight 'medium) +(set-face-attribute 'variable-pitch nil + :font "Rubik" + :height 110 + :weight 'medium) +(set-face-attribute 'font-lock-comment-face nil + :slant 'italic) +(set-face-attribute 'font-lock-keyword-face nil + :weight 'bold) + +(add-hook 'prog-mode-hook 'display-line-numbers-mode) +(visual-line-mode 1) + +(use-package catppuccin-theme + :ensure t + :config + (load-theme 'catppuccin t) + (setq catppuccin-flavor 'macchiato) + (catppuccin-reload)) + +(use-package all-the-icons + :ensure t + :if (display-graphic-p)) + +(use-package mood-line + + ;; Enable mood-line + :config + (mood-line-mode) + :custom + (mood-line-segment-modal-meow-state-alist + '((normal "N" . mood-line-meow-normal) + (insert "I" . mood-line-meow-insert) + (keypad "K" . mood-line-meow-keypad) + (beacon "B" . mood-line-meow-beacon) + (motion "M" . mood-line-meow-motion))) + (mood-line-glyph-alist mood-line-glyphs-fira-code) + :custom-face + (mood-line-meow-beacon ((t (:foreground "#f9e2af" :weight bold)))) + (mood-line-meow-insert ((t (:foreground "#a6e3a1" :weight bold)))) + (mood-line-meow-keypad ((t (:foreground "#cba6f7" :weight bold)))) + (mood-line-meow-motion ((t (:foreground "#fab387" :weight bold)))) + (mood-line-meow-normal ((t (:weight bold)))) + (mode-line-inactive ((t (:box (:line-width (2 . 6) :color "#11111b") :inverse-video nil :foreground "#6c7086" :background "#11111b")))) + (mode-line ((t (:box (:line-width (2 . 6) :color "#181825") :background "#181825"))))) + +(use-package good-scroll + :init (good-scroll-mode)) + +(use-package dashboard + :init + (dashboard-setup-startup-hook) + :config + (setq initial-buffer-choice (lambda () (get-buffer-create "*dashboard*"))) + (setq dashboard-banner-logo-title "Yep, it's emacs, not vim") + (setq dashboard-startup-banner 'logo) + (setq dashboard-center-content t) + (add-to-list 'dashboard-item-generators '(config . dashboard-open-config)) + (setq dashboard-items '((recents . 5) + (agenda . 5)))) + +(setq ring-bell-function 'ignore) + +(use-package indent-guide + :hook (prog-mode . indent-guide-mode)) + +(setq window-resize-pixelwise t) +(setq frame-resize-pixelwise t) +(save-place-mode t) +(defalias 'yes-or-no #'y-or-n-p) + +(add-hook 'org-mode-hook 'org-indent-mode) +(require 'org-tempo) + +(use-package toc-org + :hook (org-mode . toc-org-mode)) + +(use-package org-bullets + :hook (org-mode . org-bullets-mode)) + +(use-package org-auto-tangle + :hook (org-mode . org-auto-tangle-mode)) + +(use-package org-download + :hook + (dired-mode . org-download-enable)) + +(use-package direnv + :config + (direnv-mode)) + +(use-package vertico + :init + (vertico-mode) + :bind (:map vertico-map + ("M-j" . vertico-next) + ("M-k" . vertico-previous) + ("RET" . vertico-directory-enter) + ("DEL" . vertico-directory-delete-char) + ("M-DEL" . vertico-directory-delete-word))) + +(use-package emacs + :init + ;; Add prompt indicator to `completing-read-multiple'. + ;; We display [CRM], e.g., [CRM,] if the separator is a comma. + (defun crm-indicator (args) + (cons (format "[CRM%s] %s" + (replace-regexp-in-string + "\\`\\[.*?]\\*\\|\\[.*?]\\*\\'" "" + crm-separator) + (car args)) + (cdr args))) + (advice-add #'completing-read-multiple :filter-args #'crm-indicator) + + ;; Do not allow the cursor in the minibuffer prompt + (setq minibuffer-prompt-properties + '(read-only t cursor-intangible t face minibuffer-prompt)) + (add-hook 'minibuffer-setup-hook #'cursor-intangible-mode) + + ;; Emacs 28: Hide commands in M-x which do not work in the current mode. + ;; Vertico commands are hidden in normal buffers. + ;; (setq read-extended-command-predicate + ;; #'command-completion-default-include-p) + + ;; Enable recursive minibuffers + (setq enable-recursive-minibuffers t)) + +(use-package orderless + :init + (setq completion-styles '(orderless basic) + completion-category-defaults nil + completion-category-overrides '((file (styles partial-completion))))) + +(use-package marginalia + :bind (:map minibuffer-local-map + ("M-A" . marginalia-cycle)) + :init + (marginalia-mode)) + +(use-package consult + ;; Replace bindings. Lazily loaded due by `use-package'. + :bind (;; C-c bindings in `mode-specific-map' + ("C-c k" . consult-kmacro) + ("C-c m" . consult-man) + ("C-c i" . consult-info) + ([remap Info-search] . consult-info) + ("C-c f r" . consult-recent-file) + ("C-c ," . consult-buffer) + ;; C-x bindings in `ctl-x-map' + ("C-x M-:" . consult-complex-command) ;; orig. repeat-complex-command + ("C-x 4 b" . consult-buffer-other-window) ;; orig. switch-to-buffer-other-window + ("C-x 5 b" . consult-buffer-other-frame) ;; orig. switch-to-buffer-other-frame + ("C-x p b" . consult-project-buffer) ;; orig. project-switch-to-buffer + ;; Custom M-# bindings for fast register access + ("M-#" . consult-register-load) + ("M-'" . consult-register-store) ;; orig. abbrev-prefix-mark (unrelated) + ("C-M-#" . consult-register) + ;; Other custom bindings + ("M-y" . consult-yank-pop) ;; orig. yank-pop + ;; M-g bindings in `goto-map' + ("C-c c e" . consult-compile-error) + ("M-g f" . consult-flymake) ;; Alternative: consult-flycheck + ("M-g g" . consult-goto-line) ;; orig. goto-line + ("M-g M-g" . consult-goto-line) ;; orig. goto-line + ("M-g o" . consult-outline) ;; Alternative: consult-org-heading + ;; M-s bindings in `search-map' + ("M-s d" . consult-fd) + ("M-s g" . consult-grep) + ("M-s G" . consult-git-grep) + ("M-s l" . consult-line) + ("M-s L" . consult-line-multi) + ("M-s k" . consult-keep-lines) + ("M-s u" . consult-focus-lines) + ;; Isearch integration + ("M-s e" . consult-isearch-history) + :map isearch-mode-map + ("M-e" . consult-isearch-history) ;; orig. isearch-edit-string + ("M-s e" . consult-isearch-history) ;; orig. isearch-edit-string + ("M-s l" . consult-line) ;; needed by consult-line to detect isearch + ("M-s L" . consult-line-multi) ;; needed by consult-line to detect isearch + ("M-r" . consult-history) + ;; Minibuffer history + :map minibuffer-local-map + ("M-s" . consult-history) ;; orig. next-matching-history-element + ("M-r" . consult-history)) ;; orig. previous-matching-history-element) + + ;; Enable automatic preview at point in the *Completions* buffer. This is + ;; relevant when you use the default completion UI. + :hook + (completion-list-mode . consult-preview-at-point-mode) + (eshell-mode . (lambda () + (keymap-set eshell-mode-map "M-h" 'consult-history))) + + ;; The :init configuration is always executed (Not lazy) + :init + + ;; Optionally configure the register formatting. This improves the register + ;; preview for `consult-register', `consult-register-load', + ;; `consult-register-store' and the Emacs built-ins. + (setq register-preview-delay 0.5 + register-preview-function #'consult-register-format) + + ;; Optionally tweak the register preview window. + ;; This adds thin lines, sorting and hides the mode line of the window. + (advice-add #'register-preview :override #'consult-register-window) + + ;; Configure other variables and modes in the :config section, + ;; after lazily loading the package. + :config + + ;; Optionally configure preview. The default value + ;; is 'any, such that any key triggers the preview. + ;; (setq consult-preview-key 'any) + ;; (setq consult-preview-key "M-.") + ;; (setq consult-preview-key '("S-" "S-")) + ;; For some commands and buffer sources it is useful to configure the + ;; :preview-key on a per-command basis using the `consult-customize' macro. + (consult-customize + consult-ripgrep consult-git-grep consult-grep + consult-bookmark consult-recent-file consult-xref + consult--source-bookmark consult--source-file-register + consult--source-recent-file consult--source-project-recent-file) + ;; :preview-key "M-." + + ;; Optionally configure the narrowing key. + ;; Both < and C-+ work reasonably well. + (setq consult-narrow-key "<") ;; "C-+" + + ;; Optionally make narrowing help available in the minibuffer. + ;; You may want to use `embark-prefix-help-command' or which-key instead. + ;; (define-key consult-narrow-map (vconcat consult-narrow-key "?") #'consult-narrow-help) + + ;; By default `consult-project-function' uses `project-root' from project.el. + ;; Optionally configure a different project root function. +;;;; 1. project.el (the default) + ;; (setq consult-project-function #'consult--default-project--function) +;;;; 2. vc.el (vc-root-dir) + ;; (setq consult-project-function (lambda (_) (vc-root-dir))) +;;;; 3. locate-dominating-file + ;; (setq consult-project-function (lambda (_) (locate-dominating-file "." ".git"))) +;;;; 4. projectile.el (projectile-project-root) + ;; (autoload 'projectile-project-root "projectile") + ;; (setq consult-project-function (lambda (_) (projectile-project-root))) +;;;; 5. No project support + ;; (setq consult-project-function nil) + ) + +(use-package smartparens + :init (smartparens-global-mode) + :config + ;; Snitched from doom + (let ((unless-list '(sp-point-before-word-p + sp-point-after-word-p + sp-point-before-same-p))) + (sp-pair "'" nil :unless unless-list) + (sp-pair "\"" nil :unless unless-list)) + (dolist (brace '("(" "{" "[")) + (sp-pair brace nil + :post-handlers '(("||\n[i]" "RET") ("| " "SPC")) + :unless '(sp-point-before-word-p sp-point-before-same-p))) + (sp-local-pair sp-lisp-modes "(" ")" :unless '(:rem sp-point-before-same-p)) + (sp-local-pair sp-lisp-modes "(" ")" :unless '(:rem sp-point-before-same-p)) + + (sp-local-pair '(python-mode python-ts-mode) "f'" "'") + + ;; Major-mode specific fixes + (sp-local-pair 'ruby-mode "{" "}" + :pre-handlers '(:rem sp-ruby-pre-handler) + :post-handlers '(:rem sp-ruby-post-handler)) + + ;; Don't do square-bracket space-expansion where it doesn't make sense to + (sp-local-pair '(emacs-lisp-mode org-mode markdown-mode gfm-mode) + "[" nil :post-handlers '(:rem ("| " "SPC"))) + + (sp-local-pair '(emacs-lisp-mode org-mode) + "'" nil) + + ;; Reasonable default pairs for HTML-style comments + (sp-local-pair (append sp--html-modes '(markdown-mode gfm-mode)) + "" + :unless '(sp-point-before-word-p sp-point-before-same-p) + :actions '(insert) :post-handlers '(("| " "SPC"))) + ;; Expand C-style comment blocks. + (defun +default-open-doc-comments-block (&rest _ignored) + (save-excursion + (newline) + (indent-according-to-mode))) + (sp-local-pair + '(js2-mode typescript-mode rjsx-mode rust-mode c-mode c++-mode objc-mode + csharp-mode java-mode php-mode css-mode scss-mode less-css-mode + stylus-mode scala-mode) + "/*" "*/" + :actions '(insert) + :post-handlers '(("| " "SPC") + (" | " "*") + ("|[i]\n[i]" "RET")))) + +;; (use-package dap-mode +;; :defer t +;; :config +;; (require 'dap-python) +;; (setq dap-python-debugger 'debugpy)) + +(use-package move-text + :bind (("C-M-k" . move-text-up) + ("C-M-j" . move-text-down))) + +(global-visual-line-mode t) + +(use-package no-littering) + +(use-package rainbow-delimiters + :hook (prog-mode . rainbow-delimiters-mode)) + +(use-package crux + :bind (("C-c o t" . crux-visit-shell-buffer))) + +(use-package helpful + :bind (("C-h f" . 'helpful-callable) + ("C-h v" . 'helpful-variable) + ("C-h k" . 'helpful-key) + ("C-h x" . 'helpful-command) + ("C-c C-d" . 'helpful-at-point) + ("C-h F" . 'helpful-function))) + +(add-hook 'eshell-mode-hook + (lambda () + (keymap-set eshell-mode-map "M-" 'consult-fish-completions))) + +(use-package eat + :hook (eshell-mode . eat-eshell-mode) + :custom + (eat-enable-auto-line-mode t)) + +;; (defun eat-toggle () +;; "Open eat terminal as a popup." +;; (interactive) +;; (if (eq major-mode 'eat-mode) +;; (delete-window) +;; (let ((buff (get-buffer-create eat-buffer-name))) +;; (cl-assert (and buff (buffer-live-p buff))) +;; (funcall #'pop-to-buffer buff) +;; (with-current-buffer buff +;; (setq-local split-width-threshold nil) +;; (setq-local window-min-height 2) +;; (unless (derived-mode-p 'eat-mode) +;; (eat)))))) + +;; (defun eat-modes() +;; (cond +;; ((and (eq major-mode 'eat-mode) (member 'meow-normal-mode local-minor-modes)) +;; (eat-emacs-mode)) +;; ((and (eq major-mode 'eat-mode) (member 'meow-insert-mode local-minor-modes)) +;; (eat-semi-char-mode)))) +;; (add-hook 'meow-normal-mode-hook #'eat-modes) +;; (add-hook 'meow-insert-mode-hook #'eat-modes) + +(use-package fish-completion + :hook (eshell-mode . fish-completion-mode)) + +(use-package eglot + :bind (("C-c s e e" . eglot) + ("C-c s e d" . eldoc) + ("C-c s e r" . eglot-rename) + ("C-c s e s" . eglot-shutdown) + ("C-c s e f" . eglot-find-declaration) + ("C-c s e i" . eglot-find-implementation)) + :hook + (nix-mode . eglot-ensure) + (python-ts-mode . eglot-ensure) + :config + (add-to-list 'eglot-server-programs '(python-ts-mode . ("pylsp")))) + +(use-package lsp-pyright) +(use-package py-autopep8 + :hook (python-mode . py-autopep8-mode)) + +(use-package rust-mode + :mode "\\.rs\\'") +(use-package flycheck-rust + :config + (with-eval-after-load 'rust-mode + (add-hook 'flycheck-mode-hook #'flycheck-rust-setup))) + +(use-package fish-mode + :mode "\\.fish\\'") + +(use-package nix-mode + :mode ("\\.nix\\'" "\\.nix.in\\'")) +(use-package nix-drv-mode + :ensure nix-mode + :mode "\\.drv\\'") +(use-package nix-shell + :ensure nix-mode + :commands (nix-shell-unpack nix-shell-configure nix-shell-build)) +(use-package nix-repl + :ensure nix-mode + :commands (nix-repl)) + +(use-package web-mode + :mode + ("\\.phtml\\'" + "\\.tpl\\.php\\'" + "\\.[agj]sp\\'" + "\\.as[cp]x\\'" + "\\.erb\\'" + "\\.mustache\\'" + "\\.djhtml\\'")) + +(use-package js2-mode) + +(use-package corfu + :custom + (corfu-cycle t) + (corfu-preselect 'prompt) + (corfu-auto t) + (corfu-popupinfo-delay 0.0) + :bind + (:map corfu-map + ("TAB" . corfu-next) + ([tab] . corfu-next) + ("S-TAB" . corfu-previous) + ([backtab] . corfu-previous)) + + :init + (global-corfu-mode) + (corfu-history-mode) + (corfu-popupinfo-mode) + :config + (add-to-list 'savehist-additional-variables 'corfu-history)) +(use-package emacs + :init + (setq completion-cycle-threshold 3) + + (setq read-extended-command-predicate + #'command-completion-default-include-p) + + (setq tab-always-indent 'complete)) + +(use-package cape + :demand t + :config + (add-to-list 'completion-at-point-functions #'cape-dabbrev) + (add-to-list 'completion-at-point-functions #'cape-file) + (add-to-list 'completion-at-point-functions #'cape-elisp-block) + ) + +(use-package tree-sitter + :init + (global-tree-sitter-mode) + :config + (add-hook 'tree-sitter-mode-hook 'tree-sitter-hl-mode)) +(use-package treesit-auto + :custom + (treesit-auto-install 'prompt) + :config + (treesit-auto-add-to-auto-mode-alist 'all) + (global-treesit-auto-mode)) + +(use-package tree-sitter-langs) + +;; (use-package yasnippet +;; :init (yas-global-mode)) +;; (use-package yasnippet-snippets) + +(use-package flymake + :after eglot + :bind (("C-c s f f" . flymake-start) + ("C-c s f l" . flymake-show-buffer-diagnostics) + ("C-c s f p" . flymake-show-project-diagnostics))) + +(use-package dired + :custom + (dired-listing-switches "-al --group-directories-first")) + + + +;; (add-to-list 'load-path "~/telega.el") +;; (require 'telega) + +(use-package magit + :bind (("C-c o g" . magit))) + +;; (use-package exwm) +;; (require 'exwm) +;; (require 'exwm-config) +;; (exwm-config-example) + +;; (use-package code-cells) + +;; (use-package orgnote +;; :defer t) + +(use-package copilot + :hook (python-ts-mode . copilot-mode) + :bind ("M-RET" . copilot-accept-completion)) + +(setq gc-cons-threshold (* 2 1000 1000)) +(setq read-process-output-max (* 1024 1024)) +(custom-set-variables + ;; custom-set-variables was added by Custom. + ;; If you edit it by hand, you could mess it up, so be careful. + ;; Your init file should contain only one such instance. + ;; If there is more than one, they won't work right. + '(package-selected-packages + '(dired web-mode vertico use-package treesit-auto tree-sitter-langs toc-org smartparens rust-mode rainbow-delimiters py-autopep8 org-download org-bullets org-auto-tangle orderless no-littering nix-mode move-text mood-line marginalia magit lsp-pyright kakoune js2-mode indent-guide helpful good-scroll general flycheck-rust fish-mode fish-completion eglot eat direnv dashboard crux corfu copilot consult catppuccin-theme cape all-the-icons snow meow))) +(custom-set-faces + ;; custom-set-faces was added by Custom. + ;; If you edit it by hand, you could mess it up, so be careful. + ;; Your init file should contain only one such instance. + ;; If there is more than one, they won't work right. + ) diff --git a/home-manager/general/programs/emacs/config.org b/home-manager/general/programs/emacs/config.org new file mode 100644 index 0000000..5cbd3b1 --- /dev/null +++ b/home-manager/general/programs/emacs/config.org @@ -0,0 +1,866 @@ +#+Title: spl3g's Emacs config +#+AUTHOR: spl3g +#+STARTUP: showeverything +#+PROPERTY: header-args :tangle init.el +#+OPTIONS: toc:2 +#+auto_tangle: t + +* Table Of Contents :toc: +- [[#progs-to-load-first][Progs to load first]] + - [[#optimise-gc][Optimise gc]] + - [[#use-package][use-package]] + - [[#save-history][Save history]] + - [[#meow-mode][Meow mode]] + - [[#general-keybindings][General keybindings]] +- [[#gui-tweaks][GUI tweaks]] + - [[#disable-gui-shit][Disable gui shit]] + - [[#fonts][Fonts]] + - [[#display-line-numbers][Display line numbers]] + - [[#theme][Theme]] + - [[#icons][Icons]] + - [[#modeline][Modeline]] + - [[#smooth-scroll][Smooth scroll]] + - [[#dashboard][Dashboard]] + - [[#disable-ring-bell][Disable ring-bell]] + - [[#indent-guide][Indent guide]] + - [[#misc][Misc]] +- [[#org-mode][Org mode]] + - [[#enabling-toc][Enabling toc]] + - [[#org-bullets][Org bullets]] + - [[#auto-tangle][Auto-tangle]] + - [[#org-download][Org-download]] + - [[#direnv][Direnv]] +- [[#better-ux][Better UX]] + - [[#vertico][Vertico]] + - [[#consult][Consult]] + - [[#pairs][Pairs]] + - [[#debugging][Debugging]] + - [[#move-lines][Move lines]] + - [[#truncate-lines][Truncate lines]] + - [[#no-littering][No littering]] + - [[#rainbow-delimiters][Rainbow delimiters]] + - [[#crux][Crux]] + - [[#better-help][Better *help*]] +- [[#eshell][Eshell]] + - [[#fish-completions][Fish completions]] + - [[#eat][Eat]] +- [[#lsp][LSP]] + - [[#languages][Languages]] + - [[#corfu][Corfu]] + - [[#tree-sitter][Tree-sitter]] + - [[#snippets][Snippets]] + - [[#flymake][Flymake]] +- [[#dired][Dired]] + - [[#bindings][Bindings]] + - [[#dired-filter][Dired filter]] +- [[#additional-apps][Additional apps]] + - [[#telegram-lol][Telegram lol]] + - [[#magit][Magit]] + - [[#exwm][EXWM]] + - [[#jupyter][Jupyter]] + - [[#orgnote][Orgnote]] + - [[#copilot][Copilot]] +- [[#runtime-performance][Runtime Performance]] + +* Progs to load first +** Optimise gc +#+begin_src emacs-lisp + (setq gc-cons-threshold (* 50 1000 1000)) +#+end_src +** use-package +#+begin_src emacs-lisp + (require 'use-package) + (eval-and-compile + (setq use-package-always-ensure t + use-package-expand-minimally t)) +#+end_src +** Save history +#+begin_src emacs-lisp + (use-package savehist + :init + (setq savehist-file "~/.config/emacs/var/savehist.el") + :config + (setq history-length 500) + (setq savehist-additional-variables '(kill-ring search-ring)) + (savehist-mode t)) +#+end_src +** Meow mode +#+begin_src emacs-lisp + (use-package meow + :config + (defun meow-setup () + (setq meow-cheatsheet-layout meow-cheatsheet-layout-qwerty) + (meow-motion-overwrite-define-key + '("j" . meow-next) + '("k" . meow-prev) + '("" . ignore)) + (meow-leader-define-key + ;; SPC j/k will run the original command in MOTION state. + '("j" . "H-j") + '("k" . "H-k") + ;; Use SPC (0-9) for digit arguments. + '("1" . meow-digit-argument) + '("2" . meow-digit-argument) + '("3" . meow-digit-argument) + '("4" . meow-digit-argument) + '("5" . meow-digit-argument) + '("6" . meow-digit-argument) + '("7" . meow-digit-argument) + '("8" . meow-digit-argument) + '("9" . meow-digit-argument) + '("0" . meow-digit-argument) + '("/" . meow-keypad-describe-key) + '("?" . meow-cheatsheet) + '("bk" . kill-this-buffer)) + (meow-normal-define-key + '("0" . meow-expand-0) + '("9" . meow-expand-9) + '("8" . meow-expand-8) + '("7" . meow-expand-7) + '("6" . meow-expand-6) + '("5" . meow-expand-5) + '("4" . meow-expand-4) + '("3" . meow-expand-3) + '("2" . meow-expand-2) + '("1" . meow-expand-1) + '("-" . negative-argument) + '(";" . meow-reverse) + '("," . meow-inner-of-thing) + '("." . meow-bounds-of-thing) + '("[" . meow-beginning-of-thing) + '("]" . meow-end-of-thing) + '("a" . meow-append) + '("A" . meow-open-below) + '("b" . meow-back-word) + '("B" . meow-back-symbol) + '("c" . meow-change) + '("d" . meow-delete) + '("D" . meow-backward-delete) + '("e" . meow-next-word) + '("E" . meow-next-symbol) + '("f" . meow-find) + '("g" . meow-cancel-selection) + '("G" . meow-grab) + '("h" . meow-left) + '("H" . meow-left-expand) + '("i" . meow-insert) + '("I" . meow-open-above) + '("j" . meow-next) + '("J" . meow-next-expand) + '("k" . meow-prev) + '("K" . meow-prev-expand) + '("l" . meow-right) + '("L" . meow-right-expand) + '("m" . meow-join) + '("n" . meow-search) + '("o" . meow-block) + '("O" . meow-to-block) + '("p" . meow-yank) + '("q" . meow-quit) + '("Q" . meow-goto-line) + '("r" . meow-replace) + '("R" . meow-swap-grab) + '("s" . meow-kill) + '("t" . meow-till) + '("u" . meow-undo) + '("U" . meow-undo-in-selection) + '("v" . meow-visit) + '("w" . meow-mark-word) + '("W" . meow-mark-symbol) + '("x" . meow-line) + '("X" . meow-goto-line) + '("y" . meow-save) + '("Y" . meow-sync-grab) + '("z" . meow-pop-selection) + '("'" . repeat) + '("" . ignore))) + (setq meow-use-enhanced-selection-effect t) + (meow-setup) + (meow-global-mode 1)) +#+end_src +** General keybindings +#+begin_src emacs-lisp + (use-package general + :config + ;; SPC as the global leader key + (general-create-definer spl3g/leader-keys + :prefix "C-c") + + (spl3g/leader-keys + ;; Buffers + "b" '(:ignore t :wk "Buffer") + "bi" '(ibuffer :wk "ibuffer") + "bk" '(kill-this-buffer :wk "Kill this buffer") + "bn" '(next-buffer :wk "Next buffer") + "bp" '(previous-buffer :wk "Previous buffer") + "br" '(revert-buffer :wk "Reload buffer") + "." '(find-file :wk "Find file") + ;; Splits + "w" '(:ignore t :wk "Splits") + "wv" '(split-window-right :wk "Split vertical") + "ws" '(split-window-below :wk "Split") + "ww" '(other-window :wk "Cycle throug windows") + "wc" '(delete-window :wk "Close window") + "wd" '(delete-window :wk "Close window") + "wl" '(evil-window-right :wk "") + "wj" '(evil-window-down :wk "") + "wk" '(evil-window-up :wk "") + "wh" '(evil-window-left :wk "") + "wo" '(delete-other-windows :wk "") + ;; Files + "f" '(:ignore t :wk "Files") + "fc" '((lambda () (interactive) (find-file "~/nixfiles/home-manager/programs/emacs/config.org")) :wk "Edit emacs config") + "fu" '(crux-sudo-edit :wk "Sudo edit file") + ;; Compilation + "c" '(:ignore t :wk "Compilation") + "cc" '(compile :wk "Compile") + "cr" '(recompile :wk "Recompile") + )) + +#+end_src +* GUI tweaks +** Disable gui shit +#+begin_src emacs-lisp + (defun spl3g/disable-scroll-bars (frame) + (modify-frame-parameters frame + '((vertical-scroll-bars . nil) + (horizontal-scroll-bars . nil)))) + (add-hook 'after-make-frame-functions 'spl3g/disable-scroll-bars) +#+end_src +** Fonts +#+begin_src emacs-lisp + (setq default-frame-alist '((font . "Source Code Pro"))) + (set-face-attribute 'default nil + :font "Source Code Pro" + :height 110 + :weight 'medium) + (set-face-attribute 'fixed-pitch nil + :font "Source Code Pro" + :height 110 + :weight 'medium) + (set-face-attribute 'variable-pitch nil + :font "Rubik" + :height 110 + :weight 'medium) + (set-face-attribute 'font-lock-comment-face nil + :slant 'italic) + (set-face-attribute 'font-lock-keyword-face nil + :weight 'bold) +#+end_src +** Display line numbers +#+begin_src emacs-lisp +(add-hook 'prog-mode-hook 'display-line-numbers-mode) +(visual-line-mode 1) +#+end_src + +** Theme +#+begin_src emacs-lisp +(use-package catppuccin-theme + :ensure t + :config + (load-theme 'catppuccin t) + (setq catppuccin-flavor 'macchiato) + (catppuccin-reload)) +#+end_src + +** Icons +#+begin_src emacs-lisp + (use-package all-the-icons + :ensure t + :if (display-graphic-p)) +#+end_src +** Modeline +#+begin_src emacs-lisp + (use-package mood-line + + ;; Enable mood-line + :config + (mood-line-mode) + :custom + (mood-line-segment-modal-meow-state-alist + '((normal "N" . mood-line-meow-normal) + (insert "I" . mood-line-meow-insert) + (keypad "K" . mood-line-meow-keypad) + (beacon "B" . mood-line-meow-beacon) + (motion "M" . mood-line-meow-motion))) + (mood-line-glyph-alist mood-line-glyphs-fira-code) + :custom-face + (mood-line-meow-beacon ((t (:foreground "#f9e2af" :weight bold)))) + (mood-line-meow-insert ((t (:foreground "#a6e3a1" :weight bold)))) + (mood-line-meow-keypad ((t (:foreground "#cba6f7" :weight bold)))) + (mood-line-meow-motion ((t (:foreground "#fab387" :weight bold)))) + (mood-line-meow-normal ((t (:weight bold)))) + (mode-line-inactive ((t (:box (:line-width (2 . 6) :color "#11111b") :inverse-video nil :foreground "#6c7086" :background "#11111b")))) + (mode-line ((t (:box (:line-width (2 . 6) :color "#181825") :background "#181825"))))) +#+end_src + +** Smooth scroll +#+begin_src emacs-lisp + (use-package good-scroll + :init (good-scroll-mode)) +#+end_src + +** Dashboard +#+begin_src emacs-lisp + (use-package dashboard + :init + (dashboard-setup-startup-hook) + :config + (setq initial-buffer-choice (lambda () (get-buffer-create "*dashboard*"))) + (setq dashboard-banner-logo-title "Yep, it's emacs, not vim") + (setq dashboard-startup-banner 'logo) + (setq dashboard-center-content t) + (add-to-list 'dashboard-item-generators '(config . dashboard-open-config)) + (setq dashboard-items '((recents . 5) + (agenda . 5)))) +#+end_src +** Disable ring-bell +#+begin_src emacs-lisp + (setq ring-bell-function 'ignore) +#+end_src +** Indent guide +#+begin_src emacs-lisp + (use-package indent-guide + :hook (prog-mode . indent-guide-mode)) +#+end_src +** Misc +#+begin_src emacs-lisp + (setq window-resize-pixelwise t) + (setq frame-resize-pixelwise t) + (save-place-mode t) + (defalias 'yes-or-no #'y-or-n-p) +#+end_src +* Org mode +#+begin_src emacs-lisp + (add-hook 'org-mode-hook 'org-indent-mode) + (require 'org-tempo) +#+end_src + +** Enabling toc +#+begin_src emacs-lisp + (use-package toc-org + :hook (org-mode . toc-org-mode)) +#+end_src + +** Org bullets +#+begin_src emacs-lisp + (use-package org-bullets + :hook (org-mode . org-bullets-mode)) +#+end_src +** Auto-tangle +#+begin_src emacs-lisp + (use-package org-auto-tangle + :hook (org-mode . org-auto-tangle-mode)) +#+end_src +** Org-download +#+begin_src emacs-lisp + (use-package org-download + :hook + (dired-mode . org-download-enable)) +#+end_src +** Direnv +#+begin_src emacs-lisp + (use-package direnv + :config + (direnv-mode)) +#+end_src +* Better UX +** Vertico +#+begin_src emacs-lisp + (use-package vertico + :init + (vertico-mode) + :bind (:map vertico-map + ("M-j" . vertico-next) + ("M-k" . vertico-previous) + ("RET" . vertico-directory-enter) + ("DEL" . vertico-directory-delete-char) + ("M-DEL" . vertico-directory-delete-word))) + + (use-package emacs + :init + ;; Add prompt indicator to `completing-read-multiple'. + ;; We display [CRM], e.g., [CRM,] if the separator is a comma. + (defun crm-indicator (args) + (cons (format "[CRM%s] %s" + (replace-regexp-in-string + "\\`\\[.*?]\\*\\|\\[.*?]\\*\\'" "" + crm-separator) + (car args)) + (cdr args))) + (advice-add #'completing-read-multiple :filter-args #'crm-indicator) + + ;; Do not allow the cursor in the minibuffer prompt + (setq minibuffer-prompt-properties + '(read-only t cursor-intangible t face minibuffer-prompt)) + (add-hook 'minibuffer-setup-hook #'cursor-intangible-mode) + + ;; Emacs 28: Hide commands in M-x which do not work in the current mode. + ;; Vertico commands are hidden in normal buffers. + ;; (setq read-extended-command-predicate + ;; #'command-completion-default-include-p) + + ;; Enable recursive minibuffers + (setq enable-recursive-minibuffers t)) +#+end_src +*** Ordeless +#+begin_src emacs-lisp + (use-package orderless + :init + (setq completion-styles '(orderless basic) + completion-category-defaults nil + completion-category-overrides '((file (styles partial-completion))))) +#+end_src +*** Marginalia +#+begin_src emacs-lisp + (use-package marginalia + :bind (:map minibuffer-local-map + ("M-A" . marginalia-cycle)) + :init + (marginalia-mode)) +#+end_src +** Consult +#+begin_src emacs-lisp + (use-package consult + ;; Replace bindings. Lazily loaded due by `use-package'. + :bind (;; C-c bindings in `mode-specific-map' + ("C-c k" . consult-kmacro) + ("C-c m" . consult-man) + ("C-c i" . consult-info) + ([remap Info-search] . consult-info) + ("C-c f r" . consult-recent-file) + ("C-c ," . consult-buffer) + ;; C-x bindings in `ctl-x-map' + ("C-x M-:" . consult-complex-command) ;; orig. repeat-complex-command + ("C-x 4 b" . consult-buffer-other-window) ;; orig. switch-to-buffer-other-window + ("C-x 5 b" . consult-buffer-other-frame) ;; orig. switch-to-buffer-other-frame + ("C-x p b" . consult-project-buffer) ;; orig. project-switch-to-buffer + ;; Custom M-# bindings for fast register access + ("M-#" . consult-register-load) + ("M-'" . consult-register-store) ;; orig. abbrev-prefix-mark (unrelated) + ("C-M-#" . consult-register) + ;; Other custom bindings + ("M-y" . consult-yank-pop) ;; orig. yank-pop + ;; M-g bindings in `goto-map' + ("C-c c e" . consult-compile-error) + ("M-g f" . consult-flymake) ;; Alternative: consult-flycheck + ("M-g g" . consult-goto-line) ;; orig. goto-line + ("M-g M-g" . consult-goto-line) ;; orig. goto-line + ("M-g o" . consult-outline) ;; Alternative: consult-org-heading + ;; M-s bindings in `search-map' + ("M-s d" . consult-fd) + ("M-s g" . consult-grep) + ("M-s G" . consult-git-grep) + ("M-s l" . consult-line) + ("M-s L" . consult-line-multi) + ("M-s k" . consult-keep-lines) + ("M-s u" . consult-focus-lines) + ;; Isearch integration + ("M-s e" . consult-isearch-history) + :map isearch-mode-map + ("M-e" . consult-isearch-history) ;; orig. isearch-edit-string + ("M-s e" . consult-isearch-history) ;; orig. isearch-edit-string + ("M-s l" . consult-line) ;; needed by consult-line to detect isearch + ("M-s L" . consult-line-multi) ;; needed by consult-line to detect isearch + ("M-r" . consult-history) + ;; Minibuffer history + :map minibuffer-local-map + ("M-s" . consult-history) ;; orig. next-matching-history-element + ("M-r" . consult-history)) ;; orig. previous-matching-history-element) + + ;; Enable automatic preview at point in the *Completions* buffer. This is + ;; relevant when you use the default completion UI. + :hook + (completion-list-mode . consult-preview-at-point-mode) + (eshell-mode . (lambda () + (keymap-set eshell-mode-map "M-h" 'consult-history))) + + ;; The :init configuration is always executed (Not lazy) + :init + + ;; Optionally configure the register formatting. This improves the register + ;; preview for `consult-register', `consult-register-load', + ;; `consult-register-store' and the Emacs built-ins. + (setq register-preview-delay 0.5 + register-preview-function #'consult-register-format) + + ;; Optionally tweak the register preview window. + ;; This adds thin lines, sorting and hides the mode line of the window. + (advice-add #'register-preview :override #'consult-register-window) + + ;; Configure other variables and modes in the :config section, + ;; after lazily loading the package. + :config + + ;; Optionally configure preview. The default value + ;; is 'any, such that any key triggers the preview. + ;; (setq consult-preview-key 'any) + ;; (setq consult-preview-key "M-.") + ;; (setq consult-preview-key '("S-" "S-")) + ;; For some commands and buffer sources it is useful to configure the + ;; :preview-key on a per-command basis using the `consult-customize' macro. + (consult-customize + consult-ripgrep consult-git-grep consult-grep + consult-bookmark consult-recent-file consult-xref + consult--source-bookmark consult--source-file-register + consult--source-recent-file consult--source-project-recent-file) + ;; :preview-key "M-." + + ;; Optionally configure the narrowing key. + ;; Both < and C-+ work reasonably well. + (setq consult-narrow-key "<") ;; "C-+" + + ;; Optionally make narrowing help available in the minibuffer. + ;; You may want to use `embark-prefix-help-command' or which-key instead. + ;; (define-key consult-narrow-map (vconcat consult-narrow-key "?") #'consult-narrow-help) + + ;; By default `consult-project-function' uses `project-root' from project.el. + ;; Optionally configure a different project root function. + ;;;; 1. project.el (the default) + ;; (setq consult-project-function #'consult--default-project--function) + ;;;; 2. vc.el (vc-root-dir) + ;; (setq consult-project-function (lambda (_) (vc-root-dir))) + ;;;; 3. locate-dominating-file + ;; (setq consult-project-function (lambda (_) (locate-dominating-file "." ".git"))) + ;;;; 4. projectile.el (projectile-project-root) + ;; (autoload 'projectile-project-root "projectile") + ;; (setq consult-project-function (lambda (_) (projectile-project-root))) + ;;;; 5. No project support + ;; (setq consult-project-function nil) + ) +#+end_src +** Pairs +#+begin_src emacs-lisp + (use-package smartparens + :init (smartparens-global-mode) + :config + ;; Snitched from doom + (let ((unless-list '(sp-point-before-word-p + sp-point-after-word-p + sp-point-before-same-p))) + (sp-pair "'" nil :unless unless-list) + (sp-pair "\"" nil :unless unless-list)) + (dolist (brace '("(" "{" "[")) + (sp-pair brace nil + :post-handlers '(("||\n[i]" "RET") ("| " "SPC")) + :unless '(sp-point-before-word-p sp-point-before-same-p))) + (sp-local-pair sp-lisp-modes "(" ")" :unless '(:rem sp-point-before-same-p)) + (sp-local-pair sp-lisp-modes "(" ")" :unless '(:rem sp-point-before-same-p)) + + (sp-local-pair '(python-mode python-ts-mode) "f'" "'") + + ;; Major-mode specific fixes + (sp-local-pair 'ruby-mode "{" "}" + :pre-handlers '(:rem sp-ruby-pre-handler) + :post-handlers '(:rem sp-ruby-post-handler)) + + ;; Don't do square-bracket space-expansion where it doesn't make sense to + (sp-local-pair '(emacs-lisp-mode org-mode markdown-mode gfm-mode) + "[" nil :post-handlers '(:rem ("| " "SPC"))) + + (sp-local-pair '(emacs-lisp-mode org-mode) + "'" nil) + + ;; Reasonable default pairs for HTML-style comments + (sp-local-pair (append sp--html-modes '(markdown-mode gfm-mode)) + "" + :unless '(sp-point-before-word-p sp-point-before-same-p) + :actions '(insert) :post-handlers '(("| " "SPC"))) + ;; Expand C-style comment blocks. + (defun +default-open-doc-comments-block (&rest _ignored) + (save-excursion + (newline) + (indent-according-to-mode))) + (sp-local-pair + '(js2-mode typescript-mode rjsx-mode rust-mode c-mode c++-mode objc-mode + csharp-mode java-mode php-mode css-mode scss-mode less-css-mode + stylus-mode scala-mode) + "/*" "*/" + :actions '(insert) + :post-handlers '(("| " "SPC") + (" | " "*") + ("|[i]\n[i]" "RET")))) +#+end_src + +** Debugging +#+begin_src emacs-lisp + ;; (use-package dap-mode + ;; :defer t + ;; :config + ;; (require 'dap-python) + ;; (setq dap-python-debugger 'debugpy)) +#+end_src +** Move lines +#+begin_src emacs-lisp + (use-package move-text + :bind (("C-M-k" . move-text-up) + ("C-M-j" . move-text-down))) +#+end_src +** Truncate lines +#+begin_src emacs-lisp + (global-visual-line-mode t) +#+end_src +** No littering +#+begin_src emacs-lisp + (use-package no-littering) +#+end_src +** Rainbow delimiters +#+begin_src emacs-lisp + (use-package rainbow-delimiters + :hook (prog-mode . rainbow-delimiters-mode)) +#+end_src +** Crux +#+begin_src emacs-lisp + (use-package crux + :bind (("C-c o t" . crux-visit-shell-buffer))) +#+end_src +** Better *help* +#+begin_src emacs-lisp + (use-package helpful + :bind (("C-h f" . 'helpful-callable) + ("C-h v" . 'helpful-variable) + ("C-h k" . 'helpful-key) + ("C-h x" . 'helpful-command) + ("C-c C-d" . 'helpful-at-point) + ("C-h F" . 'helpful-function))) +#+end_src +* Eshell +#+begin_src emacs-lisp + (add-hook 'eshell-mode-hook + (lambda () + (keymap-set eshell-mode-map "M-" 'consult-fish-completions))) +#+end_src +** Fish completions +#+begin_src emacs-lisp + (use-package fish-completion + :hook (eshell-mode . fish-completion-mode)) +#+end_src +*** Consult fish completions +#+begin_src emacs-lisp + (use-package consult-fish-completions + :load-path "~/prog/elisp/fish-completions/consult-fish-completions.el" + :hook (eshell-mode . (lambda () + (keymap-set eshell-mode-map "M-" 'consult-fish-completions)))) +#+end_src +** Eat +#+begin_src emacs-lisp + (use-package eat + :hook (eshell-mode . eat-eshell-mode) + :custom + (eat-enable-auto-line-mode t)) +#+end_src +*** Eat-toggle +#+begin_src emacs-lisp + ;; (defun eat-toggle () + ;; "Open eat terminal as a popup." + ;; (interactive) + ;; (if (eq major-mode 'eat-mode) + ;; (delete-window) + ;; (let ((buff (get-buffer-create eat-buffer-name))) + ;; (cl-assert (and buff (buffer-live-p buff))) + ;; (funcall #'pop-to-buffer buff) + ;; (with-current-buffer buff + ;; (setq-local split-width-threshold nil) + ;; (setq-local window-min-height 2) + ;; (unless (derived-mode-p 'eat-mode) + ;; (eat)))))) +#+end_src +*** Eat modes +#+begin_src emacs-lisp + ;; (defun eat-modes() + ;; (cond + ;; ((and (eq major-mode 'eat-mode) (member 'meow-normal-mode local-minor-modes)) + ;; (eat-emacs-mode)) + ;; ((and (eq major-mode 'eat-mode) (member 'meow-insert-mode local-minor-modes)) + ;; (eat-semi-char-mode)))) + ;; (add-hook 'meow-normal-mode-hook #'eat-modes) + ;; (add-hook 'meow-insert-mode-hook #'eat-modes) +#+end_src +* LSP +#+begin_src emacs-lisp + (use-package eglot + :bind (("C-c s e e" . eglot) + ("C-c s e d" . eldoc) + ("C-c s e r" . eglot-rename) + ("C-c s e s" . eglot-shutdown) + ("C-c s e f" . eglot-find-declaration) + ("C-c s e i" . eglot-find-implementation)) + :hook + (nix-mode . eglot-ensure) + (python-ts-mode . eglot-ensure) + :config + (add-to-list 'eglot-server-programs '(python-ts-mode . ("pylsp")))) +#+end_src +** Languages +*** Python +#+begin_src emacs-lisp + (use-package lsp-pyright) + (use-package py-autopep8 + :hook (python-mode . py-autopep8-mode)) +#+end_src +*** Rust +#+begin_src emacs-lisp + (use-package rust-mode + :mode "\\.rs\\'") + (use-package flycheck-rust + :config + (with-eval-after-load 'rust-mode + (add-hook 'flycheck-mode-hook #'flycheck-rust-setup))) +#+end_src +*** Fish +#+begin_src emacs-lisp + (use-package fish-mode + :mode "\\.fish\\'") +#+end_src +*** Nix +#+begin_src emacs-lisp + (use-package nix-mode + :mode ("\\.nix\\'" "\\.nix.in\\'")) + (use-package nix-drv-mode + :ensure nix-mode + :mode "\\.drv\\'") + (use-package nix-shell + :ensure nix-mode + :commands (nix-shell-unpack nix-shell-configure nix-shell-build)) + (use-package nix-repl + :ensure nix-mode + :commands (nix-repl)) +#+end_src +*** Web +#+begin_src emacs-lisp + (use-package web-mode + :mode + ("\\.phtml\\'" + "\\.tpl\\.php\\'" + "\\.[agj]sp\\'" + "\\.as[cp]x\\'" + "\\.erb\\'" + "\\.mustache\\'" + "\\.djhtml\\'")) +#+end_src +*** JavaScript +#+begin_src emacs-lisp + (use-package js2-mode) +#+end_src +** Corfu +#+begin_src emacs-lisp + (use-package corfu + :custom + (corfu-cycle t) + (corfu-preselect 'prompt) + (corfu-auto t) + (corfu-popupinfo-delay 0.0) + :bind + (:map corfu-map + ("TAB" . corfu-next) + ([tab] . corfu-next) + ("S-TAB" . corfu-previous) + ([backtab] . corfu-previous)) + + :init + (global-corfu-mode) + (corfu-history-mode) + (corfu-popupinfo-mode) + :config + (add-to-list 'savehist-additional-variables 'corfu-history)) + (use-package emacs + :init + (setq completion-cycle-threshold 3) + + (setq read-extended-command-predicate + #'command-completion-default-include-p) + + (setq tab-always-indent 'complete)) +#+end_src +*** Cape +#+begin_src emacs-lisp + (use-package cape + :demand t + :config + (add-to-list 'completion-at-point-functions #'cape-dabbrev) + (add-to-list 'completion-at-point-functions #'cape-file) + (add-to-list 'completion-at-point-functions #'cape-elisp-block) + ) +#+end_src +** Tree-sitter +#+begin_src emacs-lisp + (use-package tree-sitter + :init + (global-tree-sitter-mode) + :config + (add-hook 'tree-sitter-mode-hook 'tree-sitter-hl-mode)) + (use-package treesit-auto + :custom + (treesit-auto-install 'prompt) + :config + (treesit-auto-add-to-auto-mode-alist 'all) + (global-treesit-auto-mode)) +#+end_src +*** Additional langs +#+begin_src emacs-lisp + (use-package tree-sitter-langs) +#+end_src +** Snippets +#+begin_src emacs-lisp + ;; (use-package yasnippet + ;; :init (yas-global-mode)) + ;; (use-package yasnippet-snippets) +#+end_src +** Flymake +#+begin_src emacs-lisp + (use-package flymake + :after eglot + :bind (("C-c s f f" . flymake-start) + ("C-c s f l" . flymake-show-buffer-diagnostics) + ("C-c s f p" . flymake-show-project-diagnostics))) +#+end_src +* Dired +** Bindings +#+begin_src emacs-lisp + (use-package dired + :custom + (dired-listing-switches "-al --group-directories-first")) + +#+end_src +** Dired filter +#+begin_src emacs-lisp + +#+end_src +* Additional apps +** Telegram lol +#+begin_src emacs-lisp + ;; (add-to-list 'load-path "~/telega.el") + ;; (require 'telega) +#+end_src +** Magit +#+begin_src emacs-lisp + (use-package magit + :bind (("C-c o g" . magit))) +#+end_src +** EXWM +#+begin_src emacs-lisp + ;; (use-package exwm) + ;; (require 'exwm) + ;; (require 'exwm-config) + ;; (exwm-config-example) +#+end_src +** Jupyter +#+begin_src emacs-lisp + ;; (use-package code-cells) +#+end_src +** Orgnote +#+begin_src emacs-lisp + ;; (use-package orgnote + ;; :defer t) +#+end_src +** Copilot +#+begin_src emacs-lisp + (use-package copilot + :hook (python-ts-mode . copilot-mode) + :bind ("M-RET" . copilot-accept-completion)) +#+end_src +* Runtime Performance +#+begin_src emacs-lisp + (setq gc-cons-threshold (* 2 1000 1000)) + (setq read-process-output-max (* 1024 1024)) +#+end_src diff --git a/home-manager/general/programs/emacs/default.nix b/home-manager/general/programs/emacs/default.nix new file mode 100644 index 0000000..7b61850 --- /dev/null +++ b/home-manager/general/programs/emacs/default.nix @@ -0,0 +1,118 @@ +{ pkgs, ... }: +let + pkgsForEmacs = with pkgs; [ + tree-sitter + emacs-all-the-icons-fonts + libappindicator + poppler_utils + nil + nodejs + ]; + + pkgsUsePackage = with pkgs; [ + (pkgs.emacsWithPackagesFromUsePackage { + package = pkgs.emacs29-pgtk; + config = ./init.el; + alwaysEnsure = true; + # TODO + # with next flake update delete this, if mood-line hash changes: + # "commit": "10b5195f1b400d64d646f73a21bf5469612a375b", + # "sha256": "0wj8rdgsqsdd2ps3w7sj8a7yhhz0iczwgnalalzws42x8s9yn4j0", + override = final: prev: { + mood-line = prev.melpaPackages.mood-line.overrideAttrs(old: { + src = pkgs.fetchgit { + url = "https://gitlab.com/jessieh/mood-line"; + sha256 = "00vbv40x04g5f9n8i1ylhawslf42fsz0046r3srs4ss6pq8s893r"; + rev = "10b5195f1b400d64d646f73a21bf5469612a375b"; + }; + }); + }; + extraEmacsPackages = epkgs: [ + epkgs.use-package + # (epkgs.melpaBuild rec { + # pname = "codeium"; + # version = "1.2.102"; + + # src = fetchFromGitHub { + # owner = "Exafunction"; + # repo = "codeium.el"; + # rev = "1.4.4"; + # sha256 = "1jjix7fn73ihjnhfivf72wris72f4kwf7xb6k5hxs41fm4kr9hdd"; + # }; + + # commit = "ddc9927ea231ecc5a32f7c9905f92fdfb7912e75"; + + # recipe = writeText "recipe" '' + # (codeium + # :repo "${src.owner}/${src.repo}" + # :fetcher github) + # ''; + # }) + # (epkgs.melpaBuild rec { + # pname = "telega"; + # version = "0.8.216"; + # src = fetchFromGitHub { + # owner = "zevlg"; + # repo = "telega.el"; + # rev = "3899aa8648b9e6deddbb34a2a817ca18acb9d97a"; + # sha256 = "05xrm86gp185mgwb62w720hcbn87salk8z0whq6zf2r2f24l6xbw"; + # }; + # commit = "3899aa8648b9e6deddbb34a2a817ca18acb9d97a"; + # recipe = writeText "recipe" '' + # (telega :fetcher github + # :repo "zevlg/telega.el" + # :files (:defaults "etc" "server" "contrib" "Makefile")) + # ''; + # }) + # (epkgs.melpaBuild rec { + # pname = "orgnote"; + # version = "0.7.17"; + + # src = fetchFromGitHub { + # owner = "Artawower"; + # repo = "orgnote.el"; + # rev = "v${version}"; + # sha256 = "1lrj47h244z4dqq2wyhpww7p3b4sy6bayk8lwlka517lhbcdgh33"; + # }; + + # commit = "ccc40cc346ebf5a6e6a55e3d4a147f0230337350"; + + # recipe = writeText "recipe" '' + # (orgnote + # :repo "${src.owner}/${src.repo}" + # :fetcher github) + # ''; + # }) + (epkgs.melpaBuild rec { + pname = "copilot"; + version = "20231219"; + + src = fetchFromGitHub { + owner = "zerolfx"; + repo = "copilot.el"; + rev = "d4fa14cea818e041b4a536c5052cf6d28c7223d7"; + sha256 = "1bn2im5ybzmwbwbi7v39s0qzmca5isp7zb0ls61y6sramh6k8fsg"; + }; + + packageRequires = with epkgs; [ editorconfig dash s ]; + + commit = "d4fa14cea818e041b4a536c5052cf6d28c7223d7"; + + recipe = writeText "recipe" '' + (copilot + :repo "${src.owner}/${src.repo}" + :fetcher github + :files ("*.el" "dist")) + ''; + }) + ]; + }) + ]; +in +{ + home.packages = pkgsForEmacs ++ pkgsUsePackage; + xdg.configFile = { + # "emacs/init.el".text = builtins.readFile ./init.el; + "emacs/early-init.el".text = builtins.readFile ./early-init.el; + }; +} diff --git a/home-manager/general/programs/emacs/early-init.el b/home-manager/general/programs/emacs/early-init.el new file mode 100644 index 0000000..6e306a1 --- /dev/null +++ b/home-manager/general/programs/emacs/early-init.el @@ -0,0 +1,4 @@ +(menu-bar-mode -1) +(tool-bar-mode -1) +(scroll-bar-mode -1) +(setq-default pgtk-wait-for-event-timeout 0) diff --git a/home-manager/general/programs/emacs/init.el b/home-manager/general/programs/emacs/init.el new file mode 100644 index 0000000..f1a4f90 --- /dev/null +++ b/home-manager/general/programs/emacs/init.el @@ -0,0 +1,675 @@ +(setq gc-cons-threshold (* 50 1000 1000)) + +(require 'use-package) +(eval-and-compile + (setq use-package-always-ensure t + use-package-expand-minimally t)) + +(use-package savehist + :init + (setq savehist-file "~/.config/emacs/var/savehist.el") + :config + (setq history-length 500) + (setq savehist-additional-variables '(kill-ring search-ring)) + (savehist-mode t)) + +(use-package meow + :config + (defun meow-setup () + (setq meow-cheatsheet-layout meow-cheatsheet-layout-qwerty) + (meow-motion-overwrite-define-key + '("j" . meow-next) + '("k" . meow-prev) + '("" . ignore)) + (meow-leader-define-key + ;; SPC j/k will run the original command in MOTION state. + '("j" . "H-j") + '("k" . "H-k") + ;; Use SPC (0-9) for digit arguments. + '("1" . meow-digit-argument) + '("2" . meow-digit-argument) + '("3" . meow-digit-argument) + '("4" . meow-digit-argument) + '("5" . meow-digit-argument) + '("6" . meow-digit-argument) + '("7" . meow-digit-argument) + '("8" . meow-digit-argument) + '("9" . meow-digit-argument) + '("0" . meow-digit-argument) + '("/" . meow-keypad-describe-key) + '("?" . meow-cheatsheet) + '("bk" . kill-this-buffer)) + (meow-normal-define-key + '("0" . meow-expand-0) + '("9" . meow-expand-9) + '("8" . meow-expand-8) + '("7" . meow-expand-7) + '("6" . meow-expand-6) + '("5" . meow-expand-5) + '("4" . meow-expand-4) + '("3" . meow-expand-3) + '("2" . meow-expand-2) + '("1" . meow-expand-1) + '("-" . negative-argument) + '(";" . meow-reverse) + '("," . meow-inner-of-thing) + '("." . meow-bounds-of-thing) + '("[" . meow-beginning-of-thing) + '("]" . meow-end-of-thing) + '("a" . meow-append) + '("A" . meow-open-below) + '("b" . meow-back-word) + '("B" . meow-back-symbol) + '("c" . meow-change) + '("d" . meow-delete) + '("D" . meow-backward-delete) + '("e" . meow-next-word) + '("E" . meow-next-symbol) + '("f" . meow-find) + '("g" . meow-cancel-selection) + '("G" . meow-grab) + '("h" . meow-left) + '("H" . meow-left-expand) + '("i" . meow-insert) + '("I" . meow-open-above) + '("j" . meow-next) + '("J" . meow-next-expand) + '("k" . meow-prev) + '("K" . meow-prev-expand) + '("l" . meow-right) + '("L" . meow-right-expand) + '("m" . meow-join) + '("n" . meow-search) + '("o" . meow-block) + '("O" . meow-to-block) + '("p" . meow-yank) + '("q" . meow-quit) + '("Q" . meow-goto-line) + '("r" . meow-replace) + '("R" . meow-swap-grab) + '("s" . meow-kill) + '("t" . meow-till) + '("u" . meow-undo) + '("U" . meow-undo-in-selection) + '("v" . meow-visit) + '("w" . meow-mark-word) + '("W" . meow-mark-symbol) + '("x" . meow-line) + '("X" . meow-goto-line) + '("y" . meow-save) + '("Y" . meow-sync-grab) + '("z" . meow-pop-selection) + '("'" . repeat) + '("" . ignore))) + (setq meow-use-enhanced-selection-effect t) + (meow-setup) + (meow-global-mode 1)) + +(use-package general + :config + ;; SPC as the global leader key + (general-create-definer spl3g/leader-keys + :prefix "C-c") + + (spl3g/leader-keys + ;; Buffers + "b" '(:ignore t :wk "Buffer") + "bi" '(ibuffer :wk "ibuffer") + "bk" '(kill-this-buffer :wk "Kill this buffer") + "bn" '(next-buffer :wk "Next buffer") + "bp" '(previous-buffer :wk "Previous buffer") + "br" '(revert-buffer :wk "Reload buffer") + "." '(find-file :wk "Find file") + ;; Splits + "w" '(:ignore t :wk "Splits") + "wv" '(split-window-right :wk "Split vertical") + "ws" '(split-window-below :wk "Split") + "ww" '(other-window :wk "Cycle throug windows") + "wc" '(delete-window :wk "Close window") + "wd" '(delete-window :wk "Close window") + "wl" '(evil-window-right :wk "") + "wj" '(evil-window-down :wk "") + "wk" '(evil-window-up :wk "") + "wh" '(evil-window-left :wk "") + "wo" '(delete-other-windows :wk "") + ;; Files + "f" '(:ignore t :wk "Files") + "fc" '((lambda () (interactive) (find-file "~/nixfiles/home-manager/programs/emacs/config.org")) :wk "Edit emacs config") + "fu" '(crux-sudo-edit :wk "Sudo edit file") + ;; Compilation + "c" '(:ignore t :wk "Compilation") + "cc" '(compile :wk "Compile") + "cr" '(recompile :wk "Recompile") + )) + +(defun spl3g/disable-scroll-bars (frame) + (modify-frame-parameters frame + '((vertical-scroll-bars . nil) + (horizontal-scroll-bars . nil)))) +(add-hook 'after-make-frame-functions 'spl3g/disable-scroll-bars) + +(setq default-frame-alist '((font . "Source Code Pro"))) +(set-face-attribute 'default nil + :font "Source Code Pro" + :height 110 + :weight 'medium) +(set-face-attribute 'fixed-pitch nil + :font "Source Code Pro" + :height 110 + :weight 'medium) +(set-face-attribute 'variable-pitch nil + :font "Rubik" + :height 110 + :weight 'medium) +(set-face-attribute 'font-lock-comment-face nil + :slant 'italic) +(set-face-attribute 'font-lock-keyword-face nil + :weight 'bold) + +(add-hook 'prog-mode-hook 'display-line-numbers-mode) +(visual-line-mode 1) + +(use-package catppuccin-theme + :ensure t + :config + (load-theme 'catppuccin t) + (setq catppuccin-flavor 'macchiato) + (catppuccin-reload)) + +(use-package all-the-icons + :ensure t + :if (display-graphic-p)) + +(use-package mood-line + + ;; Enable mood-line + :config + (mood-line-mode) + :custom + (mood-line-segment-modal-meow-state-alist + '((normal "N" . mood-line-meow-normal) + (insert "I" . mood-line-meow-insert) + (keypad "K" . mood-line-meow-keypad) + (beacon "B" . mood-line-meow-beacon) + (motion "M" . mood-line-meow-motion))) + (mood-line-glyph-alist mood-line-glyphs-fira-code) + :custom-face + (mood-line-meow-beacon ((t (:foreground "#f9e2af" :weight bold)))) + (mood-line-meow-insert ((t (:foreground "#a6e3a1" :weight bold)))) + (mood-line-meow-keypad ((t (:foreground "#cba6f7" :weight bold)))) + (mood-line-meow-motion ((t (:foreground "#fab387" :weight bold)))) + (mood-line-meow-normal ((t (:weight bold)))) + (mode-line-inactive ((t (:box (:line-width (2 . 6) :color "#11111b") :inverse-video nil :foreground "#6c7086" :background "#11111b")))) + (mode-line ((t (:box (:line-width (2 . 6) :color "#181825") :background "#181825"))))) + +(use-package good-scroll + :init (good-scroll-mode)) + +(use-package dashboard + :init + (dashboard-setup-startup-hook) + :config + (setq initial-buffer-choice (lambda () (get-buffer-create "*dashboard*"))) + (setq dashboard-banner-logo-title "Yep, it's emacs, not vim") + (setq dashboard-startup-banner 'logo) + (setq dashboard-center-content t) + (add-to-list 'dashboard-item-generators '(config . dashboard-open-config)) + (setq dashboard-items '((recents . 5) + (agenda . 5)))) + +(setq ring-bell-function 'ignore) + +(use-package indent-guide + :hook (prog-mode . indent-guide-mode)) + +(setq window-resize-pixelwise t) +(setq frame-resize-pixelwise t) +(save-place-mode t) +(defalias 'yes-or-no #'y-or-n-p) + +(add-hook 'org-mode-hook 'org-indent-mode) +(require 'org-tempo) + +(use-package toc-org + :hook (org-mode . toc-org-mode)) + +(use-package org-bullets + :hook (org-mode . org-bullets-mode)) + +(use-package org-auto-tangle + :hook (org-mode . org-auto-tangle-mode)) + +(use-package org-download + :hook + (dired-mode . org-download-enable)) + +(use-package direnv + :config + (direnv-mode)) + +(use-package vertico + :init + (vertico-mode) + :bind (:map vertico-map + ("M-j" . vertico-next) + ("M-k" . vertico-previous) + ("RET" . vertico-directory-enter) + ("DEL" . vertico-directory-delete-char) + ("M-DEL" . vertico-directory-delete-word))) + +(use-package emacs + :init + ;; Add prompt indicator to `completing-read-multiple'. + ;; We display [CRM], e.g., [CRM,] if the separator is a comma. + (defun crm-indicator (args) + (cons (format "[CRM%s] %s" + (replace-regexp-in-string + "\\`\\[.*?]\\*\\|\\[.*?]\\*\\'" "" + crm-separator) + (car args)) + (cdr args))) + (advice-add #'completing-read-multiple :filter-args #'crm-indicator) + + ;; Do not allow the cursor in the minibuffer prompt + (setq minibuffer-prompt-properties + '(read-only t cursor-intangible t face minibuffer-prompt)) + (add-hook 'minibuffer-setup-hook #'cursor-intangible-mode) + + ;; Emacs 28: Hide commands in M-x which do not work in the current mode. + ;; Vertico commands are hidden in normal buffers. + ;; (setq read-extended-command-predicate + ;; #'command-completion-default-include-p) + + ;; Enable recursive minibuffers + (setq enable-recursive-minibuffers t)) + +(use-package orderless + :init + (setq completion-styles '(orderless basic) + completion-category-defaults nil + completion-category-overrides '((file (styles partial-completion))))) + +(use-package marginalia + :bind (:map minibuffer-local-map + ("M-A" . marginalia-cycle)) + :init + (marginalia-mode)) + +(use-package consult + ;; Replace bindings. Lazily loaded due by `use-package'. + :bind (;; C-c bindings in `mode-specific-map' + ("C-c k" . consult-kmacro) + ("C-c m" . consult-man) + ("C-c i" . consult-info) + ([remap Info-search] . consult-info) + ("C-c f r" . consult-recent-file) + ("C-c ," . consult-buffer) + ;; C-x bindings in `ctl-x-map' + ("C-x M-:" . consult-complex-command) ;; orig. repeat-complex-command + ("C-x 4 b" . consult-buffer-other-window) ;; orig. switch-to-buffer-other-window + ("C-x 5 b" . consult-buffer-other-frame) ;; orig. switch-to-buffer-other-frame + ("C-x p b" . consult-project-buffer) ;; orig. project-switch-to-buffer + ;; Custom M-# bindings for fast register access + ("M-#" . consult-register-load) + ("M-'" . consult-register-store) ;; orig. abbrev-prefix-mark (unrelated) + ("C-M-#" . consult-register) + ;; Other custom bindings + ("M-y" . consult-yank-pop) ;; orig. yank-pop + ;; M-g bindings in `goto-map' + ("C-c c e" . consult-compile-error) + ("M-g f" . consult-flymake) ;; Alternative: consult-flycheck + ("M-g g" . consult-goto-line) ;; orig. goto-line + ("M-g M-g" . consult-goto-line) ;; orig. goto-line + ("M-g o" . consult-outline) ;; Alternative: consult-org-heading + ;; M-s bindings in `search-map' + ("M-s d" . consult-fd) + ("M-s g" . consult-grep) + ("M-s G" . consult-git-grep) + ("M-s l" . consult-line) + ("M-s L" . consult-line-multi) + ("M-s k" . consult-keep-lines) + ("M-s u" . consult-focus-lines) + ;; Isearch integration + ("M-s e" . consult-isearch-history) + :map isearch-mode-map + ("M-e" . consult-isearch-history) ;; orig. isearch-edit-string + ("M-s e" . consult-isearch-history) ;; orig. isearch-edit-string + ("M-s l" . consult-line) ;; needed by consult-line to detect isearch + ("M-s L" . consult-line-multi) ;; needed by consult-line to detect isearch + ("M-r" . consult-history) + ;; Minibuffer history + :map minibuffer-local-map + ("M-s" . consult-history) ;; orig. next-matching-history-element + ("M-r" . consult-history)) ;; orig. previous-matching-history-element) + + ;; Enable automatic preview at point in the *Completions* buffer. This is + ;; relevant when you use the default completion UI. + :hook + (completion-list-mode . consult-preview-at-point-mode) + (eshell-mode . (lambda () + (keymap-set eshell-mode-map "M-h" 'consult-history))) + + ;; The :init configuration is always executed (Not lazy) + :init + + ;; Optionally configure the register formatting. This improves the register + ;; preview for `consult-register', `consult-register-load', + ;; `consult-register-store' and the Emacs built-ins. + (setq register-preview-delay 0.5 + register-preview-function #'consult-register-format) + + ;; Optionally tweak the register preview window. + ;; This adds thin lines, sorting and hides the mode line of the window. + (advice-add #'register-preview :override #'consult-register-window) + + ;; Configure other variables and modes in the :config section, + ;; after lazily loading the package. + :config + + ;; Optionally configure preview. The default value + ;; is 'any, such that any key triggers the preview. + ;; (setq consult-preview-key 'any) + ;; (setq consult-preview-key "M-.") + ;; (setq consult-preview-key '("S-" "S-")) + ;; For some commands and buffer sources it is useful to configure the + ;; :preview-key on a per-command basis using the `consult-customize' macro. + (consult-customize + consult-ripgrep consult-git-grep consult-grep + consult-bookmark consult-recent-file consult-xref + consult--source-bookmark consult--source-file-register + consult--source-recent-file consult--source-project-recent-file) + ;; :preview-key "M-." + + ;; Optionally configure the narrowing key. + ;; Both < and C-+ work reasonably well. + (setq consult-narrow-key "<") ;; "C-+" + + ;; Optionally make narrowing help available in the minibuffer. + ;; You may want to use `embark-prefix-help-command' or which-key instead. + ;; (define-key consult-narrow-map (vconcat consult-narrow-key "?") #'consult-narrow-help) + + ;; By default `consult-project-function' uses `project-root' from project.el. + ;; Optionally configure a different project root function. +;;;; 1. project.el (the default) + ;; (setq consult-project-function #'consult--default-project--function) +;;;; 2. vc.el (vc-root-dir) + ;; (setq consult-project-function (lambda (_) (vc-root-dir))) +;;;; 3. locate-dominating-file + ;; (setq consult-project-function (lambda (_) (locate-dominating-file "." ".git"))) +;;;; 4. projectile.el (projectile-project-root) + ;; (autoload 'projectile-project-root "projectile") + ;; (setq consult-project-function (lambda (_) (projectile-project-root))) +;;;; 5. No project support + ;; (setq consult-project-function nil) + ) + +(use-package smartparens + :init (smartparens-global-mode) + :config + ;; Snitched from doom + (let ((unless-list '(sp-point-before-word-p + sp-point-after-word-p + sp-point-before-same-p))) + (sp-pair "'" nil :unless unless-list) + (sp-pair "\"" nil :unless unless-list)) + (dolist (brace '("(" "{" "[")) + (sp-pair brace nil + :post-handlers '(("||\n[i]" "RET") ("| " "SPC")) + :unless '(sp-point-before-word-p sp-point-before-same-p))) + (sp-local-pair sp-lisp-modes "(" ")" :unless '(:rem sp-point-before-same-p)) + (sp-local-pair sp-lisp-modes "(" ")" :unless '(:rem sp-point-before-same-p)) + + (sp-local-pair '(python-mode python-ts-mode) "f'" "'") + + ;; Major-mode specific fixes + (sp-local-pair 'ruby-mode "{" "}" + :pre-handlers '(:rem sp-ruby-pre-handler) + :post-handlers '(:rem sp-ruby-post-handler)) + + ;; Don't do square-bracket space-expansion where it doesn't make sense to + (sp-local-pair '(emacs-lisp-mode org-mode markdown-mode gfm-mode) + "[" nil :post-handlers '(:rem ("| " "SPC"))) + + (sp-local-pair '(emacs-lisp-mode org-mode) + "'" nil) + + ;; Reasonable default pairs for HTML-style comments + (sp-local-pair (append sp--html-modes '(markdown-mode gfm-mode)) + "" + :unless '(sp-point-before-word-p sp-point-before-same-p) + :actions '(insert) :post-handlers '(("| " "SPC"))) + ;; Expand C-style comment blocks. + (defun +default-open-doc-comments-block (&rest _ignored) + (save-excursion + (newline) + (indent-according-to-mode))) + (sp-local-pair + '(js2-mode typescript-mode rjsx-mode rust-mode c-mode c++-mode objc-mode + csharp-mode java-mode php-mode css-mode scss-mode less-css-mode + stylus-mode scala-mode) + "/*" "*/" + :actions '(insert) + :post-handlers '(("| " "SPC") + (" | " "*") + ("|[i]\n[i]" "RET")))) + +;; (use-package dap-mode +;; :defer t +;; :config +;; (require 'dap-python) +;; (setq dap-python-debugger 'debugpy)) + +(use-package move-text + :bind (("C-M-k" . move-text-up) + ("C-M-j" . move-text-down))) + +(global-visual-line-mode t) + +(use-package no-littering) + +(use-package rainbow-delimiters + :hook (prog-mode . rainbow-delimiters-mode)) + +(use-package crux + :bind (("C-c o t" . crux-visit-shell-buffer))) + +(use-package helpful + :bind (("C-h f" . 'helpful-callable) + ("C-h v" . 'helpful-variable) + ("C-h k" . 'helpful-key) + ("C-h x" . 'helpful-command) + ("C-c C-d" . 'helpful-at-point) + ("C-h F" . 'helpful-function))) + +(add-hook 'eshell-mode-hook + (lambda () + (keymap-set eshell-mode-map "M-" 'consult-fish-completions))) + +(use-package fish-completion + :hook (eshell-mode . fish-completion-mode)) + +(use-package consult-fish-completions + :load-path "~/prog/elisp/fish-completions/" + :hook (eshell-mode . (lambda () + (keymap-set eshell-mode-map "M-" 'consult-fish-completions)))) + +(use-package eat + :hook (eshell-mode . eat-eshell-mode) + :custom + (eat-enable-auto-line-mode t)) + +;; (defun eat-toggle () +;; "Open eat terminal as a popup." +;; (interactive) +;; (if (eq major-mode 'eat-mode) +;; (delete-window) +;; (let ((buff (get-buffer-create eat-buffer-name))) +;; (cl-assert (and buff (buffer-live-p buff))) +;; (funcall #'pop-to-buffer buff) +;; (with-current-buffer buff +;; (setq-local split-width-threshold nil) +;; (setq-local window-min-height 2) +;; (unless (derived-mode-p 'eat-mode) +;; (eat)))))) + +;; (defun eat-modes() +;; (cond +;; ((and (eq major-mode 'eat-mode) (member 'meow-normal-mode local-minor-modes)) +;; (eat-emacs-mode)) +;; ((and (eq major-mode 'eat-mode) (member 'meow-insert-mode local-minor-modes)) +;; (eat-semi-char-mode)))) +;; (add-hook 'meow-normal-mode-hook #'eat-modes) +;; (add-hook 'meow-insert-mode-hook #'eat-modes) + +(use-package eglot + :bind (("C-c s e e" . eglot) + ("C-c s e d" . eldoc) + ("C-c s e r" . eglot-rename) + ("C-c s e s" . eglot-shutdown) + ("C-c s e f" . eglot-find-declaration) + ("C-c s e i" . eglot-find-implementation)) + :hook + (nix-mode . eglot-ensure) + (python-ts-mode . eglot-ensure) + :config + (add-to-list 'eglot-server-programs '(python-ts-mode . ("pylsp")))) + +(use-package lsp-pyright) +(use-package py-autopep8 + :hook (python-mode . py-autopep8-mode)) + +(use-package rust-mode + :mode "\\.rs\\'") +(use-package flycheck-rust + :config + (with-eval-after-load 'rust-mode + (add-hook 'flycheck-mode-hook #'flycheck-rust-setup))) + +(use-package fish-mode + :mode "\\.fish\\'") + +(use-package nix-mode + :mode ("\\.nix\\'" "\\.nix.in\\'")) +(use-package nix-drv-mode + :ensure nix-mode + :mode "\\.drv\\'") +(use-package nix-shell + :ensure nix-mode + :commands (nix-shell-unpack nix-shell-configure nix-shell-build)) +(use-package nix-repl + :ensure nix-mode + :commands (nix-repl)) + +(use-package web-mode + :mode + ("\\.phtml\\'" + "\\.tpl\\.php\\'" + "\\.[agj]sp\\'" + "\\.as[cp]x\\'" + "\\.erb\\'" + "\\.mustache\\'" + "\\.djhtml\\'")) + +(use-package js2-mode) + +(use-package corfu + :custom + (corfu-cycle t) + (corfu-preselect 'prompt) + (corfu-auto t) + (corfu-popupinfo-delay 0.0) + :bind + (:map corfu-map + ("TAB" . corfu-next) + ([tab] . corfu-next) + ("S-TAB" . corfu-previous) + ([backtab] . corfu-previous)) + + :init + (global-corfu-mode) + (corfu-history-mode) + (corfu-popupinfo-mode) + :config + (add-to-list 'savehist-additional-variables 'corfu-history)) +(use-package emacs + :init + (setq completion-cycle-threshold 3) + + (setq read-extended-command-predicate + #'command-completion-default-include-p) + + (setq tab-always-indent 'complete)) + +(use-package cape + :demand t + :config + (add-to-list 'completion-at-point-functions #'cape-dabbrev) + (add-to-list 'completion-at-point-functions #'cape-file) + (add-to-list 'completion-at-point-functions #'cape-elisp-block) + ) + +(use-package tree-sitter + :init + (global-tree-sitter-mode) + :config + (add-hook 'tree-sitter-mode-hook 'tree-sitter-hl-mode)) +(use-package treesit-auto + :custom + (treesit-auto-install 'prompt) + :config + (treesit-auto-add-to-auto-mode-alist 'all) + (global-treesit-auto-mode)) + +(use-package tree-sitter-langs) + +;; (use-package yasnippet +;; :init (yas-global-mode)) +;; (use-package yasnippet-snippets) + +(use-package flymake + :after eglot + :bind (("C-c s f f" . flymake-start) + ("C-c s f l" . flymake-show-buffer-diagnostics) + ("C-c s f p" . flymake-show-project-diagnostics))) + +(use-package dired + :custom + (dired-listing-switches "-al --group-directories-first")) + + + +;; (add-to-list 'load-path "~/telega.el") +;; (require 'telega) + +(use-package magit + :bind (("C-c o g" . magit))) + +;; (use-package exwm) +;; (require 'exwm) +;; (require 'exwm-config) +;; (exwm-config-example) + +;; (use-package code-cells) + +;; (use-package orgnote +;; :defer t) + +(use-package copilot + :hook (python-ts-mode . copilot-mode) + :bind ("M-RET" . copilot-accept-completion)) + +(setq gc-cons-threshold (* 2 1000 1000)) +(setq read-process-output-max (* 1024 1024)) +(custom-set-variables + ;; custom-set-variables was added by Custom. + ;; If you edit it by hand, you could mess it up, so be careful. + ;; Your init file should contain only one such instance. + ;; If there is more than one, they won't work right. + '(package-selected-packages + '(dired web-mode vertico use-package treesit-auto tree-sitter-langs toc-org smartparens rust-mode rainbow-delimiters py-autopep8 org-download org-bullets org-auto-tangle orderless no-littering nix-mode move-text mood-line marginalia magit lsp-pyright js2-mode indent-guide helpful good-scroll general flycheck-rust fish-mode fish-completion eglot eat direnv dashboard crux corfu copilot consult catppuccin-theme cape all-the-icons snow meow))) +(custom-set-faces + ;; custom-set-faces was added by Custom. + ;; If you edit it by hand, you could mess it up, so be careful. + ;; Your init file should contain only one such instance. + ;; If there is more than one, they won't work right. + ) diff --git a/home-manager/general/programs/emacs/init.old.el b/home-manager/general/programs/emacs/init.old.el new file mode 100644 index 0000000..766d86d --- /dev/null +++ b/home-manager/general/programs/emacs/init.old.el @@ -0,0 +1,592 @@ +(require 'use-package) + +;; Evil +;; (use-package evil +;; :init +;; (setq evil-want-integration t) +;; (setq evil-want-keybinding nil) +;; (setq evil-split-window-below t) +;; (setq evil-vsplit-window-right t) +;; (evil-mode)) +;; (use-package evil-collection +;; :after evil +;; :config +;; (setq evil-collection-mode-list '(dashboard dired ibuffer)) +;; (evil-collection-init)) + +;; Meow +(use-package meow + :config +(defun meow-setup () + (setq meow-use-clipboard t) + (setq meow-cheatsheet-layout meow-cheatsheet-layout-qwerty) + (meow-motion-overwrite-define-key + '("j" . meow-next) + '("k" . meow-prev) + '("" . ignore)) + (meow-leader-define-key + ;; SPC j/k will run the original command in MOTION state. + '("j" . "H-j") + '("k" . "H-k") + ;; Use SPC (0-9) for digit arguments. + '("1" . meow-digit-argument) + '("2" . meow-digit-argument) + '("3" . meow-digit-argument) + '("4" . meow-digit-argument) + '("5" . meow-digit-argument) + '("6" . meow-digit-argument) + '("7" . meow-digit-argument) + '("8" . meow-digit-argument) + '("9" . meow-digit-argument) + '("0" . meow-digit-argument) + '("/" . meow-keypad-describe-key) + '("?" . meow-cheatsheet) + '("bk" . kill-this-buffer)) + (meow-normal-define-key + '("0" . meow-expand-0) + '("9" . meow-expand-9) + '("8" . meow-expand-8) + '("7" . meow-expand-7) + '("6" . meow-expand-6) + '("5" . meow-expand-5) + '("4" . meow-expand-4) + '("3" . meow-expand-3) + '("2" . meow-expand-2) + '("1" . meow-expand-1) + '("-" . negative-argument) + '(";" . meow-reverse) + '("," . meow-inner-of-thing) + '("." . meow-bounds-of-thing) + '("[" . meow-beginning-of-thing) + '("]" . meow-end-of-thing) + '("a" . meow-append) + '("A" . meow-open-below) + '("b" . meow-back-word) + '("B" . meow-back-symbol) + '("c" . meow-change) + '("d" . meow-delete) + '("D" . meow-backward-delete) + '("e" . meow-next-word) + '("E" . meow-next-symbol) + '("f" . meow-find) + '("g" . meow-cancel-selection) + '("G" . meow-grab) + '("h" . meow-left) + '("H" . meow-left-expand) + '("i" . meow-insert) + '("I" . meow-open-above) + '("j" . meow-next) + '("J" . meow-next-expand) + '("k" . meow-prev) + '("K" . meow-prev-expand) + '("l" . meow-right) + '("L" . meow-right-expand) + '("m" . meow-join) + '("n" . meow-search) + '("o" . meow-block) + '("O" . meow-to-block) + '("p" . meow-yank) + '("q" . meow-quit) + '("Q" . meow-goto-line) + '("r" . meow-replace) + '("R" . meow-swap-grab) + '("s" . meow-kill) + '("t" . meow-till) + '("u" . meow-undo) + '("U" . meow-undo-in-selection) + '("v" . meow-visit) + '("w" . meow-mark-word) + '("W" . meow-mark-symbol) + '("x" . meow-line) + '("X" . meow-goto-line) + '("y" . meow-save) + '("Y" . meow-sync-grab) + '("z" . meow-pop-selection) + '("'" . repeat) + '("" . ignore))) +(meow-setup) +(meow-global-mode 1)) + +;; General Keybindings +(use-package general + :config + + ;; SPC as the global leader key + (general-create-definer spl3g/leader-keys + :prefix "C-c") + + (spl3g/leader-keys + ;; Buffers + "b" '(:ignore t :wk "Buffer") + "bi" '(ibuffer :wk "ibuffer") + "bk" '(kill-this-buffer :wk "Kill this buffer") + "bn" '(next-buffer :wk "Next buffer") + "bp" '(previous-buffer :wk "Previous buffer") + "br" '(revert-buffer :wk "Reload buffer") + "," '(consult-buffer :wk "Switch to buffer") + "." '(find-file :wk "Find file") + ;; Splits + "w" '(:ignore t :wk "Evil splits") + "wv" '(evil-window-vsplit :wk "Split vertical") + "ws" '(evil-window-split :wk "Split") + "ww" '(evil-window-next :wk "Cycle throug windows") + "wc" '(evil-window-delete :wk "Close window") + "wd" '(evil-window-delete :wk "Close window") + ;; Files + "f" '(:ignore t :wk "Files") + "fr" '(consult-recent-file :wk "Resent files") + "fc" '((lambda () (interactive) (find-file "~/.config/emacs/init.el")) :wk "Edit emacs config") + "fu" '(sudo-edit-find-file :wk "Sudo find file") + "fU" '(sudo-edit :wk "Sudo edit file") + ;; Quiting + "q" '(:ignore t :wk "Quiting") + "qq" '(:ignore t :wk "Quit TBD") + "qr" '(:ignore t :wk "Restart TBD") + "qe" '(eval-buffer :wk "Eval buffer") + "r" '(reload-init-file :wk "Reload config") + "l" '(lsp-keymap-prefix :wk "LSP"))) + +;; Which key +(use-package which-key + :init + (which-key-mode 1) + :config + (setq which-key-side-window-location 'bottom + which-key-sort-order #'which-key-key-order-alpha + which-key-sort-uppercase-first nil + which-key-add-column-padding 1 + which-key-max-display-columns nil + which-key-side-window-slot -10 + which-key-side-window-max-height 0.25 + which-key-idle-deley 0.8 + which-key-max-description-length 25 + which-key-allow-imprecise-window-fit t + which-key-separator " -> ")) + + + + +;; Vertico +(use-package vertico + :init + (vertico-mode)) + +;; For persistent history +(savehist-mode 1) +;; Idk what it means but they said that i need it +(use-package emacs + :init + ;; Add prompt indicator to `completing-read-multiple'. + ;; We display [CRM], e.g., [CRM,] if the separator is a comma. + (defun crm-indicator (args) + (cons (format "[CRM%s] %s" + (replace-regexp-in-string + "\\`\\[.*?]\\*\\|\\[.*?]\\*\\'" "" + crm-separator) + (car args)) + (cdr args))) + (advice-add #'completing-read-multiple :filter-args #'crm-indicator) + + ;; Do not allow the cursor in the minibuffer prompt + (setq minibuffer-prompt-properties + '(read-only t cursor-intangible t face minibuffer-prompt)) + (add-hook 'minibuffer-setup-hook #'cursor-intangible-mode) + + ;; Emacs 28: Hide commands in M-x which do not work in the current mode. + ;; Vertico commands are hidden in normal buffers. + ;; (setq read-extended-command-predicate + ;; #'command-completion-default-include-p) + + ;; Enable recursive minibuffers + (setq enable-recursive-minibuffers t)) +;; Orderless +(use-package orderless + :init + (setq completion-styles '(orderless basic) + completion-category-defaults nil + completion-category-overrides '((file (styles partial-completion))))) +(use-package marginalia + :bind (:map minibuffer-local-map + ("M-A" . marginalia-cycle)) + :init + (marginalia-mode)) + +;; Consult +(use-package consult + ;; Replace bindings. Lazily loaded due by `use-package'. + :bind (;; C-c bindings in `mode-specific-map' + ("C-c M-x" . consult-mode-command) + ("C-c h" . consult-history) + ("C-c k" . consult-kmacro) + ("C-c m" . consult-man) + ("C-c i" . consult-info) + ([remap Info-search] . consult-info) + ;; C-x bindings in `ctl-x-map' + ("C-x M-:" . consult-complex-command) ;; orig. repeat-complex-command + ("C-x b" . consult-buffer) ;; orig. switch-to-buffer + ("C-x 4 b" . consult-buffer-other-window) ;; orig. switch-to-buffer-other-window + ("C-x 5 b" . consult-buffer-other-frame) ;; orig. switch-to-buffer-other-frame + ("C-x r b" . consult-bookmark) ;; orig. bookmark-jump + ("C-x p b" . consult-project-buffer) ;; orig. project-switch-to-buffer + ;; Custom M-# bindings for fast register access + ("M-#" . consult-register-load) + ("M-'" . consult-register-store) ;; orig. abbrev-prefix-mark (unrelated) + ("C-M-#" . consult-register) + ;; Other custom bindings + ("M-y" . consult-yank-pop) ;; orig. yank-pop + ;; M-g bindings in `goto-map' + ("M-g e" . consult-compile-error) + ("M-g f" . consult-flymake) ;; Alternative: consult-flycheck + ("M-g g" . consult-goto-line) ;; orig. goto-line + ("M-g M-g" . consult-goto-line) ;; orig. goto-line + ("M-g o" . consult-outline) ;; Alternative: consult-org-heading + ("M-g m" . consult-mark) + ("M-g k" . consult-global-mark) + ("M-g i" . consult-imenu) + ("M-g I" . consult-imenu-multi) + ;; M-s bindings in `search-map' + ("M-s d" . consult-find) + ("M-s D" . consult-locate) + ("M-s g" . consult-grep) + ("M-s G" . consult-git-grep) + ("M-s r" . consult-ripgrep) + ("M-s l" . consult-line) + ("M-s L" . consult-line-multi) + ("M-s k" . consult-keep-lines) + ("M-s u" . consult-focus-lines) + ;; Isearch integration + ("M-s e" . consult-isearch-history) + :map isearch-mode-map + ("M-e" . consult-isearch-history) ;; orig. isearch-edit-string + ("M-s e" . consult-isearch-history) ;; orig. isearch-edit-string + ("M-s l" . consult-line) ;; needed by consult-line to detect isearch + ("M-s L" . consult-line-multi) ;; needed by consult-line to detect isearch + ;; Minibuffer history + :map minibuffer-local-map + ("M-s" . consult-history) ;; orig. next-matching-history-element + ("M-r" . consult-history)) ;; orig. previous-matching-history-element + + ;; Enable automatic preview at point in the *Completions* buffer. This is + ;; relevant when you use the default completion UI. + :hook (completion-list-mode . consult-preview-at-point-mode) + + ;; The :init configuration is always executed (Not lazy) + :init + + ;; Optionally configure the register formatting. This improves the register + ;; preview for `consult-register', `consult-register-load', + ;; `consult-register-store' and the Emacs built-ins. + (setq register-preview-delay 0.5 + register-preview-function #'consult-register-format) + + ;; Optionally tweak the register preview window. + ;; This adds thin lines, sorting and hides the mode line of the window. + (advice-add #'register-preview :override #'consult-register-window) + + ;; Use Consult to select xref locations with preview + (setq xref-show-xrefs-function #'consult-xref + xref-show-definitions-function #'consult-xref) + + ;; Configure other variables and modes in the :config section, + ;; after lazily loading the package. + :config + + ;; Optionally configure preview. The default value + ;; is 'any, such that any key triggers the preview. + ;; (setq consult-preview-key 'any) + ;; (setq consult-preview-key "M-.") + ;; (setq consult-preview-key '("S-" "S-")) + ;; For some commands and buffer sources it is useful to configure the + ;; :preview-key on a per-command basis using the `consult-customize' macro. + (consult-customize + consult-ripgrep consult-git-grep consult-grep + consult-bookmark consult-recent-file consult-xref + consult--source-bookmark consult--source-file-register + consult--source-recent-file consult--source-project-recent-file) + ;; :preview-key "M-." + + ;; Optionally configure the narrowing key. + ;; Both < and C-+ work reasonably well. + (setq consult-narrow-key "<") ;; "C-+" + + ;; Optionally make narrowing help available in the minibuffer. + ;; You may want to use `embark-prefix-help-command' or which-key instead. + ;; (define-key consult-narrow-map (vconcat consult-narrow-key "?") #'consult-narrow-help) + + ;; By default `consult-project-function' uses `project-root' from project.el. + ;; Optionally configure a different project root function. + ;;;; 1. project.el (the default) + ;; (setq consult-project-function #'consult--default-project--function) + ;;;; 2. vc.el (vc-root-dir) + ;; (setq consult-project-function (lambda (_) (vc-root-dir))) + ;;;; 3. locate-dominating-file + ;; (setq consult-project-function (lambda (_) (locate-dominating-file "." ".git"))) + ;;;; 4. projectile.el (projectile-project-root) + ;; (autoload 'projectile-project-root "projectile") + ;; (setq consult-project-function (lambda (_) (projectile-project-root))) + ;;;; 5. No project support + ;; (setq consult-project-function nil) +) + +;; Hotfuzz +;; (use-package hotfuzz +;; :config +;; (setq completion-styles '(hotfuzz)) +;; (setq completion-ignore-case t)) + +;; Lsp +(use-package lsp-mode + :hook + (python-mode . lsp) + (rust-mode . lsp) + (lsp-mode . lsp-enable-which-key-integration) + (sh-mode . lsp) + :commands lsp) +(use-package lsp-pyright + :ensure t) +(use-package lsp-ui + :hook (lsp-mode-hook . lsp-ui-mode) + :custom + (lsp-ui-peek-always-show t) + (lsp-ui-sideline-show-hover t) + (lsp-ui-doc-enable t)) + +(use-package lsp-treemacs) + +;; Flycheck +(use-package flycheck) + +;; Corfu + Cape +(use-package corfu + :custom + (corfu-cycle t) + (corfu-auto t) + (corfu-preselect 'prompt) + :bind + (:map corfu-map + ("TAB" . corfu-next) + ([tab] . corfu-next) + ("S-TAB" . corfu-previous) + ([backtab] . corfu-previous)) + :init + (global-corfu-mode)) + ;;(use-package cape + ;; :bind (("C-c a f" . cape-file)) + ;; :init + ;; (add-to-list 'completion-at-point-functions # 'cape-file))) +(use-package cape + :init + (add-to-list 'completion-at-point-functions #'cape-file)) +(use-package emacs + :init + (setq completion-cycle-threshold 3) + (setq tab-always-indent 'complete)) + +;; Treemacs +(use-package treemacs + :config + (setq treemacs-no-png-images t)) +(use-package treemacs-evil) +(use-package treemacs-all-the-icons) + +;; Resent files +(recentf-mode 1) +(setq recentf-max-menu-items 25) +(setq recentf-max-saved-items 50) + +;; Sudo +(use-package sudo-edit) + +;; (defun sudo-find-file-hook () +;; (when (and (not (file-writable-p buffer-file-name)) +;; (y-or-n-p-with-timeout "File not writable. Open as root?" 2 t)) +;; (let ((obuf (current-buffer))) +;; (sudo-edit) +;; (unless (equal (current-buffer) obuf) +;; (let) + +;; Parinfer +(electric-pair-mode 1) + +;; NixOS +(use-package nix-mode + :mode "(.nix)$") +;; (use-package nix-drv-mode :elpaca nil +;; :ensure nix-mode +;; :mode ".drv") +;; (use-package nix-shell :elpaca nil +;; :ensure nix-mode +;; :commands (nix-shell-unpack nix-shell-configure nix-shell-build)) +;; (use-package nix-repl :elpaca nil +;; :ensure nix-mode +;; :commands (nix-repl)) + +;; Reload config +(defun reload-init-file () (interactive) + (load-file user-init-file) + (load-file user-init-file)) + +;; Magit +(use-package magit) + +;; Fish +(use-package fish-mode + :mode "(.fish)$") + +;; Rust +(use-package rustic + :ensure + :bind (:map rustic-mode-map + ("M-j" . lsp-ui-imenu) + ("M-?" . lsp-find-references) + ("C-c C-c l" . flycheck-list-errors) + ("C-c C-c a" . lsp-execute-code-action) + ("C-c C-c r" . lsp-rename) + ("C-c C-c q" . lsp-workspace-restart) + ("C-c C-c Q" . lsp-workspace-shutdown) + ("C-c C-c s" . lsp-rust-analyzer-status)) + :config + ;; uncomment for less flashiness + ;; (setq lsp-eldoc-hook nil) + ;; (setq lsp-enable-symbol-highlighting nil) + ;; (setq lsp-signature-auto-activate nil) + + ;; comment to disable rustfmt on save + (setq rustic-format-on-save t) + (add-hook 'rustic-mode-hook 'rk/rustic-mode-hook)) + +(defun rk/rustic-mode-hook () + ;; so that run C-c C-c C-r works without having to confirm, but don't try to + ;; save rust buffers that are not file visiting. Once + ;; https://github.com/brotzeit/rustic/issues/253 has been resolved this should + ;; no longer be necessary. + (when buffer-file-name + (setq-local buffer-save-without-query t)) + (add-hook 'before-save-hook 'lsp-format-buffer nil t)) + +;; Tree-sitter +(use-package treesit-auto + :config + (global-treesit-auto-mode) + (setq treesit-auto-install t)) + +;; Vterm +(use-package vterm) + +;; Org mode +(use-package toc-org + :hook (org-mode-hook . toc-org-enable)) +(add-hook 'org-mode-hook 'org-indent-mode) +(use-package org-bullets + :hook (org-mode-hook . (lambda () (org-bullets-mode)))) + +;; GUI tweaks +;; Display numbers +(global-display-line-numbers-mode 1) +(global-visual-line-mode t) + +;; Theme +(use-package autothemer) +(use-package catppuccin-theme + :ensure t + :config + (load-theme 'catppuccin t) + (setq catppuccin-flavor 'mocha) + (catppuccin-reload)) + +;; Fonts +(set-face-attribute 'default nil + :font "Source Code Pro" + :height 113 + :weight 'medium) +(set-face-attribute 'fixed-pitch nil + :font "Source Code Pro" + :height 113 + :weight 'medium) +(set-face-attribute 'variable-pitch nil + :font "Rubik" + :height 113 + :weight 'medium) +(set-face-attribute 'font-lock-comment-face nil + :slant 'italic) +(set-face-attribute 'font-lock-keyword-face nil + :weight 'bold) + +;; Icons +(use-package all-the-icons + :ensure t + :if (display-graphic-p)) +(use-package all-the-icons-dired + :hook (dired-mode . (lambda () + all-the-icons-dired-mode t))) + +;; Modeline +(use-package mood-line + :init + (mood-line-mode) + :config + (setq mood-line-glyph-alist mood-line-glyphs-unicode)) + +;; Scrolling +(use-package good-scroll + :init (good-scroll-mode)) + +;; Dashboard +(use-package dashboard + :init + (dashboard-setup-startup-hook) + :config + (setq initial-buffer-choice (lambda () (get-buffer-create "*dashboard*"))) + (setq dashboard-banner-logo-title "Yep, it's emacs, not vim") + (setq dashboard-startup-banner 'logo) + (setq dashboard-center-content t)) + +;; Vterm + + +(custom-set-variables + ;; custom-set-variables was added by Custom. + ;; If you edit it by hand, you could mess it up, so be careful. + ;; Your init file should contain only one such instance. + ;; If there is more than one, they won't work right. + '(package-selected-packages '(nix-mode)) + '(warning-suppress-types + '((comp) + (comp) + (comp) + (comp) + (comp) + (comp) + (comp) + (comp) + (comp) + (comp) + (comp) + (comp) + (comp)))) +(custom-set-faces) + ;; custom-set-faces was added by Custom. + ;; If you edit it by hand, you could mess it up, so be careful. + ;; Your init file should contain only one such instance. + ;; If there is more than one, they won't work right. + + ;; custom-set-faces was added by Custom. + ;; If you edit it by hand, you could mess it up, so be careful. + ;; Your init file should contain only one such instance. + ;; If there is more than one, they won't work right. + + ;; custom-set-faces was added by Custom. + ;; If you edit it by hand, you could mess it up, so be careful. + ;; Your init file should contain only one such instance. + ;; If there is more than one, they won't work right. + + ;; custom-set-faces was added by Custom. + ;; If you edit it by hand, you could mess it up, so be careful. + ;; Your init file should contain only one such instance. + ;; If there is more than one, they won't work right. + + ;; custom-set-faces was added by Custom. + ;; If you edit it by hand, you could mess it up, so be careful. + ;; Your init file should contain only one such instance. + ;; If there is more than one, they won't work right. + diff --git a/home-manager/general/programs/emacs/tmpWCGTRZ b/home-manager/general/programs/emacs/tmpWCGTRZ new file mode 100644 index 0000000..b17a54b --- /dev/null +++ b/home-manager/general/programs/emacs/tmpWCGTRZ @@ -0,0 +1,735 @@ +(setq gc-cons-threshold (* 50 1000 1000)) + +(require 'use-package) +(eval-and-compile + (setq use-package-always-ensure t + use-package-expand-minimally t)) + +(use-package savehist + :init + (setq savehist-file "~/.config/emacs/var/savehist.el") + :config + (setq history-length 500) + (setq savehist-additional-variables '(kill-ring search-ring)) + (savehist-mode t)) + +(use-package meow + :config + (defun meow-setup () + (setq meow-cheatsheet-layout meow-cheatsheet-layout-qwerty) + (meow-motion-overwrite-define-key + '("j" . meow-next) + '("k" . meow-prev) + '("" . ignore)) + (meow-leader-define-key + ;; SPC j/k will run the original command in MOTION state. + '("j" . "H-j") + '("k" . "H-k") + ;; Use SPC (0-9) for digit arguments. + '("1" . meow-digit-argument) + '("2" . meow-digit-argument) + '("3" . meow-digit-argument) + '("4" . meow-digit-argument) + '("5" . meow-digit-argument) + '("6" . meow-digit-argument) + '("7" . meow-digit-argument) + '("8" . meow-digit-argument) + '("9" . meow-digit-argument) + '("0" . meow-digit-argument) + '("/" . meow-keypad-describe-key) + '("?" . meow-cheatsheet) + '("bk" . kill-this-buffer)) + (meow-normal-define-key + '("0" . meow-expand-0) + '("9" . meow-expand-9) + '("8" . meow-expand-8) + '("7" . meow-expand-7) + '("6" . meow-expand-6) + '("5" . meow-expand-5) + '("4" . meow-expand-4) + '("3" . meow-expand-3) + '("2" . meow-expand-2) + '("1" . meow-expand-1) + '("-" . negative-argument) + '(";" . meow-reverse) + '("," . meow-inner-of-thing) + '("." . meow-bounds-of-thing) + '("[" . meow-beginning-of-thing) + '("]" . meow-end-of-thing) + '("a" . meow-append) + '("A" . meow-open-below) + '("b" . meow-back-word) + '("B" . meow-back-symbol) + '("c" . meow-change) + '("d" . meow-delete) + '("D" . meow-backward-delete) + '("e" . meow-next-word) + '("E" . meow-next-symbol) + '("f" . meow-find) + '("g" . meow-cancel-selection) + '("G" . meow-grab) + '("h" . meow-left) + '("H" . meow-left-expand) + '("i" . meow-insert) + '("I" . meow-open-above) + '("j" . meow-next) + '("J" . meow-next-expand) + '("k" . meow-prev) + '("K" . meow-prev-expand) + '("l" . meow-right) + '("L" . meow-right-expand) + '("m" . meow-join) + '("n" . meow-search) + '("o" . meow-block) + '("O" . meow-to-block) + '("p" . meow-yank) + '("q" . meow-quit) + '("Q" . meow-goto-line) + '("r" . meow-replace) + '("R" . meow-swap-grab) + '("s" . meow-kill) + '("t" . meow-till) + '("u" . meow-undo) + '("U" . meow-undo-in-selection) + '("v" . meow-visit) + '("w" . meow-mark-word) + '("W" . meow-mark-symbol) + '("x" . meow-line) + '("X" . meow-goto-line) + '("y" . meow-save) + '("Y" . meow-sync-grab) + '("z" . meow-pop-selection) + '("'" . repeat) + '("" . ignore))) + (setq meow-use-enhanced-selection-effect t) + (meow-setup)) + ;; (meow-global-mode 1)) + +(use-package kakoune + ;; Having a non-chord way to escape is important, since key-chords don't work in macros + :bind ("C-z" . ryo-modal-mode) + :hook (after-init . my/kakoune-setup) + :config + (defun ryo-enter () "Enter normal mode" (interactive) (ryo-modal-mode 1)) + (defun my/kakoune-setup () + "Call kakoune-setup-keybinds and then add some personal config." + (kakoune-setup-keybinds) + (setq ryo-modal-cursor-type 'box) + (add-hook 'prog-mode-hook #'ryo-enter) + (define-key ryo-modal-mode-map (kbd "SPC h") 'help-command) + ;; Access all C-x bindings easily + (define-key ryo-modal-mode-map (kbd "z") ctl-x-map) + (ryo-modal-keys + ("," save-buffer) + ("P" counsel-yank-pop) + ("m" mc/mark-next-like-this) + ("M" mc/skip-to-next-like-this) + ("n" mc/mark-previous-like-this) + ("N" mc/skip-to-previous-like-this) + ("M-m" mc/edit-lines) + ("*" mc/mark-all-like-this) + ("v" er/expand-region) + ("C-v" set-rectangular-region-anchor) + ("M-s" mc/split-region) + (";" (("q" delete-window) + ("v" split-window-horizontally) + ("s" split-window-vertically))) + ("C-h" windmove-left) + ("C-j" windmove-down) + ("C-k" windmove-up) + ("C-l" windmove-right) + ("C-u" scroll-down-command :first '(deactivate-mark)) + ("C-d" scroll-up-command :first '(deactivate-mark))))) + +;; This overrides the default mark-in-region with a prettier-looking one, +;; and provides a couple extra commands +(use-package visual-regexp + :ryo + ("s" vr/mc-mark) + ("?" vr/replace) + ("M-/" vr/query-replace)) + +;; Emacs incremental search doesn't work with multiple cursors, but this fixes that +(use-package phi-search + :bind (("C-s" . phi-search) + ("C-r" . phi-search-backward))) + +;; Probably the first thing you'd miss is undo and redo, which requires an extra package +;; to work like it does in kakoune (and almost every other editor). +(use-package undo-tree + :config + (global-undo-tree-mode) + :ryo + ("u" undo-tree-undo) + ("U" undo-tree-redo) + ("SPC u" undo-tree-visualize) + :bind (:map undo-tree-visualizer-mode-map + ("h" . undo-tree-visualize-switch-branch-left) + ("j" . undo-tree-visualize-redo) + ("k" . undo-tree-visualize-undo) + ("l" . undo-tree-visualize-switch-branch-right))) + + +(use-package general + :config + ;; SPC as the global leader key + (general-create-definer spl3g/leader-keys + :prefix "C-c") + + (spl3g/leader-keys + ;; Buffers + "b" '(:ignore t :wk "Buffer") + "bi" '(ibuffer :wk "ibuffer") + "bk" '(kill-this-buffer :wk "Kill this buffer") + "bn" '(next-buffer :wk "Next buffer") + "bp" '(previous-buffer :wk "Previous buffer") + "br" '(revert-buffer :wk "Reload buffer") + "." '(find-file :wk "Find file") + ;; Splits + "w" '(:ignore t :wk "Splits") + "wv" '(split-window-right :wk "Split vertical") + "ws" '(split-window-below :wk "Split") + "ww" '(other-window :wk "Cycle throug windows") + "wc" '(delete-window :wk "Close window") + "wd" '(delete-window :wk "Close window") + "wl" '(evil-window-right :wk "") + "wj" '(evil-window-down :wk "") + "wk" '(evil-window-up :wk "") + "wh" '(evil-window-left :wk "") + "wo" '(delete-other-windows :wk "") + ;; Files + "f" '(:ignore t :wk "Files") + "fc" '((lambda () (interactive) (find-file "~/nixfiles/home-manager/programs/emacs/config.org")) :wk "Edit emacs config") + "fu" '(crux-sudo-edit :wk "Sudo edit file") + ;; Compilation + "c" '(:ignore t :wk "Compilation") + "cc" '(compile :wk "Compile") + "cr" '(recompile :wk "Recompile") + )) + +(defun spl3g/disable-scroll-bars (frame) + (modify-frame-parameters frame + '((vertical-scroll-bars . nil) + (horizontal-scroll-bars . nil)))) +(add-hook 'after-make-frame-functions 'spl3g/disable-scroll-bars) + +(setq default-frame-alist '((font . "Source Code Pro"))) +(set-face-attribute 'default nil + :font "Source Code Pro" + :height 110 + :weight 'medium) +(set-face-attribute 'fixed-pitch nil + :font "Source Code Pro" + :height 110 + :weight 'medium) +(set-face-attribute 'variable-pitch nil + :font "Rubik" + :height 110 + :weight 'medium) +(set-face-attribute 'font-lock-comment-face nil + :slant 'italic) +(set-face-attribute 'font-lock-keyword-face nil + :weight 'bold) + +(add-hook 'prog-mode-hook 'display-line-numbers-mode) +(visual-line-mode 1) + +(use-package catppuccin-theme + :ensure t + :config + (load-theme 'catppuccin t) + (setq catppuccin-flavor 'macchiato) + (catppuccin-reload)) + +(use-package all-the-icons + :ensure t + :if (display-graphic-p)) + +(use-package mood-line + + ;; Enable mood-line + :config + (mood-line-mode) + :custom + (mood-line-segment-modal-meow-state-alist + '((normal "N" . mood-line-meow-normal) + (insert "I" . mood-line-meow-insert) + (keypad "K" . mood-line-meow-keypad) + (beacon "B" . mood-line-meow-beacon) + (motion "M" . mood-line-meow-motion))) + (mood-line-glyph-alist mood-line-glyphs-fira-code) + :custom-face + (mood-line-meow-beacon ((t (:foreground "#f9e2af" :weight bold)))) + (mood-line-meow-insert ((t (:foreground "#a6e3a1" :weight bold)))) + (mood-line-meow-keypad ((t (:foreground "#cba6f7" :weight bold)))) + (mood-line-meow-motion ((t (:foreground "#fab387" :weight bold)))) + (mood-line-meow-normal ((t (:weight bold)))) + (mode-line-inactive ((t (:box (:line-width (2 . 6) :color "#11111b") :inverse-video nil :foreground "#6c7086" :background "#11111b")))) + (mode-line ((t (:box (:line-width (2 . 6) :color "#181825") :background "#181825"))))) + +(use-package good-scroll + :init (good-scroll-mode)) + +(use-package dashboard + :init + (dashboard-setup-startup-hook) + :config + (setq initial-buffer-choice (lambda () (get-buffer-create "*dashboard*"))) + (setq dashboard-banner-logo-title "Yep, it's emacs, not vim") + (setq dashboard-startup-banner 'logo) + (setq dashboard-center-content t) + (add-to-list 'dashboard-item-generators '(config . dashboard-open-config)) + (setq dashboard-items '((recents . 5) + (agenda . 5)))) + +(setq ring-bell-function 'ignore) + +(use-package indent-guide + :hook (prog-mode . indent-guide-mode)) + +(setq window-resize-pixelwise t) +(setq frame-resize-pixelwise t) +(save-place-mode t) +(defalias 'yes-or-no #'y-or-n-p) + +(add-hook 'org-mode-hook 'org-indent-mode) +(require 'org-tempo) + +(use-package toc-org + :hook (org-mode . toc-org-mode)) + +(use-package org-bullets + :hook (org-mode . org-bullets-mode)) + +(use-package org-auto-tangle + :hook (org-mode . org-auto-tangle-mode)) + +(use-package org-download + :hook + (dired-mode . org-download-enable)) + +(use-package direnv + :config + (direnv-mode)) + +(use-package vertico + :init + (vertico-mode) + :bind (:map vertico-map + ("M-j" . vertico-next) + ("M-k" . vertico-previous) + ("RET" . vertico-directory-enter) + ("DEL" . vertico-directory-delete-char) + ("M-DEL" . vertico-directory-delete-word))) + +(use-package emacs + :init + ;; Add prompt indicator to `completing-read-multiple'. + ;; We display [CRM], e.g., [CRM,] if the separator is a comma. + (defun crm-indicator (args) + (cons (format "[CRM%s] %s" + (replace-regexp-in-string + "\\`\\[.*?]\\*\\|\\[.*?]\\*\\'" "" + crm-separator) + (car args)) + (cdr args))) + (advice-add #'completing-read-multiple :filter-args #'crm-indicator) + + ;; Do not allow the cursor in the minibuffer prompt + (setq minibuffer-prompt-properties + '(read-only t cursor-intangible t face minibuffer-prompt)) + (add-hook 'minibuffer-setup-hook #'cursor-intangible-mode) + + ;; Emacs 28: Hide commands in M-x which do not work in the current mode. + ;; Vertico commands are hidden in normal buffers. + ;; (setq read-extended-command-predicate + ;; #'command-completion-default-include-p) + + ;; Enable recursive minibuffers + (setq enable-recursive-minibuffers t)) + +(use-package orderless + :init + (setq completion-styles '(orderless basic) + completion-category-defaults nil + completion-category-overrides '((file (styles partial-completion))))) + +(use-package marginalia + :bind (:map minibuffer-local-map + ("M-A" . marginalia-cycle)) + :init + (marginalia-mode)) + +(use-package consult + ;; Replace bindings. Lazily loaded due by `use-package'. + :bind (;; C-c bindings in `mode-specific-map' + ("C-c k" . consult-kmacro) + ("C-c m" . consult-man) + ("C-c i" . consult-info) + ([remap Info-search] . consult-info) + ("C-c f r" . consult-recent-file) + ("C-c ," . consult-buffer) + ;; C-x bindings in `ctl-x-map' + ("C-x M-:" . consult-complex-command) ;; orig. repeat-complex-command + ("C-x 4 b" . consult-buffer-other-window) ;; orig. switch-to-buffer-other-window + ("C-x 5 b" . consult-buffer-other-frame) ;; orig. switch-to-buffer-other-frame + ("C-x p b" . consult-project-buffer) ;; orig. project-switch-to-buffer + ;; Custom M-# bindings for fast register access + ("M-#" . consult-register-load) + ("M-'" . consult-register-store) ;; orig. abbrev-prefix-mark (unrelated) + ("C-M-#" . consult-register) + ;; Other custom bindings + ("M-y" . consult-yank-pop) ;; orig. yank-pop + ;; M-g bindings in `goto-map' + ("C-c c e" . consult-compile-error) + ("M-g f" . consult-flymake) ;; Alternative: consult-flycheck + ("M-g g" . consult-goto-line) ;; orig. goto-line + ("M-g M-g" . consult-goto-line) ;; orig. goto-line + ("M-g o" . consult-outline) ;; Alternative: consult-org-heading + ;; M-s bindings in `search-map' + ("M-s d" . consult-fd) + ("M-s g" . consult-grep) + ("M-s G" . consult-git-grep) + ("M-s l" . consult-line) + ("M-s L" . consult-line-multi) + ("M-s k" . consult-keep-lines) + ("M-s u" . consult-focus-lines) + ;; Isearch integration + ("M-s e" . consult-isearch-history) + :map isearch-mode-map + ("M-e" . consult-isearch-history) ;; orig. isearch-edit-string + ("M-s e" . consult-isearch-history) ;; orig. isearch-edit-string + ("M-s l" . consult-line) ;; needed by consult-line to detect isearch + ("M-s L" . consult-line-multi) ;; needed by consult-line to detect isearch + ("M-r" . consult-history) + ;; Minibuffer history + :map minibuffer-local-map + ("M-s" . consult-history) ;; orig. next-matching-history-element + ("M-r" . consult-history)) ;; orig. previous-matching-history-element) + + ;; Enable automatic preview at point in the *Completions* buffer. This is + ;; relevant when you use the default completion UI. + :hook + (completion-list-mode . consult-preview-at-point-mode) + (eshell-mode . (lambda () + (keymap-set eshell-mode-map "M-h" 'consult-history))) + + ;; The :init configuration is always executed (Not lazy) + :init + + ;; Optionally configure the register formatting. This improves the register + ;; preview for `consult-register', `consult-register-load', + ;; `consult-register-store' and the Emacs built-ins. + (setq register-preview-delay 0.5 + register-preview-function #'consult-register-format) + + ;; Optionally tweak the register preview window. + ;; This adds thin lines, sorting and hides the mode line of the window. + (advice-add #'register-preview :override #'consult-register-window) + + ;; Configure other variables and modes in the :config section, + ;; after lazily loading the package. + :config + + ;; Optionally configure preview. The default value + ;; is 'any, such that any key triggers the preview. + ;; (setq consult-preview-key 'any) + ;; (setq consult-preview-key "M-.") + ;; (setq consult-preview-key '("S-" "S-")) + ;; For some commands and buffer sources it is useful to configure the + ;; :preview-key on a per-command basis using the `consult-customize' macro. + (consult-customize + consult-ripgrep consult-git-grep consult-grep + consult-bookmark consult-recent-file consult-xref + consult--source-bookmark consult--source-file-register + consult--source-recent-file consult--source-project-recent-file) + ;; :preview-key "M-." + + ;; Optionally configure the narrowing key. + ;; Both < and C-+ work reasonably well. + (setq consult-narrow-key "<") ;; "C-+" + + ;; Optionally make narrowing help available in the minibuffer. + ;; You may want to use `embark-prefix-help-command' or which-key instead. + ;; (define-key consult-narrow-map (vconcat consult-narrow-key "?") #'consult-narrow-help) + + ;; By default `consult-project-function' uses `project-root' from project.el. + ;; Optionally configure a different project root function. +;;;; 1. project.el (the default) + ;; (setq consult-project-function #'consult--default-project--function) +;;;; 2. vc.el (vc-root-dir) + ;; (setq consult-project-function (lambda (_) (vc-root-dir))) +;;;; 3. locate-dominating-file + ;; (setq consult-project-function (lambda (_) (locate-dominating-file "." ".git"))) +;;;; 4. projectile.el (projectile-project-root) + ;; (autoload 'projectile-project-root "projectile") + ;; (setq consult-project-function (lambda (_) (projectile-project-root))) +;;;; 5. No project support + ;; (setq consult-project-function nil) + ) + +(use-package smartparens + :init (smartparens-global-mode) + :config + ;; Snitched from doom + (let ((unless-list '(sp-point-before-word-p + sp-point-after-word-p + sp-point-before-same-p))) + (sp-pair "'" nil :unless unless-list) + (sp-pair "\"" nil :unless unless-list)) + (dolist (brace '("(" "{" "[")) + (sp-pair brace nil + :post-handlers '(("||\n[i]" "RET") ("| " "SPC")) + :unless '(sp-point-before-word-p sp-point-before-same-p))) + (sp-local-pair sp-lisp-modes "(" ")" :unless '(:rem sp-point-before-same-p)) + (sp-local-pair sp-lisp-modes "(" ")" :unless '(:rem sp-point-before-same-p)) + + (sp-local-pair '(python-mode python-ts-mode) "f'" "'") + + ;; Major-mode specific fixes + (sp-local-pair 'ruby-mode "{" "}" + :pre-handlers '(:rem sp-ruby-pre-handler) + :post-handlers '(:rem sp-ruby-post-handler)) + + ;; Don't do square-bracket space-expansion where it doesn't make sense to + (sp-local-pair '(emacs-lisp-mode org-mode markdown-mode gfm-mode) + "[" nil :post-handlers '(:rem ("| " "SPC"))) + + (sp-local-pair '(emacs-lisp-mode org-mode) + "'" nil) + + ;; Reasonable default pairs for HTML-style comments + (sp-local-pair (append sp--html-modes '(markdown-mode gfm-mode)) + "" + :unless '(sp-point-before-word-p sp-point-before-same-p) + :actions '(insert) :post-handlers '(("| " "SPC"))) + ;; Expand C-style comment blocks. + (defun +default-open-doc-comments-block (&rest _ignored) + (save-excursion + (newline) + (indent-according-to-mode))) + (sp-local-pair + '(js2-mode typescript-mode rjsx-mode rust-mode c-mode c++-mode objc-mode + csharp-mode java-mode php-mode css-mode scss-mode less-css-mode + stylus-mode scala-mode) + "/*" "*/" + :actions '(insert) + :post-handlers '(("| " "SPC") + (" | " "*") + ("|[i]\n[i]" "RET")))) + +;; (use-package dap-mode +;; :defer t +;; :config +;; (require 'dap-python) +;; (setq dap-python-debugger 'debugpy)) + +(use-package move-text + :bind (("C-M-k" . move-text-up) + ("C-M-j" . move-text-down))) + +(global-visual-line-mode t) + +(use-package no-littering) + +(use-package rainbow-delimiters + :hook (prog-mode . rainbow-delimiters-mode)) + +(use-package crux + :bind (("C-c o t" . crux-visit-shell-buffer))) + +(use-package helpful + :bind (("C-h f" . 'helpful-callable) + ("C-h v" . 'helpful-variable) + ("C-h k" . 'helpful-key) + ("C-h x" . 'helpful-command) + ("C-c C-d" . 'helpful-at-point) + ("C-h F" . 'helpful-function))) + +(add-hook 'eshell-mode-hook + (lambda () + (keymap-set eshell-mode-map "M-" 'consult-fish-completions))) + +(use-package eat + :hook (eshell-mode . eat-eshell-mode) + :custom + (eat-enable-auto-line-mode t)) + +;; (defun eat-toggle () +;; "Open eat terminal as a popup." +;; (interactive) +;; (if (eq major-mode 'eat-mode) +;; (delete-window) +;; (let ((buff (get-buffer-create eat-buffer-name))) +;; (cl-assert (and buff (buffer-live-p buff))) +;; (funcall #'pop-to-buffer buff) +;; (with-current-buffer buff +;; (setq-local split-width-threshold nil) +;; (setq-local window-min-height 2) +;; (unless (derived-mode-p 'eat-mode) +;; (eat)))))) + +;; (defun eat-modes() +;; (cond +;; ((and (eq major-mode 'eat-mode) (member 'meow-normal-mode local-minor-modes)) +;; (eat-emacs-mode)) +;; ((and (eq major-mode 'eat-mode) (member 'meow-insert-mode local-minor-modes)) +;; (eat-semi-char-mode)))) +;; (add-hook 'meow-normal-mode-hook #'eat-modes) +;; (add-hook 'meow-insert-mode-hook #'eat-modes) + +(use-package fish-completion + :hook (eshell-mode . fish-completion-mode)) + +(use-package eglot + :bind (("C-c s e e" . eglot) + ("C-c s e d" . eldoc) + ("C-c s e r" . eglot-rename) + ("C-c s e s" . eglot-shutdown) + ("C-c s e f" . eglot-find-declaration) + ("C-c s e i" . eglot-find-implementation)) + :hook + (nix-mode . eglot-ensure) + (python-ts-mode . eglot-ensure) + :config + (add-to-list 'eglot-server-programs '(python-ts-mode . ("pylsp")))) + +(use-package lsp-pyright) +(use-package py-autopep8 + :hook (python-mode . py-autopep8-mode)) + +(use-package rust-mode + :mode "\\.rs\\'") +(use-package flycheck-rust + :config + (with-eval-after-load 'rust-mode + (add-hook 'flycheck-mode-hook #'flycheck-rust-setup))) + +(use-package fish-mode + :mode "\\.fish\\'") + +(use-package nix-mode + :mode ("\\.nix\\'" "\\.nix.in\\'")) +(use-package nix-drv-mode + :ensure nix-mode + :mode "\\.drv\\'") +(use-package nix-shell + :ensure nix-mode + :commands (nix-shell-unpack nix-shell-configure nix-shell-build)) +(use-package nix-repl + :ensure nix-mode + :commands (nix-repl)) + +(use-package web-mode + :mode + ("\\.phtml\\'" + "\\.tpl\\.php\\'" + "\\.[agj]sp\\'" + "\\.as[cp]x\\'" + "\\.erb\\'" + "\\.mustache\\'" + "\\.djhtml\\'")) + +(use-package js2-mode) + +(use-package corfu + :custom + (corfu-cycle t) + (corfu-preselect 'prompt) + (corfu-auto t) + (corfu-popupinfo-delay 0.0) + :bind + (:map corfu-map + ("TAB" . corfu-next) + ([tab] . corfu-next) + ("S-TAB" . corfu-previous) + ([backtab] . corfu-previous)) + + :init + (global-corfu-mode) + (corfu-history-mode) + (corfu-popupinfo-mode) + :config + (add-to-list 'savehist-additional-variables 'corfu-history)) +(use-package emacs + :init + (setq completion-cycle-threshold 3) + + (setq read-extended-command-predicate + #'command-completion-default-include-p) + + (setq tab-always-indent 'complete)) + +(use-package cape + :demand t + :config + (add-to-list 'completion-at-point-functions #'cape-dabbrev) + (add-to-list 'completion-at-point-functions #'cape-file) + (add-to-list 'completion-at-point-functions #'cape-elisp-block) + ) + +(use-package tree-sitter + :init + (global-tree-sitter-mode) + :config + (add-hook 'tree-sitter-mode-hook 'tree-sitter-hl-mode)) +(use-package treesit-auto + :custom + (treesit-auto-install 'prompt) + :config + (treesit-auto-add-to-auto-mode-alist 'all) + (global-treesit-auto-mode)) + +(use-package tree-sitter-langs) + +;; (use-package yasnippet +;; :init (yas-global-mode)) +;; (use-package yasnippet-snippets) + +(use-package flymake + :after eglot + :bind (("C-c s f f" . flymake-start) + ("C-c s f l" . flymake-show-buffer-diagnostics) + ("C-c s f p" . flymake-show-project-diagnostics))) + +(use-package dired + :custom + (dired-listing-switches "-al --group-directories-first")) + + + +;; (add-to-list 'load-path "~/telega.el") +;; (require 'telega) + +(use-package magit + :bind (("C-c o g" . magit))) + +;; (use-package exwm) +;; (require 'exwm) +;; (require 'exwm-config) +;; (exwm-config-example) + +;; (use-package code-cells) + +;; (use-package orgnote +;; :defer t) + +(use-package copilot + :hook (python-ts-mode . copilot-mode) + :bind ("M-RET" . copilot-accept-completion)) + +(setq gc-cons-threshold (* 2 1000 1000)) +(setq read-process-output-max (* 1024 1024)) +(custom-set-variables + ;; custom-set-variables was added by Custom. + ;; If you edit it by hand, you could mess it up, so be careful. + ;; Your init file should contain only one such instance. + ;; If there is more than one, they won't work right. + '(package-selected-packages + '(dired web-mode vertico use-package treesit-auto tree-sitter-langs toc-org smartparens rust-mode rainbow-delimiters py-autopep8 org-download org-bullets org-auto-tangle orderless no-littering nix-mode move-text mood-line marginalia magit lsp-pyright kakoune js2-mode indent-guide helpful good-scroll general flycheck-rust fish-mode fish-completion eglot eat direnv dashboard crux corfu copilot consult catppuccin-theme cape all-the-icons snow meow))) +(custom-set-faces + ;; custom-set-faces was added by Custom. + ;; If you edit it by hand, you could mess it up, so be careful. + ;; Your init file should contain only one such instance. + ;; If there is more than one, they won't work right. + ) diff --git a/home-manager/general/programs/firefox/default.nix b/home-manager/general/programs/firefox/default.nix new file mode 100644 index 0000000..b08ae0c --- /dev/null +++ b/home-manager/general/programs/firefox/default.nix @@ -0,0 +1,109 @@ +{ pkgs, config, inputs, ... }: +let + nur = import inputs.nurpkgs { + inherit pkgs; + nurpkgs = pkgs; + }; + extensions = with nur.repos.rycee.firefox-addons; [ + bitwarden + ublock-origin + switchyomega + sponsorblock + return-youtube-dislikes + firefox-color + tampermonkey + duckduckgo-privacy-essentials + sidebery + ]; + userConfig = builtins.readFile ./user.js; + configOverrides = '' + user_pref("browser.search.suggest.enabled", true); + user_pref("mousewheel.default.delta_multiplier_y", 75); + user_pref("network.captive-portal-service.enabled", true); + user_pref("captivedetect.canonicalURL", "http://detectportal.firefox.com/canonical.html"); + user_pref("network.connectivity-service.enabled", true); + ''; + extraConfig = userConfig + configOverrides; + engines = { + "Brave" = { + urls = [{ template = "https://search.brave.com/search?q={searchTerms}"; }]; + iconUpdateURL = "https://cdn.search.brave.com/serp/v2/_app/immutable/assets/safari-pinned-tab.539899c7.svg"; + updateInterval = 24 * 60 * 60 * 1000; + definedAliases = [ "!br" ]; + }; + "NixOS" = { + urls = [{ template = "https://search.nixos.org/packages?channel=unstable&from=0&size=50&sort=relevance&type=packages&query={searchTerms}"; }]; + iconUpdateURL = "https://nixos.org/favicon.png"; + updateInterval = 24 * 60 * 60 * 1000; + definedAliases = [ "!ns" ]; + }; + "HomeManager" = { + urls = [{ template = "https://mipmip.github.io/home-manager-option-search/?query={searchTerms}"; }]; + iconUpdateURL = "https://github.com/mipmip/home-manager-option-search/blob/main/images/favicon.png"; + updateInterval = 24 * 60 * 60 * 1000; + definedAliases = [ "!hs" ]; + }; + "ai question" = { + urls = [{ template = "https://iask.ai/?mode=question&q={searchTerms}"; }]; + iconUpdateURL = "https://iask.ai/favicons/favicon-32x32-650bd8771fdea8866630408578e381cc.png?vsn=d"; + updateInterval = 24 * 60 * 60 * 1000; + definedAliases = [ "!aq" ]; + }; + "ai forums" = { + urls = [{ template = "https://iask.ai/?mode=forums&q={searchTerms}"; }]; + iconUpdateURL = "https://iask.ai/favicons/favicon-32x32-650bd8771fdea8866630408578e381cc.png?vsn=d"; + updateInterval = 24 * 60 * 60 * 1000; + definedAliases = [ "!af" ]; + }; + "ai wiki" = { + urls = [{ template = "https://iask.ai/?mode=wiki&q={searchTerms}"; }]; + iconUpdateURL = "https://iask.ai/favicons/favicon-32x32-650bd8771fdea8866630408578e381cc.png?vsn=d"; + updateInterval = 24 * 60 * 60 * 1000; + definedAliases = [ "!aw" ]; + }; + "FastGPT" = { + urls = [{ template = "https://labs.kagi.com/fastgpt?query={searchTerms}"; }]; + definedAliases = [ "!fq" ]; + }; + "NixWiki" = { + urls = [{ template = "https://nixos.wiki/index.php?search={searchTerms}&go=Go"; }]; + iconUpdateURL = "https://nixos.org/favicon.png"; + updateInterval = 24 * 60 * 60 * 1000; + definedAliases = [ "!nw" ]; + }; + "Kinopoisk" = { + urls = [{ template = "https://www.kinopoisk.ru/index.php?kp_query={searchTerms}"; }]; + iconUpdateURL = "https://www.kinopoisk.ru/favicon.ico"; + updateInterval = 24 * 60 * 60 * 1000; + definedAliases = [ "!ks" ]; + }; + "AnimeGo" = { + urls = [{ template = "https://animego.org/search/all?q={searchTerms}"; }]; + iconUpdateURL = "https://animego.org/favicon-32x32.png"; + updateInterval = 24 * 60 * 60 * 1000; + definedAliases = [ "!as" ]; + }; + }; + force = true; +in +{ + programs.firefox = { + enable = true; + profiles.nothing = { + isDefault = false; + id = 1; + }; + profiles.Betterfox = { + isDefault = true; + inherit extensions extraConfig; + search = { + inherit engines force; + default = "Brave"; + }; + }; + }; + home.file."chrome" = { + source = ./userChrome.css; + target = ".mozilla/firefox/Betterfox/chrome/userChrome.css"; + }; +} diff --git a/home-manager/general/programs/firefox/user.js b/home-manager/general/programs/firefox/user.js new file mode 100644 index 0000000..cbf15bb --- /dev/null +++ b/home-manager/general/programs/firefox/user.js @@ -0,0 +1,262 @@ +// +/* You may copy+paste this file and use it as it is. + * + * If you make changes to your about:config while the program is running, the + * changes will be overwritten by the user.js when the application restarts. + * + * To make lasting changes to preferences, you will have to edit the user.js. + */ + +/**************************************************************************** + * Betterfox * + * "Ad meliora" * + * version: 115 * + * url: https://github.com/yokoffing/Betterfox * +****************************************************************************/ + +/**************************************************************************** + * SECTION: FASTFOX * +****************************************************************************/ +user_pref("nglayout.initialpaint.delay", 0); +user_pref("nglayout.initialpaint.delay_in_oopif", 0); +user_pref("content.notify.interval", 100000); +user_pref("browser.startup.preXulSkeletonUI", false); + +/** EXPERIMENTAL ***/ +user_pref("layout.css.grid-template-masonry-value.enabled", true); +user_pref("dom.enable_web_task_scheduling", true); + +/** GFX ***/ +user_pref("gfx.webrender.all", true); +user_pref("gfx.webrender.precache-shaders", true); +user_pref("gfx.webrender.compositor", true); +user_pref("layers.gpu-process.enabled", true); +user_pref("media.hardware-video-decoding.enabled", true); +user_pref("gfx.canvas.accelerated", true); +user_pref("gfx.canvas.accelerated.cache-items", 32768); +user_pref("gfx.canvas.accelerated.cache-size", 4096); +user_pref("gfx.content.skia-font-cache-size", 80); +user_pref("image.cache.size", 10485760); +user_pref("image.mem.decode_bytes_at_a_time", 131072); +user_pref("image.mem.shared.unmap.min_expiration_ms", 120000); +user_pref("media.memory_cache_max_size", 1048576); +user_pref("media.memory_caches_combined_limit_kb", 2560000); +user_pref("media.cache_readahead_limit", 9000); +user_pref("media.cache_resume_threshold", 6000); + +/** BROWSER CACHE ***/ +user_pref("browser.cache.memory.max_entry_size", 153600); + +/** NETWORK ***/ +user_pref("network.buffer.cache.size", 262144); +user_pref("network.buffer.cache.count", 128); +user_pref("network.http.max-connections", 1800); +user_pref("network.http.max-persistent-connections-per-server", 10); +user_pref("network.ssl_tokens_cache_capacity", 32768); + +/**************************************************************************** + * SECTION: SECUREFOX * +****************************************************************************/ +/** TRACKING PROTECTION ***/ +user_pref("browser.contentblocking.category", "strict"); +user_pref("urlclassifier.trackingSkipURLs", "*.reddit.com, *.twitter.com, *.twimg.com, *.tiktok.com"); +user_pref("urlclassifier.features.socialtracking.skipURLs", "*.instagram.com, *.twitter.com, *.twimg.com"); +user_pref("privacy.query_stripping.strip_list", "__hsfp __hssc __hstc __s _hsenc _openstat dclid fbclid gbraid gclid hsCtaTracking igshid mc_eid ml_subscriber ml_subscriber_hash msclkid oft_c oft_ck oft_d oft_id oft_ids oft_k oft_lk oft_sk oly_anon_id oly_enc_id rb_clickid s_cid twclid vero_conv vero_id wbraid wickedid yclid"); +user_pref("browser.uitour.enabled", false); +user_pref("privacy.globalprivacycontrol.enabled", true); +user_pref("privacy.globalprivacycontrol.functionality.enabled", true); + +/** OCSP & CERTS / HPKP ***/ +user_pref("security.OCSP.enabled", 0); +user_pref("security.remote_settings.crlite_filters.enabled", true); +user_pref("security.pki.crlite_mode", 2); +user_pref("security.cert_pinning.enforcement_level", 2); + +/** SSL / TLS ***/ +user_pref("security.ssl.treat_unsafe_negotiation_as_broken", true); +user_pref("browser.xul.error_pages.expert_bad_cert", true); +user_pref("security.tls.enable_0rtt_data", false); + +/** DISK AVOIDANCE ***/ +user_pref("browser.cache.disk.enable", false); +user_pref("browser.privatebrowsing.forceMediaMemoryCache", true); +user_pref("browser.sessionstore.privacy_level", 2); + +/** SHUTDOWN & SANITIZING ***/ +user_pref("privacy.history.custom", true); + +/** SPECULATIVE CONNECTIONS ***/ +user_pref("network.http.speculative-parallel-limit", 0); +user_pref("network.dns.disablePrefetch", true); +user_pref("browser.urlbar.speculativeConnect.enabled", false); +user_pref("browser.places.speculativeConnect.enabled", false); +user_pref("network.prefetch-next", false); +user_pref("network.predictor.enabled", false); +user_pref("network.predictor.enable-prefetch", false); + +/** SEARCH / URL BAR ***/ +user_pref("browser.search.separatePrivateDefault.ui.enabled", true); +user_pref("browser.urlbar.update2.engineAliasRefresh", true); +user_pref("browser.search.suggest.enabled", false); +user_pref("browser.urlbar.suggest.quicksuggest.sponsored", false); +user_pref("browser.urlbar.suggest.quicksuggest.nonsponsored", false); +user_pref("security.insecure_connection_text.enabled", true); +user_pref("security.insecure_connection_text.pbmode.enabled", true); +user_pref("network.IDN_show_punycode", true); + +/** HTTPS-FIRST MODE ***/ +user_pref("dom.security.https_first", true); + +/** PROXY / SOCKS / IPv6 ***/ +user_pref("network.proxy.socks_remote_dns", true); +user_pref("network.file.disable_unc_paths", true); +user_pref("network.gio.supported-protocols", ""); + +/** PASSWORDS AND AUTOFILL ***/ +user_pref("signon.formlessCapture.enabled", false); +user_pref("signon.privateBrowsingCapture.enabled", false); +user_pref("signon.autofillForms", false); +user_pref("signon.rememberSignons", false); +user_pref("editor.truncate_user_pastes", false); + +/** ADDRESS + CREDIT CARD MANAGER ***/ +user_pref("extensions.formautofill.addresses.enabled", false); +user_pref("extensions.formautofill.creditCards.enabled", false); +user_pref("extensions.formautofill.heuristics.enabled", false); +user_pref("browser.formfill.enable", false); + +/** MIXED CONTENT + CROSS-SITE ***/ +user_pref("network.auth.subresource-http-auth-allow", 1); +user_pref("pdfjs.enableScripting", false); +user_pref("extensions.postDownloadThirdPartyPrompt", false); +user_pref("permissions.delegation.enabled", false); + +/** HEADERS / REFERERS ***/ +user_pref("network.http.referer.XOriginTrimmingPolicy", 2); + +/** CONTAINERS ***/ +user_pref("privacy.userContext.ui.enabled", true); + +/** WEBRTC ***/ +user_pref("media.peerconnection.ice.proxy_only_if_behind_proxy", true); +user_pref("media.peerconnection.ice.default_address_only", true); + +/** SAFE BROWSING ***/ +user_pref("browser.safebrowsing.downloads.remote.enabled", false); + +/** MOZILLA ***/ +user_pref("accessibility.force_disabled", 1); +user_pref("identity.fxaccounts.enabled", false); +user_pref("browser.tabs.firefox-view", false); +user_pref("permissions.default.desktop-notification", 2); +user_pref("permissions.default.geo", 2); +user_pref("geo.provider.network.url", "https://location.services.mozilla.com/v1/geolocate?key=%MOZILLA_API_KEY%"); +user_pref("geo.provider.ms-windows-location", false); // WINDOWS +user_pref("geo.provider.use_corelocation", false); // MAC +user_pref("geo.provider.use_gpsd", false); // LINUX +user_pref("geo.provider.use_geoclue", false); // LINUX +user_pref("permissions.manager.defaultsUrl", ""); +user_pref("webchannel.allowObject.urlWhitelist", ""); + +/** TELEMETRY ***/ +user_pref("toolkit.telemetry.unified", false); +user_pref("toolkit.telemetry.enabled", false); +user_pref("toolkit.telemetry.server", "data:,"); +user_pref("toolkit.telemetry.archive.enabled", false); +user_pref("toolkit.telemetry.newProfilePing.enabled", false); +user_pref("toolkit.telemetry.shutdownPingSender.enabled", false); +user_pref("toolkit.telemetry.updatePing.enabled", false); +user_pref("toolkit.telemetry.bhrPing.enabled", false); +user_pref("toolkit.telemetry.firstShutdownPing.enabled", false); +user_pref("toolkit.telemetry.coverage.opt-out", true); +user_pref("toolkit.coverage.opt-out", true); +user_pref("datareporting.healthreport.uploadEnabled", false); +user_pref("datareporting.policy.dataSubmissionEnabled", false); +user_pref("app.shield.optoutstudies.enabled", false); +user_pref("browser.discovery.enabled", false); +user_pref("breakpad.reportURL", ""); +user_pref("browser.tabs.crashReporting.sendReport", false); +user_pref("browser.crashReports.unsubmittedCheck.autoSubmit2", false); +user_pref("captivedetect.canonicalURL", ""); +user_pref("network.captive-portal-service.enabled", false); +user_pref("network.connectivity-service.enabled", false); +user_pref("default-browser-agent.enabled", false); +user_pref("app.normandy.enabled", false); +user_pref("app.normandy.api_url", ""); +user_pref("browser.ping-centre.telemetry", false); +user_pref("browser.newtabpage.activity-stream.feeds.telemetry", false); +user_pref("browser.newtabpage.activity-stream.telemetry", false); + +/**************************************************************************** + * SECTION: PESKYFOX * +****************************************************************************/ +/** MOZILLA UI ***/ +user_pref("layout.css.prefers-color-scheme.content-override", 2); +user_pref("toolkit.legacyUserProfileCustomizations.stylesheets", true); +user_pref("app.update.suppressPrompts", true); +user_pref("browser.compactmode.show", true); +user_pref("browser.privatebrowsing.vpnpromourl", ""); +user_pref("extensions.getAddons.showPane", false); +user_pref("extensions.htmlaboutaddons.recommendations.enabled", false); +user_pref("browser.shell.checkDefaultBrowser", false); +user_pref("browser.newtabpage.activity-stream.asrouter.userprefs.cfr.addons", false); +user_pref("browser.newtabpage.activity-stream.asrouter.userprefs.cfr.features", false); +user_pref("browser.preferences.moreFromMozilla", false); +user_pref("browser.tabs.tabmanager.enabled", false); +user_pref("browser.aboutwelcome.enabled", false); +user_pref("findbar.highlightAll", true); +user_pref("middlemouse.contentLoadURL", false); +user_pref("browser.privatebrowsing.enable-new-indicator", false); + +/** FULLSCREEN ***/ +user_pref("full-screen-api.transition-duration.enter", "0 0"); +user_pref("full-screen-api.transition-duration.leave", "0 0"); +user_pref("full-screen-api.warning.delay", -1); +user_pref("full-screen-api.warning.timeout", 0); + +/** URL BAR ***/ +user_pref("browser.urlbar.suggest.engines", false); +user_pref("browser.urlbar.suggest.topsites", false); +user_pref("browser.urlbar.suggest.calculator", true); +user_pref("browser.urlbar.unitConversion.enabled", true); + +/** NEW TAB PAGE ***/ +user_pref("browser.newtabpage.activity-stream.feeds.topsites", false); +user_pref("browser.newtabpage.activity-stream.feeds.section.topstories", false); + +/*** POCKET ***/ +user_pref("extensions.pocket.enabled", false); + +/** DOWNLOADS ***/ +user_pref("browser.download.useDownloadDir", false); +user_pref("browser.download.alwaysOpenPanel", false); +user_pref("browser.download.manager.addToRecentDocs", false); +user_pref("browser.download.always_ask_before_handling_new_types", true); + +/** PDF ***/ +user_pref("browser.download.open_pdf_attachments_inline", true); + +/** TAB BEHAVIOR ***/ +user_pref("browser.tabs.loadBookmarksInTabs", true); +user_pref("browser.bookmarks.openInTabClosesMenu", false); +user_pref("layout.css.has-selector.enabled", true); +user_pref("cookiebanners.service.mode", 2); +user_pref("cookiebanners.service.mode.privateBrowsing", 2); + +/**************************************************************************** + * SECTION: SMOOTHFOX * +****************************************************************************/ +// visit https://github.com/yokoffing/Betterfox/blob/master/Smoothfox.js +// Enter your scrolling prefs below this line: +user_pref("apz.overscroll.enabled", true); +user_pref("general.smoothScroll", true); +user_pref("mousewheel.default.delta_multiplier_y", 275); + +/**************************************************************************** + * START: MY OVERRIDES * +****************************************************************************/ +// Enter your personal prefs below this line: + +/**************************************************************************** + * END: BETTERFOX * +****************************************************************************/ diff --git a/home-manager/general/programs/firefox/userChrome.css b/home-manager/general/programs/firefox/userChrome.css new file mode 100644 index 0000000..c4390dc --- /dev/null +++ b/home-manager/general/programs/firefox/userChrome.css @@ -0,0 +1,98 @@ +:root[tabsintitlebar]{ --uc-toolbar-height: 40px; } +:root[tabsintitlebar][uidensity="compact"]{ --uc-toolbar-height: 32px } + +#TabsToolbar{ visibility: collapse !important } + +:root[sizemode="fullscreen"] #TabsToolbar > :is(#window-controls,.titlebar-buttonbox-container){ + visibility: visible !important; + z-index: 2; +} + +:root:not([inFullscreen]) #nav-bar{ + margin-top: calc(0px - var(--uc-toolbar-height,0px)); +} + +:root[tabsintitlebar] #toolbar-menubar[autohide="true"]{ + min-height: unset !important; + height: var(--uc-toolbar-height,0px) !important; + position: relative; +} + +#toolbar-menubar[autohide="false"]{ + margin-bottom: var(--uc-toolbar-height,0px) +} + +:root[tabsintitlebar] #toolbar-menubar[autohide="true"] #main-menubar{ + flex-grow: 1; + align-items: stretch; + background-color: var(--toolbar-bgcolor,--toolbar-non-lwt-bgcolor); + background-clip: padding-box; + border-right: 30px solid transparent; + border-image: linear-gradient(to left, transparent, var(--toolbar-bgcolor,--toolbar-non-lwt-bgcolor) 30px) 20 / 30px +} + + +#toolbar-menubar:not([inactive]){ z-index: 2 } +#toolbar-menubar[autohide="true"][inactive] > #menubar-items { + opacity: 0; + pointer-events: none; + margin-left: var(--uc-window-drag-space-pre,0px) +} + +.titlebar-close { + display: none !important; +} + +element { + --toolbar-bgcolor: var(--lwt-accent-color) !important; +} + + +#appcontent +> #tabbrowser-tabbox +> #tabbrowser-tabpanels +> .deck-selected +> .browserContainer +> .browserStack +> browser { + border-radius: 10px; + margin: 10px; + border-color: transparent; +} + +.browserStack { + background: var(--lwt-accent-color); +} + +.browserContainer { + background-color: var(--lwt-accent-color); + background-position: right top, var(--lwt-background-alignment); +} + +#sidebar-button { + margin-left: 10px; +} + +#sidebar-box { + min-width: 250px; + max-width: 250px; + min-height: unset; + max-height: unset; + border-right: none; +} + +#sidebar-splitter { + display: none; +} + +#PersonalToolbar { + display: none; +} + +#navigator-toolbox { + border-bottom: none !important; +} + +#sidebar-header { + display: none; +} diff --git a/home-manager/general/programs/fish/default.nix b/home-manager/general/programs/fish/default.nix new file mode 100644 index 0000000..fc91367 --- /dev/null +++ b/home-manager/general/programs/fish/default.nix @@ -0,0 +1,46 @@ +{ pkgs, ... }: + +let + nixPlugins = [ + { name = "colored-man-output"; src = pkgs.fishPlugins.colored-man-pages.src; } + { name = "fzf-fish"; src = pkgs.fishPlugins.fzf-fish.src; } + { name = "pure"; src = pkgs.fishPlugins.pure.src; } + { name = "autopair"; src = pkgs.fishPlugins.autopair.src; } + ]; + customPlugins = []; + plugins = nixPlugins ++ customPlugins; + interactiveShellInit = '' + set fish_greeting + pokemon-colorscripts -r --no-title + ''; + # loginShellInit = '' + # Hyprland + # ''; + functions = { + ranger_func = '' + ranger $argv + set -l quit_cd_wd_file "$HOME/.ranger_quit_cd_wd" + if test -s "$quit_cd_wd_file" + cd "$(cat $quit_cd_wd_file)" + true > "$quit_cd_wd_file" + end + ''; + }; + shellAliases = { + rn = "ranger_func"; + ls = "ls --hyperlink=auto --color=auto"; + iamatomic = "sudo nixos-rebuild switch --flake ~/nixfiles#ltrr"; + }; + +in +{ + programs.direnv = { + enable = true; + nix-direnv.enable = true; + }; + + programs.fish = { + enable = true; + inherit plugins interactiveShellInit functions shellAliases; + }; +} diff --git a/home-manager/general/programs/ranger/commands.py b/home-manager/general/programs/ranger/commands.py new file mode 100644 index 0000000..a41d42f --- /dev/null +++ b/home-manager/general/programs/ranger/commands.py @@ -0,0 +1,183 @@ +from ranger.api.commands import Command +from ranger.container.file import File +from ranger.ext.get_executables import get_executables +from collections import deque +import os +import subprocess + +# fd search + + +class fd_search(Command): + """ + :fd_search [-d] + Executes "fd -d " in the current directory and focuses the + first match. defaults to 1, i.e. only the contents of the current + directory. + + See https://github.com/sharkdp/fd + """ + + SEARCH_RESULTS = deque() + + def execute(self): + import re + import subprocess + from ranger.ext.get_executables import get_executables + + self.SEARCH_RESULTS.clear() + + if "fdfind" in get_executables(): + fd = "fdfind" + elif "fd" in get_executables(): + fd = "fd" + else: + self.fm.notify("Couldn't find fd in the PATH.", bad=True) + return + + if self.arg(1): + if self.arg(1)[:2] == "-d": + depth = self.arg(1) + target = self.rest(2) + else: + depth = "-d1" + target = self.rest(1) + else: + self.fm.notify(":fd_search needs a query.", bad=True) + return + + hidden = "--hidden" if self.fm.settings.show_hidden else "" + exclude = "--no-ignore-vcs --exclude '.git' --exclude '*.py[co]' --exclude '__pycache__'" + command = "{} --follow {} {} {} --print0 {}".format( + fd, depth, hidden, exclude, target + ) + fd = self.fm.execute_command( + command, universal_newlines=True, stdout=subprocess.PIPE + ) + stdout, _ = fd.communicate() + + if fd.returncode == 0: + results = filter(None, stdout.split("\0")) + if not self.fm.settings.show_hidden and self.fm.settings.hidden_filter: + hidden_filter = re.compile(self.fm.settings.hidden_filter) + results = filter( + lambda res: not hidden_filter.search(os.path.basename(res)), results + ) + results = map( + lambda res: os.path.abspath(os.path.join(self.fm.thisdir.path, res)), + results, + ) + self.SEARCH_RESULTS.extend(sorted(results, key=str.lower)) + if len(self.SEARCH_RESULTS) > 0: + self.fm.notify( + "Found {} result{}.".format( + len(self.SEARCH_RESULTS), + ("s" if len(self.SEARCH_RESULTS) > 1 else ""), + ) + ) + self.fm.select_file(self.SEARCH_RESULTS[0]) + else: + self.fm.notify("No results found.") + + +class fd_next(Command): + """ + :fd_next + Selects the next match from the last :fd_search. + """ + + def execute(self): + if len(fd_search.SEARCH_RESULTS) > 1: + fd_search.SEARCH_RESULTS.rotate(-1) # rotate left + self.fm.select_file(fd_search.SEARCH_RESULTS[0]) + elif len(fd_search.SEARCH_RESULTS) == 1: + self.fm.select_file(fd_search.SEARCH_RESULTS[0]) + + +class fd_prev(Command): + """ + :fd_prev + Selects the next match from the last :fd_search. + """ + + def execute(self): + if len(fd_search.SEARCH_RESULTS) > 1: + fd_search.SEARCH_RESULTS.rotate(1) # rotate right + self.fm.select_file(fd_search.SEARCH_RESULTS[0]) + elif len(fd_search.SEARCH_RESULTS) == 1: + self.fm.select_file(fd_search.SEARCH_RESULTS[0]) + + +# yank content +class YankContentWl(Command): + def execute(self): + if "wl-copy" not in get_executables(): + self.fm.notify("wl-clipboard is not found.", bad=True) + return + + arg = self.rest(1) + if arg: + if not os.path.isfile(arg): + self.fm.notify("{} is not a file".format(arg)) + return + file = File(arg) + else: + file = self.fm.thisfile + if not file.is_file: + self.fm.notify("{} is not a file".format(file.relative_path)) + return + if file.is_binary or file.image: + subprocess.check_call("wl-copy" + " < " + file.path, shell=True) + else: + self.fm.notify( + "{} is not an image file or a text file".format(file.relative_path) + ) + + +import os +import subprocess +from ranger.api.commands import Command +from ranger.container.file import File +from ranger.ext.get_executables import get_executables + + +class YankContent(Command): + """ + Copy the content of image file and text file with xclip + """ + + def execute(self): + if "xclip" not in get_executables(): + self.fm.notify("xclip is not found.", bad=True) + return + + arg = self.rest(1) + if arg: + if not os.path.isfile(arg): + self.fm.notify("{} is not a file.".format(arg)) + return + file = File(arg) + else: + file = self.fm.thisfile + if not file.is_file: + self.fm.notify("{} is not a file.".format(file.relative_path)) + return + + relative_path = file.relative_path + cmd = ["xclip", "-selection", "clipboard"] + if not file.is_binary(): + with open(file.path, "rb") as fd: + subprocess.check_call(cmd, stdin=fd) + elif file.image: + cmd += ["-t", file.mimetype, file.path] + subprocess.check_call(cmd) + self.fm.notify( + "Content of {} is copied to x clipboard".format(relative_path) + ) + else: + self.fm.notify( + "{} is not an image file or a text file.".format(relative_path) + ) + + def tab(self, tabnum): + return self._tab_directory_content() diff --git a/home-manager/general/programs/ranger/default.nix b/home-manager/general/programs/ranger/default.nix new file mode 100644 index 0000000..4dbced5 --- /dev/null +++ b/home-manager/general/programs/ranger/default.nix @@ -0,0 +1,11 @@ +{ pkgs, ... }: +{ + home.packages = with pkgs; [ ranger wl-clipboard ]; + xdg.configFile = { + "ranger/rc.conf".text = builtins.readFile ./rc.conf; + "ranger/rifle.conf".text = builtins.readFile ./rifle.conf; + "ranger/scope.sh".text = builtins.readFile ./scope.sh; + "ranger/commands.py".source = ./commands.py; + "ranger/plugins".source = ./plugins; + }; +} diff --git a/home-manager/general/programs/ranger/default.nix~ b/home-manager/general/programs/ranger/default.nix~ new file mode 100644 index 0000000..ea1b298 --- /dev/null +++ b/home-manager/general/programs/ranger/default.nix~ @@ -0,0 +1,7 @@ +{ pkgs, ... }: +let + "ranger/rc.conf".text = builtins.readFile ./rc.conf; + "ranger/rifle.conf".text = builtins.readFile ./rifle.conf; + "ranger/scope.sh".text = builtins.readFile ./scope.sh; + "ranger/commands.py".source = ./commands.py; + "ranger/plugins".source = ./plugins; diff --git a/home-manager/general/programs/ranger/plugins/__init__.py b/home-manager/general/programs/ranger/plugins/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/home-manager/general/programs/ranger/plugins/__pycache__/__init__.cpython-310.pyc b/home-manager/general/programs/ranger/plugins/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000..1a26aa3 Binary files /dev/null and b/home-manager/general/programs/ranger/plugins/__pycache__/__init__.cpython-310.pyc differ diff --git a/home-manager/general/programs/ranger/plugins/__pycache__/__init__.cpython-311.pyc b/home-manager/general/programs/ranger/plugins/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000..87b2e7f Binary files /dev/null and b/home-manager/general/programs/ranger/plugins/__pycache__/__init__.cpython-311.pyc differ diff --git a/home-manager/general/programs/ranger/plugins/__pycache__/fd.cpython-311.pyc b/home-manager/general/programs/ranger/plugins/__pycache__/fd.cpython-311.pyc new file mode 100644 index 0000000..146af23 Binary files /dev/null and b/home-manager/general/programs/ranger/plugins/__pycache__/fd.cpython-311.pyc differ diff --git a/home-manager/general/programs/ranger/plugins/__pycache__/quit_cd_wd.cpython-310.pyc b/home-manager/general/programs/ranger/plugins/__pycache__/quit_cd_wd.cpython-310.pyc new file mode 100644 index 0000000..49d1db9 Binary files /dev/null and b/home-manager/general/programs/ranger/plugins/__pycache__/quit_cd_wd.cpython-310.pyc differ diff --git a/home-manager/general/programs/ranger/plugins/__pycache__/quit_cd_wd.cpython-311.pyc b/home-manager/general/programs/ranger/plugins/__pycache__/quit_cd_wd.cpython-311.pyc new file mode 100644 index 0000000..7b3ac1c Binary files /dev/null and b/home-manager/general/programs/ranger/plugins/__pycache__/quit_cd_wd.cpython-311.pyc differ diff --git a/home-manager/general/programs/ranger/plugins/quit_cd_wd.py b/home-manager/general/programs/ranger/plugins/quit_cd_wd.py new file mode 100644 index 0000000..e47837f --- /dev/null +++ b/home-manager/general/programs/ranger/plugins/quit_cd_wd.py @@ -0,0 +1,38 @@ +import ranger.api +from ranger.api.commands import * +import os + +def save_wd(command): + with open(os.path.expanduser('~/.ranger_quit_cd_wd'), 'w') as f: + f.write(command.fm.thisdir.path); + +class quit_cd_wd(Command): + """:chdir to working directory of ranger after quiting on ranger. + + """ + def _exit_no_work(self): + if self.fm.loader.has_work(): + self.fm.notify('Not quitting: Tasks in progress: Use `quit!` to force quit') + else: + self.fm.exit() + + def execute(self): + if len(self.fm.tabs) >= 2: + self.fm.tab_close() + else: + save_wd(self) + self._exit_no_work() + +class quitall_cd_wd(Command): + """:chdir to working directory of ranger after quitalling on ranger. + + """ + def _exit_no_work(self): + if self.fm.loader.has_work(): + self.fm.notify('Not quitting: Tasks in progress: Use `quitall!` to force quit') + else: + self.fm.exit() + + def execute(self): + save_wd(self) + self._exit_no_work() diff --git a/home-manager/general/programs/ranger/plugins/ranger_fzf_filter/.gitignore b/home-manager/general/programs/ranger/plugins/ranger_fzf_filter/.gitignore new file mode 100644 index 0000000..846dc44 --- /dev/null +++ b/home-manager/general/programs/ranger/plugins/ranger_fzf_filter/.gitignore @@ -0,0 +1,132 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +pip-wheel-metadata/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +.python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow +__pypackages__/ + +# Celery stuff +celerybeat-schedule +celerybeat.pid + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ + +# Pycharm +.idea diff --git a/home-manager/general/programs/ranger/plugins/ranger_fzf_filter/LICENSE b/home-manager/general/programs/ranger/plugins/ranger_fzf_filter/LICENSE new file mode 100644 index 0000000..bd840f1 --- /dev/null +++ b/home-manager/general/programs/ranger/plugins/ranger_fzf_filter/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2021 MuXiu1997 + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/home-manager/general/programs/ranger/plugins/ranger_fzf_filter/README.md b/home-manager/general/programs/ranger/plugins/ranger_fzf_filter/README.md new file mode 100644 index 0000000..6a65e17 --- /dev/null +++ b/home-manager/general/programs/ranger/plugins/ranger_fzf_filter/README.md @@ -0,0 +1,47 @@ +# ranger-fzf-filter +This is a plugin for [`ranger`](https://github.com/ranger/ranger) that add a fuzzy filter. It depends on [`fzf`](https://github.com/junegunn/fzf) + +https://user-images.githubusercontent.com/49554020/173509108-dc3edca4-8949-4026-a3ca-0ba8dac9bbce.mp4 + + +## Install + +For ranger >= 1.9.3, use Git to clone this repository into your `~/.config/ranger/plugins` folder. For example: + +```sh +git clone git@github.com:MuXiu1997/ranger-fzf-filter.git ~/.config/ranger/plugins/ranger_fzf_filter +``` + +**Legacy Install** + +For ranger versions older than 1.9.3, or to install without Git, download `__init__.py` to your `~/.config/ranger/plugins` directory. For example: + +```shell +mkdir -p ~/.config/ranger/plugins +wget -O ~/.config/ranger/plugins/ranger_fzf_filter.py https://raw.githubusercontent.com/MuXiu1997/ranger-fzf-filter/main/__init__.py +``` + + + +## Usage + +Command: + +- `:fzf_filter [query]`: filtering files with fzf, see this [search syntax](https://github.com/junegunn/fzf#search-syntax) + + + +## Keyboard Shortcut + +Add a binding to your `~/.config/ranger/rc.conf` file to quickly use `:fzf_filter`: + +``` +map f console fzf_filter%space +``` + + + +## License + +[MIT](LICENSE) + diff --git a/home-manager/general/programs/ranger/plugins/ranger_fzf_filter/__init__.py b/home-manager/general/programs/ranger/plugins/ranger_fzf_filter/__init__.py new file mode 100644 index 0000000..b5d5b46 --- /dev/null +++ b/home-manager/general/programs/ranger/plugins/ranger_fzf_filter/__init__.py @@ -0,0 +1,35 @@ +import ranger.api +import ranger.container.directory +# noinspection PyUnresolvedReferences +from .command import fzf_filter, KEY_FZF_FILTER + +# region overwrite hook_init +HOOK_INIT_OLD = ranger.api.hook_init + + +def hook_init(fm): + def clear_fzf_filter(signal): + if fm.settings.clear_filters_on_dir_change and signal.previous: + signal.previous.__dict__[KEY_FZF_FILTER] = None + signal.previous.refilter() + + fm.signal_bind('cd', clear_fzf_filter) + return HOOK_INIT_OLD(fm) + + +ranger.api.hook_init = hook_init +# endregion overwrite hook_init + +# region overwrite accept_file +ACCEPT_FILE_OLD = ranger.container.directory.accept_file + + +def accept_file(fobj, filters): + _fzf_filter = fobj.fm.thisdir.__dict__.get(KEY_FZF_FILTER, None) + if _fzf_filter: + filters.append(_fzf_filter) + return ACCEPT_FILE_OLD(fobj, filters) + + +ranger.container.directory.accept_file = accept_file +# endregion overwrite accept_file diff --git a/home-manager/general/programs/ranger/plugins/ranger_fzf_filter/command.py b/home-manager/general/programs/ranger/plugins/ranger_fzf_filter/command.py new file mode 100644 index 0000000..92aee83 --- /dev/null +++ b/home-manager/general/programs/ranger/plugins/ranger_fzf_filter/command.py @@ -0,0 +1,59 @@ +import ranger.api.commands +from .filter import FzfFilter + +# noinspection PyUnreachableCode +# This is done to enhance auto-completion and inference in the editor. +if False: + import ranger.core.fm + +KEY_FZF_FILTER = 'fzf_filter' + + +# noinspection PyPep8Naming,PyUnresolvedReferences +class fzf_filter(ranger.api.commands.Command): + """ + :fzf_filter + + This command allows you to use fzf fuzzy search to filter files and directories in the ranger. + """ + + def execute(self): + fm = self.fm # type: ranger.core.fm.FM + # Check if a filter is already set + _filter = fm.thisdir.__dict__.get(KEY_FZF_FILTER, None) + if isinstance(_filter, FzfFilter): + # If a filter is set, just update the query + _filter.set_query(self._get_query()) + else: + # If no filter is set, build a new one + fm.thisdir.__dict__[KEY_FZF_FILTER] = self._build_filter() + + fm.thisdir.refilter() + if self.quickly_executed: + fm.open_console(self.line) + + def cancel(self): + fm = self.fm # type: ranger.core.fm.FM + fm.thisdir.__dict__[KEY_FZF_FILTER] = None + fm.thisdir.refilter() + + def quick(self): + return True + + def _get_query(self): + """ + Get the search query. + + Returns: + str: The search query. + """ + return self.rest(1) + + def _build_filter(self): + """ + Build a new FzfFilter. + + Returns: + FzfFilter: A new FzfFilter object with the current directory and search query. + """ + return FzfFilter(self.fm.thisdir, self._get_query()) diff --git a/home-manager/general/programs/ranger/plugins/ranger_fzf_filter/filter.py b/home-manager/general/programs/ranger/plugins/ranger_fzf_filter/filter.py new file mode 100644 index 0000000..3d12756 --- /dev/null +++ b/home-manager/general/programs/ranger/plugins/ranger_fzf_filter/filter.py @@ -0,0 +1,84 @@ +import os.path +import subprocess + + +class FzfFilter: + """ + A filter class for FZF fuzzy search. + + Attributes: + thisdir (ranger.container.directory.Directory): The current directory. + query (str): The search query. + source (list[str]): List of relative paths of all files in the current directory. + result (list[str]): The result of fzf search. + """ + + def __init__(self, thisdir, query): + """ + Initialize the FzfFilter class. + + Args: + thisdir (ranger.container.directory.Directory): The current directory. + query (str): The search query. + """ + self.thisdir = thisdir + self.files_all = thisdir.files_all + + self.query = query + + self.source = [] + self.recalc_source() + + self.result = [] + self.recalc_result() + + def recalc_source(self): + """ + Recalculate the source list based on the files in the current directory. + """ + self.source = [f.relative_path for f in self.thisdir.files_all] + + def recalc_result(self): + """ + Recalculate the result list by executing the fzf command. + """ + cmd = subprocess.Popen( + ['fzf', '-f', self.query], + stdin=subprocess.PIPE, + stdout=subprocess.PIPE, + ) + stdout, _ = cmd.communicate('\n'.join(self.source).encode('utf-8')) + self.result = stdout.decode('utf-8').strip().splitlines() + + def set_query(self, query): + """ + Update the query and recalculate the result list. + + Args: + query (str): The new search query. + """ + self.query = query + self.recalc_result() + + def __call__(self, fobj): + """ + Perform the actual filtering. + + Args: + fobj (ranger.container.file.File | ranger.container.directory.Directory): The file or directory to check. + + Returns: + bool: True if the file or directory is in the result list, False otherwise. + """ + # Check if the files in the current directory have changed, and if so, recalculate source and result + if self.thisdir.files_all is not self.files_all: + self.files_all = self.thisdir.files_all + self.recalc_source() + self.recalc_result() + + # Ensure the relative path start of the file or directory is in the current directory + if os.path.relpath(fobj.path, fobj.relative_path) != '.': + return True + + # Check if the relative path of the file or directory is in the result list + return fobj.relative_path in self.result diff --git a/home-manager/general/programs/ranger/rc.conf b/home-manager/general/programs/ranger/rc.conf new file mode 100644 index 0000000..271d239 --- /dev/null +++ b/home-manager/general/programs/ranger/rc.conf @@ -0,0 +1,12 @@ +map f console fzf_filter%space +map x quit_cd_wd +map X quitall_cd_wd +map / console fd_search -d5%space +map n fd_next +map p fd_prev +map e shell dragon -x %p & +map yc YankContent +set preview_images true +set preview_images_method kitty +set use_preview_script True +map gj cd /run/media/jerpo/ diff --git a/home-manager/general/programs/ranger/rifle.conf b/home-manager/general/programs/ranger/rifle.conf new file mode 100644 index 0000000..3b565af --- /dev/null +++ b/home-manager/general/programs/ranger/rifle.conf @@ -0,0 +1,284 @@ +# vim: ft=cfg +# +# This is the configuration file of "rifle", ranger's file executor/opener. +# Each line consists of conditions and a command. For each line the conditions +# are checked and if they are met, the respective command is run. +# +# Syntax: +# , , ... = command +# +# The command can contain these environment variables: +# $1-$9 | The n-th selected file +# $@ | All selected files +# +# If you use the special command "ask", rifle will ask you what program to run. +# +# Prefixing a condition with "!" will negate its result. +# These conditions are currently supported: +# match | The regexp matches $1 +# ext | The regexp matches the extension of $1 +# mime | The regexp matches the mime type of $1 +# name | The regexp matches the basename of $1 +# path | The regexp matches the absolute path of $1 +# has | The program is installed (i.e. located in $PATH) +# env | The environment variable "variable" is non-empty +# file | $1 is a file +# directory | $1 is a directory +# number | change the number of this command to n +# terminal | stdin, stderr and stdout are connected to a terminal +# X | A graphical environment is available (darwin, Xorg, or Wayland) +# +# There are also pseudo-conditions which have a "side effect": +# flag | Change how the program is run. See below. +# label