diff options
Diffstat (limited to 'home-manager/homeModules')
53 files changed, 4133 insertions, 0 deletions
diff --git a/home-manager/homeModules/alacritty.nix b/home-manager/homeModules/alacritty.nix new file mode 100644 index 0000000..0f9d5ba --- /dev/null +++ b/home-manager/homeModules/alacritty.nix @@ -0,0 +1,27 @@ +{ pkgs, config, lib, ... }: + +{ + options = { + alacritty.enable = lib.mkEnableOption "enable alacritty"; + }; + + config = lib.mkIf config.alacritty.enable { + programs.alacritty = { + enable = true; + settings = { + cursor = { + style = "Beam"; + thickness = 0.25; + }; + window = { + padding = { + x = 10; + }; + }; + }; + }; + }; +} + + + diff --git a/home-manager/homeModules/attachments/basecat.aseprite b/home-manager/homeModules/attachments/basecat.aseprite Binary files differnew file mode 100644 index 0000000..16caffd --- /dev/null +++ b/home-manager/homeModules/attachments/basecat.aseprite diff --git a/home-manager/homeModules/attachments/basecat.png b/home-manager/homeModules/attachments/basecat.png Binary files differnew file mode 100644 index 0000000..d202c64 --- /dev/null +++ b/home-manager/homeModules/attachments/basecat.png diff --git a/home-manager/homeModules/attachments/cat.png b/home-manager/homeModules/attachments/cat.png Binary files differnew file mode 100644 index 0000000..5657a78 --- /dev/null +++ b/home-manager/homeModules/attachments/cat.png diff --git a/home-manager/homeModules/attachments/hypr-scripts/battery-level.sh b/home-manager/homeModules/attachments/hypr-scripts/battery-level.sh new file mode 100755 index 0000000..cc2d5cd --- /dev/null +++ b/home-manager/homeModules/attachments/hypr-scripts/battery-level.sh @@ -0,0 +1,22 @@ +#!/bin/sh +while true; do + # Check the battery level and charging status + battery_info=$(acpi -b) + + # Extract the battery level from the output of `acpi` + battery_level=$(echo $battery_info | grep -o "[0-9]*%" | sed "s/%//") + + # Check if the laptop is charging + if [[ $battery_info == *"Charging"* ]]; then + # If the laptop is charging, do nothing + : + else + # If the battery level is less than 15%, send a notification + if [ "$battery_level" -lt 15 ]; then + notify-send "Battery Low" "Battery level is at $battery_level%. Charge your laptop." + fi + fi + + # Sleep for 5 minutes before checking the battery level again + sleep 300 +done diff --git a/home-manager/homeModules/attachments/hypr-scripts/hshot b/home-manager/homeModules/attachments/hypr-scripts/hshot new file mode 100755 index 0000000..0d02b9c --- /dev/null +++ b/home-manager/homeModules/attachments/hypr-scripts/hshot @@ -0,0 +1,45 @@ +#!/bin/sh + +declare -a cmd + +usage() { + echo -e "-m | monitor\n-s | slurp\n-w | active window\n-c | add copy" +} + +monitor() { + cmd=("grim -o \"\$(hyprctl -j monitors | jq -r '.[] | select(.focused) | .name')\"") +} + +slurp() { + cmd=("grim -g \"\$(slurp)\"") +} + +window() { + cmd=("grim -g \"\$(hyprctl activewindow -j | jq -j '\"\(.at | .[0]),\(.at | .[1]) \(.size | .[0])x\(.size | .[1])\"')\"") +} + +copy() { + if [[ -n ${cmd[0]} ]]; then + cmd+=("- | wl-copy") + else + usage + fi +} + +while getopts ":mswc" opt; do + case ${opt} in + m) monitor;; + s) slurp;; + w) window;; + c) copy;; + *) usage + exit 1;; + esac +done + +if [[ -z $1 ]]; then + usage + exit 1 +fi + +bash -c "${cmd[*]}" diff --git a/home-manager/homeModules/attachments/hypr-scripts/kill b/home-manager/homeModules/attachments/hypr-scripts/kill new file mode 100755 index 0000000..40ab4a9 --- /dev/null +++ b/home-manager/homeModules/attachments/hypr-scripts/kill @@ -0,0 +1,7 @@ +#!/bin/sh + +if [[ $(hyprctl activewindow -j | jq -r '.class') =~ (kitty) ]]; then + kill $(hyprctl activewindow -j | jq '.pid') -s 9 +else + hyprctl dispatch killactive +fi diff --git a/home-manager/homeModules/attachments/hypr-scripts/rnew.fish b/home-manager/homeModules/attachments/hypr-scripts/rnew.fish new file mode 100755 index 0000000..743d7fd --- /dev/null +++ b/home-manager/homeModules/attachments/hypr-scripts/rnew.fish @@ -0,0 +1,8 @@ +#!/usr/bin/env fish + +ranger $argv +set quit_cd_wd_file "$HOME/.ranger_quit_cd_wd" +if test -s "$quit_cd_wd_file" + kitty -d "$(cat $quit_cd_wd_file)" --detach + true >"$quit_cd_wd_file" +end diff --git a/home-manager/homeModules/attachments/hypr-scripts/rofi-modes b/home-manager/homeModules/attachments/hypr-scripts/rofi-modes new file mode 100755 index 0000000..2d52802 --- /dev/null +++ b/home-manager/homeModules/attachments/hypr-scripts/rofi-modes @@ -0,0 +1,20 @@ +#!/bin/sh + +case $(echo -e "clipboard\nemoji\ncalc" | rofi -dmenu) in + emoji) arg=emoji;; + calc) arg=calc;; + clipboard) cliphist list | rofi -dmenu -display-columns 2 | cliphist decode | wl-copy + exit;; + bitwarden) if [[ $XDG_BACKEND == "wayland" ]]; then + typer=wtype + clip=wl-copy + else + typer=xdotool + clip=xclip + fi + rofi-rbw --typer $typer --clip $clip + exit;; + *)exit;; +esac + +rofi -modi $arg -show $arg diff --git a/home-manager/homeModules/attachments/rofi-theme.rasi b/home-manager/homeModules/attachments/rofi-theme.rasi new file mode 100644 index 0000000..bba4f6c --- /dev/null +++ b/home-manager/homeModules/attachments/rofi-theme.rasi @@ -0,0 +1,79 @@ +/******************************************************************************* + * SNITCHED FROM: + * User : LR-Tech + * Theme Repo : https://github.com/lr-tech/rofi-themes-collection + *******************************************************************************/ + +window { + location: center; + width: 480; + y-offset: -160; + border-radius: 7px; + + background-color: @bg0; +} + +inputbar { + spacing: 8px; + padding: 8px; + + background-color: @bg1; +} + +prompt, entry, element-icon, element-text { + vertical-align: 0.5; +} + +prompt { + text-color: @accent-color; +} + +textbox { + padding: 8px; + background-color: @bg1; +} + +listview { + padding: 4px 0; + lines: 8; + columns: 1; + + fixed-height: false; +} + +element { + padding: 8px; + spacing: 8px; +} + +element normal normal { + text-color: @fg0; +} + +element normal urgent { + text-color: @urgent-color; +} + +element normal active { + text-color: @accent-color; +} + +element selected { + text-color: @bg0; +} + +element selected normal, element selected active { + background-color: @accent-color; +} + +element selected urgent { + background-color: @urgent-color; +} + +element-icon { + size: 0.8em; +} + +element-text { + text-color: inherit; +} diff --git a/home-manager/homeModules/attachments/waybar-style.css b/home-manager/homeModules/attachments/waybar-style.css new file mode 100644 index 0000000..7d0143a --- /dev/null +++ b/home-manager/homeModules/attachments/waybar-style.css @@ -0,0 +1,31 @@ +* { + font-family: Material Design Icons, Rubik Medium; + font-size: 14px; + color: @base05; +} + +window#waybar { + border-radius: 10px; + background: @base01; + border: 3px solid @base02; +} + +#battery { + margin-right: 6px; +} + +#workspaces button label { + font-size: 15px; + color: @base05; + transition: all 100ms ease-out; +} + +#workspaces button.active label { + font-weight: bolder; + color: @base0A; + transition: all 100ms ease-out; +} + +#battery { + color: @base0A; +} diff --git a/home-manager/homeModules/bspwm.nix b/home-manager/homeModules/bspwm.nix new file mode 100644 index 0000000..f700f13 --- /dev/null +++ b/home-manager/homeModules/bspwm.nix @@ -0,0 +1,58 @@ +{ pkgs, config, lib, ... }: + +{ + imports = [ + ./picom.nix + ./dunst.nix + ./sxhkd.nix + ]; + + options = { + bspwm.enable = lib.mkEnableOption "enable bspwm"; + }; + + config = lib.mkIf config.bspwm.enable { + picom.enable = true; + dunst.enable = true; + sxhkd.enable = true; + + rofi = { + enable = true; + package = pkgs.rofi; + }; + + xsession.windowManager.bspwm = { + enable = true; + + monitors = + let + workspaces = [ + "α" + "β" + "γ" + "δ" + "ε" + ]; + in { + "^1" = workspaces; + "^2" = workspaces; + }; + + settings = { + focused_border_color = "#908caa"; + normal_border_color = "#363a4f"; + presel_feedback_color = "#752f20"; + border_width = 3; + window_gap = 12; + focus_follows_pointer = true; + split_ratio = 0.5; + }; + + startupPrograms = [ + "picom -b" + "emacs --daemon" + "feh --bg-fill ~/dotfiles/cat.png" + ]; + }; + }; +} diff --git a/home-manager/homeModules/default.nix b/home-manager/homeModules/default.nix new file mode 100644 index 0000000..49569f0 --- /dev/null +++ b/home-manager/homeModules/default.nix @@ -0,0 +1,19 @@ +{ + imports = [ + ./emacs + ./firefox + ./ranger + ./niri.nix + ./mako.nix + ./rofi.nix + ./nvim.nix + ./bspwm.nix + ./hyprland.nix + ./picom.nix + ./alacritty.nix + ./fish.nix + ./waybar.nix + ./fuzzel.nix + ./stylix.nix + ]; +} diff --git a/home-manager/homeModules/dunst.nix b/home-manager/homeModules/dunst.nix new file mode 100644 index 0000000..3b25f41 --- /dev/null +++ b/home-manager/homeModules/dunst.nix @@ -0,0 +1,24 @@ +{ pkgs, config, lib, ... }: + +{ + options = { + dunst.enable = lib.mkEnableOption "enable dunst"; + }; + config = lib.mkIf config.dunst.enable { + home.packages = [ pkgs.libnotify ]; + services.dunst = { + enable = false; + settings = { + global = { + origin = "bottom-right"; + frame_color = "#c4a7e7"; + notification_limit = 5; + progress_bar = true; + background = "#232136"; + foreground = "#e0def4"; + separator_color = "foreground"; + }; + }; + }; + }; +} diff --git a/home-manager/homeModules/emacs/aliases b/home-manager/homeModules/emacs/aliases new file mode 100644 index 0000000..26dc4e1 --- /dev/null +++ b/home-manager/homeModules/emacs/aliases @@ -0,0 +1,2 @@ +alias nr sudo nixos-rebuild switch --flake /home/jerpo/nixfiles#ltrr-mini +alias hr home-manager switch --flake /home/jerpo/nixfiles diff --git a/home-manager/homeModules/emacs/config.org b/home-manager/homeModules/emacs/config.org new file mode 100644 index 0000000..bb438c8 --- /dev/null +++ b/home-manager/homeModules/emacs/config.org @@ -0,0 +1,989 @@ +#+Title: spl3g's Emacs config +#+AUTHOR: spl3g +#+STARTUP: showeverything +#+OPTIONS: toc:2 + +* Table Of Contents :toc: +- [[#progs-to-load-first][Progs to load first]] + - [[#optimisations][Optimisations]] + - [[#elpaca][elpaca]] + - [[#native-comp-warnings][Native comp warnings]] + - [[#save-history][Save history]] + - [[#meow-mode][Meow mode]] + - [[#general-keybindings][General keybindings]] + - [[#which-key][Which key]] +- [[#gui-tweaks][GUI tweaks]] + - [[#disable-gui-shit][Disable gui shit]] + - [[#fonts][Fonts]] + - [[#display-line-numbers][Display line numbers]] + - [[#theme][Theme]] + - [[#icons][Icons]] + - [[#modeline][Modeline]] + - [[#scroll][Scroll]] + - [[#dashboard][Dashboard]] + - [[#disable-ring-bell][Disable ring-bell]] + - [[#indent-guide][Indent guide]] + - [[#misc][Misc]] +- [[#projects][Projects]] +- [[#org-mode][Org mode]] + - [[#enabling-toc][Enabling toc]] + - [[#org-bullets][Org bullets]] + - [[#auto-tangle][Auto-tangle]] + - [[#org-download][Org-download]] +- [[#better-ux][Better UX]] + - [[#vertico][Vertico]] + - [[#consult][Consult]] + - [[#embark][Embark]] +- [[#eshell][Eshell]] + - [[#fish-completions][Fish completions]] + - [[#eat][Eat]] +- [[#lsp][LSP]] + - [[#flycheck][Flycheck]] + - [[#lsp-ui][lsp-ui]] + - [[#lsp-booster][LSP-booster]] + - [[#corfu][Corfu]] + - [[#tree-sitter][Tree-sitter]] + - [[#snippets][Snippets]] + - [[#languages][Languages]] + - [[#direnv][Direnv]] + - [[#better-scratch][Better scratch]] +- [[#dired][Dired]] + - [[#bindings][Bindings]] + - [[#dired-hacks][Dired hacks]] +- [[#sql][Sql]] +- [[#additional-apps][Additional apps]] + - [[#telegram-lol][Telegram lol]] + - [[#magit][Magit]] + - [[#exwm][EXWM]] + - [[#jupyter][Jupyter]] + - [[#orgnote][Orgnote]] + - [[#copilot][Copilot]] + +* Progs to load first +** Optimisations +#+begin_src emacs-lisp + (setq gc-cons-threshold 100000000) + (setq read-process-output-max (* 1024 1024)) +#+end_src +** elpaca +#+begin_src emacs-lisp + (defvar elpaca-installer-version 0.7) + (defvar elpaca-directory (expand-file-name "elpaca/" user-emacs-directory)) + (defvar elpaca-builds-directory (expand-file-name "builds/" elpaca-directory)) + (defvar elpaca-repos-directory (expand-file-name "repos/" elpaca-directory)) + (defvar elpaca-order '(elpaca :repo "https://github.com/progfolio/elpaca.git" + :ref nil + :files (:defaults "elpaca-test.el" (:exclude "extensions")) + :build (:not elpaca--activate-package))) + (let* ((repo (expand-file-name "elpaca/" elpaca-repos-directory)) + (build (expand-file-name "elpaca/" elpaca-builds-directory)) + (order (cdr elpaca-order)) + (default-directory repo)) + (add-to-list 'load-path (if (file-exists-p build) build repo)) + (unless (file-exists-p repo) + (make-directory repo t) + (when (< emacs-major-version 28) (require 'subr-x)) + (condition-case-unless-debug err + (if-let ((buffer (pop-to-buffer-same-window "*elpaca-bootstrap*")) + ((zerop (call-process "git" nil buffer t "clone" + (plist-get order :repo) repo))) + ((zerop (call-process "git" nil buffer t "checkout" + (or (plist-get order :ref) "--")))) + (emacs (concat invocation-directory invocation-name)) + ((zerop (call-process emacs nil buffer nil "-Q" "-L" "." "--batch" + "--eval" "(byte-recompile-directory \".\" 0 'force)"))) + ((require 'elpaca)) + ((elpaca-generate-autoloads "elpaca" repo))) + (progn (message "%s" (buffer-string)) (kill-buffer buffer)) + (error "%s" (with-current-buffer buffer (buffer-string)))) + ((error) (warn "%s" err) (delete-directory repo 'recursive)))) + (unless (require 'elpaca-autoloads nil t) + (require 'elpaca) + (elpaca-generate-autoloads "elpaca" repo) + (load "./elpaca-autoloads"))) + (add-hook 'after-init-hook #'elpaca-process-queues) + (elpaca `(,@elpaca-order)) + + (elpaca elpaca-use-package + ;; Enable :elpaca use-package keyword. + (elpaca-use-package-mode) + ;; Assume :elpaca t unless otherwise specified. + (setq elpaca-use-package-by-default t)) + + (elpaca-wait) +#+end_src +** Native comp warnings +#+begin_src emacs-lisp + (setq native-comp-async-report-warnings-errors nil) +#+end_src +** Save history +#+begin_src emacs-lisp + (use-package savehist :ensure nil + :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-negative-find () + "Find text backward." + (interactive) + (let ((current-prefix-arg -1)) + (call-interactively #'meow-find))) + + (defun meow-negative-till () + "Find text backward." + (interactive) + (let ((current-prefix-arg -1)) + (call-interactively #'meow-till))) + + (defun meow-setup () + (setq meow-cheatsheet-layout meow-cheatsheet-layout-qwerty) + (meow-motion-overwrite-define-key + '("j" . meow-next) + '("k" . meow-prev) + '("<escape>" . 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) + '("F" . meow-negative-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) + '("T" . meow-negative-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) + '("<escape>" . ignore))) + (meow-setup) + (meow-global-mode 1)) +#+end_src +** General keybindings +#+begin_src emacs-lisp + (use-package general + :demand t + :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" '(windmove-right :wk "") + "wj" '(windmove-down :wk "") + "wk" '(windmove-up :wk "") + "wh" '(windmove-left :wk "") + "wo" '(delete-other-windows :wk "") + ;; Files + "f" '(:ignore t :wk "Files") + "fc" '((lambda () (interactive) (find-file "~/.config/emacs/config.org")) :wk "Edit emacs config") + "fu" '(crux-sudo-edit :wk "Sudo edit file") + ;; Compilation + "r" '(recompile :wk "Recompile"))) + (elpaca-wait) +#+end_src +** Which key +#+begin_src emacs-lisp + (use-package which-key + :init + (which-key-mode)) +#+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 . "Sauce Code Pro Nerd Font"))) + (set-face-attribute 'default nil + :font "SauceCodePro Nerd Font" + :height 110 + :weight 'medium) + (set-face-attribute 'fixed-pitch nil + :font "SauceCodePro Nerd Font" + :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 + :config + ;; (setq catppuccin-flavor 'macchiato) + (load-theme 'catppuccin t)) + ;; (use-package monokai-pro-theme + ;; :config + ;; (load-theme 'monokai-pro-octagon t)) +#+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 + (defvar after-load-theme-hook nil + "Hook run after a color theme is loaded using `load-theme'.") + (defadvice load-theme (after run-after-load-theme-hook activate) + "Run `after-load-theme-hook'." + (run-hooks 'after-load-theme-hook)) + + (defadvice consult-theme (after run-after-load-theme-hook activate) + "Run `after-load-theme-hook'." + (run-hooks 'after-load-theme-hook)) + + (defun widen-mode-line () + "Widen the mode-line." + (interactive) + (set-face-attribute 'mode-line nil + :inherit 'mode-line + :box '(:line-width 8 :style flat-button)) + (set-face-attribute 'mode-line-inactive nil + :inherit 'mode-line-inactive + :box '(:line-width 8 :style flat-button))) + + (add-hook 'after-load-theme-hook 'widen-mode-line) + + (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 (:inherit 'font-lock-function-name-face :weight bold)))) + (mood-line-meow-insert ((t (:inherit 'font-lock-string-face :weight bold)))) + (mood-line-meow-keypad ((t (:inherit 'font-lock-keyword-face :weight bold)))) + (mood-line-meow-motion ((t (:inherit 'font-lock-constant-face :weight bold)))) + (mood-line-meow-normal ((t (:inherit 'font-lock-variable-use-face :weight bold))))) +#+end_src +** Scroll +#+begin_src emacs-lisp + (setq scroll-margin 5 + scroll-conservatively 101 + mouse-wheel-progressive-speed nil) +#+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 'official) + (setq dashboard-center-content t) + (setq dashboard-items '((projects . 5) + (recents . 5) + (bookmarks . 5) + (registers . 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 +* Projects +#+begin_src emacs-lisp + (use-package projectile + :init + (projectile-mode) + :config + (define-key projectile-mode-map (kbd "C-c p") 'projectile-command-map)) +#+end_src +* Org mode +#+begin_src emacs-lisp + (add-hook 'org-mode-hook 'org-indent-mode) + (require 'org-tempo) + (use-package org-mode :ensure nil + :mode "\\.org\\'") +#+end_src +** Enabling toc +#+begin_src emacs-lisp + (use-package toc-org + :ghook 'org-mode-hook) +#+end_src +** Org bullets +#+begin_src emacs-lisp + (use-package org-bullets + :ghook 'org-mode-hook) +#+end_src +** Auto-tangle +#+begin_src emacs-lisp + (use-package org-auto-tangle + :ghook 'org-mode-hook) +#+end_src +** Org-download +#+begin_src emacs-lisp + (use-package org-download + :ghook 'org-mode-hook) +#+end_src +* Better UX +** Vertico +#+begin_src emacs-lisp + (use-package vertico + :init + (vertico-mode) + :general + (:keymaps '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 :ensure nil + :init + ;; Add prompt indicator to `completing-read-multiple'. + ;; We display [CRM<separator>], 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 + :general + ;; my binds + (:prefix "C-c" + "f r" 'consult-recent-file + "," 'consult-buffer) + + ;; general + (:prefix "C-c" + "k" 'consult-kmacro + "m" 'consult-man + "i" 'consult-info) + + ;; one lonely command that i dont use + (:prefix "C-x" + "M-:" 'consult-complex-command) + + ;; 'registers' and pop + ("M-#" 'consult-register-load + "M-'" 'consult-register-store + "M-y" 'consult-yank-pop) + + ;; 'goto' + (:prefix "M-g" + "" '(:ignore t :wk "consult goto") + "c" 'consult-compile-error + "f" 'consult-goto-line + "M-g" 'consult-goto-line + "o" 'consult-outline) + + ;; 'search' + (:prefix "M-s" + "" '(:ignore t :wk "consult search") + "d" 'consult-fd + "r" 'consult-ripgrep + "g" 'consult-git-grep + "l" 'consult-line + "L" 'consult-line-multi + "k" 'consult-keep-lines + "u" 'consult-focus-lines + "e" 'consult-isearch-history) + + ;; Isearch + (:prefix "M-s" :keymaps 'isearch-mode-map + "e" 'consult-isearch-history + "l" 'consult-line + "L" 'consult-line-multi) + (:keymaps 'isearch-mode-map + "M-e" 'consult-isearch-history + "M-r" 'consult-history) + + ;; Minibuffer history + (:keymaps 'minibufer-local-map + "M-s" 'consult-history + "M-r" 'consult-history) + :hook + (completion-list-mode . consult-preview-at-point-mode) + (eshell-mode . (lambda () + (keymap-set eshell-mode-map "M-h" 'consult-history))) + + :init + (setq register-preview-delay 0 + register-preview-function #'consult-register-format) + + (advice-add #'register-preview :override #'consult-register-window) + + :config + (consult-customize + consult-theme :preview-key '(:debounce 0.2 any) + 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-." + :preview-key '(:debounce 0.4 any)) + (setq consult-narrow-key "C-+")) + +#+end_src +*** Consult-lsp +#+begin_src emacs-lisp + (use-package consult-lsp + :after consult lsp + :general + (:keymaps 'lsp-mode-map :prefix "M-g" + "f" 'consult-lsp-diagnostics + "s" 'consult-lsp-symbols + "S" 'consult-lsp-file-symbols)) +#+end_src +*** Consult-dir +#+begin_src emacs-lisp + (use-package consult-dir + :ensure t + :general + (:prefix "C-x" :keymaps 'vertico-map + "C-d" '('consult-dir :keymaps nil) + "C-d" 'consult-dir + "C-j" 'consult-dir-jump-file)) +#+end_src +** Embark +#+begin_src emacs-lisp + (use-package embark + :ensure t + + :bind + (("C-." . embark-act) ;; pick some comfortable binding + ("C-;" . embark-dwim) ;; good alternative: M-. + ("C-h B" . embark-bindings)) ;; alternative for `describe-bindings' + + :init + + ;; Optionally replace the key help with a completing-read interface + (setq prefix-help-command #'embark-prefix-help-command) + + ;; Show the Embark target at point via Eldoc. You may adjust the + ;; Eldoc strategy, if you want to see the documentation from + ;; multiple providers. Beware that using this can be a little + ;; jarring since the message shown in the minibuffer can be more + ;; than one line, causing the modeline to move up and down: + + ;; (add-hook 'eldoc-documentation-functions #'embark-eldoc-first-target) + ;; (setq eldoc-documentation-strategy #'eldoc-documentation-compose-eagerly) + + :config + + ;; Hide the mode line of the Embark live/completions buffers + (add-to-list 'display-buffer-alist + '("\\`\\*Embark Collect \\(Live\\|Completions\\)\\*" + nil + (window-parameters (mode-line-format . none))))) + + ;; Consult users will also want the embark-consult package. + (use-package embark-consult + :ensure t ; only need to install it, embark loads it after consult if found + :hook config.el + (embark-collect-mode . consult-preview-at-point-mode)) +#+end_src +** Pairs +#+begin_src emacs-lisp + (electric-pair-mode 1) +#+end_src +*** Debugging +#+begin_src emacs-lisp + (use-package dape + :config + (setq dape-cwd-fn 'projectile-project-root)) +#+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 +*** Better other-window +#+begin_src emacs-lisp + (use-package ace-window + :bind (("C-x o" . ace-window) + ("C-c w w" . ace-window))) +#+end_src +*** Undo Tree +#+begin_src emacs-lisp + (use-package vundo + :custom + (vundo-glyph-alist vundo-unicode-symbols) + (vundo-compact-display t)) +#+end_src +* Eshell +#+begin_src emacs-lisp + (add-hook 'eshell-mode-hook + (lambda () + (setq-local corfu-auto nil) + (corfu-mode))) + (add-to-list 'display-buffer-alist + '("*eshell*" + (display-buffer-reuse-window display-buffer-at-bottom) + (window-height . 0.35))) +#+end_src +** Fish completions +#+begin_src emacs-lisp + (use-package fish-completion + :hook (eshell-mode . fish-completion-mode)) +#+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 +* LSP +#+begin_src emacs-lisp + (use-package lsp-mode + :custom + (lsp-completion-provider :none) + :init + (defun lsp-mode-setup-completion () + (setf (alist-get 'styles (alist-get 'lsp-capf completion-category-defaults)) + '(orderless))) + + :hook + (lsp-completion-mode . lsp-mode-setup-completion)) + + + (setq lsp-sqls-workspace-config-path nil + lsp-sqls-connections + '(((driver . "postgresql") (dataSourceName . "host=127.0.0.1 port=38746 user=sirius_2024 password=changed dbname=postgres sslmode=disable")))) +#+end_src +** Flycheck +#+begin_src emacs-lisp + (use-package flycheck + :init + (global-flycheck-mode) + :config + (add-to-list 'display-buffer-alist + '("\\*Flycheck" + (display-buffer-reuse-window display-buffer-at-bottom) + (reusable-frames . visible) + (window-height . 0.35)))) +#+end_src +** lsp-ui +#+begin_src emacs-lisp + (use-package lsp-ui + :custom + (lsp-ui-doc-show-with-mouse nil)) +#+end_src +** LSP-booster +#+begin_src emacs-lisp + (defun lsp-booster--advice-json-parse (old-fn &rest args) + "Try to parse bytecode instead of json." + (or + (when (equal (following-char) ?#) + (let ((bytecode (read (current-buffer)))) + (when (byte-code-function-p bytecode) + (funcall bytecode)))) + (apply old-fn args))) + (advice-add (if (progn (require 'json) + (fboundp 'json-parse-buffer)) + 'json-parse-buffer + 'json-read) + :around + #'lsp-booster--advice-json-parse) + + (defun lsp-booster--advice-final-command (old-fn cmd &optional test?) + "Prepend emacs-lsp-booster command to lsp CMD." + (let ((orig-result (funcall old-fn cmd test?))) + (if (and (not test?) ;; for check lsp-server-present? + (not (file-remote-p default-directory)) ;; see lsp-resolve-final-command, it would add extra shell wrapper + lsp-use-plists + (not (functionp 'json-rpc-connection)) ;; native json-rpc + (executable-find "emacs-lsp-booster")) + (progn + (message "Using emacs-lsp-booster for %s!" orig-result) + (cons "emacs-lsp-booster" orig-result)) + orig-result))) + (advice-add 'lsp-resolve-final-command :around #'lsp-booster--advice-final-command) +#+end_src +** Corfu +#+begin_src emacs-lisp + (use-package corfu + :bind (:map corfu-map + ("M-j" . corfu-next) + ("M-k" . corfu-previous)) + :custom + (corfu-preselect 'prompt) + (corfu-auto t) + (corfu-popupinfo-delay 0.5) + (corfu-auto-delay 0.1) + (corfu-auto-prefix 2) + (corfu-count 16) + (corfu-max-width 120) + (corfu-scroll-margin 4) + (corfu-on-exact-match nil) + (tab-always-indent 'complete) + :init + (global-corfu-mode) + (corfu-popupinfo-mode)) + +#+end_src +*** Cape +#+begin_src emacs-lisp + (use-package cape + :custom + (dabbrev-ignored-buffer-modes '(archive-mode image-mode eshell-mode)) + :config + (advice-add #'lsp-completion-at-point :around #'cape-wrap-noninterruptible) + (advice-add #'lsp-completion-at-point :around #'cape-wrap-nonexclusive) + (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 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 tempel + :custom + (tempel-trigger-prefix "<") + :config + (add-to-list 'completion-at-point-functions #'tempel-complete)) + (use-package tempel-collection + :ensure t + :after tempel) + (use-package yasnippet) + (use-package yasnippet-snippets + :after yasnippet) + (use-package yasnippet-capf + :config + (add-to-list 'completion-at-point-functions #'yasnippet-capf)) +#+end_src +** Languages +*** Python +#+begin_src emacs-lisp + (use-package py-autopep8 + :hook (python-mode . py-autopep8-mode)) + (use-package lsp-pyright) +#+end_src +*** Rust +#+begin_src emacs-lisp + (use-package rust-mode + :mode "\\.rs\\'") + (use-package cargo-mode + :hook + (rust-ts-mode . cargo-minor-mode) + :config + (setq compilation-scroll-output t)) +#+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 :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 +#+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 +** Direnv +#+begin_src emacs-lisp + (use-package direnv + :config + (direnv-mode)) +#+end_src +** Better scratch +#+begin_src emacs-lisp + (use-package scratch) +#+end_src +* Dired +** Bindings +#+begin_src emacs-lisp + (use-package dired :ensure nil + :ensure nil + :commands (dired dired-jump) + :bind (:map dired-mode-map + ("h" . dired-up-directory) + ("l" . dired-find-file)) + :custom + (dired-listing-switches "-hal --group-directories-first")) +#+end_src +** Dired hacks +#+begin_src emacs-lisp + (use-package dired-ranger + :bind (:map dired-mode-map + ("r c" . dired-ranger-copy) + ("r m" . dired-ranger-move) + ("r p" . dired-ranger-paste) + ("\\" . dired-ranger-bookmark) + ("`" . dired-ranger-bookmark-visit))) + (use-package dired-narrow + :bind (:map dired-mode-map + ("n" . dired-narrow))) +#+end_src +** Dired quick sort +#+begin_src emacs-lisp + (use-package dired-quick-sort + :config + (dired-quick-sort-setup)) +#+end_src +** Async copy +#+begin_src emacs-lisp + (use-package dired-rsync + :general (:prefix "C-c" :keymaps 'dired-mode-map + "C-r" 'dired-rsync + "C-x" 'dired-rsync-transient)) +#+end_src +* Sql + +#+begin_src emacs-lisp + (use-package sql-indent + :hook (sql-mode . sqlind-minor-mode)) + + (setq sql-connection-alist + '(("postgres-sirius" + (sql-product 'postgres) + (sql-user "sirius_2024") + (sql-password "changed") + (sql-server "127.0.0.1") + (sql-database "postgres") + (sql-port 38746)))) + + (setq sql-sqlite-program "sqlite3") +#+end_src +* Additional apps +** Magit +#+begin_src emacs-lisp + (use-package magit + :bind (("C-c o g" . magit))) +#+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 + ;; :elpaca nil ;; (:host github :repo "copilot-emacs/copilot.el" :files ("dist" "*.el")) + ;; :hook (python-ts-mode . copilot-mode) + ;; :bind ("M-RET" . copilot-accept-completion)) +#+end_src +** Dash +#+begin_src emacs-lisp + (use-package consult-dash + :general + ("M-s D" 'consult-dash)) +#+end_src diff --git a/home-manager/homeModules/emacs/default.nix b/home-manager/homeModules/emacs/default.nix new file mode 100644 index 0000000..a95b81b --- /dev/null +++ b/home-manager/homeModules/emacs/default.nix @@ -0,0 +1,37 @@ +{ pkgs, config, lib, ... }: + +let + mkMutableSymlink = config.lib.meta.mkMutableSymlink; +in +{ + options = { + emacs.enable = lib.mkEnableOption "enable emacs"; + }; + config = lib.mkIf config.emacs.enable { + home.packages = with pkgs; with python311Packages; [ + # required dependencies + ripgrep + fd + tree-sitter + emacs-all-the-icons-fonts + libappindicator + poppler_utils + emacs-lsp-booster + nixd + sqlite + ]; + + programs.emacs = { + enable = true; + package = pkgs.emacs29-pgtk; + }; + + xdg.configFile = { + "emacs/config.org".source = mkMutableSymlink ./config.org; + "emacs/early-init.el".source = mkMutableSymlink ./early-init.el; + "emacs/init.el".source = mkMutableSymlink ./init.el; + "emacs/etc/tempel/templates.eld".source = mkMutableSymlink ./templates.eld; + "emacs/etc/eshell/aliases".source = mkMutableSymlink ./aliases; + }; + }; +} diff --git a/home-manager/homeModules/emacs/early-init.el b/home-manager/homeModules/emacs/early-init.el new file mode 100644 index 0000000..c767bdc --- /dev/null +++ b/home-manager/homeModules/emacs/early-init.el @@ -0,0 +1,6 @@ +(setq package-enable-at-startup nil) +(setenv "LSP_USE_PLISTS" "true") +(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/homeModules/emacs/init.el b/home-manager/homeModules/emacs/init.el new file mode 100644 index 0000000..6b3828c --- /dev/null +++ b/home-manager/homeModules/emacs/init.el @@ -0,0 +1,20 @@ +(org-babel-load-file + (expand-file-name + "config.org" + user-emacs-directory)) +(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. + '(auth-source-save-behavior nil) + '(custom-safe-themes + '("d77d6ba33442dd3121b44e20af28f1fae8eeda413b2c3d3b9f1315fbda021992" "80214de566132bf2c844b9dee3ec0599f65c5a1f2d6ff21a2c8309e6e70f9242" default)) + '(package-selected-packages '(marginalia embark-consult))) +(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. + ) +(put 'upcase-region 'disabled nil) diff --git a/home-manager/homeModules/emacs/templates.eld b/home-manager/homeModules/emacs/templates.eld new file mode 100644 index 0000000..7a06758 --- /dev/null +++ b/home-manager/homeModules/emacs/templates.eld @@ -0,0 +1,12 @@ +nix-mode + +(opt "{ pkgs, config, lib, ... }:" + n + n "{" + n> "options = {" + n> (p "option name" name) ".enable = lib.mkEnableOption \"enable " (s name) "\";" + n " };" + n> "config = lib.mkIf config." (s name) ".enable {" + n> q + n " };" + n "}") diff --git a/home-manager/homeModules/firefox/default.nix b/home-manager/homeModules/firefox/default.nix new file mode 100644 index 0000000..804e9c2 --- /dev/null +++ b/home-manager/homeModules/firefox/default.nix @@ -0,0 +1,119 @@ +{ pkgs, config, lib, inputs, ... }: + +{ + options = { + firefox.enable = lib.mkEnableOption "enable firefox"; + }; + config = lib.mkIf config.firefox.enable { + programs.firefox = { + enable = false; + profiles.nothing = { + isDefault = false; + id = 1; + }; + profiles.Betterfox = { + isDefault = true; + extensions = + let + nur = import inputs.nurpkgs.homeManagerModules.nurpkgs { + inherit pkgs; + nurpkgs = pkgs; + }; + in + with nur.repos.rycee.firefox-addons; [ + bitwarden + ublock-origin + switchyomega + sponsorblock + return-youtube-dislikes + firefox-color + tampermonkey + duckduckgo-privacy-essentials + sidebery + ]; + + extraConfig = + let + 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); + ''; + in + userConfig + configOverrides; + search = { + force = true; + 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" ]; + }; + }; + default = "Brave"; + }; + }; + }; + home.file."chrome" = { + source = ./userChrome.css; + target = ".mozilla/firefox/Betterfox/chrome/userChrome.css"; + }; + + }; +} diff --git a/home-manager/homeModules/firefox/user.js b/home-manager/homeModules/firefox/user.js new file mode 100644 index 0000000..cbf15bb --- /dev/null +++ b/home-manager/homeModules/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/homeModules/firefox/userChrome.css b/home-manager/homeModules/firefox/userChrome.css new file mode 100644 index 0000000..c4390dc --- /dev/null +++ b/home-manager/homeModules/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/homeModules/fish.nix b/home-manager/homeModules/fish.nix new file mode 100644 index 0000000..65d0d51 --- /dev/null +++ b/home-manager/homeModules/fish.nix @@ -0,0 +1,44 @@ +{ pkgs, config, lib, ... }: + +{ + options = { + fish.enable = lib.mkEnableOption "enable fish"; + }; + config = lib.mkIf config.fish.enable { + programs.direnv = { + enable = true; + nix-direnv.enable = true; + }; + + programs.fish = { + enable = true; + plugins = [ + { 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; } + ]; + interactiveShellInit = '' + set fish_greeting + pokemon-colorscripts -r --no-title + ''; + + 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"; + }; + }; + }; +} + + diff --git a/home-manager/homeModules/fuzzel.nix b/home-manager/homeModules/fuzzel.nix new file mode 100644 index 0000000..7fc8703 --- /dev/null +++ b/home-manager/homeModules/fuzzel.nix @@ -0,0 +1,28 @@ +{ pkgs, config, lib, ... }: + +{ + options = { + fuzzel.enable = lib.mkEnableOption "enable fuzzel"; + }; + + config = lib.mkIf config.fuzzel.enable { + programs.fuzzel = { + enable = true; + settings = { + colors = { + background = "1f1d2eff"; + text = "6e6a86ff"; + selection = "908caaff"; + selection-text = "1f1d2eff"; + }; + main = { + lines = 9; + terminal = "alacritty -e"; + vertical-pad = 0; + horizontal-pad = 0; + }; + border.width = 0; + }; + }; + }; +} diff --git a/home-manager/homeModules/hyprland.nix b/home-manager/homeModules/hyprland.nix new file mode 100644 index 0000000..3304636 --- /dev/null +++ b/home-manager/homeModules/hyprland.nix @@ -0,0 +1,204 @@ +{ pkgs, lib, config, ... }: + +{ + imports = [ + ./waybar.nix + ./rofi.nix + ./mako.nix + ]; + + options = { + hyprland.enable = lib.mkEnableOption "enable hyprland"; + }; + + config = lib.mkIf config.hyprland.enable { + waybar.enable = true; + rofi.enable = true; + mako.enable = true; + + home.packages = with pkgs; [ + swww + brightnessctl + grimblast + cliphist + polkit_gnome + xwaylandvideobridge + wl-clipboard + ]; + + xdg.portal = { + enable = true; + extraPortals = with pkgs; [ + xdg-desktop-portal-hyprland + ]; + configPackages = with pkgs; [ + xdg-desktop-portal-hyprland + ]; + }; + + wayland.windowManager.hyprland = { + enable = true; + package = pkgs.hyprland; + settings = { + "$scripts" = "${./attachments/hypr-scripts}"; + "$mainMod" = "SUPER"; + "$terminal" = "alacritty"; + + exec-once = [ + "emacs --daemon" + "swww-daemon" + "swww img ${config.wallpaper}" + ]; + + monitor = ",preferred,auto,1,mirror,eDP-1"; + + input = { + kb_layout = "us,ru"; + kb_options = "grp:win_space_toggle"; + touchpad = { + natural_scroll = "yes"; + disable_while_typing = "no"; + }; + sensitivity = 0.1; + }; + + general = { + gaps_in = 5; + gaps_out = 20; + border_size = 3; + layout = "dwindle"; + allow_tearing = false; + }; + + decoration = { + rounding = 7; + drop_shadow = "yes"; + shadow_range = 4; + shadow_render_power = 3; + blur = { + enabled = true; + size = 3; + passes = 1; + }; + }; + + animations = { + enabled = 1; + bezier = "overshot,0.13,0.99,0.29,1.1,"; + animation = [ + "fade,1,4,default" + "workspaces,1,4,default,fade" + "windows,1,4,overshot,popin 95%" + ]; + }; + + dwindle = { + pseudotile = "yes"; + preserve_split = "yes"; + }; + + master.new_is_master = true; + gestures.workspace_swipe = "on"; + misc.force_default_wallpaper = 1; + + windowrulev2 = [ + "float, title:^(Firrfox — Sharing Indicator)$" + "noborder, title:^(Firefox — Sharing Indicator)$" + "rounding 0, title:^(Firefox — Sharing Indicator)$" + "float, title:^(firefox)$, title:^(Picture-in-Picture)$" + "pin, title:^(firefox)$, title:^(Picture-in-Picture)$" + "float, title:^(Save File)$" + "pin, title:^(Save File)$" + "float, title:^(Torrent Options)$" + "pin, title:^(Torrent Options)$" + "opacity 0.0 override 0.0 override,class:^(xwaylandvideobridge)$" + "noanim,class:^(xwaylandvideobridge)$" + "noinitialfocus,class:^(xwaylandvideobridge)$" + "maxsize 1 1,class:^(xwaylandvideobridge)$" + "noblur,class:^(xwaylandvideobridge)$" + "windowdance,class:^(kompas.exe)$,title:^(RoamingWindow)$" + "stayfocused,class:^(kompas.exe)$,title:^(RoamingWindow)$" + ]; + + windowrule = [ + "windowdance,title:^(Rhythm Doctor)$" + "forceinput,title:^(Rhythm Doctor)$" + ]; + + layerrule = "blur, waybar"; + + bind = [ + "$mainMod, V, togglefloating, " + "$mainMod, P, pseudo," + "$mainMod, I, togglesplit," + "$mainMod, F, fullscreen, 0" + "$mainMod, M, fullscreen, 1" + "$mainMod SHIFT,F,fakefullscreen" + "$mainMod SHIFT, Q, killactive, " + "$mainMod SHIFT, E, exit," + + # Apps + "$mainMod, D, exec, killall rofi || rofi -show-icons -show drun" + "$mainMod, Q, exec, $terminal" + "$mainMod, B, exec, brave --enable-features=TouchpadOverscrollHistoryNavigation" + "$mainMod, T, exec, telegram-desktop" + "$mainMod, E, exec, emacsclient -c -a emacs" + "$mainMod CONTROL, E, exec, emacs" + "$mainMod SHIFT, Esc, exec, swww img ${config.wallpaper}" + + # Screenshooting + ", Print, exec, grimblast save screen" + "ALT, Print, exec, grimblast save active" + "SHIFT, Print, exec, grimblast save area" + "CONTROL, Print, exec, grimblast copy screen" + "ALT_CONTROL, Print, exec, grimblast copy active" + "CONTROL_SHIFT, Print, exec, grimblast copy area " + + # Volume + ",0x1008FF11,exec,wpctl set-volume @DEFAULT_SINK@ 5%-" + ",0x1008FF13,exec,wpctl set-volume @DEFAULT_SINK@ 5%+" + ",0x1008FF12,exec,wpctl set-mute @DEFAULT_SINK@ toggle" + ",XF86AudioMicMute, exec, wpctl set-mute @DEFAULT_SOURCE@ toggle" + + # Brightness + ",XF86MonBrightnessUp,exec,brightnessctl s +5%" + ",XF86MonBrightnessDown,exec,brightnessctl s 5%-" + + # Windows + "$mainMod, J, movefocus, d" + "$mainMod, K, movefocus, u" + "$mainMod, H, movefocus, l" + "$mainMod, L, movefocus, r" + "SUPER_SHIFT,J,movewindow,d" + "SUPER_SHIFT,K,movewindow,u" + "SUPER_SHIFT,H,movewindow,l" + "SUPER_SHIFT,L,movewindow,r" + "$mainMod, S, togglespecialworkspace, magic" + "$mainMod SHIFT, S, movetoworkspace, special:magic" + "$mainMod, mouse_down, workspace, e+1" + "$mainMod, mouse_up, workspace, e-1" + ] ++ ( + # workspaces + # binds $mod + [shift +] {1..10} to [move to] workspace {1..10} + builtins.concatLists (builtins.genList ( + x: let + ws = let + c = (x + 1) / 10; + in + builtins.toString (x + 1 - (c * 10)); + in [ + "$mainMod, ${ws}, workspace, ${toString (x + 1)}" + "$mainMod SHIFT, ${ws}, movetoworkspacesilent, ${toString (x + 1)}" + ] + ) + 10) + ); + + bindm = [ + "$mainMod, mouse:272, movewindow" + "$mainMod, mouse:273, resizewindow" + ]; + }; + }; + }; +} diff --git a/home-manager/homeModules/mako.nix b/home-manager/homeModules/mako.nix new file mode 100644 index 0000000..b88687f --- /dev/null +++ b/home-manager/homeModules/mako.nix @@ -0,0 +1,21 @@ +{ pkgs, config, lib, ... }: + +{ + options = { + mako.enable = lib.mkEnableOption "enable mako"; + }; + + config = lib.mkIf config.mako.enable { + services.mako = { + enable = true; + anchor = "bottom-right"; + # backgroundColor = "#1f1d2e"; + # borderColor = "#e0def4"; + # textColor = "#e0def4"; + defaultTimeout = 5000; + borderSize = 3; + borderRadius = 7; + # font = "Rubik 11"; + }; + }; +} diff --git a/home-manager/homeModules/niri.nix b/home-manager/homeModules/niri.nix new file mode 100644 index 0000000..81a3352 --- /dev/null +++ b/home-manager/homeModules/niri.nix @@ -0,0 +1,159 @@ +{ pkgs, config, lib, inputs, ... }: + +{ + imports = [ + ./fuzzel.nix + inputs.niri.homeModules.niri + ]; + + options = { + niri.enable = lib.mkEnableOption "enable niri config"; + }; + + config = lib.mkIf config.niri.enable { + fuzzel.enable = true; + + programs.niri = { + settings = { + input = { + keyboard.xkb = { + layout = "us,ru"; + options = "grp:win_space_toggle,compose:ralt,ctrl:nocaps"; + }; + touchpad = { + tap = true; + dwt = true; + dwtp = true; + natural-scroll = true; + }; + warp-mouse-to-focus = true; + focus-follows-mouse = true; + }; + cursor = { + theme = "Bibata-Modern-Ice"; + size = 24; + }; + layout = { + gaps = 16; + center-focused-column = "never"; + preset-column-widths = [ + { proportion = 0.33333; } + { proportion = 0.5; } + { proportion = 0.66667; } + ]; + border = { + enable = true; + }; + focus-ring.enable = false; + }; + prefer-no-csd = true; + binds = with config.lib.niri.actions; { + "Mod+Q".action.spawn = "alacritty"; + "Mod+D".action.spawn = [ "rofi --show drun" ]; + "Mod+B".action.spawn = [ "brave" "--enable-features=TouchpadOverscrollHistoryNavigation" ]; + "Mod+E".action.spawn = [ "emacsclient" "-c" "-a" "emacs" ]; + "Super+Alt+L".action.spawn = "swaylock"; + "XF86AudioRaiseVolume".action.spawn = [ "wpctl" "set-volume" "@DEFAULT_AUDIO_SINK@" "0.05+" ]; + "XF86AudioLowerVolume".action.spawn = [ "wpctl" "set-volume" "@DEFAULT_AUDIO_SINK@" "0.05-" ]; + "XF86AudioMute".action.spawn = [ "wpctl" "set-mute" "@DEFAULT_AUDIO_SINK@" "toggle" ]; + "XF86AudioMicMute".action.spawn = [ "wpctl" "set-mute" "@DEFAULT_AUDIO_SOURCE@" "toggle" ]; + "XF86MonBrightnessUp".action.spawn = [ "brightnessctl" "s" "+5%" ]; + "XF86MonBrightnessDown".action.spawn = [ "brightnessctl" "s" "5%-" ]; + "Mod+Shift+Slash".action = show-hotkey-overlay; + "Mod+Shift+Q".action = close-window; + "Mod+Left".action = focus-column-left; + "Mod+Down".action = focus-window-down; + "Mod+Up".action = focus-window-up; + "Mod+Right".action = focus-column-right; + "Mod+H".action = focus-column-left; + "Mod+J".action = focus-window-down; + "Mod+K".action = focus-window-up; + "Mod+L".action = focus-column-right; + "Mod+Shift+Left".action = move-column-left; + "Mod+Shift+Down".action = move-window-down; + "Mod+Shift+Up".action = move-window-up; + "Mod+Shift+Right".action = move-column-right; + "Mod+Shift+H".action = move-column-left; + "Mod+Shift+J".action = move-window-down; + "Mod+Shift+K".action = move-window-up; + "Mod+Shift+L".action = move-column-right; + "Mod+Home".action = focus-column-first; + "Mod+End".action = focus-column-last; + "Mod+Ctrl+Home".action = move-column-to-first; + "Mod+Ctrl+End".action = move-column-to-last; + "Mod+Ctrl+Left".action = focus-monitor-left; + "Mod+Ctrl+Down".action = focus-monitor-down; + "Mod+Ctrl+Up".action = focus-monitor-up; + "Mod+Ctrl+Right".action = focus-monitor-right; + "Mod+Ctrl+H".action = focus-monitor-left; + "Mod+Ctrl+J".action = focus-monitor-down; + "Mod+Ctrl+K".action = focus-monitor-up; + "Mod+Ctrl+L".action = focus-monitor-right; + "Mod+Shift+Ctrl+Left".action = move-column-to-monitor-left; + "Mod+Shift+Ctrl+Down".action = move-column-to-monitor-down; + "Mod+Shift+Ctrl+Up".action = move-column-to-monitor-up; + "Mod+Shift+Ctrl+Right".action = move-column-to-monitor-right; + "Mod+Shift+Ctrl+H".action = move-column-to-monitor-left; + "Mod+Shift+Ctrl+J".action = move-column-to-monitor-down; + "Mod+Shift+Ctrl+K".action = move-column-to-monitor-up; + "Mod+Shift+Ctrl+L".action = move-column-to-monitor-right; + "Mod+Page_Down".action = focus-workspace-down; + "Mod+Page_Up".action = focus-workspace-up; + "Mod+U".action = focus-workspace-down; + "Mod+I".action = focus-workspace-up; + "Mod+Ctrl+Page_Down".action = move-column-to-workspace-down; + "Mod+Ctrl+Page_Up".action = move-column-to-workspace-up; + "Mod+Ctrl+U".action = move-column-to-workspace-down; + "Mod+Ctrl+I".action = move-column-to-workspace-up; + "Mod+Shift+Page_Down".action = move-workspace-down; + "Mod+Shift+Page_Up".action = move-workspace-up; + "Mod+Shift+U".action = move-workspace-down; + "Mod+WheelScrollRight".action = focus-column-right; + "Mod+WheelScrollLeft".action = focus-column-left; + "Mod+Ctrl+WheelScrollRight".action = move-column-right; + "Mod+Ctrl+WheelScrollLeft".action = move-column-left; + "Mod+Shift+WheelScrollDown".action = focus-column-right; + "Mod+Shift+WheelScrollUp".action = focus-column-left; + "Mod+Ctrl+Shift+WheelScrollDown".action = move-column-right; + "Mod+Ctrl+Shift+WheelScrollUp".action = move-column-left; + + "Mod+1".action.focus-workspace = 1; + "Mod+2".action.focus-workspace = 2; + "Mod+3".action.focus-workspace = 3; + "Mod+4".action.focus-workspace = 4; + "Mod+5".action.focus-workspace = 5; + "Mod+6".action.focus-workspace = 6; + "Mod+7".action.focus-workspace = 7; + "Mod+8".action.focus-workspace = 8; + "Mod+9".action.focus-workspace = 9; + "Mod+Shift+1".action.move-column-to-workspace = 1; + "Mod+Shift+2".action.move-column-to-workspace = 2; + "Mod+Shift+3".action.move-column-to-workspace = 3; + "Mod+Shift+4".action.move-column-to-workspace = 4; + "Mod+Shift+5".action.move-column-to-workspace = 5; + "Mod+Shift+6".action.move-column-to-workspace = 6; + "Mod+Shift+7".action.move-column-to-workspace = 7; + "Mod+Shift+8".action.move-column-to-workspace = 8; + "Mod+Shift+9".action.move-column-to-workspace = 9; + "Mod+Comma".action = consume-window-into-column; + "Mod+Period".action = expel-window-from-column; + "Mod+BracketLeft".action = consume-or-expel-window-left; + "Mod+BracketRight".action = consume-or-expel-window-right; + "Mod+R".action = switch-preset-column-width; + "Mod+M".action = maximize-column; + "Mod+F".action = fullscreen-window; + "Mod+C".action = center-column; + "Mod+Minus".action.set-column-width = "-10%"; + "Mod+Equal".action.set-column-width = "+10%"; + "Mod+Shift+Minus".action.set-window-height = "-10%"; + "Mod+Shift+Equal".action.set-window-height = "+10%"; + "Print".action = screenshot; + "Ctrl+Print".action = screenshot-screen; + "Alt+Print".action = screenshot-window; + "Mod+Shift+E".action = quit; + "Mod+Shift+P".action = power-off-monitors; + }; + }; + }; + }; +} diff --git a/home-manager/homeModules/nvim.nix b/home-manager/homeModules/nvim.nix new file mode 100644 index 0000000..5339326 --- /dev/null +++ b/home-manager/homeModules/nvim.nix @@ -0,0 +1,193 @@ +{ pkgs, config, lib, helpers, inputs, ... }: + +{ + imports = [ + inputs.nixvim.homeManagerModules.nixvim + ]; + + options = { + nvim.enable = lib.mkEnableOption "enable nvim"; + }; + + config = lib.mkIf config.nvim.enable { + programs.nixvim = { + opts = { + number = true; + relativenumber = true; + tabstop = 4; + softtabstop = 4; + smartindent = true; + expandtab = true; + scrolloff = 5; + }; + colorschemes.catppuccin.enable = true; + globals.mapleader = " "; + + keymaps = [ + # Most used + { + action = ":Telescope file_browser<CR>"; + key = "<leader>."; + } + { + action = ":Telescope buffers sort_lastused=true<CR>"; + key = "<leader>,"; + } + # File related + { + action = ":Telescope frecency<CR>"; + key = "<leader>fr"; + } + { + action = ":Telescope find_files<CR>"; + key = "<leader>ff"; + } + { + action = ":Telescope find_files cwd=~/nixfiles<CR>"; + key = "<leader>fn"; + } + { + action = ":Telescope projects<CR>"; + key = "<leader>op"; + } + # Terminal + { + action = ":ToggleTerm direction=vertical<CR>"; + key = "<leader>ot"; + } + { + action = ":ToggleTerm direction=horizontal<CR>"; + key = "<leader>oT"; + } + { + action = "<C-\\><C-N>"; + key = "<esc>"; + mode = "t"; + } + ]; + autoCmd = [ + { + event = "FileType"; + pattern = [ "sql" "mysql" "plsql" ]; + command = "lua require('cmp').setup.buffer({ sources = {{ name = 'vim-dadbod-completion' }} })"; + } + ]; + + # lsps + plugins = { + lsp = { + enable = true; + servers = { + pyright.enable = true; + nixd.enable = true; + }; + }; + + cmp = { + enable = true; + autoEnableSources = true; + settings = { + snippet.expand = "luasnip"; + sources = [ + {name = "nvim_lsp";} + {name = "luasnip";} + {name = "path";} + {name = "buffer";} + ]; + mapping = { + "<CR>" = "cmp.mapping.confirm({select = false})"; + "<M-j>" = "cmp.mapping.select_next_item(cmp_select_opts)"; + "<M-k>" = "cmp.mapping.select_prev_item(cmp_select_opts)"; + "<Tab>" = "cmp.mapping.confirm({select = true})"; + }; + }; + }; + + luasnip.enable = true; + }; + + plugins = { + nix.enable = true; + comment-nvim.enable = true; + nvim-autopairs.enable = true; + intellitab.enable = true; + project-nvim.enable = true; + undotree.enable = true; + treesitter = { + enable = true; + indent = true; + nixvimInjections = true; + }; + codeium-vim = { + enable = true; + settings = { + disable_binds = true; + manual = true; + no_map_tab = true; + }; + keymaps.accept = "<M-Tab>"; + }; + toggleterm = { + enable = true; + autochdir = true; + persistSize = false; + size = "function(term) + if term.direction == 'horizontal' then + return 15 + elseif term.direction == 'vertical' then + return vim.o.columns * 0.4 + end + end"; + }; + telescope = { + enable = true; + defaults = { + mappings = { + i = { + "<M-j>" = "move_selection_next"; + "<M-k>" = "move_selection_previous"; + "<M-m>" = "toggle_selection"; + "<Tab>" = "select_default"; + }; + n = { + "<M-m>" = "toggle_selection"; + "<M-j>" = "move_selection_next"; + "<M-k>" = "move_selection_previous"; + "<Tab>" = "select_default"; + }; + }; + }; + extensions = { + file-browser = { + enable = true; + path = "%:p:h"; + }; + frecency.enable = true; + project-nvim.enable = true; + }; + }; + lualine = { + enable = true; + sectionSeparators = { + left = " "; + right = " "; + }; + componentSeparators = { + left = " "; + right = " "; + }; + }; + }; + extraPlugins = with pkgs; with vimPlugins; [ + vim-dadbod-ui + vim-dadbod-completion + direnv-vim + ]; + extraPackages = with pkgs; [ + sqls + ]; + extraConfigLua = builtins.readFile ./extralua.lua; + }; + }; +} + diff --git a/home-manager/homeModules/picom.nix b/home-manager/homeModules/picom.nix new file mode 100644 index 0000000..4ee50de --- /dev/null +++ b/home-manager/homeModules/picom.nix @@ -0,0 +1,53 @@ +{ pkgs, config, lib, ... }: + +{ + options = { + picom.enable = lib.mkEnableOption "enable picom"; + }; + + config = lib.mkIf config.picom.enable { + services.picom = { + enable = true; + settings = { + fading = true; + fade-in-step = 0.05; + fade-out-step = 0.05; + blur-background = false; + corner-radius = 8; + # blur = { + # method = "dual_kawase"; + # size = 12; + # deviation = false; + # strength = 2; + # kern = "3x3box"; + # }; + backend = "glx"; + vsync = true; + mark = { + wmwin-focused = true; + overdir-focused = true; + }; + detect = { + rounded-corners = true; + client-opacity = true; + transient = true; + }; + use-ewmh-active-win = true; + glx-no-stencil = true; + use-damage = true; + }; + wintypes = { + tooltip = { + fade = true; + shadow = true; + full-shadow = false; + blur = false; + focus = true; + }; + dock = { + shadow = false; + }; + }; + }; + }; +} diff --git a/home-manager/homeModules/ranger/commands.py b/home-manager/homeModules/ranger/commands.py new file mode 100644 index 0000000..a41d42f --- /dev/null +++ b/home-manager/homeModules/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<depth>] <query> + Executes "fd -d<depth> <query>" in the current directory and focuses the + first match. <depth> 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/homeModules/ranger/default.nix b/home-manager/homeModules/ranger/default.nix new file mode 100644 index 0000000..7e5fb88 --- /dev/null +++ b/home-manager/homeModules/ranger/default.nix @@ -0,0 +1,17 @@ +{ pkgs, config, lib, ... }: + +{ + options = { + ranger.enable = lib.mkEnableOption "enable ranger"; + }; + config = lib.mkIf config.ranger.enable { + home.packages = with pkgs; [ ranger ]; + 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/homeModules/ranger/plugins/__init__.py b/home-manager/homeModules/ranger/plugins/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/home-manager/homeModules/ranger/plugins/__init__.py diff --git a/home-manager/homeModules/ranger/plugins/__pycache__/__init__.cpython-310.pyc b/home-manager/homeModules/ranger/plugins/__pycache__/__init__.cpython-310.pyc Binary files differnew file mode 100644 index 0000000..1a26aa3 --- /dev/null +++ b/home-manager/homeModules/ranger/plugins/__pycache__/__init__.cpython-310.pyc diff --git a/home-manager/homeModules/ranger/plugins/__pycache__/__init__.cpython-311.pyc b/home-manager/homeModules/ranger/plugins/__pycache__/__init__.cpython-311.pyc Binary files differnew file mode 100644 index 0000000..87b2e7f --- /dev/null +++ b/home-manager/homeModules/ranger/plugins/__pycache__/__init__.cpython-311.pyc diff --git a/home-manager/homeModules/ranger/plugins/__pycache__/fd.cpython-311.pyc b/home-manager/homeModules/ranger/plugins/__pycache__/fd.cpython-311.pyc Binary files differnew file mode 100644 index 0000000..146af23 --- /dev/null +++ b/home-manager/homeModules/ranger/plugins/__pycache__/fd.cpython-311.pyc diff --git a/home-manager/homeModules/ranger/plugins/__pycache__/quit_cd_wd.cpython-310.pyc b/home-manager/homeModules/ranger/plugins/__pycache__/quit_cd_wd.cpython-310.pyc Binary files differnew file mode 100644 index 0000000..49d1db9 --- /dev/null +++ b/home-manager/homeModules/ranger/plugins/__pycache__/quit_cd_wd.cpython-310.pyc diff --git a/home-manager/homeModules/ranger/plugins/__pycache__/quit_cd_wd.cpython-311.pyc b/home-manager/homeModules/ranger/plugins/__pycache__/quit_cd_wd.cpython-311.pyc Binary files differnew file mode 100644 index 0000000..7b3ac1c --- /dev/null +++ b/home-manager/homeModules/ranger/plugins/__pycache__/quit_cd_wd.cpython-311.pyc diff --git a/home-manager/homeModules/ranger/plugins/quit_cd_wd.py b/home-manager/homeModules/ranger/plugins/quit_cd_wd.py new file mode 100644 index 0000000..e47837f --- /dev/null +++ b/home-manager/homeModules/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/homeModules/ranger/plugins/ranger_fzf_filter/.gitignore b/home-manager/homeModules/ranger/plugins/ranger_fzf_filter/.gitignore new file mode 100644 index 0000000..846dc44 --- /dev/null +++ b/home-manager/homeModules/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/homeModules/ranger/plugins/ranger_fzf_filter/LICENSE b/home-manager/homeModules/ranger/plugins/ranger_fzf_filter/LICENSE new file mode 100644 index 0000000..bd840f1 --- /dev/null +++ b/home-manager/homeModules/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/homeModules/ranger/plugins/ranger_fzf_filter/README.md b/home-manager/homeModules/ranger/plugins/ranger_fzf_filter/README.md new file mode 100644 index 0000000..6a65e17 --- /dev/null +++ b/home-manager/homeModules/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/homeModules/ranger/plugins/ranger_fzf_filter/__init__.py b/home-manager/homeModules/ranger/plugins/ranger_fzf_filter/__init__.py new file mode 100644 index 0000000..b5d5b46 --- /dev/null +++ b/home-manager/homeModules/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/homeModules/ranger/plugins/ranger_fzf_filter/command.py b/home-manager/homeModules/ranger/plugins/ranger_fzf_filter/command.py new file mode 100644 index 0000000..92aee83 --- /dev/null +++ b/home-manager/homeModules/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 <query> + + 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/homeModules/ranger/plugins/ranger_fzf_filter/filter.py b/home-manager/homeModules/ranger/plugins/ranger_fzf_filter/filter.py new file mode 100644 index 0000000..3d12756 --- /dev/null +++ b/home-manager/homeModules/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/homeModules/ranger/rc.conf b/home-manager/homeModules/ranger/rc.conf new file mode 100644 index 0000000..271d239 --- /dev/null +++ b/home-manager/homeModules/ranger/rc.conf @@ -0,0 +1,12 @@ +map f console fzf_filter%space +map x quit_cd_wd +map X quitall_cd_wd +map <alt>/ console fd_search -d5%space +map <alt>n fd_next +map <alt>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/homeModules/ranger/rifle.conf b/home-manager/homeModules/ranger/rifle.conf new file mode 100644 index 0000000..3b565af --- /dev/null +++ b/home-manager/homeModules/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: +# <condition1> , <condition2> , ... = 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 <regexp> | The regexp matches $1 +# ext <regexp> | The regexp matches the extension of $1 +# mime <regexp> | The regexp matches the mime type of $1 +# name <regexp> | The regexp matches the basename of $1 +# path <regexp> | The regexp matches the absolute path of $1 +# has <program> | The program is installed (i.e. located in $PATH) +# env <variable> | The environment variable "variable" is non-empty +# file | $1 is a file +# directory | $1 is a directory +# number <n> | 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 <flags> | Change how the program is run. See below. +# label <label> | Assign a label or name to the command so it can +# | be started with :open_with <label> in ranger +# | or `rifle -p <label>` in the standalone executable. +# else | Always true. +# +# Flags are single characters which slightly transform the command: +# f | Fork the program, make it run in the background. +# | New command = setsid $command >& /dev/null & +# r | Execute the command with root permissions +# | New command = sudo $command +# t | Run the program in a new terminal. If $TERMCMD is not defined, +# | rifle will attempt to extract it from $TERM. +# | New command = $TERMCMD -e $command +# Note: The "New command" serves only as an illustration, the exact +# implementation may differ. +# Note: When using rifle in ranger, there is an additional flag "c" for +# only running the current file even if you have marked multiple files. + +#------------------------------------------- +# Websites +#------------------------------------------- +# Rarely installed browsers get higher priority; It is assumed that if you +# install a rare browser, you probably use it. Firefox/konqueror/w3m on the +# other hand are often only installed as fallback browsers. +ext x?html?, has surf, X, flag f = surf -- file://"$1" +ext x?html?, has vimprobable, X, flag f = vimprobable -- "$@" +ext x?html?, has vimprobable2, X, flag f = vimprobable2 -- "$@" +ext x?html?, has qutebrowser, X, flag f = qutebrowser -- "$@" +ext x?html?, has dwb, X, flag f = dwb -- "$@" +ext x?html?, has jumanji, X, flag f = jumanji -- "$@" +ext x?html?, has luakit, X, flag f = luakit -- "$@" +ext x?html?, has uzbl, X, flag f = uzbl -- "$@" +ext x?html?, has uzbl-tabbed, X, flag f = uzbl-tabbed -- "$@" +ext x?html?, has uzbl-browser, X, flag f = uzbl-browser -- "$@" +ext x?html?, has uzbl-core, X, flag f = uzbl-core -- "$@" +ext x?html?, has midori, X, flag f = midori -- "$@" +ext x?html?, has opera, X, flag f = opera -- "$@" +ext x?html?, has firefox, X, flag f = firefox -- "$@" +ext x?html?, has seamonkey, X, flag f = seamonkey -- "$@" +ext x?html?, has iceweasel, X, flag f = iceweasel -- "$@" +ext x?html?, has chromium-browser, X, flag f = chromium-browser -- "$@" +ext x?html?, has chromium, X, flag f = chromium -- "$@" +ext x?html?, has google-chrome, X, flag f = google-chrome -- "$@" +ext x?html?, has epiphany, X, flag f = epiphany -- "$@" +ext x?html?, has konqueror, X, flag f = konqueror -- "$@" +ext x?html?, has elinks, terminal = elinks "$@" +ext x?html?, has links2, terminal = links2 "$@" +ext x?html?, has links, terminal = links "$@" +ext x?html?, has lynx, terminal = lynx -- "$@" +ext x?html?, has w3m, terminal = w3m "$@" + +#------------------------------------------- +# Misc +#------------------------------------------- +# Define the "editor" for text files as first action +mime ^text, label editor = ${VISUAL:-$EDITOR} -- "$@" +mime ^text, label pager = "$PAGER" -- "$@" +!mime ^text, label editor, ext xml|json|csv|tex|py|pl|rb|js|sh|php = ${VISUAL:-$EDITOR} -- "$@" +!mime ^text, label pager, ext xml|json|csv|tex|py|pl|rb|js|sh|php = "$PAGER" -- "$@" + +ext 1 = man "$1" +ext s[wmf]c, has zsnes, X = zsnes "$1" +ext s[wmf]c, has snes9x-gtk,X = snes9x-gtk "$1" +ext nes, has fceux, X = fceux "$1" +ext exe = wine "$1" +name ^[mM]akefile$ = make + +#-------------------------------------------- +# Scripts +#------------------------------------------- +ext py = python -- "$1" +ext pl = perl -- "$1" +ext rb = ruby -- "$1" +ext js = node -- "$1" +ext sh = sh -- "$1" +ext php = php -- "$1" + +#-------------------------------------------- +# Audio without X +#------------------------------------------- +mime ^audio|ogg$, terminal, has mpv = mpv -- "$@" +mime ^audio|ogg$, terminal, has mplayer2 = mplayer2 -- "$@" +mime ^audio|ogg$, terminal, has mplayer = mplayer -- "$@" +ext midi?, terminal, has wildmidi = wildmidi -- "$@" + +#-------------------------------------------- +# Video/Audio with a GUI +#------------------------------------------- +mime ^video|audio, has gmplayer, X, flag f = gmplayer -- "$@" +mime ^video|audio, has smplayer, X, flag f = smplayer "$@" +mime ^video, has mpv, X, flag f = mpv -- "$@" +mime ^video, has mpv, X, flag f = mpv --fs -- "$@" +mime ^video, has mplayer2, X, flag f = mplayer2 -- "$@" +mime ^video, has mplayer2, X, flag f = mplayer2 -fs -- "$@" +mime ^video, has mplayer, X, flag f = mplayer -- "$@" +mime ^video, has mplayer, X, flag f = mplayer -fs -- "$@" +mime ^video|audio, has vlc, X, flag f = vlc -- "$@" +mime ^video|audio, has totem, X, flag f = totem -- "$@" +mime ^video|audio, has totem, X, flag f = totem --fullscreen -- "$@" + +#-------------------------------------------- +# Video without X +#------------------------------------------- +mime ^video, terminal, !X, has mpv = mpv -- "$@" +mime ^video, terminal, !X, has mplayer2 = mplayer2 -- "$@" +mime ^video, terminal, !X, has mplayer = mplayer -- "$@" + +#------------------------------------------- +# Documents +#------------------------------------------- +ext pdf, has llpp, X, flag f = llpp "$@" +ext pdf, has zathura, X, flag f = zathura -- "$@" +ext pdf, has mupdf, X, flag f = mupdf "$@" +ext pdf, has mupdf-x11,X, flag f = mupdf-x11 "$@" +ext pdf, has apvlv, X, flag f = apvlv -- "$@" +ext pdf, has xpdf, X, flag f = xpdf -- "$@" +ext pdf, has evince, X, flag f = evince -- "$@" +ext pdf, has atril, X, flag f = atril -- "$@" +ext pdf, has okular, X, flag f = okular -- "$@" +ext pdf, has epdfview, X, flag f = epdfview -- "$@" +ext pdf, has qpdfview, X, flag f = qpdfview "$@" +ext pdf, has open, X, flag f = open "$@" + +ext docx?, has catdoc, terminal = catdoc -- "$@" | "$PAGER" + +ext sxc|xlsx?|xlt|xlw|gnm|gnumeric, has gnumeric, X, flag f = gnumeric -- "$@" +ext sxc|xlsx?|xlt|xlw|gnm|gnumeric, has kspread, X, flag f = kspread -- "$@" +ext pptx?|od[dfgpst]|docx?|sxc|xlsx?|xlt|xlw|gnm|gnumeric, has libreoffice, X, flag f = libreoffice "$@" +ext pptx?|od[dfgpst]|docx?|sxc|xlsx?|xlt|xlw|gnm|gnumeric, has soffice, X, flag f = soffice "$@" +ext pptx?|od[dfgpst]|docx?|sxc|xlsx?|xlt|xlw|gnm|gnumeric, has ooffice, X, flag f = ooffice "$@" + +ext djvu, has zathura,X, flag f = zathura -- "$@" +ext djvu, has evince, X, flag f = evince -- "$@" +ext djvu, has atril, X, flag f = atril -- "$@" +ext djvu, has djview, X, flag f = djview -- "$@" + +ext epub, has ebook-viewer, X, flag f = ebook-viewer -- "$@" +ext epub, has zathura, X, flag f = zathura -- "$@" +ext epub, has mupdf, X, flag f = mupdf -- "$@" +ext mobi, has ebook-viewer, X, flag f = ebook-viewer -- "$@" + +ext cbr, has zathura, X, flag f = zathura -- "$@" +ext cbz, has zathura, X, flag f = zathura -- "$@" + +#------------------------------------------- +# Images +#------------------------------------------- +mime ^image/svg, has inkscape, X, flag f = inkscape -- "$@" +mime ^image/svg, has display, X, flag f = display -- "$@" + +mime ^image, has geeqie, X, flag f = geeqie -- "$@" +mime ^image, has imv, X, flag f = imv -- "$@" +mime ^image, has pqiv, X, flag f = pqiv -- "$@" +mime ^image, has sxiv, X, flag f = sxiv -- "$@" +mime ^image, has feh, X, flag f = feh -- "$@" +mime ^image, has mirage, X, flag f = mirage -- "$@" +mime ^image, has ristretto, X, flag f = ristretto "$@" +mime ^image, has eog, X, flag f = eog -- "$@" +mime ^image, has eom, X, flag f = eom -- "$@" +mime ^image, has nomacs, X, flag f = nomacs -- "$@" +mime ^image, has gpicview, X, flag f = gpicview -- "$@" +mime ^image, has gwenview, X, flag f = gwenview -- "$@" +mime ^image, has gimp, X, flag f = gimp -- "$@" +ext xcf, X, flag f = gimp -- "$@" + +#------------------------------------------- +# Archives +#------------------------------------------- + +# avoid password prompt by providing empty password +ext 7z, has 7z = 7z -p l "$@" | "$PAGER" +# This requires atool +ext ace|ar|arc|bz2?|cab|cpio|cpt|deb|dgc|dmg|gz, has atool = atool --list --each -- "$@" | "$PAGER" +ext iso|jar|msi|pkg|rar|shar|tar|tgz|xar|xpi|xz|zip, has atool = atool --list --each -- "$@" | "$PAGER" +ext 7z|ace|ar|arc|bz2?|cab|cpio|cpt|deb|dgc|dmg|gz, has atool = atool --extract --each -- "$@" +ext iso|jar|msi|pkg|rar|shar|tar|tgz|xar|xpi|xz|zip, has atool = atool --extract --each -- "$@" + +# Listing and extracting archives without atool: +ext tar|gz|bz2|xz, has tar = tar vvtf "$1" | "$PAGER" +ext tar|gz|bz2|xz, has tar = for file in "$@"; do tar vvxf "$file"; done +ext bz2, has bzip2 = for file in "$@"; do bzip2 -dk "$file"; done +ext zip, has unzip = unzip -l "$1" | less +ext zip, has unzip = for file in "$@"; do unzip -d "${file%.*}" "$file"; done +ext ace, has unace = unace l "$1" | less +ext ace, has unace = for file in "$@"; do unace e "$file"; done +ext rar, has unrar = unrar l "$1" | less +ext rar, has unrar = for file in "$@"; do unrar x "$file"; done + +#------------------------------------------- +# Fonts +#------------------------------------------- +mime ^font, has fontforge, X, flag f = fontforge "$@" + +#------------------------------------------- +# Flag t fallback terminals +#------------------------------------------- +# Rarely installed terminal emulators get higher priority; It is assumed that +# if you install a rare terminal emulator, you probably use it. +# gnome-terminal/konsole/xterm on the other hand are often installed as part of +# a desktop environment or as fallback terminal emulators. +mime ^ranger/x-terminal-emulator, has terminology = terminology -e "$@" +mime ^ranger/x-terminal-emulator, has kitty = kitty -- "$@" +mime ^ranger/x-terminal-emulator, has alacritty = alacritty -e "$@" +mime ^ranger/x-terminal-emulator, has sakura = sakura -e "$@" +mime ^ranger/x-terminal-emulator, has lilyterm = lilyterm -e "$@" +#mime ^ranger/x-terminal-emulator, has cool-retro-term = cool-retro-term -e "$@" +mime ^ranger/x-terminal-emulator, has termite = termite -x '"$@"' +#mime ^ranger/x-terminal-emulator, has yakuake = yakuake -e "$@" +mime ^ranger/x-terminal-emulator, has guake = guake -ne "$@" +mime ^ranger/x-terminal-emulator, has tilda = tilda -c "$@" +mime ^ranger/x-terminal-emulator, has st = st -e "$@" +mime ^ranger/x-terminal-emulator, has terminator = terminator -x "$@" +mime ^ranger/x-terminal-emulator, has urxvt = urxvt -e "$@" +mime ^ranger/x-terminal-emulator, has pantheon-terminal = pantheon-terminal -e "$@" +mime ^ranger/x-terminal-emulator, has lxterminal = lxterminal -e "$@" +mime ^ranger/x-terminal-emulator, has mate-terminal = mate-terminal -x "$@" +mime ^ranger/x-terminal-emulator, has xfce4-terminal = xfce4-terminal -x "$@" +mime ^ranger/x-terminal-emulator, has konsole = konsole -e "$@" +mime ^ranger/x-terminal-emulator, has gnome-terminal = gnome-terminal -- "$@" +mime ^ranger/x-terminal-emulator, has xterm = xterm -e "$@" + +#------------------------------------------- +# Misc +#------------------------------------------- +label wallpaper, number 11, mime ^image, has feh, X = feh --bg-scale "$1" +label wallpaper, number 12, mime ^image, has feh, X = feh --bg-tile "$1" +label wallpaper, number 13, mime ^image, has feh, X = feh --bg-center "$1" +label wallpaper, number 14, mime ^image, has feh, X = feh --bg-fill "$1" + +#------------------------------------------- +# Generic file openers +#------------------------------------------- +label open, has xdg-open = xdg-open -- "$@" +label open, has open = open -- "$@" + +# Define the editor for non-text files + pager as last action + !mime ^text, !ext xml|json|csv|tex|py|pl|rb|js|sh|php = ask +label editor, !mime ^text, !ext xml|json|csv|tex|py|pl|rb|js|sh|php = ${VISUAL:-$EDITOR} -- "$@" +label pager, !mime ^text, !ext xml|json|csv|tex|py|pl|rb|js|sh|php = "$PAGER" -- "$@" + + +###################################################################### +# The actions below are left so low down in this file on purpose, so # +# they are never triggered accidentally. # +###################################################################### + +# Execute a file as program/script. +mime application/x-executable = "$1" + +# Move the file to trash using trash-cli. +label trash, has trash-put = trash-put -- "$@" +label trash = mkdir -p -- ${XDG_DATA_DIR:-$HOME/.ranger}/ranger-trash; mv -- "$@" ${XDG_DATA_DIR:-$HOME/.ranger}/ranger-trash diff --git a/home-manager/homeModules/ranger/scope.sh b/home-manager/homeModules/ranger/scope.sh new file mode 100755 index 0000000..f9c7648 --- /dev/null +++ b/home-manager/homeModules/ranger/scope.sh @@ -0,0 +1,351 @@ +#!/usr/bin/env bash + +set -o noclobber -o noglob -o nounset -o pipefail +IFS=$'\n' + +## If the option `use_preview_script` is set to `true`, +## then this script will be called and its output will be displayed in ranger. +## ANSI color codes are supported. +## STDIN is disabled, so interactive scripts won't work properly + +## This script is considered a configuration file and must be updated manually. +## It will be left untouched if you upgrade ranger. + +## Because of some automated testing we do on the script #'s for comments need +## to be doubled up. Code that is commented out, because it's an alternative for +## example, gets only one #. + +## Meanings of exit codes: +## code | meaning | action of ranger +## -----+------------+------------------------------------------- +## 0 | success | Display stdout as preview +## 1 | no preview | Display no preview at all +## 2 | plain text | Display the plain content of the file +## 3 | fix width | Don't reload when width changes +## 4 | fix height | Don't reload when height changes +## 5 | fix both | Don't ever reload +## 6 | image | Display the image `$IMAGE_CACHE_PATH` points to as an image preview +## 7 | image | Display the file directly as an image + +## Script arguments +FILE_PATH="${1}" # Full path of the highlighted file +PV_WIDTH="${2}" # Width of the preview pane (number of fitting characters) +## shellcheck disable=SC2034 # PV_HEIGHT is provided for convenience and unused +PV_HEIGHT="${3}" # Height of the preview pane (number of fitting characters) +IMAGE_CACHE_PATH="${4}" # Full path that should be used to cache image preview +PV_IMAGE_ENABLED="${5}" # 'True' if image previews are enabled, 'False' otherwise. + +FILE_EXTENSION="${FILE_PATH##*.}" +FILE_EXTENSION_LOWER="$(printf "%s" "${FILE_EXTENSION}" | tr '[:upper:]' '[:lower:]')" + +## Settings +HIGHLIGHT_SIZE_MAX=262143 # 256KiB +HIGHLIGHT_TABWIDTH=${HIGHLIGHT_TABWIDTH:-8} +HIGHLIGHT_STYLE=${HIGHLIGHT_STYLE:-pablo} +HIGHLIGHT_OPTIONS="--replace-tabs=${HIGHLIGHT_TABWIDTH} --style=${HIGHLIGHT_STYLE} ${HIGHLIGHT_OPTIONS:-}" +PYGMENTIZE_STYLE=${PYGMENTIZE_STYLE:-autumn} +OPENSCAD_IMGSIZE=${RNGR_OPENSCAD_IMGSIZE:-1000,1000} +OPENSCAD_COLORSCHEME=${RNGR_OPENSCAD_COLORSCHEME:-Tomorrow Night} + +handle_extension() { + case "${FILE_EXTENSION_LOWER}" in + ## Archive + a|ace|alz|arc|arj|bz|bz2|cab|cpio|deb|gz|jar|lha|lz|lzh|lzma|lzo|\ + rpm|rz|t7z|tar|tbz|tbz2|tgz|tlz|txz|tZ|tzo|war|xpi|xz|Z|zip) + atool --list -- "${FILE_PATH}" && exit 5 + bsdtar --list --file "${FILE_PATH}" && exit 5 + exit 1;; + rar) + ## Avoid password prompt by providing empty password + unrar lt -p- -- "${FILE_PATH}" && exit 5 + exit 1;; + 7z) + ## Avoid password prompt by providing empty password + 7z l -p -- "${FILE_PATH}" && exit 5 + exit 1;; + + ## PDF + pdf) + ## Preview as text conversion + pdftotext -l 10 -nopgbrk -q -- "${FILE_PATH}" - | \ + fmt -w "${PV_WIDTH}" && exit 5 + mutool draw -F txt -i -- "${FILE_PATH}" 1-10 | \ + fmt -w "${PV_WIDTH}" && exit 5 + exiftool "${FILE_PATH}" && exit 5 + exit 1;; + + ## BitTorrent + torrent) + transmission-show -- "${FILE_PATH}" && exit 5 + exit 1;; + + ## OpenDocument + odt|ods|odp|sxw) + ## Preview as text conversion + odt2txt "${FILE_PATH}" && exit 5 + ## Preview as markdown conversion + pandoc -s -t markdown -- "${FILE_PATH}" && exit 5 + exit 1;; + + ## XLSX + xlsx) + ## Preview as csv conversion + ## Uses: https://github.com/dilshod/xlsx2csv + xlsx2csv -- "${FILE_PATH}" && exit 5 + exit 1;; + + ## HTML + htm|html|xhtml) + ## Preview as text conversion + w3m -dump "${FILE_PATH}" && exit 5 + lynx -dump -- "${FILE_PATH}" && exit 5 + elinks -dump "${FILE_PATH}" && exit 5 + pandoc -s -t markdown -- "${FILE_PATH}" && exit 5 + ;; + + ## JSON + json) + jq --color-output . "${FILE_PATH}" && exit 5 + python -m json.tool -- "${FILE_PATH}" && exit 5 + ;; + + ## Direct Stream Digital/Transfer (DSDIFF) and wavpack aren't detected + ## by file(1). + dff|dsf|wv|wvc) + mediainfo "${FILE_PATH}" && exit 5 + exiftool "${FILE_PATH}" && exit 5 + ;; # Continue with next handler on failure + esac +} + +handle_image() { + ## Size of the preview if there are multiple options or it has to be + ## rendered from vector graphics. If the conversion program allows + ## specifying only one dimension while keeping the aspect ratio, the width + ## will be used. + local DEFAULT_SIZE="1920x1080" + + local mimetype="${1}" + case "${mimetype}" in + ## SVG + # image/svg+xml|image/svg) + # convert -- "${FILE_PATH}" "${IMAGE_CACHE_PATH}" && exit 6 + # exit 1;; + + ## DjVu + # image/vnd.djvu) + # ddjvu -format=tiff -quality=90 -page=1 -size="${DEFAULT_SIZE}" \ + # - "${IMAGE_CACHE_PATH}" < "${FILE_PATH}" \ + # && exit 6 || exit 1;; + + ## Image + image/*) + local orientation + orientation="$( identify -format '%[EXIF:Orientation]\n' -- "${FILE_PATH}" )" + ## If orientation data is present and the image actually + ## needs rotating ("1" means no rotation)... + if [[ -n "$orientation" && "$orientation" != 1 ]]; then + ## ...auto-rotate the image according to the EXIF data. + convert -- "${FILE_PATH}" -auto-orient "${IMAGE_CACHE_PATH}" && exit 6 + fi + kitty +kitten icat "${IMAGE_CACHE_PATH}" + + ## `w3mimgdisplay` will be called for all images (unless overriden + ## as above), but might fail for unsupported types. + exit 7;; + + ## Video + video/*) + # Thumbnail + ffmpegthumbnailer -i "${FILE_PATH}" -o "${IMAGE_CACHE_PATH}" -s 0 && exit 6 + exit 1;; + + ## PDF + application/pdf) + pdftoppm -f 1 -l 1 \ + -scale-to-x "${DEFAULT_SIZE%x*}" \ + -scale-to-y -1 \ + -singlefile \ + -jpeg -tiffcompression jpeg \ + -- "${FILE_PATH}" "${IMAGE_CACHE_PATH%.*}" \ + && exit 6 || exit 1;; + + + ## ePub, MOBI, FB2 (using Calibre) + application/epub+zip|application/x-mobipocket-ebook|\ + application/x-fictionbook+xml) + # ePub (using https://github.com/marianosimone/epub-thumbnailer) + epub-thumbnailer "${FILE_PATH}" "${IMAGE_CACHE_PATH}" \ + "${DEFAULT_SIZE%x*}" && exit 6 + ebook-meta --get-cover="${IMAGE_CACHE_PATH}" -- "${FILE_PATH}" \ + >/dev/null && exit 6 + exit 1;; + + ## Font + application/font*|application/*opentype) + preview_png="/tmp/$(basename "${IMAGE_CACHE_PATH%.*}").png" + if fontimage -o "${preview_png}" \ + --pixelsize "120" \ + --fontname \ + --pixelsize "80" \ + --text " ABCDEFGHIJKLMNOPQRSTUVWXYZ " \ + --text " abcdefghijklmnopqrstuvwxyz " \ + --text " 0123456789.:,;(*!?') ff fl fi ffi ffl " \ + --text " The quick brown fox jumps over the lazy dog. " \ + "${FILE_PATH}"; + then + convert -- "${preview_png}" "${IMAGE_CACHE_PATH}" \ + && rm "${preview_png}" \ + && exit 6 + else + exit 1 + fi + ;; + + ## Preview archives using the first image inside. + ## (Very useful for comic book collections for example.) + # application/zip|application/x-rar|application/x-7z-compressed|\ + # application/x-xz|application/x-bzip2|application/x-gzip|application/x-tar) + # local fn=""; local fe="" + # local zip=""; local rar=""; local tar=""; local bsd="" + # case "${mimetype}" in + # application/zip) zip=1 ;; + # application/x-rar) rar=1 ;; + # application/x-7z-compressed) ;; + # *) tar=1 ;; + # esac + # { [ "$tar" ] && fn=$(tar --list --file "${FILE_PATH}"); } || \ + # { fn=$(bsdtar --list --file "${FILE_PATH}") && bsd=1 && tar=""; } || \ + # { [ "$rar" ] && fn=$(unrar lb -p- -- "${FILE_PATH}"); } || \ + # { [ "$zip" ] && fn=$(zipinfo -1 -- "${FILE_PATH}"); } || return + # + # fn=$(echo "$fn" | python -c "import sys; import mimetypes as m; \ + # [ print(l, end='') for l in sys.stdin if \ + # (m.guess_type(l[:-1])[0] or '').startswith('image/') ]" |\ + # sort -V | head -n 1) + # [ "$fn" = "" ] && return + # [ "$bsd" ] && fn=$(printf '%b' "$fn") + # + # [ "$tar" ] && tar --extract --to-stdout \ + # --file "${FILE_PATH}" -- "$fn" > "${IMAGE_CACHE_PATH}" && exit 6 + # fe=$(echo -n "$fn" | sed 's/[][*?\]/\\\0/g') + # [ "$bsd" ] && bsdtar --extract --to-stdout \ + # --file "${FILE_PATH}" -- "$fe" > "${IMAGE_CACHE_PATH}" && exit 6 + # [ "$bsd" ] || [ "$tar" ] && rm -- "${IMAGE_CACHE_PATH}" + # [ "$rar" ] && unrar p -p- -inul -- "${FILE_PATH}" "$fn" > \ + # "${IMAGE_CACHE_PATH}" && exit 6 + # [ "$zip" ] && unzip -pP "" -- "${FILE_PATH}" "$fe" > \ + # "${IMAGE_CACHE_PATH}" && exit 6 + # [ "$rar" ] || [ "$zip" ] && rm -- "${IMAGE_CACHE_PATH}" + # ;; + esac + + # openscad_image() { + # TMPPNG="$(mktemp -t XXXXXX.png)" + # openscad --colorscheme="${OPENSCAD_COLORSCHEME}" \ + # --imgsize="${OPENSCAD_IMGSIZE/x/,}" \ + # -o "${TMPPNG}" "${1}" + # mv "${TMPPNG}" "${IMAGE_CACHE_PATH}" + # } + + # case "${FILE_EXTENSION_LOWER}" in + # ## 3D models + # ## OpenSCAD only supports png image output, and ${IMAGE_CACHE_PATH} + # ## is hardcoded as jpeg. So we make a tempfile.png and just + # ## move/rename it to jpg. This works because image libraries are + # ## smart enough to handle it. + # csg|scad) + # openscad_image "${FILE_PATH}" && exit 6 + # ;; + # 3mf|amf|dxf|off|stl) + # openscad_image <(echo "import(\"${FILE_PATH}\");") && exit 6 + # ;; + # esac +} + +handle_mime() { + local mimetype="${1}" + case "${mimetype}" in + ## RTF and DOC + text/rtf|*msword) + ## Preview as text conversion + ## note: catdoc does not always work for .doc files + ## catdoc: http://www.wagner.pp.ru/~vitus/software/catdoc/ + catdoc -- "${FILE_PATH}" && exit 5 + exit 1;; + + ## DOCX, ePub, FB2 (using markdown) + ## You might want to remove "|epub" and/or "|fb2" below if you have + ## uncommented other methods to preview those formats + *wordprocessingml.document|*/epub+zip|*/x-fictionbook+xml) + ## Preview as markdown conversion + pandoc -s -t markdown -- "${FILE_PATH}" && exit 5 + exit 1;; + + ## XLS + *ms-excel) + ## Preview as csv conversion + ## xls2csv comes with catdoc: + ## http://www.wagner.pp.ru/~vitus/software/catdoc/ + xls2csv -- "${FILE_PATH}" && exit 5 + exit 1;; + + ## Text + text/* | */xml) + ## Syntax highlight + if [[ "$( stat --printf='%s' -- "${FILE_PATH}" )" -gt "${HIGHLIGHT_SIZE_MAX}" ]]; then + exit 2 + fi + if [[ "$( tput colors )" -ge 256 ]]; then + local pygmentize_format='terminal256' + local highlight_format='xterm256' + else + local pygmentize_format='terminal' + local highlight_format='ansi' + fi + env HIGHLIGHT_OPTIONS="${HIGHLIGHT_OPTIONS}" highlight \ + --out-format="${highlight_format}" \ + --force -- "${FILE_PATH}" && exit 5 + env COLORTERM=8bit bat --color=always --style="plain" \ + -- "${FILE_PATH}" && exit 5 + pygmentize -f "${pygmentize_format}" -O "style=${PYGMENTIZE_STYLE}"\ + -- "${FILE_PATH}" && exit 5 + exit 2;; + + ## DjVu + image/vnd.djvu) + ## Preview as text conversion (requires djvulibre) + djvutxt "${FILE_PATH}" | fmt -w "${PV_WIDTH}" && exit 5 + exiftool "${FILE_PATH}" && exit 5 + exit 1;; + + ## Image + image/*) + ## Preview as text conversion + # img2txt --gamma=0.6 --width="${PV_WIDTH}" -- "${FILE_PATH}" && exit 4 + exiftool "${FILE_PATH}" && exit 5 + exit 1;; + + ## Video and audio + video/* | audio/*) + mediainfo "${FILE_PATH}" && exit 5 + exiftool "${FILE_PATH}" && exit 5 + exit 1;; + esac +} + +handle_fallback() { + echo '----- File Type Classification -----' && file --dereference --brief -- "${FILE_PATH}" && exit 5 + exit 1 +} + + +MIMETYPE="$( file --dereference --brief --mime-type -- "${FILE_PATH}" )" +if [[ "${PV_IMAGE_ENABLED}" == 'True' ]]; then + handle_image "${MIMETYPE}" +fi +handle_extension +handle_mime "${MIMETYPE}" +handle_fallback + +exit 1 diff --git a/home-manager/homeModules/result b/home-manager/homeModules/result new file mode 120000 index 0000000..aa276de --- /dev/null +++ b/home-manager/homeModules/result @@ -0,0 +1 @@ +/nix/store/22dk6x6n10hd08npa3f8ninid2bp53p6-home-manager-generation
\ No newline at end of file diff --git a/home-manager/homeModules/rofi.nix b/home-manager/homeModules/rofi.nix new file mode 100644 index 0000000..59b27aa --- /dev/null +++ b/home-manager/homeModules/rofi.nix @@ -0,0 +1,47 @@ +{ pkgs, config, lib, ... }: + +{ + options = { + rofi.enable = lib.mkEnableOption "enable rofi"; + rofi.package = lib.mkPackageOption pkgs "rofi package" { default = [ "rofi-wayland" ]; }; + }; + + config = lib.mkIf config.rofi.enable { + programs.rofi = { + enable = true; + package = config.rofi.package; + theme = + with config.lib.stylix.colors.withHashtag; + builtins.toFile "theme.rasi" '' + * { + font: "FiraCode Nerd Font Medium 12"; + + bg0: ${base01}; + bg1: ${base02}; + fg0: ${base04}; + + accent-color: ${base03}; + urgent-color: #ffffff; + + background-color: transparent; + text-color: @fg0; + + margin: 0; + padding: 0; + spacing: 0; + } + + ${builtins.readFile ./attachments/rofi-theme.rasi}''; + cycle = true; + plugins = with pkgs; [ + rofi-emoji + rofi-calc + ]; + extraConfig = { + kb-row-up = "Up,Alt+k"; + kb-row-down = "Down,Alt+j"; + }; + }; + }; +} + diff --git a/home-manager/homeModules/stylix.nix b/home-manager/homeModules/stylix.nix new file mode 100644 index 0000000..ae08607 --- /dev/null +++ b/home-manager/homeModules/stylix.nix @@ -0,0 +1,76 @@ +{ pkgs, config, lib, inputs, ... }: +with config.lib.stylix.colors.withHashtag; + +{ + imports = [ + inputs.stylix.homeManagerModules.stylix + ]; + + options = { + stylixConfig = { + enable = lib.mkEnableOption "enable stylix"; + theme = lib.mkOption { type = lib.types.str; }; + }; + wallpaper = lib.mkOption { type = with lib.types; oneOf [str path package]; }; + }; + config = lib.mkIf config.stylixConfig.enable { + wallpaper = pkgs.runCommand "cat.png" {} '' + pastel=${pkgs.pastel}/bin/pastel + SHADOWS=$($pastel darken 0.1 '${base05}' | $pastel format hex) + TAIL=$($pastel lighten 0.1 '${base02}' | $pastel format hex) + HIGHLIGHTS=$($pastel lighten 0.1 '${base05}' | $pastel format hex) + + ${pkgs.imagemagick}/bin/convert ${./attachments/basecat.png} \ + -fill '${base00}' -opaque black \ + -fill '${base05}' -opaque white \ + -fill '${base08}' -opaque blue \ + -fill $SHADOWS -opaque gray \ + -fill '${base02}' -opaque orange \ + -fill $TAIL -opaque green \ + -fill $HIGHLIGHTS -opaque brown \ + $out''; + stylix = { + targets = { + rofi.enable = false; + waybar.enable = false; + }; + + polarity = "dark"; + + opacity = { + terminal = 0.7; + # applications = 0.7; + }; + + base16Scheme = "${pkgs.base16-schemes}/share/themes/${config.stylixConfig.theme}.yaml"; + image = config.wallpaper; + cursor = { + package = pkgs.bibata-cursors; + name = "Bibata-Modern-Ice"; + size = 24; + }; + + fonts = { + serif = { + package = pkgs.noto-fonts; + name = "Noto Serif"; + }; + + sansSerif = { + package = pkgs.rubik; + name = "Rubik"; + }; + + monospace = { + package = pkgs.nerdfonts.override { fonts = ["SourceCodePro"]; }; + name = "Sauce Code Pro Nerd Font"; + }; + + emoji = { + package = pkgs.noto-fonts-emoji; + name = "Noto Color Emoji"; + }; + }; + }; + }; +} diff --git a/home-manager/homeModules/sxhkd.nix b/home-manager/homeModules/sxhkd.nix new file mode 100644 index 0000000..43774ab --- /dev/null +++ b/home-manager/homeModules/sxhkd.nix @@ -0,0 +1,46 @@ +{ pkgs, config, lib, ... }: + +{ + options = { + sxhkd.enable = lib.mkEnableOption "enable sxhkd"; + }; + + config = lib.mkIf config.sxhkd.enable { + services.sxhkd = + let + apps = { + "{_,shift} + {_,control} + Print" = "xfce4-screenshooter -{r,f} {_,-c}"; # Screenshooter + "super + apostrophe" = "betterlockscreen -l"; # Lockscreen + "super + grave" = "polybar -r"; # Restart polybar + "super + q" = "kitty"; # Open terminal + "super + d" = "rofi -show-icons -show drun"; # Open app chooser + "super + shift + d" = "CM_LAUNCHER=rofi clipmenu"; + "super + b" = "firefox"; # Open browser + "super + e" = "emacsclient -c -a 'emacs'"; # Open emacs + "super + shift + o" = "obsidian"; # Open obsidian + }; + bspwm = { + "super + Escape" = "pkill -USR1 -x sxhkd"; # Restart sxhkd + "super + shift + {e,r}" = "bspc {quit,wm -r}"; # Quit/restart bspwm + "super + {control,shift} + q" = "bspc node -{k,c}"; # Close/kill window + "super + m" = "bspc desktop -l next"; # Maximise window + "super + {t,shift + t,v,f}" = "bspc node -t {tiled,pseudo_tiled,floating,fullscreen}"; # Set window state + "super + {_,shift + }{h,j,k,l}" = "bspc node -{f,s} {west,south,north,east}"; # Focus window in the given direction + "super + {Left,Down,Up,Right}" = "bspc node -v {-20 0,0 20,0 -20,20 0}"; # Move a floating window + "super + s : {h,j,k,l}" = ''STEP=20; SELECTION={1,2,3,4};\ + bspc node -z $(echo "left -$STEP 0,bottom 0 $STEP,top 0 -$STEP,right $STEP 0" | cut -d',' -f$SELECTION) ||\ + bspc node -z $(echo "right -$STEP 0,top 0 $STEP,bottom 0 -$STEP,left $STEP 0" | cut -d',' -f$SELECTION)''; # Better window resize + "super + bracket{left,right}" = "bspc desktop -f {prev,next}.local"; # Focus next/previos desktop + "super + {_,shift + }{1-9,0}" = "bspc {desktop -f,node -d} $(bspc query -D -m focused | awk 'NR=={1-9,0}')"; # Focus/send window to the given desktop on the focused monitor + "super + o" = "bspc node -m last -f"; # Send window to the last used monitor + "super + ctrl + {1-9}" = "bspc node -o 0.{1-9}"; # Preselect the window ratio + "super + ctrl + space" = "bspc node -p cancel"; # Cansel the preselected ratio + "super + n" = "fish ~/.nixfiles/home-manager/home/services/polybar/hide.fish"; + }; + keybindings = apps ++ bspwm; + in { + enable = true; + inherit keybindings; + }; + }; +} diff --git a/home-manager/homeModules/waybar.nix b/home-manager/homeModules/waybar.nix new file mode 100644 index 0000000..4862d0e --- /dev/null +++ b/home-manager/homeModules/waybar.nix @@ -0,0 +1,113 @@ +{ pkgs, lib, config, ... }: + +{ + options = { + waybar.enable = lib.mkEnableOption "enable waybar"; + }; + + config = lib.mkIf config.waybar.enable { + programs.waybar = { + enable = true; + systemd.enable = true; + style = + with config.lib.stylix.colors.withHashtag; + '' + @define-color base00 ${base00}; @define-color base01 ${base01}; @define-color base02 ${base02}; @define-color base03 ${base03}; + @define-color base04 ${base04}; @define-color base05 ${base05}; @define-color base06 ${base06}; @define-color base07 ${base07}; + + @define-color base08 ${base08}; @define-color base09 ${base09}; @define-color base0A ${base0A}; @define-color base0B ${base0B}; + @define-color base0C ${base0C}; @define-color base0D ${base0D}; @define-color base0E ${base0E}; @define-color base0F ${base0F}; + '' + builtins.readFile ./attachments/waybar-style.css; + settings = { + bar = { + layer = "top"; + height = 40; + spacing = 8; + margin-top = 20; + margin-left = 20; + margin-right = 20; + margin-down = 5; + modules-left = ["hyprland/workspaces"]; + modules-center = ["clock"]; + modules-right = ["network" "memory" "backlight" "pulseaudio" "hyprland/language" "tray" "battery"]; + "hyprland/workspaces" = { + format = "{icon}"; + "format-icons" = { + "1" = "α"; + "2" = "β"; + "3" = "γ"; + "4" = "δ"; + "5" = "ε"; + urgent = "λ"; + focused = "σ"; + default = "ω"; + }; + }; + "hyprland/language" = { + format = "{} <span font-family='Material Design Icons' rise='-1000' size='medium'></span>"; + format-ru = "ru"; + format-en = "en"; + }; + "tray" = { + spacing = 10; + }; + "clock" = { + format = "{:%H:%M }"; + tooltip-format = "<big>{:%Y %B}</big>\n<tt><small>{calendar}</small></tt>"; + format-alt = "{:%d %h %Y }"; + on-click = "killall calcure || alacritty -t calcure -e calcure;sudo ydotool click 0xc1"; + }; + "memory" = { + format = "{}% "; + on-click = "killall btop || alacritty -t btop -e btop;sudo ydotool click 0xc1"; + }; + "backlight" = { + format = "{percent}% {icon}"; + format-icons = ["" "" ""]; + }; + "battery" = { + "states" = { + good = 95; + warning = 30; + critical = 15; + }; + format = "{capacity}% {icon}"; + format-charging = "{capacity}% "; + format-plugged = "{capacity}% "; + format-alt = "{icon}"; + format-icons = ["" "" "" "" "" "" "" "" "" ""]; + + }; + "network" = { + interface = "wlp2*"; + format-wifi = "{essid} ({signalStrength}%) "; + format-ethernet = "{ipaddr}/{cidr} "; + tooltip-format = "{ifname} via {gwaddr} "; + format-linked = "{ifname} (No IP) "; + format-disconnected = ""; + on-click = "killall connman-gtk || connman-gtk;sudo ydotool click 0xc1"; + }; + "pulseaudio" = { + format = "{volume}% {icon} {format_source}"; + format-bluetooth = "{volume}% <span font-family='Material Design Icons' rise='-2000' font-size='x-large'></span> {format_source}"; + format-bluetooth-muted = " {format_source}"; + format-muted = " {format_source}"; + format-source = "{volume}% "; + format-source-muted = ""; + on-click = "killall bluetuith || alacritty -t blue -e bluetuith; sudo ydotool click 0xc1"; + "format-icons" = { + headphone = ""; + hands-free = ""; + headset = ""; + phone = ""; + portable = ""; + car = ""; + muted-icon = ""; + default = ["" "" ""]; + }; + }; + }; + }; + }; + }; +} |
