diff --git a/flake.nix b/flake.nix index 95b4c15..23ece59 100644 --- a/flake.nix +++ b/flake.nix @@ -75,7 +75,9 @@ pkgs = import inputs.nixpkgs nixpkgsConfig; lib = inputs.nixpkgs.lib; - old_overlays = (import ./overlays { inherit inputs; }); + packages = import ./pkgs { inherit pkgs inputs; }; + + old_overlays = (import ./overlays { inherit packages inputs; }); specialArgs = { inherit inputs; @@ -85,6 +87,8 @@ { nixpkgs.pkgs = pkgs; } ./system/configuration.nix ./system/secrets.nix + ./system/greetd.nix + { login-manager.greetd.enable = desktop == "sway"; } inputs.agenix.nixosModules.default inputs.dzgui-nix.nixosModules.default @@ -120,6 +124,7 @@ ./hosts/monolith ./system/monolith-gitlab-runner.nix ./system/monolith-forgejo-runner.nix + ./system/nix-serve.nix ./system/steam.nix ] ++ common_modules; }; @@ -167,7 +172,7 @@ modules = [ ./user/home.nix ]; }; - packages.${system} = pkgs; + packages.${system} = pkgs // packages; formatter.${system} = pkgs.nixfmt-rfc-style; }; diff --git a/overlays/default.nix b/overlays/default.nix index 8719bb5..2ac2ae1 100644 --- a/overlays/default.nix +++ b/overlays/default.nix @@ -1,9 +1,10 @@ -{ inputs, ... }: +{ inputs, packages, ... }: rec { all = [ scripts themes new-packages + patches lib_extended disko ]; @@ -34,7 +35,9 @@ rec { ); new-packages = ( - final: prev: { + final: prev: + packages + // { dhist = inputs.dhist.packages.${prev.system}.dhist; demoji = inputs.demoji.packages.${prev.system}.default; tlauncher = inputs.tlauncher.packages.${prev.system}.tlauncher; @@ -42,6 +45,18 @@ rec { } ); + patches = ( + final: prev: { + mySway = prev.sway.override { + withBaseWrapper = true; + withGtkWrapper = true; + sway-unwrapped = prev.sway-unwrapped.overrideAttrs (old: { + patches = old.patches ++ [ ../patches/sway/fix-hide_cursor-clearing-focus.patch ]; + }); + }; + } + ); + lib_extended = ( final: prev: { lib = prev.lib // rec { diff --git a/patches/orchis-fix-warnings.patch b/patches/orchis-fix-warnings.patch new file mode 100644 index 0000000..36ebdca --- /dev/null +++ b/patches/orchis-fix-warnings.patch @@ -0,0 +1,19 @@ +commit 9c516cc61775a88312280f7732328d5fdf7af825 +Author: lelgenio +Date: Mon May 22 11:30:01 2023 -0300 + + fix: limit lowest value for corner-radious at 0 + +diff --git a/src/_sass/_variables.scss b/src/_sass/_variables.scss +index 9915a22..6e87a4f 100644 +--- a/src/_sass/_variables.scss ++++ b/src/_sass/_variables.scss +@@ -24,7 +24,7 @@ $large-icon-size: 32px; + // + + $window-radius: $default_corner + $space-size; +-$corner-radius: if($compact == 'false', $default_corner, $default_corner - 2px); ++$corner-radius: if($compact == 'false', $default_corner, max(0, $default_corner - 2px)); + $material-radius: $default_corner / 2 + 4px; + $menu-radius: $default_corner / 4 + $space-size + 2px; + $popup-radius: $default_corner + $space-size + 2px; diff --git a/patches/sway/fix-hide_cursor-clearing-focus.patch b/patches/sway/fix-hide_cursor-clearing-focus.patch new file mode 100644 index 0000000..29746aa --- /dev/null +++ b/patches/sway/fix-hide_cursor-clearing-focus.patch @@ -0,0 +1,24 @@ +From b21dc487ac4bfc086cf295e06b8d8765a99e7266 Mon Sep 17 00:00:00 2001 +From: lelgenio +Date: Thu, 24 Jun 2021 22:36:10 -0300 +Subject: [PATCH] Fix #6297 + +This makes it so that `seat hide_cursor` no longer clears cursor focus when hidding. + +Clearing focus casuses problems whenever keyboard and mouse are to be used in conjunction. +--- + sway/input/cursor.c | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/sway/input/cursor.c b/sway/input/cursor.c +index 96b5b93514..99fe3b4e3f 100644 +--- a/sway/input/cursor.c ++++ b/sway/input/cursor.c +@@ -236,7 +236,6 @@ void cursor_update_image(struct sway_cursor *cursor, + static void cursor_hide(struct sway_cursor *cursor) { + wlr_cursor_set_image(cursor->cursor, NULL, 0, 0, 0, 0, 0, 0); + cursor->hidden = true; +- wlr_seat_pointer_notify_clear_focus(cursor->seat->wlr_seat); + } + + static int hide_notify(void *data) { diff --git a/pkgs/blade-formatter/default.nix b/pkgs/blade-formatter/default.nix new file mode 100644 index 0000000..f824066 --- /dev/null +++ b/pkgs/blade-formatter/default.nix @@ -0,0 +1,64 @@ +{ + lib, + mkYarnPackage, + fetchFromGitHub, + fetchYarnDeps, + testers, + writeText, + runCommand, + blade-formatter, +}: + +mkYarnPackage rec { + pname = "blade-formatter"; + version = "1.38.2"; + + src = fetchFromGitHub { + owner = "shufo"; + repo = pname; + rev = "v${version}"; + hash = "sha256-JvILLw7Yp4g/dSsYtZ2ylmlXfS9t+2KADlBrYOJWTpg="; + }; + + packageJSON = ./package.json; + offlineCache = fetchYarnDeps { + yarnLock = "${src}/yarn.lock"; + hash = "sha256-UFDxw3fYMzSUhZw+TCEh/dN7OioKI75LzKSnEwGPKDA="; + }; + + postBuild = "yarn build"; + + passthru.tests = { + version = testers.testVersion { + package = blade-formatter; + command = "blade-formatter --version"; + }; + + simple = testers.testEqualContents { + assertion = "blade-formatter formats a basic blade file"; + expected = writeText "expected" '' + @if (true) + Hello world! + @endif + ''; + actual = + runCommand "actual" + { + nativeBuildInputs = [ blade-formatter ]; + base = writeText "base" '' + @if( true ) Hello world! @endif + ''; + } + '' + blade-formatter $base > $out + ''; + }; + }; + + meta = with lib; { + description = "Laravel Blade template formatter"; + homepage = "https://github.com/shufo/blade-formatter"; + license = licenses.mit; + maintainers = with maintainers; [ lelgenio ]; + }; +} diff --git a/pkgs/blade-formatter/package.json b/pkgs/blade-formatter/package.json new file mode 100755 index 0000000..b43fa5c --- /dev/null +++ b/pkgs/blade-formatter/package.json @@ -0,0 +1,120 @@ +{ + "name": "blade-formatter", + "engines": { + "node": ">= 14.0.0" + }, + "keywords": [ + "php", + "formatter", + "laravel" + ], + "version": "1.38.2", + "description": "An opinionated blade template formatter for Laravel", + "main": "./dist/bundle.cjs", + "types": "./dist/types/main.d.ts", + "type": "module", + "exports": { + ".": { + "import": "./dist/bundle.js", + "require": "./dist/bundle.cjs", + "default": "./dist/bundle.js" + }, + "./*": "./*" + }, + "scripts": { + "build": "cross-env NODE_ENV=production node esbuild.js && cross-env NODE_ENV=production ESM_BUILD=true node esbuild.js", + "prepublish": "tsc src/main.ts --declaration --emitDeclarationOnly --outDir ./dist/types || true", + "watch": "node esbuild.js", + "test": "yarn run build && node --experimental-vm-modules node_modules/.bin/jest", + "lint": "eslint src -c .eslintrc.json --ext ts", + "fix": "prettier {src,__tests__}/**/*.ts --write", + "check_formatted": "prettier **/*.ts -c", + "changelog": "conventional-changelog -p angular -i CHANGELOG.md -s -r 0", + "prepare": "husky install", + "bin": "cross-env ./bin/blade-formatter.cjs" + }, + "bin": { + "blade-formatter": "bin/blade-formatter.cjs" + }, + "author": "Shuhei Hayashibara", + "license": "MIT", + "dependencies": { + "@prettier/plugin-php": "^0.19.7", + "@shufo/tailwindcss-class-sorter": "3.0.1", + "aigle": "^1.14.1", + "ajv": "^8.9.0", + "chalk": "^4.1.0", + "concat-stream": "^2.0.0", + "detect-indent": "^6.0.0", + "find-config": "^1.0.0", + "glob": "^8.0.1", + "html-attribute-sorter": "^0.4.3", + "ignore": "^5.1.8", + "js-beautify": "^1.14.8", + "lodash": "^4.17.19", + "php-parser": "3.1.5", + "prettier": "^2.2.0", + "tailwindcss": "^3.1.8", + "vscode-oniguruma": "1.7.0", + "vscode-textmate": "^7.0.1", + "xregexp": "^5.0.1", + "yargs": "^17.3.1" + }, + "devDependencies": { + "@babel/core": "^7.6.4", + "@babel/plugin-transform-modules-commonjs": "^7.16.5", + "@babel/preset-env": "^7.13.12", + "@babel/preset-typescript": "^7.16.5", + "@types/concat-stream": "^2.0.0", + "@types/find-config": "^1.0.1", + "@types/fs-extra": "^11.0.0", + "@types/glob": "^8.0.0", + "@types/jest": "^29.0.0", + "@types/js-beautify": "^1.13.3", + "@types/lodash": "^4.14.178", + "@types/mocha": "^10.0.0", + "@types/node": "^18.0.0", + "@types/xregexp": "^4.4.0", + "@typescript-eslint/eslint-plugin": "^5.8.1", + "@typescript-eslint/parser": "^5.8.1", + "app-root-path": "^3.0.0", + "babel-jest": "^29.0.0", + "codecov": "^3.8.3", + "cross-env": "^7.0.3", + "esbuild": "^0.19.0", + "esbuild-node-externals": "^1.4.1", + "eslint": "^8.5.0", + "eslint-config-airbnb-base": "^15.0.0", + "eslint-config-airbnb-typescript": "^17.0.0", + "eslint-config-prettier": "^9.0.0", + "eslint-import-resolver-typescript": "^3.0.0", + "eslint-plugin-import": "^2.25.3", + "eslint-plugin-jest": "^26.0.0", + "eslint-plugin-prettier": "^5.0.0", + "fs-extra": "^11.0.0", + "husky": "^8.0.0", + "jest": "^29.0.0", + "lint-staged": ">=10", + "source-map-loader": "^4.0.0", + "ts-jest": "^29.0.0", + "ts-loader": "^9.2.6", + "ts-migrate": "^0.1.27", + "ts-node": "^10.4.0", + "typescript": "^5.0.0" + }, + "repository": { + "type": "git", + "url": "https://github.com/shufo/blade-formatter.git" + }, + "files": [ + "dist", + "src", + "bin", + "wasm", + "syntaxes", + "CHANGELOG.md" + ], + "lint-staged": { + "*.ts": "yarn run fix" + } +} diff --git a/pkgs/cargo-checkmate.nix b/pkgs/cargo-checkmate.nix new file mode 100644 index 0000000..a85ff80 --- /dev/null +++ b/pkgs/cargo-checkmate.nix @@ -0,0 +1,38 @@ +{ + lib, + rustPlatform, + fetchFromGitHub, + pkg-config, + openssl, + zlib, + stdenv, + Security ? null, +}: + +rustPlatform.buildRustPackage rec { + pname = "cargo-checkmate"; + version = "0.1.10"; + + src = fetchFromGitHub { + owner = "cargo-checkmate"; + repo = pname; + rev = "v${version}"; + hash = "sha256-I8l/r26cDdimjgy/+IsasF4iHX09UGjVj0Yf6ScI3wQ="; + }; + + cargoSha256 = "sha256-hOB84u55ishahIFSqBnqccqH3OlC9J8mCYzsd23jTyA="; + + nativeBuildInputs = [ pkg-config ]; + buildInputs = [ openssl ] ++ lib.optionals stdenv.isDarwin [ Security ]; + + meta = with lib; { + description = "Check all the things."; + longDescriptin = '' + Perform a series of useful checks out of the box. cargo-checkmate + ensures your project builds, tests pass, has good format, doesn't + have dependencies with known vulnerabilities, and so on. + ''; + homepage = "https://github.com/cargo-checkmate/cargo-checkmate"; + license = with licenses; [ mit ]; + }; +} diff --git a/pkgs/default.nix b/pkgs/default.nix new file mode 100644 index 0000000..eccb020 --- /dev/null +++ b/pkgs/default.nix @@ -0,0 +1,13 @@ +# Custom packages, that can be defined similarly to ones from nixpkgs +# You can build them using 'nix build .#example' or (legacy) 'nix-build -A example' + +{ pkgs, inputs }: +rec { + blade-formatter = pkgs.callPackage ./blade-formatter { }; + cargo-checkmate = pkgs.callPackage ./cargo-checkmate.nix { }; + lipsum = pkgs.callPackage ./lipsum.nix { }; + emmet-cli = pkgs.callPackage ./emmet-cli.nix { }; + material-wifi-icons = pkgs.callPackage ./material-wifi-icons.nix { }; + gnome-pass-search-provider = pkgs.callPackage ./gnome-pass-search-provider.nix { }; + kak-tree-sitter = pkgs.callPackage ./kak-tree-sitter.nix { }; +} diff --git a/pkgs/emmet-cli.nix b/pkgs/emmet-cli.nix new file mode 100644 index 0000000..043aff6 --- /dev/null +++ b/pkgs/emmet-cli.nix @@ -0,0 +1,27 @@ +{ + lib, + buildNpmPackage, + fetchFromGitHub, +}: + +buildNpmPackage rec { + pname = "emmet-cli"; + version = "0.0.1"; + + src = fetchFromGitHub { + owner = "Delapouite"; + repo = "emmet-cli"; + rev = "407b0e8c59f65f205967d6be71105e0bd2001d62"; + hash = "sha256-8lDgD1eIc2r5aB2baaiHKbkFdAxErX5p96MNqztR9rg="; + }; + + npmDepsHash = "sha256-Utgk/Cw83ffGr2/4aNkp3n3wSOojLZLA7OR+OakYBC0="; + + dontNpmBuild = true; + + meta = { + description = "Emmet command line interface"; + homepage = "https://github.com/Delapouite/emmet-cli"; + mainProgram = "emmet"; + }; +} diff --git a/pkgs/gnome-pass-search-provider.nix b/pkgs/gnome-pass-search-provider.nix new file mode 100644 index 0000000..e149505 --- /dev/null +++ b/pkgs/gnome-pass-search-provider.nix @@ -0,0 +1,64 @@ +{ + stdenv, + fetchFromGitHub, + python3Packages, + wrapGAppsHook, + gtk3, + gobject-introspection, + gnome, +}: + +let + inherit (python3Packages) + dbus-python + pygobject3 + fuzzywuzzy + levenshtein + ; +in + +stdenv.mkDerivation rec { + pname = "gnome-pass-search-provider"; + version = "1.4.0"; + + src = fetchFromGitHub { + owner = "jle64"; + repo = "gnome-pass-search-provider"; + rev = version; + hash = "sha256-PDR8fbDoT8IkHiTopQp0zd4DQg7JlacA6NdKYKYmrWw="; + }; + + nativeBuildInputs = [ + python3Packages.wrapPython + wrapGAppsHook + ]; + + propagatedBuildInputs = [ + dbus-python + pygobject3 + fuzzywuzzy + levenshtein + + gtk3 + gobject-introspection + ]; + + env = { + LIBDIR = builtins.placeholder "out" + "/lib"; + DATADIR = builtins.placeholder "out" + "/share"; + }; + + postPatch = '' + substituteInPlace conf/org.gnome.Pass.SearchProvider.service.{dbus,systemd} \ + --replace-fail "/usr/lib" "$LIBDIR" + ''; + + installPhase = '' + bash ./install.sh + ''; + + postFixup = '' + makeWrapperArgs=( "''${gappsWrapperArgs[@]}" ) + wrapPythonProgramsIn "$out/lib" "$out $propagatedBuildInputs" + ''; +} diff --git a/pkgs/kak-tree-sitter.nix b/pkgs/kak-tree-sitter.nix new file mode 100644 index 0000000..3e3d9d1 --- /dev/null +++ b/pkgs/kak-tree-sitter.nix @@ -0,0 +1,34 @@ +{ + lib, + stdenv, + rustPlatform, + fetchFromSourcehut, + makeWrapper, +}: + +rustPlatform.buildRustPackage rec { + pname = "kak-tree-sitter"; + version = "1.1.2"; + + src = fetchFromSourcehut { + owner = "~hadronized"; + repo = "kak-tree-sitter"; + rev = "kak-tree-sitter-v${version}"; + hash = "sha256-wBWfSyR8LGtug/mCD0bJ4lbdN3trIA/03AnCxZoEOSA="; + }; + + cargoSha256 = "sha256-OQPUWqJAts8DbFNSsC/CmMCbuZ9TVxRTR05O7oiodKI="; + + nativeBuildInputs = [ makeWrapper ]; + + postFixup = '' + wrapProgram "$out/bin/ktsctl" \ + --suffix PATH : ${stdenv.cc} + ''; + + meta = with lib; { + description = "Server that interfaces tree-sitter with kakoune"; + homepage = "https://git.sr.ht/~hadronized/kak-tree-sitter"; + license = with licenses; [ mit ]; + }; +} diff --git a/pkgs/lipsum.nix b/pkgs/lipsum.nix new file mode 100644 index 0000000..de1b75a --- /dev/null +++ b/pkgs/lipsum.nix @@ -0,0 +1,32 @@ +{ + stdenv, + fetchFromGitHub, + pkg-config, + vala, + wrapGAppsHook, +}: +stdenv.mkDerivation rec { + pname = "lipsum"; + version = "0.0.1"; + + src = fetchFromGitHub { + owner = "hannenz"; + repo = "lipsum"; + rev = "0fb31e6ede10fbd78d7652f5fb21670cddd8e3ed"; + hash = "sha256-a6uv0tJulN9cAGWxvQr8B0PUJEY8Rx4e759xzS66Xlo="; + }; + + nativeBuildInputs = [ + pkg-config + vala + wrapGAppsHook + ]; + + makeFlags = [ "PRG=${pname}" ]; + + installPhase = '' + install -Dm 755 "$pname" "$out/bin/$pname" + install -Dm 755 "./data/de.hannenz.lipsum.gschema.xml" "$out/share/glib-2.0/schemas/de.hannenz.lipsum.gschema.xml" + glib-compile-schemas "$out/share/glib-2.0/schemas/" + ''; +} diff --git a/pkgs/material-wifi-icons.nix b/pkgs/material-wifi-icons.nix new file mode 100644 index 0000000..c8b0dcc --- /dev/null +++ b/pkgs/material-wifi-icons.nix @@ -0,0 +1,16 @@ +{ stdenv, fetchFromGitHub }: +stdenv.mkDerivation rec { + pname = "material-wifi-icons"; + version = "0.0.1"; + + src = fetchFromGitHub { + owner = "dcousens"; + repo = "material-wifi-icons"; + rev = "2daf6b3d96d65beb2a3e37a9a53556aab3826d97"; + hash = "sha256-KykU5J7SdpBDG+6rkD//XeHd+6pK3qabe+88RduhwKc="; + }; + + installPhase = '' + install -D material-wifi.ttf $out/share/fonts/${pname} + ''; +} diff --git a/scripts/_diffr b/scripts/_diffr new file mode 100755 index 0000000..f387dd7 --- /dev/null +++ b/scripts/_diffr @@ -0,0 +1,12 @@ +#!/bin/sh + +exec diffr \ + --colors 'refine-added:foreground:green:underline' \ + --colors 'refine-added:background:none' \ + --colors 'refine-removed:foreground:red:underline' \ + --colors 'refine-removed:background:none' \ + --colors 'added:foreground:green' \ + --colors 'added:background:none' \ + --colors 'removed:foreground:red' \ + --colors 'removed:background:none' \ + "$@" diff --git a/scripts/_gpg-unlock.nix b/scripts/_gpg-unlock.nix new file mode 100644 index 0000000..e9196ab --- /dev/null +++ b/scripts/_gpg-unlock.nix @@ -0,0 +1,30 @@ +{ pkgs, ... }: +pkgs.writeShellScriptBin "_gpg-unlock" '' + ${pkgs.gnupg}/bin/gpg-connect-agent reloadagent /bye + + set -e + + test -f "$HOME/.config/.preset-password" || { + ${pkgs.libnotify}/bin/notify-send "No preset password found" + exit 0; + } + + get_keygrip() { + ${pkgs.gnupg}/bin/gpg --list-secret-keys --with-keygrip | + ${pkgs.gawk}/bin/awk ' + /^ssb/ { + ssb=1 + } + /Keygrip/{ + if (ssb) print $3 + }' + } + + keygrip=$(get_keygrip) + + test -n "$keygrip" || exit 0 + + ${pkgs.coreutils}/bin/cat "$HOME/.config/.preset-password" | + ${pkgs.coreutils}/bin/base64 -d | + ${pkgs.gnupg}/libexec/gpg-preset-passphrase --preset "$keygrip" +'' diff --git a/scripts/_sway_idle_toggle b/scripts/_sway_idle_toggle new file mode 100755 index 0000000..e77952c --- /dev/null +++ b/scripts/_sway_idle_toggle @@ -0,0 +1,11 @@ +#!/bin/sh + +swayidlectl() { + systemctl --user $1 swayidle.service +} + +if swayidlectl status > /dev/null; then + swayidlectl stop +else + swayidlectl start +fi diff --git a/scripts/_thunar-terminal b/scripts/_thunar-terminal new file mode 100755 index 0000000..64971b8 --- /dev/null +++ b/scripts/_thunar-terminal @@ -0,0 +1,10 @@ +#!/bin/sh + +for path +do + test -f "$path" && + path=$(dirname "$path") + + cd "$path" + terminal +done diff --git a/scripts/bmenu b/scripts/bmenu new file mode 100755 index 0000000..c793269 --- /dev/null +++ b/scripts/bmenu @@ -0,0 +1,53 @@ +#!/usr/bin/env fish + +# wrapper around bemenu +# bmenu * - use as dmenu, -p for custom prompt (man bemenu) +# bmenu run - select from .desktop files and run it +# bmenu start - internal option + +if test "$argv[1]" = "run" + test -n "$argv[2]" && set t "$argv[2]" || set t "terminal" + + test -n "$i3SOCK" && set wrapper 'i3-msg exec --' + test -n "$SWAYSOCK" && set wrapper 'swaymsg exec --' + + exec j4-dmenu-desktop \ + --dmenu="bmenu start -p Iniciar:" \ + --term "$t" \ + --wrapper="$wrapper" \ + --no-generic +end + +if test -n "$SWAYSOCK" + swaymsg -t get_outputs | + jq -r 'map(.focused)|reverse|index(true)' | + read focused_output + + test -n "$focused_output" + and set focused_output "-m $focused_output" +end + +set -l config "$HOME/.config/bmenu.conf" +if test -f $config + source $config +end + +exec dhist wrap -- bemenu \ + $focused_output\ + --ignorecase\ + --border 2\ + --center\ + --width-factor 0.5\ + --no-overlap\ + --list 30\ + --prefix '>'\ + --bdr "$bdr"\ + --fn "$fn"\ + --tb "$tb" --tf "$tf" \ + --fb "$fb" --ff "$ff" \ + --nb "$nb" --nf "$nf" \ + --ab "$ab" --af "$af" \ + --hb "$hb" --hf "$hf" \ + $argv + +# vim: ft=fish diff --git a/scripts/br b/scripts/br new file mode 100755 index 0000000..06a0dea --- /dev/null +++ b/scripts/br @@ -0,0 +1,47 @@ +#!/bin/sh + +set -e -u + +end(){ + rm -r -- "$(dirname -- "$namebase")" + [ $# -ne 0 ] && echo $@ >&2 + exit $# +} + +if [ $# -ne 0 ] ; then + for i in "$@" ; do + printf "%s\n" "$i" + done | "$0" + exit $? +fi + +namebase="$(mktemp -d)/blkrn" +echo '# Modify filenames without removing any line, quitting aborts' \ + > "$namebase.2" +tee -- "$namebase.1" >> "$namebase.2" +exec /dev/tty || + end 'Interactive terminal needed' + +"$EDITOR" -- "$namebase.2" +sed -i -- '1d' "$namebase.2" + +! diff -- "$namebase.1" "$namebase.2" &> /dev/null || end "no changes" +[ `wc -l < "$namebase.1"` -eq `wc -l < "$namebase.2"` ] || end "Wrong number of lines" + +{ + echo '# Please review/modify this script or empty it to do nothing' + echo 'run(){' + echo ' mkdir -p "$(dirname "$2")"' + echo ' mv -T -- "$1" "$2"' + echo '}' + while read -r l1 <&3 && read -r l2 <&4; do + [ "$l1" = "$l2" ] || printf "%s\n%s\n" "$l1" "$l2" + done 3<"$namebase.1" 4<"$namebase.2" | + sed 's/\([\\"$`]\)/\\\1/g;s/^.*$/"&"/' | + xargs -d"\n" -L2 echo 'run' +} > "$namebase.sh" + +"$EDITOR" -- "$namebase.sh" +sh -e -- "$namebase.sh" + +end # exit normaly diff --git a/scripts/color_picker b/scripts/color_picker new file mode 100755 index 0000000..e0ac75f --- /dev/null +++ b/scripts/color_picker @@ -0,0 +1,10 @@ +#!/bin/sh + +set -xe + +grim -g "$(slurp -b aabbcc00 -p)" - | + convert - txt:- | + grep -oE '#[0-9A-Fa-f]{6}' | + wl-copy -n + +notify-send "$(wl-paste)" "Copied to clipboard" diff --git a/scripts/default.nix b/scripts/default.nix index ff25367..47aaac5 100644 --- a/scripts/default.nix +++ b/scripts/default.nix @@ -18,13 +18,112 @@ --suffix PATH : ${lib.makeBinPath runtimeInputs} ''; createScripts = lib.mapAttrs (name: deps: wrapScript name ./${name} deps); + + myPass = final.pass.withExtensions (ex: with ex; [ pass-otp ]); in with final; createScripts { + br = [ ]; + bmenu = [ + bemenu + dhist + fish + j4-dmenu-desktop + jq + sway + ]; + down_meme = [ + wl-clipboard + yt-dlp + libnotify + ]; wl-copy-file = [ wl-clipboard fish ]; + _diffr = [ diffr ]; + _thunar-terminal = [ terminal ]; + _sway_idle_toggle = [ swayidle ]; + kak-pager = [ + fish + _diffr + ]; + kak-man-pager = [ kak-pager ]; + helix-pager = [ + fish + _diffr + ]; + helix-man-pager = [ helix-pager ]; + musmenu = [ + mpc-cli + wdmenu + trash-cli + xdg-user-dirs + libnotify + sd + wl-clipboard + ]; + showkeys = [ ]; # This will not work unless programs.wshowkeys is enabled systemwide + terminal = [ alacritty ]; + playerctl-status = [ playerctl ]; + pass-export = [ + pass2csv + gnupg + sd + ]; + wpass = [ + wdmenu + fd + myPass + sd + wl-clipboard + wtype + ]; + screenshotsh = [ + capitaine-cursors + grim + slurp + jq + sway + wl-clipboard + xdg-user-dirs + ]; + volumesh = [ + pulseaudio + libnotify + ]; + pulse_sink = [ + pulseaudio + pamixer + wdmenu + ]; + color_picker = [ + grim + slurp + wl-clipboard + libnotify + imagemagick + ]; + dzadd = [ + procps + libnotify + wdmenu + jq + mpv + pqiv + python3Packages.deemix + mpc-cli + mpdDup + ]; + mpdDup = [ + mpc-cli + perl + ]; + readQrCode = [ + grim + zbar + wl-clipboard + ]; auto_connect_gamepad = [ bluez coreutils @@ -36,4 +135,9 @@ libratbag ]; } + // lib.mapAttrs importScript { + wdmenu = ./wdmenu.nix; + wlauncher = ./wlauncher.nix; + _gpg-unlock = ./_gpg-unlock.nix; + } ) diff --git a/scripts/down_meme b/scripts/down_meme new file mode 100755 index 0000000..133fe33 --- /dev/null +++ b/scripts/down_meme @@ -0,0 +1,19 @@ +#!/bin/sh + +DIR=$(mktemp -d) + +cd "$DIR" + +yt-dlp --merge-output-format mp4 "$(wl-paste)" + +FILENAME="$(ls | head -n1)" + +mkdir -p "$HOME/Downloads/Memes" + +cp "$FILENAME" "$HOME/Downloads/Memes/$FILENAME" + +wl-copy-file "$HOME/Downloads/Memes/$FILENAME" + +notify-send "Meme downloaded" "$FILENAME" + +rm -rf "$DIR" diff --git a/scripts/dzadd b/scripts/dzadd new file mode 100755 index 0000000..585275f --- /dev/null +++ b/scripts/dzadd @@ -0,0 +1,176 @@ +#!/bin/sh + +set -ex + +tmpf=$(mktemp /tmp/dzadd.XXXXXX) + +clean() { + test "$?" -eq "0" || + notify-send "Exiting with error" + + set +e + kill "$mpvPid" + rm -f "$tmpf" +} + +trap clean EXIT + +main() { + sType=$(printf "Track\nAlbum\nArtist" | wdmenu | tr '[:upper:]' '[:lower:]') + test -n "$sType" || exit 1 + + query=$(echo -n | wdmenu | sed 's/[^ a-z0-9]//g;s/ /+/g') + test -n "$query" || exit 1 + + case "$sType" in + track) + deezer_category="track" + jqFilter='.data[]| "\(.title) - \(.album.title) - \(.artist.name) |\(.id)"' + ;; + album) + deezer_category="album" + jqFilter='.data[]| "\(.nb_tracks) - \(.title) - \(.artist.name) |\(.id)"' + ;; + artist) + deezer_category="artist" + jqFilter='.data[]| "\(.nb_fan) - \(.name) |\(.id)"' + ;; + top50) + deezer_category="artist" + jqFilter='.data[]| "\(.nb_fan) - \(.name) |\(.id)"' + ;; + *) + exit 1 + ;; + esac + + curl -m30 -s "api.deezer.com/search/${deezer_category}?q=${query}" | + sed 's/|//g' | + jq -r "$jqFilter" >"$tmpf" + + pick_song +} + +pick_song() { + choice=$(cat "$tmpf" | cut -d\| -f1 | wdmenu) + choice=$(grep "$choice" "$tmpf" | head -n 1) + choiceId=$(printf "%s" "$choice" | cut -d\| -f2) + + case "$sType" in + top50) + choiceUrl="http://deezer.com/${deezer_category}/${choiceId}/top?=limit=50" + ;; + *) + choiceUrl="http://deezer.com/${deezer_category}/${choiceId}" + ;; + esac + + + pick_action "$choiceUrl" +} + +pick_action() { + + choiceUrl="$1" + + COMMON_CHOISES="View Image\nDownload\nCopy URL\nAnother" + choice=$(printf "Preview\n${COMMON_CHOISES}" | wdmenu) + + case "$choice" in + + "Preview") + common_preview + ;; + + "View Image") + common_art + ;; + + "Download") + common_download + ;; + + "Copy URL") + wl-copy + ;; + + "Another") + pick_song + ;; + + *) + exit 1 + ;; + + esac + +} + +common_preview() { + + case "$sType" in + track) + ;; + album) + preview_suffix=tracks + ;; + artist) + preview_suffix=top + ;; + top50) + preview_suffix=top + ;; + *) + exit 1 + ;; + esac + + choicePreview=$( + curl -m30 -s "http://api.deezer.com/${deezer_category}/${choiceId}/${preview_suffix}" | + jq -r '.preview, .data[0].preview | select(. != null)' + ) + + mpv --quiet --volume=50 --no-resume-playback "$choicePreview" & + mpvPid="$!" + choice=$(printf "$COMMON_CHOISES" | wdmenu -p 'Download?') + kill "$mpvPid" || true +} + +common_art() { + + case "$sType" in + track) + image_filter='.album.cover_big' + ;; + album) + image_filter='.cover_big' + ;; + artist) + image_filter='.picture_big' + ;; + top50) + image_filter='.picture_big' + ;; + *) + exit 1 + ;; + esac + + curl -m30 -s "api.deezer.com/${deezer_category}/${choiceId}" | + jq -r "$image_filter" | + xargs curl -m30 -s | + pqiv - + + pick_action +} + +common_download() { + notify-send "Starting Download" + deemix "$choiceUrl" ; + set buffer filetype man; + rmhl global/number-lines; + set global scrolloff 10,0 +' diff --git a/scripts/kak-pager b/scripts/kak-pager new file mode 100755 index 0000000..33af67b --- /dev/null +++ b/scripts/kak-pager @@ -0,0 +1,33 @@ +#!/usr/bin/env fish + +if test (count $argv) -ne 0 + for i in $argv + cat "$i" + end | eval (status filename) + exit 0 +end + +set term_line_count (tput lines) + +while read line + set -a input_lines "$line" + + set input_line_count (printf "%s\n" $input_lines | wc -l) + + if test "$term_line_count" -lt "$input_line_count" + begin + printf "%s\n" $input_lines + cat + end | kak -e ' + exec + map global normal q :q; + rmhl global/number-lines; + set global scrolloff 10,0; + ' + + exit 0 + end + +end + +printf "%s\n" $input_lines diff --git a/scripts/mpdDup b/scripts/mpdDup new file mode 100755 index 0000000..69b1732 --- /dev/null +++ b/scripts/mpdDup @@ -0,0 +1,5 @@ +#!/bin/sh +mpc playlist -f '%position%\t%file%' | + sort -k 2 | + perl -ne 'm/(.*)\t(.*)/; print "$1\n" if $2 eq $prev; $prev=$2' | + mpc del diff --git a/scripts/musmenu b/scripts/musmenu new file mode 100755 index 0000000..0fc2c31 --- /dev/null +++ b/scripts/musmenu @@ -0,0 +1,111 @@ +#!/bin/sh +set -e + +menu=wdmenu + +search() { + tabs 8 + + mpc playlist --format '%artist% : %title%@pos:%position%' | + sed '/^ : \t/d'| + column -ts"@" | + $menu | + grep -o 'pos:.*' | + cut -d: -f2 | + xargs -r mpc play +} + +get_current() { + music_root=$(xdg-user-dir MUSIC || echo "$HOME/Music") + current_file=$(mpc current -f %file%) + + echo "${music_root}/${current_file}" +} + +delete() { + current=$(get_current) + answer=$(printf "nothing\n$current" | $menu -p"delete?") + if test "$answer" = "$current"; then + trash "$answer" + mpc --quiet next + mpc --quiet update + + path=$(echo $answer | sd "$HOME" '~') + notify-send "Removed Music" "$path" + fi +} + +yank() { + current=$(get_current) + + # Some programs need you to pass a path, not the contents + wl-copy --type 'text/uri-list' "file:///${current}" + + notify-send "Yanked Music" "$(echo $current | sd "$HOME" "~")" +} + +padd() { + get_current + cd "$music_root" + choice=$(fd -E '*.lrc' -E '*.m3u8' | sort | $menu -p "Add Songs(Use Ctrl):") + mpc add "$choice" && + notify-send "Added Music" "$(echo $choice | sd "$HOME" "~")" || + notify-send "Failed to Add Music" "$(echo $choice | sd "$HOME" "~")" + mpdDup +} + +pclear() { + mpc clear && + notify-send "Cleared Playlist" || + notify-send "Failed Clear Playlist" +} + +psave() { + name=$(mpc playlist | $menu -p 'Save Playlist(Use Shift): ') + + mpc save "$name" && + notify-send "Created playlist" "$name" || + notify-send "Failed to Create Playlist" "$name" +} + +pload() { + name=$(mpc lsplaylists | $menu -p 'Load Playlist: ') + + mpc clear + mpc load "$name" && + notify-send "Loaded playlist" "$name" || + notify-send "Failed to Load Playlist" "$name" +} + +pdelete() { + name=$(mpc lsplaylists | $menu -p 'Delete Playlist: ') + + mpc delete "$name" && + notify-send "Deleted playlist" "$name" || + notify-send "Failed to Delete Playlist" "$name" +} + +usage() { + cmdname=$(basename "$0") + echo "Commands:" + echo " $cmdname search -- Search and play songs." + echo " $cmdname delete -- Prompt to delete the current song." + echo " $cmdname yank -- Copy current music to clipboard." + echo "Playlist Commands:" + echo " $cmdname padd -- Add song" + echo " $cmdname pclear -- Clear" + echo " $cmdname psave -- Save" + echo " $cmdname pload -- Load" + echo " $cmdname pdelete -- Delete" +} + +case "$1" in + delete | search | yank | padd | pclear | psave | pload | pdelete) + "$1" + ;; + *) + usage + test -n "$1" + echo "Unreconized option: $1" + ;; +esac diff --git a/scripts/pass-export b/scripts/pass-export new file mode 100755 index 0000000..27596fc --- /dev/null +++ b/scripts/pass-export @@ -0,0 +1,13 @@ +#!/bin/sh + +if test -z "$PASSWORD_STORE_DIR"; then + PASSWORD_STORE_DIR="$HOME/.password-store" +fi + +pass2csv "$PASSWORD_STORE_DIR" "$HOME/passwords.csv" \ + -f User '(user|login)(:\s*)?' \ + -f TOTP 'otpauth(:)?' \ + -f URL 'url(:\s*)?' + +# Fix TOTP format for keepass +sd '"//totp/.*?secret=(.*?)(&.*?)?"' '"$1"' "$HOME/passwords.csv" \ No newline at end of file diff --git a/scripts/playerctl-status b/scripts/playerctl-status new file mode 100755 index 0000000..76b2262 --- /dev/null +++ b/scripts/playerctl-status @@ -0,0 +1,10 @@ +#!/bin/sh + +PLAYERCTL="playerctl --ignore-player=mpd" + +test "$(LC_ALL=C $PLAYERCTL status)" = "Playing" \ +&& printf " %s" "$($PLAYERCTL metadata title)" \ +&& test -n "$($PLAYERCTL metadata artist)" \ +&& printf " - %s" "$($PLAYERCTL metadata artist)" + +echo "" diff --git a/scripts/pulse_sink b/scripts/pulse_sink new file mode 100755 index 0000000..b38437c --- /dev/null +++ b/scripts/pulse_sink @@ -0,0 +1,26 @@ +#!/bin/sh + +list_sinks() { + env LC_ALL=C pactl list sinks +} + +desc=$( + list_sinks | + grep -ie "description:" | + cut -d: -f2 | + sed 's/^ //g;s/ $//g;' | + wdmenu -i -p "Output:" +) +device=$( + list_sinks | + grep -C2 "Description: $desc"| + grep Name | + cut -d: -f2 | + xargs +) + +vol=$(pamixer --get-volume) + +pactl set-default-sink "$device" + +pamixer --set-volume "$vol" diff --git a/scripts/readQrCode b/scripts/readQrCode new file mode 100755 index 0000000..a86de59 --- /dev/null +++ b/scripts/readQrCode @@ -0,0 +1,18 @@ +#!/bin/sh + +set -o pipefail + +main() { + + if wl-paste | zbarimg -q --raw - | wl-copy + then + notify-send "Copied" "QrCode was copied to clipboard" + rm "$LOGFILE" + else + notify-send "Failed to read QrCode" "Log file is '$LOGFILE'" + fi + +} + +LOGFILE=$(mktemp /tmp/qrcode-XXXXXXXX.log) +main > "$LOGFILE" 2>&1 diff --git a/scripts/screenshotsh b/scripts/screenshotsh new file mode 100755 index 0000000..98aa17e --- /dev/null +++ b/scripts/screenshotsh @@ -0,0 +1,49 @@ +#!/bin/sh + +export XCURSOR_SIZE=40 +export XCURSOR_THEME='capitaine-cursors-light' + +screenshot="grim" +copy="wl-copy -t image/png" + +if which xdg-user-dir >/dev/null 2>&1; then + DESTFOLDER="$(xdg-user-dir PICTURES)" +else + for i in Images Imagens Pictures Fotos ""; do + DESTFOLDER="$HOME/$i" + test -d "$DESTFOLDER" && + break + done +fi + +DESTFOLDER="$DESTFOLDER/Screenshots" +mkdir -p "$DESTFOLDER" +DESTFILE="$DESTFOLDER/$(date +'%Y-%m-%d-%H%M%S_screenshot.png')" + +case $1 in + def) + # Screenshot to file + $screenshot "$DESTFILE" + echo "$DESTFILE" + ;; + + area) + # Screen area to file + $screenshot -g "$(slurp -d -b 30303088)" "$DESTFILE" + echo "$DESTFILE" + ;; + area-clip) + # Screen area to clipboard + $screenshot -g "$(slurp -d -b 30303088)" - | $copy + ;; + + clip) + # Focused monitor to clipboard + cur_output=$(swaymsg -t get_outputs | + jq -r '.[] | select(.focused) | .name') + + test -n "$cur_output" && + $screenshot -o "$cur_output" - | $copy || + $screenshot - | $copy + ;; +esac diff --git a/scripts/showkeys b/scripts/showkeys new file mode 100755 index 0000000..30629b8 --- /dev/null +++ b/scripts/showkeys @@ -0,0 +1,10 @@ +#!/bin/sh + +pidof wshowkeys && pkill wshowkeys || +exec wshowkeys \ + -a bottom -a right \ + -F 'Inter 20' \ + -b 202020AA \ + -s DD5050 \ + -t 1 \ + -m 100 diff --git a/scripts/terminal b/scripts/terminal new file mode 100755 index 0000000..b363f01 --- /dev/null +++ b/scripts/terminal @@ -0,0 +1,18 @@ +#!/bin/sh + +CLASS="terminal" + +while test $# -gt 0;do + case $1 in + -c|--class) + shift + CLASS=$1 + shift + ;; + *) + break + ;; + esac +done + +exec alacritty --class "$CLASS" "$@" diff --git a/scripts/volumesh b/scripts/volumesh new file mode 100755 index 0000000..010cbc9 --- /dev/null +++ b/scripts/volumesh @@ -0,0 +1,139 @@ +#!/bin/sh + +set -xe + +# depends on: awk, pactl, pacmd, notify-send + +MAX_VOL=150 +STEP=10 + +notify() { + volume=$(get_vol_$TARGET) + + if is_muted_$TARGET; then + s="Muted" + else + s="Volume" + fi + + s=$(echo "${TARGET} ${s}" | sed 's/^\(.\)/\U\1/') + + notify-send "${s}" "${volume}%" \ + --app-name=volumesh \ + --hint=int:value:"$volume" + +} + +round() { + awk '{ + print int($1/'$STEP')*'$STEP'; + }' +} + +round_vol() { + rounded=$(get_vol_$TARGET | round) + newvol=$(min $MAX_VOL $rounded) +} + +min() { + printf '%i\n' ${@} | sort -n | head -n1 +} + +# Pulse{{{ +get_vol_system() { + pamixer --get-volume +} + +is_muted_system() { + test "$(pamixer --get-mute)" = "true" >/dev/null +} + +change_vol_system() { + pamixer "-$1" "$(min 120 $2)" + round_vol + pamixer --set-volume "${newvol}" + if + test -n "$VOLUME_CHANGE_SOUND" + then + paplay "$VOLUME_CHANGE_SOUND" + fi +} + +toggle_mute_system() { + pactl set-sink-mute @DEFAULT_SINK@ toggle +} +#}}} +# Mpd {{{ + +get_vol_mpd() { + env LC_ALL=C mpc vol | + sed -e 's/^.*://g' -e 's/%.*$//g' -e 's/ //g' +} + +is_muted_mpd() { + env LC_ALL=C mpc status | grep '\[paused\]' 1>/dev/null +} +change_vol_mpd() { + case $1 in + d) + op="-";; + i) + op="+";; + esac + mpc vol "${op}${2}" &>/dev/null + round_vol + mpc vol "${newvol}" &>/dev/null +} + +toggle_mute_mpd() { + mpc toggle +} +#}}} +usage() { + local CNAME=$(basename $0) + echo "${CNAME} [-m][-di ]" + echo "${CNAME} [-m][-t]" + echo "" + echo "Options:" + echo " -m --mpd Target mpd instead of PulseAudio" + echo " -i --increase of volume to increase" + echo " -d --decrease of volume to decrease" + echo " -t --toggle Mute/Unmute target" + echo " -h --help Show This help message" + + exit "$1" +} +TARGET=system + +while [ $# -gt 0 ]; do + case $1 in + -m | --mpd) + TARGET=mpd + shift + ;; + -i | --increase) + shift + change_vol_$TARGET i $1 + shift + ;; + -d | --decrease) + shift + change_vol_$TARGET d $1 + shift + ;; + -t | --toggle) + toggle_mute_$TARGET + shift + ;; + -h | --help) + usage 0 + ;; + *) + usage 1 + ;; + esac +done + +notify + +# vim: fdm=marker diff --git a/scripts/wdmenu.nix b/scripts/wdmenu.nix new file mode 100644 index 0000000..3505781 --- /dev/null +++ b/scripts/wdmenu.nix @@ -0,0 +1,4 @@ +{ pkgs, ... }: +pkgs.writeShellScriptBin "wdmenu" '' + exec bmenu "$@" +'' diff --git a/scripts/wfile-picker.nix b/scripts/wfile-picker.nix new file mode 100644 index 0000000..d8ced8a --- /dev/null +++ b/scripts/wfile-picker.nix @@ -0,0 +1,12 @@ +{ pkgs, ... }: +let + inherit (config.my) dmenu; + available_menus = { + bmenu = "bmenu run"; + rofi = "rofi -show drun -sort"; + }; + menu_cmd = available_menus.${dmenu}; +in +pkgs.writeShellScriptBin "wlauncher" '' + exec ${menu_cmd} "$@" +'' diff --git a/scripts/wlauncher.nix b/scripts/wlauncher.nix new file mode 100644 index 0000000..d2c2dec --- /dev/null +++ b/scripts/wlauncher.nix @@ -0,0 +1,4 @@ +{ pkgs, ... }: +pkgs.writeShellScriptBin "wlauncher" '' + exec bmenu run "$@" +'' diff --git a/switch-with-home-cache b/switch-with-home-cache new file mode 100755 index 0000000..cff021a --- /dev/null +++ b/switch-with-home-cache @@ -0,0 +1,6 @@ +#!/bin/sh + +./switch \ + --option extra-substituters "http://nixcache.lelgenio.1337.cx:5000" \ + --option extra-trusted-public-keys "nixcache.lelgenio.1337.cx:HZCwDaM39BOF+MLuviMQTUrz3rBWLTLV9H+GV4zcxVI=" \ + "$@" diff --git a/system/cachix.nix b/system/cachix.nix new file mode 100644 index 0000000..7ff9b29 --- /dev/null +++ b/system/cachix.nix @@ -0,0 +1,18 @@ +{ + pkgs, + lib, + config, + ... +}: +{ + services.cachix-watch-store = { + enable = true; + cacheName = "lelgenio"; + cachixTokenFile = config.age.secrets.lelgenio-cachix.path; + }; + systemd.services.cachix-watch-store-agent = { + serviceConfig.TimeoutStopSec = 3; + # If we don't do this, cachix tends to timeout + serviceConfig.KillMode = lib.mkForce "control-group"; + }; +} diff --git a/system/configuration.nix b/system/configuration.nix index 309b831..c8095f6 100644 --- a/system/configuration.nix +++ b/system/configuration.nix @@ -9,8 +9,11 @@ }: { imports = [ + ./gamemode.nix + ./cachix.nix ./media-packages.nix ./boot.nix + ./thunar.nix ./nix.nix ./fonts.nix ./sound.nix diff --git a/system/gamemode.nix b/system/gamemode.nix new file mode 100644 index 0000000..92207cd --- /dev/null +++ b/system/gamemode.nix @@ -0,0 +1,27 @@ +{ + config, + pkgs, + inputs, + ... +}: +{ + programs.gamemode.enable = true; + programs.gamemode.enableRenice = true; + programs.gamemode.settings = { + general = { + renice = 10; + }; + + # Warning: GPU optimisations have the potential to damage hardware + gpu = { + apply_gpu_optimisations = "accept-responsibility"; + gpu_device = 0; + amd_performance_level = "high"; + }; + + custom = { + start = "${pkgs.libnotify}/bin/notify-send 'GameMode started'"; + end = "${pkgs.libnotify}/bin/notify-send 'GameMode ended'"; + }; + }; +} diff --git a/system/gnome.nix b/system/gnome.nix index 6759dfe..f56f938 100644 --- a/system/gnome.nix +++ b/system/gnome.nix @@ -42,5 +42,6 @@ chrome-gnome-shell gnomeExtensions.quick-settings-audio-devices-hider + gnome-pass-search-provider ]; } diff --git a/system/greetd.nix b/system/greetd.nix new file mode 100644 index 0000000..2b5f22f --- /dev/null +++ b/system/greetd.nix @@ -0,0 +1,97 @@ +{ + lib, + pkgs, + config, + ... +}: +let + inherit (config.my) + key + accent + font + theme + desktop + ; + + cfg = config.login-manager.greetd; +in +{ + options.login-manager.greetd = { + enable = lib.mkEnableOption "Use greetd as login manager"; + }; + + config = lib.mkIf cfg.enable { + + # Enable the X11 windowing system. + services.xserver.enable = false; + + # enable sway window manager + programs.sway = { + enable = true; + package = pkgs.mySway; + wrapperFeatures.gtk = true; + }; + + services.dbus.enable = true; + programs.wshowkeys.enable = true; + xdg.portal = { + enable = true; + wlr.enable = true; + # Always pick the first monitor, this is fine since I only ever use a single monitor + wlr.settings.screencast.chooser_type = "none"; + # gtk portal needed to make gtk apps happy + extraPortals = [ pkgs.xdg-desktop-portal-gtk ]; + }; + services.greetd = + let + greetd_main_script = pkgs.writeShellScriptBin "main" '' + export XDG_CURRENT_DESKTOP=sway GTK_THEME="${theme.gtk_theme}" XCURSOR_THEME="${theme.cursor_theme}" + ${pkgs.greetd.gtkgreet}/bin/gtkgreet -l -c ${desktop} + swaymsg exit + ''; + swayConfig = pkgs.writeText "greetd-sway-config" '' + # `-l` activates layer-shell mode. Notice that `swaymsg exit` will run after gtkgreet. + exec "${greetd_main_script}/bin/main" + bindsym Mod4+shift+e exec swaynag \ + -t warning \ + -m 'What do you want to do?' \ + -b 'Poweroff' 'systemctl poweroff' \ + -b 'Reboot' 'systemctl reboot' + input "*" { + repeat_delay 200 + repeat_rate 30 + xkb_layout us(colemak) + xkb_numlock enabled + xkb_options lv3:lsgt_switch,grp:shifts_toggle + } + ''; + in + { + enable = true; + settings = { + initial_session = { + command = desktop; + user = "lelgenio"; + }; + default_session = { + command = "${pkgs.sway}/bin/sway --config ${swayConfig}"; + }; + }; + }; + environment.systemPackages = with pkgs; [ + sway + swaylock + swayidle + + wayland + pkgs.xdg-desktop-portal + pkgs.xdg-desktop-portal-wlr + + ## Theme + capitaine-cursors + bibata-cursors + orchis_theme_compact + papirus_red + ]; + }; +} diff --git a/system/kde.nix b/system/kde.nix new file mode 100644 index 0000000..c5ef277 --- /dev/null +++ b/system/kde.nix @@ -0,0 +1,15 @@ +{ config, pkgs, ... }: +{ + # Enable the X11 windowing system. + services.xserver.enable = true; + # Enable the KDE Desktop Environment. + services.xserver.displayManager.sddm.enable = true; + services.xserver.desktopManager.plasma5.enable = true; + # services.xserver.displayManager.autologin.user = "lelgenio"; + programs.dconf.enable = true; + # environment.systemPackages = with pkgs; + # with gnome; [ + # gnome-tweaks + # dconf-editor + # ]; +} diff --git a/system/media-packages.nix b/system/media-packages.nix index 491cb11..8458087 100644 --- a/system/media-packages.nix +++ b/system/media-packages.nix @@ -13,16 +13,19 @@ in }; config = lib.mkIf cfg.enable { environment.systemPackages = with pkgs; [ + down_meme yt-dlp ffmpeg obs-studio imagemagick + mpc-cli helvum gimp inkscape krita kdePackages.breeze kdePackages.kdenlive + pitivi blender-hip libreoffice godot_4 diff --git a/system/nix-serve.nix b/system/nix-serve.nix new file mode 100644 index 0000000..6cc7161 --- /dev/null +++ b/system/nix-serve.nix @@ -0,0 +1,12 @@ +{ + config, + pkgs, + lib, + ... +}: +{ + services.nix-serve = { + enable = true; + secretKeyFile = config.age.secrets.monolith-nix-serve-privkey.path; + }; +} diff --git a/system/thunar.nix b/system/thunar.nix new file mode 100644 index 0000000..fcb9e3b --- /dev/null +++ b/system/thunar.nix @@ -0,0 +1,32 @@ +{ + config, + pkgs, + inputs, + ... +}: +{ + programs.thunar = { + enable = true; + plugins = with pkgs.xfce; [ + thunar-archive-plugin + thunar-volman + ]; + }; + # Mount, trash, and other functionalities + services.gvfs.enable = true; + # Thumbnail support for images + services.tumbler.enable = true; + + environment.systemPackages = [ + (pkgs.writeTextFile { + name = "thumbs"; + text = '' + [Thumbnailer Entry] + TryExec=unzip + Exec=sh -c "${pkgs.unzip}/bin/unzip -p %i preview.png > %o" + MimeType=application/x-krita; + ''; + destination = "/share/thumbnailers/kra.thumbnailer"; + }) + ]; +} diff --git a/user/alacritty.nix b/user/alacritty.nix new file mode 100644 index 0000000..eaaa414 --- /dev/null +++ b/user/alacritty.nix @@ -0,0 +1,179 @@ +{ + config, + pkgs, + lib, + ... +}: +let + inherit (config.my) + key + theme + accent + font + ; + inherit (theme) color; +in +{ + config = { + programs.alacritty = { + enable = true; + settings = { + font = { + size = font.size.small; + normal = { + family = font.mono; + }; + }; + colors = { + primary = { + background = "${color.bg}"; + foreground = "${color.txt}"; + }; + cursor = { + text = "#000000"; + cursor = "${accent.color}"; + }; + normal = { + black = "${color.normal.black}"; + red = "${color.normal.red}"; + green = "${color.normal.green}"; + yellow = "${color.normal.yellow}"; + blue = "${color.normal.blue}"; + magenta = "${color.normal.magenta}"; + cyan = "${color.normal.cyan}"; + white = "${color.normal.white}"; + }; + draw_bold_text_with_bright_colors = false; + }; + window = { + opacity = theme.opacity / 100.0; + dynamic_padding = true; + }; + + hints = { + alphabet = key.hints; + enabled = [ + { + regex = + let + mimes = "(mailto:|gemini:|gopher:|https:|http:|news:|file:|git:|ssh:|ftp:)"; + # I fucking hate regex, look at this bullshit + delimiters = ''^\\u0000-\\u001F\\u007F-\\u009F<>"\\s{-}\\^⟨⟩`''; + # Kakoune uses these characters to represent whitespace, + # but alacritty doesn't know about them + whitespace_characters = ''¬·→''; + in + "${mimes}[${delimiters}${whitespace_characters}]+"; + command = "xdg-open"; + post_processing = true; + mouse = { + enabled = true; + mods = "None"; + }; + binding = { + key = "U"; + mods = "Control|Shift"; + }; + } + ]; + }; + mouse = { + hide_when_typing = true; + }; + keyboard.bindings = [ + { + key = lib.toUpper key.up; + mode = "Vi|~Search"; + action = "Up"; + } + { + key = lib.toUpper key.down; + mode = "Vi|~Search"; + action = "Down"; + } + { + key = lib.toUpper key.left; + mode = "Vi|~Search"; + action = "Left"; + } + { + key = lib.toUpper key.right; + mode = "Vi|~Search"; + action = "Right"; + } + { + key = lib.toUpper key.insertMode; + mode = "Vi|~Search"; + action = "ScrollToBottom"; + } + { + key = lib.toUpper key.insertMode; + mode = "Vi|~Search"; + action = "ToggleViMode"; + } + { + key = lib.toUpper key.next; + mode = "Vi|~Search"; + action = "SearchNext"; + } + { + key = lib.toUpper key.next; + mods = "Shift"; + mode = "Vi|~Search"; + action = "SearchPrevious"; + } + { + key = "Up"; + mods = "Control|Shift"; + mode = "~Alt"; + action = "ScrollLineUp"; + } + { + key = "Down"; + mods = "Control|Shift"; + mode = "~Alt"; + action = "ScrollLineDown"; + } + { + key = "PageUp"; + mods = "Control|Shift"; + mode = "~Alt"; + action = "ScrollHalfPageUp"; + } + { + key = "PageDown"; + mods = "Control|Shift"; + mode = "~Alt"; + action = "ScrollHalfPageDown"; + } + { + key = "N"; + mods = "Control|Shift"; + action = "SpawnNewInstance"; + } + # {%@@ if key.layout == "colemak" @@%} + { + key = "T"; + mode = "Vi|~Search"; + action = "SemanticRightEnd"; + } + # {%@@ endif @@%} + ]; + }; + }; + + home.sessionVariables = { + TERMINAL = "alacritty"; + }; + + # Look at this fucking bullshit: + # https://gitlab.gnome.org/GNOME/glib/-/blob/20c4fcb2a7246a2b205649eae3ebda4296217afc/gio/gdesktopappinfo.c#L2702 + # Theres a fucking hard coded list of terminals! + home.packages = with pkgs; [ + (pkgs.writeShellScriptBin "gnome-terminal" '' + [ "$1" = "--" ] && shift + exec terminal -e "$@" + '') + ]; + }; +} diff --git a/user/desktop-entries.nix b/user/desktop-entries.nix index e4b4b60..c513d45 100644 --- a/user/desktop-entries.nix +++ b/user/desktop-entries.nix @@ -6,6 +6,41 @@ }: { xdg.desktopEntries = { + kak = { + name = "Kakoune"; + genericName = "Text Editor"; + comment = "Edit text files"; + exec = "kak %F"; + terminal = true; + type = "Application"; + icon = "kak.desktop"; + categories = [ + "Utility" + "TextEditor" + ]; + startupNotify = true; + mimeType = [ + "text/english" + "text/plain" + "text/x-makefile" + "text/x-c++hdr" + "text/x-c++src" + "text/x-chdr" + "text/x-csrc" + "text/x-java" + "text/x-moc" + "text/x-pascal" + "text/x-tcl" + "text/x-tex" + "application/x-shellscript" + "text/x-c" + "text/x-c++" + ]; + settings = { + Keywords = "Text;editor;"; + TryExec = "kak"; + }; + }; down_meme = { name = "DownMeme"; genericName = "Download memes"; diff --git a/user/eww/eww.scss b/user/eww/eww.scss new file mode 100644 index 0000000..6d22386 --- /dev/null +++ b/user/eww/eww.scss @@ -0,0 +1,61 @@ + +* { + all: unset; //Unsets everything so you can style everything from scratch +} + +//Global Styles +.bar { + background-color: #202020; + color: #b0b4bc; + padding: 10px; +} + +// Styles on classes (see eww.yuck for more information) + +.sidestuff slider { + all: unset; + color: #cc5757; +} + +.metric scale trough highlight { + all: unset; + background-color: #D35D6E; + color: #000000; + border-radius: 10px; +} +.metric scale trough { + all: unset; + background-color: #4e4e4e; + border-radius: 50px; + min-height: 3px; + min-width: 50px; + margin-left: 10px; + margin-right: 20px; +} +.metric scale trough highlight { + all: unset; + background-color: #D35D6E; + color: #000000; + border-radius: 10px; +} +.metric scale trough { + all: unset; + background-color: #4e4e4e; + border-radius: 50px; + min-height: 3px; + min-width: 50px; + margin-left: 10px; + margin-right: 20px; +} +.label-ram { + font-size: large; +} +.workspaces button:hover { + color: #D35D6E; +} + +.workspaces button.active { + color: #D35D6E; +} + + diff --git a/user/eww/eww.yuck b/user/eww/eww.yuck new file mode 100644 index 0000000..8d2994a --- /dev/null +++ b/user/eww/eww.yuck @@ -0,0 +1,80 @@ +(defwidget bar [] + (centerbox :orientation "h" + (workspaces) + (music) + (sidestuff))) + +(defwidget sidestuff [] + (box :class "sidestuff" :orientation "h" :space-evenly false :halign "end" + ; (metric :label "🔊" + ; :value volume + ; :onchange "amixer -D pulse sset Master {}%") + (metric :label "" + :value {EWW_RAM.used_mem_perc} + :onchange "") + (metric :label "💾" + :value {round((1 - (EWW_DISK["/"].free / EWW_DISK["/"].total)) * 100, 0)} + :onchange "") + time)) + +(defwidget workspaces [] + (box :class "workspaces" + :orientation "h" + :space-evenly true + :halign "start" + :spacing 10 + (button :class "${active_workspace == 1 ? 'active' : '' }" :onclick "wmctrl -s 0" 1) + (button :class "${active_workspace == 2 ? 'active' : '' }" :onclick "wmctrl -s 1" 2) + (button :class "${active_workspace == 3 ? 'active' : '' }" :onclick "wmctrl -s 2" 3) + (button :class "${active_workspace == 4 ? 'active' : '' }" :onclick "wmctrl -s 3" 4) + (button :class "${active_workspace == 5 ? 'active' : '' }" :onclick "wmctrl -s 4" 5) + (button :class "${active_workspace == 6 ? 'active' : '' }" :onclick "wmctrl -s 5" 6) + (button :class "${active_workspace == 7 ? 'active' : '' }" :onclick "wmctrl -s 6" 7) + (button :class "${active_workspace == 8 ? 'active' : '' }" :onclick "wmctrl -s 7" 8) + (button :class "${active_workspace == 9 ? 'active' : '' }" :onclick "wmctrl -s 8" 9))) + +(defwidget music [] + (box :class "music" + :orientation "h" + :space-evenly false + :halign "center" + {music != "" ? "🎵${music}" : ""})) + + +(defwidget metric [label value onchange] + (box :orientation "h" + :class "metric" + :space-evenly false + (box :class "label" label) + (scale :min 0 + :max 101 + :active {onchange != ""} + :value value + :onchange onchange))) + + + +(deflisten music :initial "" + "playerctl --follow metadata --format '{{ artist }} - {{ title }}' || true") + +; (defpoll volume :interval "1s" +; "scripts/getvol") + +(defpoll time :interval "10s" + "date '+%H:%M %b %d, %Y'") + +(defpoll active_workspace :interval "10ms" + "hyprctl monitors -j | jq '.[]|.activeWorkspace.id'") + +(defwindow bar + :monitor 0 + :windowtype "dock" + :geometry (geometry :x "0%" + :y "0%" + :width "100%" + :height "10px" + :anchor "top center") + :reserve (struts :side "top" :distance "4%") + :exclusive true + (bar)) + diff --git a/user/eww/scripts/getram b/user/eww/scripts/getram new file mode 100755 index 0000000..791a5a5 --- /dev/null +++ b/user/eww/scripts/getram @@ -0,0 +1,2 @@ +#!/bin/sh +printf "%.0f\n" $(free -m | grep Mem | awk '{print ($3/$2)*100}') diff --git a/user/eww/scripts/getvol b/user/eww/scripts/getvol new file mode 100755 index 0000000..6a95077 --- /dev/null +++ b/user/eww/scripts/getvol @@ -0,0 +1,2 @@ +#!/bin/sh +amixer -D pulse sget Master | grep 'Left:' | awk -F'[][]' '{ print $2 }' | tr -d '%' | head -1 diff --git a/user/fish/default.nix b/user/fish/default.nix index 5086444..a744d02 100644 --- a/user/fish/default.nix +++ b/user/fish/default.nix @@ -40,6 +40,12 @@ in }; shellAbbrs = { off = "shutdown now"; + v = + { + "helix" = "hx"; + "kakoune" = "kak"; + } + .${editor}; ns = "nix develop --command $SHELL"; wcf = "wl-copy-file"; c = "cargo"; diff --git a/user/git.nix b/user/git.nix index 444e68f..94532f3 100644 --- a/user/git.nix +++ b/user/git.nix @@ -28,6 +28,11 @@ in autoSquash = true; autoStash = true; }; + pager = { + log = "${pkgs._diffr}/bin/_diffr | ${pkgs.kak-pager}/bin/kak-pager"; + show = "${pkgs._diffr}/bin/_diffr | ${pkgs.kak-pager}/bin/kak-pager"; + diff = "${pkgs._diffr}/bin/_diffr | ${pkgs.kak-pager}/bin/kak-pager"; + }; alias = { graph = "log --graph --oneline --branches"; root = "rev-parse --show-toplevel"; diff --git a/user/gpg.nix b/user/gpg.nix new file mode 100644 index 0000000..f1c472f --- /dev/null +++ b/user/gpg.nix @@ -0,0 +1,47 @@ +{ + config, + pkgs, + lib, + ... +}: +{ + config = { + services.gpg-agent = { + enable = true; + defaultCacheTtl = 604800; + maxCacheTtl = 604800; + extraConfig = '' + allow-preset-passphrase + ''; + }; + systemd.user.services = { + gpg_unlock = { + Unit = { + Description = "Unlock gpg keyring"; + PartOf = [ "graphical-session.target" ]; + After = [ "graphical-session.target" ]; + }; + Service = { + ExecStart = "${pkgs._gpg-unlock}/bin/_gpg-unlock"; + }; + }; + }; + systemd.user.timers = { + gpg_unlock = { + Unit = { + Description = "Unlock gpg keyring"; + PartOf = [ "graphical-session.target" ]; + After = [ "graphical-session.target" ]; + }; + Timer = { + OnBootSec = "0"; + OnUnitActiveSec = "300"; + Unit = "gpg_unlock.service"; + }; + Install = { + WantedBy = [ "sway-session.target" ]; + }; + }; + }; + }; +} diff --git a/user/home.nix b/user/home.nix index 089ecce..e606b4f 100644 --- a/user/home.nix +++ b/user/home.nix @@ -9,20 +9,36 @@ { imports = [ ./controller.nix + ./waybar ./helix.nix + ./kakoune ./vscode ./fish ./firefox.nix + ./alacritty.nix ./git.nix ./ssh.nix + ./gpg.nix + ./rofi.nix + ./mpv.nix ./mangohud.nix ./pipewire.nix ./mimeapps.nix ./desktop-entries.nix ./chat.nix + ./syncthing.nix + ./bmenu.nix ./fzf.nix + ./ranger + ./lf + ./pass.nix + ./pqiv.nix + ./zathura.nix ./man.nix + ./mpd.nix + ./sway ./gnome.nix + ./thunar.nix ./xdg-dirs.nix inputs.nix-index-database.hmModules.nix-index ../settings @@ -41,6 +57,9 @@ home.packages = with pkgs; [ # home-manager + terminal # see flake.nix + + pulse_sink pulseaudio ## CLI @@ -53,6 +72,8 @@ p7zip tealdeer micro + _diffr + br # bulk rename comma @@ -67,6 +88,7 @@ sd ripgrep translate-shell + lipsum par mate.engrampa @@ -111,6 +133,7 @@ clang-tools # c/c++ lsp server rust-analyzer # rust analyzer + blade-formatter nixfmt-rfc-style ]; diff --git a/user/kakoune/colors.nix b/user/kakoune/colors.nix new file mode 100644 index 0000000..a0917d4 --- /dev/null +++ b/user/kakoune/colors.nix @@ -0,0 +1,225 @@ +{ + pkgs, + lib, + color, + accent, +}: +let + colors = lib.mapAttrs (_: lib.replaceStrings [ "#" ] [ "rgb:" ]) { + accent_fg = accent.fg; + accent_color = accent.color; + bg_light = color.bg_light; + bg_dark = color.bg_dark; + nontxt = color.nontxt; + orange = color.normal.orange; + brown = color.normal.brown; + }; +in +with colors; +'' + crosshairs-enable + + face global crosshairs_line default,${bg_dark} + face global crosshairs_column default+b + + # For Code + face global value magenta + face global type yellow + face global variable blue + face global module ${brown} + face global function ${orange} + face global string green + face global keyword ${accent_color} + face global operator yellow + face global attribute cyan + face global comment ${bg_light} + face global documentation comment + face global meta +i@function + face global builtin blue + + # For markup + face global title blue + face global header cyan + face global mono green + face global block magenta + face global link cyan + face global bullet cyan + face global list yellow + + # builtin faces + face global Default default,default + + face global PrimaryCursor ${accent_fg},${accent_color}+fg + face global PrimaryCursorEol PrimaryCursor + face global PrimarySelection default,${bg_light}+f + + face global SecondaryCursor default,default+rfg + face global SecondaryCursorEol SecondaryCursor + face global SecondarySelection PrimarySelection + + face global InactiveCursor ${accent_fg},${bg_light}+fg + + face global MenuForeground ${accent_fg},${accent_color} + face global MenuBackground default,${bg_dark} + face global MenuInfo cyan + + face global Information default,${bg_dark} + face global Error default,red+g + + face global StatusLine %sh{ + printf "rgb:" + head /dev/urandom | + base64 | + rg --text -o "${color.random_range}" | + head -n 6 | + sd '\n' "" + } + face global StatusLineMode StatusLine + face global StatusLineInfo StatusLine + face global StatusLineValue StatusLine + face global StatusCursor ${accent_fg},${accent_color} + + face global Prompt yellow,default + try %{add-highlighter global/ show-matching} + face global MatchingChar ${accent_color},default+b + + # Goodies + try %{add-highlighter global/number-lines number-lines -relative -hlcursor} + face global LineNumbers ${bg_light},default + face global LineNumberCursor default,${bg_dark} + face global LineNumbersWrapped red,default + + try %{add-highlighter global/ show-whitespaces} + face global Whitespace ${nontxt},default+f + face global BufferPadding ${nontxt},default + ## highlight trailing whitespace + # add-highlighter global/ regex '\h*$' 0:red,red+u + + face global Reference default+bu + face global InlayHint ${bg_light}+buif + + # Lsp +'' ++ (lib.concatStringsSep "\n" ( + lib.mapAttrsToList + (name: color: '' + face global HighlightDiagnostic${name} ${color},default+bu + face global Diagnostic${name} ${color},default+bu + face global TextDiagnostic${name} ${color},default+b + face global InlayDiagnostic${name} ${color},default+br + '') + { + Error = "red"; + Warning = "yellow"; + Hint = "blue"; + } +)) ++ '' + # Color palette + declare-option str red "red" + declare-option str mauve "magenta" + declare-option str maroon "rgb:ee99a0" + declare-option str pink "rgb:f5bde6" + declare-option str cyan "cyan" + declare-option str yellow "yellow" + declare-option str green "green" + declare-option str white "white" + declare-option str blue "blue" + declare-option str sky "rgb:91d7e3" + declare-option str lavender "rgb:b7bdf8" + declare-option str black1 "rgb:202020" + declare-option str black2 "rgb:272727" + declare-option str black3 "rgb:3a3a3a" + declare-option str orange ${orange} + declare-option str teal "rgb:8bd5ca" + declare-option str flamingo "rgb:f0c6c6" + declare-option str gray0 "rgb:606060" + declare-option str gray1 "rgb:737373" + declare-option str bright_red "%opt{red}+b" + declare-option str bright_green "%opt{green}+b" + declare-option str bright_yellow "%opt{yellow}+b" + declare-option str bright_blue "%opt{blue}+b" + declare-option str bright_cyan "%opt{cyan}+b" + declare-option str foreground %opt{white} + declare-option str background %opt{black2} + declare-option str overlay0 "rgb:878787" + declare-option str overlay1 "rgb:9a9a9a" + + # Tree-sitter () + set-face global ts_attribute "%opt{cyan}" + set-face global ts_comment "%opt{overlay0}+i" + set-face global ts_conceal "%opt{mauve}+i" + set-face global ts_constant "%opt{orange}" + set-face global ts_constant_builtin_boolean "%opt{sky}" + set-face global ts_constant_character "%opt{yellow}" + set-face global ts_constant_macro "%opt{mauve}" + set-face global ts_constructor "%opt{cyan}" + set-face global ts_diff_plus "%opt{green}" + set-face global ts_diff_minus "%opt{red}" + set-face global ts_diff_delta "%opt{blue}" + set-face global ts_diff_delta_moved "%opt{mauve}" + set-face global ts_error "%opt{red}+b" + set-face global ts_function "%opt{blue}" + set-face global ts_function_builtin "%opt{blue}+i" + set-face global ts_function_macro "%opt{mauve}" + set-face global ts_hint "%opt{blue}+b" + set-face global ts_info "%opt{green}+b" + set-face global ts_keyword "%opt{mauve}" + set-face global ts_keyword_conditional "%opt{mauve}+i" + set-face global ts_keyword_control_conditional "%opt{mauve}+i" + set-face global ts_keyword_control_directive "%opt{mauve}+i" + set-face global ts_keyword_control_import "%opt{mauve}+i" + set-face global ts_keyword_directive "%opt{mauve}+i" + set-face global ts_keyword_storage "%opt{mauve}" + set-face global ts_keyword_storage_modifier "%opt{mauve}" + set-face global ts_keyword_storage_modifier_mut "%opt{mauve}" + set-face global ts_keyword_storage_modifier_ref "%opt{teal}" + set-face global ts_label "%opt{cyan}+i" + set-face global ts_markup_bold "%opt{orange}+b" + set-face global ts_markup_heading "%opt{red}" + set-face global ts_markup_heading_1 "%opt{red}" + set-face global ts_markup_heading_2 "%opt{mauve}" + set-face global ts_markup_heading_3 "%opt{green}" + set-face global ts_markup_heading_4 "%opt{yellow}" + set-face global ts_markup_heading_5 "%opt{pink}" + set-face global ts_markup_heading_6 "%opt{teal}" + set-face global ts_markup_heading_marker "%opt{orange}+b" + set-face global ts_markup_italic "%opt{pink}+i" + set-face global ts_markup_list_checked "%opt{green}" + set-face global ts_markup_list_numbered "%opt{blue}+i" + set-face global ts_markup_list_unchecked "%opt{teal}" + set-face global ts_markup_list_unnumbered "%opt{mauve}" + set-face global ts_markup_link_label "%opt{blue}" + set-face global ts_markup_link_url "%opt{teal}+u" + set-face global ts_markup_link_uri "%opt{teal}+u" + set-face global ts_markup_link_text "%opt{blue}" + set-face global ts_markup_quote "%opt{gray1}" + set-face global ts_markup_raw "%opt{green}" + set-face global ts_markup_strikethrough "%opt{gray1}+s" + set-face global ts_namespace "%opt{blue}+i" + set-face global ts_operator "%opt{sky}" + set-face global ts_property "%opt{sky}" + set-face global ts_punctuation "%opt{overlay1}" + set-face global ts_punctuation_special "%opt{sky}" + set-face global ts_special "%opt{blue}" + set-face global ts_spell "%opt{mauve}" + set-face global ts_string "%opt{green}" + set-face global ts_string_regex "%opt{orange}" + set-face global ts_string_regexp "%opt{orange}" + set-face global ts_string_escape "%opt{mauve}" + set-face global ts_string_special "%opt{blue}" + set-face global ts_string_special_path "%opt{orange}" + set-face global ts_string_special_symbol "%opt{mauve}" + set-face global ts_string_symbol "%opt{red}" + set-face global ts_tag "%opt{mauve}" + set-face global ts_tag_error "%opt{red}" + set-face global ts_text "%opt{white}" + set-face global ts_text_title "%opt{mauve}" + set-face global ts_type "%opt{yellow}" + set-face global ts_type_enum_variant "%opt{flamingo}" + set-face global ts_variable "%opt{blue}" + set-face global ts_variable_builtin "%opt{red}" + set-face global ts_variable_other_member "%opt{teal}" + set-face global ts_variable_parameter "%opt{maroon}+i" + set-face global ts_warning "%opt{orange}+b" +'' diff --git a/user/kakoune/default.nix b/user/kakoune/default.nix new file mode 100644 index 0000000..051f21d --- /dev/null +++ b/user/kakoune/default.nix @@ -0,0 +1,154 @@ +{ + config, + pkgs, + lib, + ... +}: +let + inherit (config.my) + dmenu + editor + theme + accent + ; + inherit (theme) color; + inherit (pkgs) kakounePlugins; + inherit (pkgs.kakouneUtils) buildKakounePlugin; +in +{ + imports = [ ./kak-tree-sitter.nix ]; + config = { + programs.kakoune = { + enable = true; + plugins = with kakounePlugins; [ + kak-ansi + active-window-kak + (buildKakounePlugin rec { + pname = "auto-pairs.kak"; + version = "0.1"; + src = pkgs.fetchFromGitHub { + owner = "alexherbo2"; + repo = pname; + rev = "bfdcb8566076f653ec707f86207f83ea75173ce9"; + sha256 = "sha256-MgqCuGj03ctKty2yQgQvy6qV/0s7euNwukhSjqauqW8="; + }; + }) + (buildKakounePlugin rec { + pname = "kakoune-mirror-colemak"; + version = "0.1"; + src = pkgs.fetchFromGitHub { + owner = "lelgenio"; + repo = pname; + rev = "8f191172590d7615d0a56c857e9331ce69164670"; + sha256 = "sha256-ERNtWOn8rq53YmByTQnwDObN7Fs5HYBwvNIyTJrj2hw="; + }; + }) + (buildKakounePlugin rec { + pname = "kakoune-palette"; + version = "0.1"; + src = pkgs.fetchFromGitHub { + owner = "delapouite"; + repo = pname; + rev = "052cab5f48578679d94717ed5f62429be9865d5d"; + sha256 = "sha256-fk0TL6qG3zX8cPp1xvhMw0/g9xSKKp04uyagaPq/Nd0="; + }; + }) + (buildKakounePlugin rec { + pname = "kak-crosshairs"; + version = "0.1"; + src = pkgs.fetchFromGitHub { + owner = "lelgenio"; + repo = pname; + rev = "3a6bcd9b50737a9280de109e32048991a2f85f7c"; + sha256 = "sha256-wZQ9tsAOqG4eW28DwJ6VcsR9gSrCGqFjbTARhvTLWTQ="; + }; + }) + (buildKakounePlugin rec { + pname = "kakoune-colemak-neio"; + version = "0.1"; + src = pkgs.fetchFromGitHub { + owner = "lelgenio"; + repo = pname; + rev = "28b9aabafb8d422a4c52b2a15424056fb87c8d90"; + sha256 = "sha256-d3OTjo02QFsbNqmgd28fHgSjPcdF8BJleCJGCyOFc18="; + }; + }) + (buildKakounePlugin rec { + pname = "kakoune-multi-file"; + version = "0.1"; + src = pkgs.fetchFromGitHub { + owner = "natasky"; + repo = pname; + rev = "1cc6baeb14b773916eb9209469aa77b3cfa67a0a"; + sha256 = "sha256-3PLxG9UtT0MMSibvTviXQIgTH3rApZ3WSbNCEH3c7HE="; + }; + }) + ]; + extraConfig = + lib.concatStringsSep "\n" ( + map (lib.readFile) ( + [ + ./filetypes.kak + ./hooks.kak + ./indent.kak + ./keys.kak + ./lsp-config.kak + ./usermode.kak + ./git-mode.kak + ] + ++ lib.optional (dmenu == "rofi") ./rofi-commands.kak + ) + ) + + '' + try %{ + eval %sh{ kak-tree-sitter -vvvv -dks --init $kak_session } + } + + set global scrolloff 10,20 + set global autoreload yes + set global startup_info_version 99999999 + + '' + + (import ./colors.nix { + inherit + pkgs + lib + color + accent + ; + }); + }; + home.file = { + ".config/kak-lsp/kak-lsp.toml".source = ./kak-lsp.toml; + }; + + home.packages = with pkgs; [ + terminal + ranger + bmenu + kak-lsp + kak-tree-sitter + kak-pager + kak-man-pager + + emmet-cli + nodePackages.prettier + + aspell + aspellDicts.en + aspellDicts.pt_BR + ]; + home.activation = { + update_kakoune = lib.hm.dag.entryAfter [ "writeBoundary" ] '' + $DRY_RUN_CMD timeout 1s kak -clear && + $DRY_RUN_CMD timeout 1s kak -l | xargs -r -n1 timeout 1s kak -e "config-source;quit" -ui dummy -c || + $DRY_RUN_CMD true + ''; + }; + home.sessionVariables = lib.mkIf (editor == "kakoune") { + EDITOR = "kak"; + # Some plugins(kak_ansi) like to compile stuff + CC = "cc"; + }; + }; +} diff --git a/user/kakoune/filetypes.kak b/user/kakoune/filetypes.kak new file mode 100644 index 0000000..fd0b87c --- /dev/null +++ b/user/kakoune/filetypes.kak @@ -0,0 +1,235 @@ + +try %{ + require-module python + add-highlighter shared/python/code/function regex '\b([a-zA-Z_][a-zA-Z0-9_]*)\s*\(' 1:function +} + +hook global WinSetOption filetype=sh %{ + set buffer formatcmd 'shfmt -s -ci -i "4"' +} +hook global WinSetOption filetype=c %{ + set buffer formatcmd 'clang-format' +} + +hook global WinSetOption filetype=nix %{ + set buffer formatcmd 'nixfmt' +} + +hook global BufCreate .*\.html %{ + set buffer formatcmd 'prettier --parser html' +} + +hook global BufCreate .*\.component\.html %{ + set buffer filetype angular +} + +hook global WinSetOption filetype=angular %[ + set-option buffer extra_word_chars '_' '-' + + require-module html + add-highlighter buffer/angular ref html +] + +hook global BufCreate .*\.js %{ + set buffer formatcmd 'prettier --parser babel' +} + +hook global BufCreate .*\.vue %{ + set buffer formatcmd 'prettier --parser vue' + hook buffer InsertCompletionHide { + execute-keys 'Ghs$1c' + } +} + +hook global BufCreate .*\.jsonc %[ set buffer filetype jsonc ] +hook global BufCreate .*\.blade.php %[ set buffer filetype blade ] +hook global BufCreate .*\.less %[ set buffer filetype less ] +hook global BufCreate .*\.(tera|askama)\.?.* %[ + require-module jinja + add-highlighter buffer/jinja ref jinja +] + +hook global WinSetOption filetype=rust %[ + require-module rust + + add-highlighter window/rust-custom regions + + require-module html + add-highlighter window/rust-custom/html region -recurse '\{' '(html|view)!\s*\{\K' '(?=\})' ref html + + require-module sql + add-highlighter window/rust-custom/sql region 'r#"\K--\s*sql' '"#' group + add-highlighter window/rust-custom/sql/ fill white + add-highlighter window/rust-custom/sql/ ref sql +] + +hook global WinSetOption filetype=sql %[ + set buffer comment_line '--' +] + +hook global WinSetOption filetype=jsonc %[ + set buffer comment_line '//' + + require-module json + add-highlighter buffer/jsonc regions + add-highlighter buffer/jsonc/base default-region ref json + add-highlighter buffer/jsonc/double_string region ["] ["] fill string + add-highlighter buffer/jsonc/line-comment region // $ fill comment +] + + +hook global WinSetOption filetype=blade %[ + set buffer formatcmd 'blade-formatter \ + --end-with-newline \ + --indent-size "4" \ + --wrap-line-length "80" \ + --stdin' + set-option buffer extra_word_chars '_' '-' + + hook window ModeChange pop:insert:.* -group blade-trim-indent blade-trim-indent + hook window InsertChar .* -group blade-indent blade-indent-on-char + hook window InsertChar \n -group blade-indent blade-indent-on-new-line + + hook -once -always window WinSetOption filetype=.* %{ remove-hooks window blade-.+ } + + require-module php + require-module javascript + + add-highlighter buffer/blade regions + add-highlighter buffer/blade/base default-region group + + add-highlighter buffer/blade/string region '"' '"' regions + add-highlighter buffer/blade/string/base default-region fill string + add-highlighter buffer/blade/string/expression region '\{\{(?!--)' '(?!--)\}\}' ref php + add-highlighter buffer/blade/string/raw-expression region '\{!!' '!!\}' ref php + + add-highlighter buffer/blade/base/ ref html + + add-highlighter buffer/blade/php region '@php' '@endphp' group + add-highlighter buffer/blade/php/ ref php + add-highlighter buffer/blade/php/ regex '@((end)?php)' 1:block + + add-highlighter buffer/blade/js region '' group + add-highlighter buffer/blade/js/ ref javascript + + add-highlighter buffer/blade/expression region '\{\{(?!--)' '(?!--)\}\}' ref php + add-highlighter buffer/blade/statement region -recurse '\(' '@(if|foreach|for|section|yield|include)\s*\(' '\)' ref php + add-highlighter buffer/blade/base/ regex '@(else(if)?|include|case|break)' 1:keyword + add-highlighter buffer/blade/base/ regex '@((end)?(if|isset|foreach|for|section|switch))' 1:keyword + + add-highlighter buffer/blade/comment region '\{\{--' '--\}\}' fill comment + set-option buffer comment_block_begin '{{-- ' + set-option buffer comment_block_end ' --}}' + + map buffer user 'c' '_: comment-block;' -docstring 'comment block' +] + +try %§ + +define-command -hidden blade-trim-indent %{ + # remove trailing white spaces + try %{ execute-keys -draft -itersel s \h+$ d } +} + +define-command -hidden blade-indent-on-char %< + evaluate-commands -draft -itersel %< + # align closer token to its opener when alone on a line + try %/ execute-keys -draft ^\h+[\]}]$ m s \A|.\z 1 / + > +> + +define-command -hidden blade-indent-on-new-line %< + evaluate-commands -draft -itersel %< + # copy // comments or docblock * prefix and following white spaces + try %{ execute-keys -draft s [^/] k s ^\h*\K(?://|[*][^/])\h* y gh j P } + # preserve previous line indent + try %{ execute-keys -draft K } + # filter previous line + try %{ execute-keys -draft k : blade-trim-indent } + # indent after lines beginning / ending with opener token + try %_ execute-keys -draft k ^\h*[[{]|[[{]$ j _ + # append " * " on lines starting a multiline /** or /* comment + try %{ execute-keys -draft k s ^\h*/[*][* ]? j gi i * } + # deindent closer token(s) when after cursor + try %_ execute-keys -draft ^\h*[})] gh / [})] m 1 _ + > +> +§ + +hook global WinSetOption filetype=less %[ + set buffer formatcmd 'prettier \ + --tab-width "4" \ + --print-width "80" \ + --parser less' + + set-option buffer extra_word_chars '_' '-' + + set buffer comment_line '//' + set buffer comment_block_begin '/*' + set buffer comment_block_end '*/' + + hook window ModeChange pop:insert:.* -group less-trim-indent less-trim-indent + hook window InsertChar \n -group less-indent less-indent-on-new-line + hook window InsertChar \} -group less-indent less-indent-on-closing-curly-brace + + map buffer insert 'xs\$\d+) c' + + hook -once -always window WinSetOption filetype=.* %{ remove-hooks window less-.+ } + + add-highlighter buffer/less regions + add-highlighter buffer/less/code default-region group + + add-highlighter buffer/less/line-comment region // $ fill comment + add-highlighter buffer/less/comment region /[*] [*]/ fill comment + add-highlighter buffer/less/double_string region ["] ["] fill string + add-highlighter buffer/less/single_string region ['] ['] fill string + + add-highlighter buffer/less/code/ regex ([A-Za-z][A-Za-z0-9_-]*)\h*: 1:keyword + add-highlighter buffer/less/code/ regex ::?(\w+) 0:attribute + add-highlighter buffer/less/code/ regex !important 0:keyword + + add-highlighter buffer/less/code/selector group + add-highlighter buffer/less/code/selector/ regex [A-Za-z][A-Za-z0-9_-]* 0:keyword + add-highlighter buffer/less/code/selector/ regex [*]|[#.][A-Za-z][A-Za-z0-9_-]* 0:variable + add-highlighter buffer/less/code/selector/ regex &([A-Za-z0-9_-]*) 1:variable + add-highlighter buffer/less/code/selector/ regex & 0:operator + add-highlighter buffer/less/code/selector/ regex (\.?[A-Za-z][A-Za-z0-9_-]*)\s*\( 1:function + + add-highlighter buffer/less/code/ regex (\b(\d*\.)?\d+(ch|cm|em|ex|mm|pc|pt|px|rem|vh|vmax|vmin|vw|%|s|ms)?) 0:value 3:type + add-highlighter buffer/less/code/ regex (#)[0-9A-Fa-f]{3}([0-9A-Fa-f]{3}([0-9A-Fa-f]{2})?)?\b 0:value 1:operator + + add-highlighter buffer/less/code/ regex (?i)\b(AliceBlue|AntiqueWhite|Aqua|Aquamarine|Azure|Beige|Bisque|Black|BlanchedAlmond|Blue|BlueViolet|Brown|BurlyWood|CadetBlue|Chartreuse|Chocolate|Coral|CornflowerBlue|Cornsilk|Crimson|Cyan|DarkBlue|DarkCyan|DarkGoldenRod|DarkGray|DarkGrey|DarkGreen|DarkKhaki|DarkMagenta|DarkOliveGreen|DarkOrange|DarkOrchid|DarkRed|DarkSalmon|DarkSeaGreen|DarkSlateBlue|DarkSlateGray|DarkSlateGrey|DarkTurquoise|DarkViolet|DeepPink|DeepSkyBlue|DimGray|DimGrey|DodgerBlue|FireBrick|FloralWhite|ForestGreen|Fuchsia|Gainsboro|GhostWhite|Gold|GoldenRod|Gray|Grey|Green|GreenYellow|HoneyDew|HotPink|IndianRed|Indigo|Ivory|Khaki|Lavender|LavenderBlush|LawnGreen|LemonChiffon|LightBlue|LightCoral|LightCyan|LightGoldenRodYellow|LightGray|LightGrey|LightGreen|LightPink|LightSalmon|LightSeaGreen|LightSkyBlue|LightSlateGray|LightSlateGrey|LightSteelBlue|LightYellow|Lime|LimeGreen|Linen|Magenta|Maroon|MediumAquaMarine|MediumBlue|MediumOrchid|MediumPurple|MediumSeaGreen|MediumSlateBlue|MediumSpringGreen|MediumTurquoise|MediumVioletRed|MidnightBlue|MintCream|MistyRose|Moccasin|NavajoWhite|Navy|OldLace|Olive|OliveDrab|Orange|OrangeRed|Orchid|PaleGoldenRod|PaleGreen|PaleTurquoise|PaleVioletRed|PapayaWhip|PeachPuff|Peru|Pink|Plum|PowderBlue|Purple|RebeccaPurple|Red|RosyBrown|RoyalBlue|SaddleBrown|Salmon|SandyBrown|SeaGreen|SeaShell|Sienna|Silver|SkyBlue|SlateBlue|SlateGray|SlateGrey|Snow|SpringGreen|SteelBlue|Tan|Teal|Thistle|Tomato|Turquoise|Violet|Wheat|White|WhiteSmoke|Yellow|YellowGreen)\b 0:value + + add-highlighter buffer/less/code/ regex ([\w-_]+)\s*: 1:attribute + add-highlighter buffer/less/code/ regex @[\w\d-_]+ 0:variable + +] + +try %§ + +define-command -hidden less-trim-indent %{ + # remove trailing white spaces + try %{ execute-keys -draft -itersel s \h+$ d } +} + +define-command -hidden less-indent-on-new-line %[ + evaluate-commands -draft -itersel %[ + # preserve previous line indent + try %[ execute-keys -draft K ] + # filter previous line + try %[ execute-keys -draft k : less-trim-indent ] + # indent after lines ending with with { + try %[ execute-keys -draft k \{$ j ] + # deindent closing brace when after cursor + try %[ execute-keys -draft ^\h*\} gh / \} m 1 ] + ] +] + +define-command -hidden less-indent-on-closing-curly-brace %[ + evaluate-commands -draft -itersel %[ + # align to opening curly brace when alone on a line + try %[ execute-keys -draft ^\h+\}$ m s \A|.\z 1 ] + ] +] + +§ diff --git a/user/kakoune/git-mode.kak b/user/kakoune/git-mode.kak new file mode 100644 index 0000000..e016f1b --- /dev/null +++ b/user/kakoune/git-mode.kak @@ -0,0 +1,134 @@ +try %{ + # declare-user-mode surround + declare-user-mode git +} + +map global user 'v' ': enter-user-mode git' -docstring 'git vcs mode' +map global user 'V' ': enter-user-mode -lock git' -docstring 'git vcs mode' + +# show status +map global git 's' ': git status' -docstring 'status' +map global git 'S' '_: git show %val{selection} --' -docstring 'show' +map global git 'g' ': git-graph ' -docstring 'graph all commits' +map global git 'G' ': git-graph-simpified ' -docstring 'graph all branches' +map global git '' ': git-graph-with-remotes' -docstring 'graph all branches and remotes' +map global git 'd' ': git diff %reg{%}' -docstring 'diff current' +map global git 'D' ': git diff' -docstring 'diff all' +map global git '' ': git diff --staged' -docstring 'diff staged' + +map global git 'n' ': git next-hunk ' -docstring 'next git modification' +map global git 'p' ': git prev-hunk ' -docstring 'previous git modification' + +# make commits +map global git 'a' ': git add' -docstring 'add current' +map global git 'A' ': git add --all' -docstring 'add all' +map global git 'c' ': git commit -v' -docstring 'commit' + +# discard work +map global git 'r' ': git checkout %reg{%}' -docstring 'restore current' + +# deal with merges +map global git 'N' ': git-next-merge-conflict ' -docstring 'next git merge conflict' +map global git 'P' ': git-prev-merge-conflict ' -docstring 'previous git merge conflict' +map global git 'm' ': git-merge-head ' -docstring 'merge using head' +map global git 'M' ': git-merge-new ' -docstring 'merge using new' +map global git '' ': git-merge-head-and-new ' -docstring 'merge using both head and new' +map global git '' ': git-merge-original ' -docstring 'merge using original' + +define-command -override git-next-merge-conflict %{ + try %{ + execute-keys /^{6,}.*?^{6,}.*?$ + } catch %{ + fail "No hunks found forward" + } +} -docstring "next git merge hunk" + +define-command -override git-prev-merge-conflict %{ + try %{ + execute-keys ^{6,}.*?^{6,}.*?$ + } catch %{ + fail "No hunks found backwards" + } +} -docstring "previous git merge hunk" + +define-command -override git-merge-head %{ + evaluate-commands -draft %{ + # delete head marker + execute-keys ^{4,}xd + try %{ + # select original marker + execute-keys /^[|]{4,} + # extend to theirs marker + execute-keys ?^={4,}x + } catch %{ + # select theirs marker + execute-keys /^={4,}x + } + # extend to end marker + execute-keys ?^{4,}xd + } +} -docstring "merge using head" + +define-command -override git-merge-original %{ + evaluate-commands -draft %{ + # select head marker + execute-keys ^{4,} + # select to middle of conflict + execute-keys ?^[|]{4,}xd + # select theirs marker + execute-keys /^={4,} + # extend to end marker + execute-keys ?^{4,}xd + } +} -docstring "merge using original" + +define-command -override git-merge-new %{ + evaluate-commands -draft %{ + # select head marker + execute-keys ^{4,} + # extend to theirs marker + execute-keys ?^={4,}\nd + # delete end marker + execute-keys /^{4,}xd + } +} -docstring "merge using new" + +define-command -override git-merge-head-and-new %{ + evaluate-commands -draft %{ + # delete head marker + execute-keys ^{4,}xd + # select middle of conflict + execute-keys /^[|]{4,}x + # extendo to theirs marker + execute-keys ?^={4,}xd + # delete end marker + execute-keys /^{4,}xd + } +} -docstring "merge using head and new" + +define-command -override git-graph %{ + try %{ delete-buffer '*git-graph*' } + edit -scratch '*git-graph*' + execute-keys ' timeout 10s git graph --color=always --decorate --branches' + execute-keys 'gg' + try ansi-render + map buffer normal q ': delete-buffer!' +} + +define-command -override git-graph-simpified %{ + try %{ delete-buffer '*git-graph*' } + edit -scratch '*git-graph*' + execute-keys ' timeout 10s git graph --color=always --decorate --all --simplify-by-decoration' + execute-keys 'gg' + try ansi-render + map buffer normal q ': delete-buffer!' +} + +define-command -override git-graph-with-remotes %{ + try %{ delete-buffer '*git-graph*' } + edit -scratch '*git-graph*' + execute-keys ' timeout 10s git graph --color=always --decorate --all' + execute-keys 'gg' + try ansi-render + map buffer normal q ': delete-buffer!' +} diff --git a/user/kakoune/hooks.kak b/user/kakoune/hooks.kak new file mode 100644 index 0000000..79d85cc --- /dev/null +++ b/user/kakoune/hooks.kak @@ -0,0 +1,56 @@ +set global idle_timeout 500 + +enable-auto-pairs + +hook global NormalIdle .* %{ evaluate-commands %sh{ + hex_with_size() { + for i in 3 4 6 8; do + printf "[0-9a-f]{$i}|" + done + } + echo "$kak_selection" | grep -P "^#?($(hex_with_size))$" > /dev/null && + echo 'palette-status' +} } + +define-command -hidden -override git-try-show-diff %{ + evaluate-commands -draft %sh{ + test -f "$kak_buffile" || exit 0 + cd $(dirname "$kak_buffile") + git rev-parse --git-dir > /dev/null && + echo "git show-diff" + } +} + +evaluate-commands %sh{ + for hook in NormalIdle FocusIn FocusOut BufWritePost BufOpenFile; do + printf "hook global %s .* 'git-try-show-diff'\n" "$hook" + done +} + +define-command -override diffr %{ try %{ + execute-keys -draft 'ggxsdiff' + execute-keys -draft '%J| _diffr' + ansi-render +} } + +hook global BufOpenFile .* diffr + +hook global BufOpenFile .* %{ + modeline-parse +} + +hook global BufOpenFile .*/COMMIT_EDITMSG %{ + execute-keys -draft 'gegit log -1000 --oneline' + write +} + +hook global RegisterModified '"' %{ nop %sh{ { + printf %s "$kak_reg_dquote" | wl-copy -n + printf %s "$kak_reg_dquote" | xclip -i -selection clipboard +} > /dev/null 2>&1 < /dev/null & }} -group sync-clipboard + +# Trim trailing whitespace +hook global BufWritePre .* %{ try %{ + execute-keys -draft \%s\h+$d +} } -group remove-whitespace + diff --git a/user/kakoune/indent.kak b/user/kakoune/indent.kak new file mode 100644 index 0000000..95b2f39 --- /dev/null +++ b/user/kakoune/indent.kak @@ -0,0 +1,33 @@ +# {{@@ header() @@}} +# _ __ _ +# | |/ /__ _| | _____ _ _ _ __ ___ +# | ' // _` | |/ / _ \| | | | '_ \ / _ \ +# | . \ (_| | < (_) | |_| | | | | __/ +# |_|\_\__,_|_|\_\___/ \__,_|_| |_|\___| + +set global tabstop 4 + +hook global BufCreate .*\.py %{ + set global indentwidth 4 +} + +hook global BufCreate .*\.nix %{ + set global indentwidth 2 +} + +################################################################# +# Spaces +################################################################# + +set global indentwidth 4 + +# use spaces insted of tabs +hook global BufCreate .* %{ + hook buffer InsertChar \t %{ + exec -draft -itersel h@ + } -group replace-tabs-with-spaces +} + +hook global WinSetOption filetype=makefile %{ + remove-hooks buffer replace-tabs-with-spaces +} diff --git a/user/kakoune/kak-lsp.toml b/user/kakoune/kak-lsp.toml new file mode 100644 index 0000000..b3a6c8e --- /dev/null +++ b/user/kakoune/kak-lsp.toml @@ -0,0 +1,155 @@ +snippet_support = false +verbosity = 2 + +[server] +# exit session if no requests were received during given period in seconds +# works only in unix sockets mode (-s/--session) +# set to 0 to disable +timeout = 1800 # seconds = 30 minutes + +[language_server.angular] +filetypes = ["angular"] +roots = [".angular", ".git"] +command = "node" +args = [ + "/home/lelgenio/.config/yarn/global/node_modules/@angular/language-server", + "--ngProbeLocations", + "/home/lelgenio/.config/yarn/global/node_modules", + "--tsProbeLocations", + "/home/lelgenio/.config/yarn/global/node_modules", + "--stdio", +] + +[language_server.bash-language-server] +filetypes = ["sh"] +roots = [".git", ".hg"] +command = "bash-language-server" +args = ["start"] + +[language_server.clangd] +filetypes = ["c", "cpp"] +roots = ["compile_commands.json", ".clangd", ".git", ".hg"] +command = "clangd" + +[language_server.css-language-server] +filetypes = ["css"] +roots = ["package.json", ".git", ".hg"] +command = "vscode-css-languageserver" +args = ["--stdio"] + +[language_server.less-language-server] +filetypes = ["less"] +roots = ["package.json", ".git", ".hg"] +command = "vscode-css-languageserver" +args = ["--stdio"] + +[language_server.html-language-server] +filetypes = ["html"] +roots = ["package.json"] +command = "vscode-html-languageserver" +args = ["--stdio"] +settings_section = "_" +[language_server.html-language-server.settings._] +# quotePreference = "single" +# javascript.format.semicolons = "insert" + +[language_server.typescript-language-server] +filetypes = ["javascript", "typescript"] +roots = ["package.json", "tsconfig.json", "jsconfig.json", ".git", ".hg"] +command = "typescript-language-server" +args = ["--stdio"] +settings_section = "_" +[language_server.typescript-language-server.settings._] +# quotePreference = "double" +# typescript.format.semicolons = "insert" + +[language_server.json-language-server] +filetypes = ["json"] +roots = ["package.json"] +command = "vscode-json-languageserver" +args = ["--stdio"] + +[language_server.nil] +filetypes = ["nix"] +command = "nil" +roots = ["flake.nix", "shell.nix", ".git"] +[language_server.nil.settings.nil] +formatting.command = [ "nixfmt" ] + +[language_server.intelephense] +filetypes = ["php"] +roots = [".htaccess", "composer.json"] +command = "intelephense" +args = ["--stdio"] +settings_section = "intelephense" +[language_server.intelephense.settings.intelephense] +storagePath = "/tmp/intelephense" + +format.braces = "k&r" +environment.includePaths = [ + "./vendor", + "./vendor/autoload", + "./vendor/laravel/framework/", + "./vendor/laravel/framework/src/", + "./vendor/laravel/framework/src/Illuminate/" +] +files.exclude = [ + "**/.git/**", + "**/.svn/**", + "**/.hg/**", + "**/.direnv/**", + "**/CVS/**", + "**/.DS_Store/**", + "**/node_modules/**", + "**/bower_components/**", + "**/resources/views/**" +] + +[language_server.rust-analyzer] +filetypes = ["rust"] +roots = ["Cargo.toml"] +command = "sh" +args = [ + "-c", + """ + if path=$(rustup which rust-analyzer 2>/dev/null); then + "$path" + else + rust-analyzer + fi + """, +] +[language_server.rust-analyzer.settings.rust-analyzer] +# See https://rust-analyzer.github.io/manual.html#configuration +# cargo.features = [] +checkOnSave.command = "clippy" +hoverActions.enable = false # kak-lsp doesn't support this at the moment + +[language_server.godot] +filetypes = ["gd", "gdscript", "gdscript3"] +roots = ["project.godot", ".git/"] +command = "nc" +args = [ "localhost", "6008"] + +# Semantic tokens support +# See https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_semanticTokens +# for the default list of tokens and modifiers. +# However, many language servers implement their own values. +# Make sure to check the output of `lsp-capabilities` and each server's documentation and source code as well. +# Examples: +# - TypeScript: https://github.com/microsoft/vscode-languageserver-node/blob/main/client/src/common/semanticTokens.ts +# - Rust Analyzer: https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ide/src/syntax_highlighting.rs +[semantic_tokens] +faces = [ + {face="documentation", token="comment", modifiers=["documentation"]}, + {face="comment", token="comment"}, + {face="function", token="function"}, + {face="keyword", token="keyword"}, + {face="module", token="namespace"}, + {face="operator", token="operator"}, + {face="string", token="string"}, + {face="type", token="type"}, + {face="default+d", token="variable", modifiers=["readonly"]}, + {face="default+d", token="variable", modifiers=["constant"]}, + {face="variable", token="variable"}, +] diff --git a/user/kakoune/kak-tree-sitter.nix b/user/kakoune/kak-tree-sitter.nix new file mode 100644 index 0000000..8818f1f --- /dev/null +++ b/user/kakoune/kak-tree-sitter.nix @@ -0,0 +1,64 @@ +{ pkgs, lib, ... }: +let + hx-src = pkgs.helix.src; + kts-src = pkgs.kak-tree-sitter.src; + inherit (pkgs) fetchFromGitHub; +in +with pkgs.tree-sitter-grammars; +{ + xdg.configFile."kak-tree-sitter/config.toml".text = + lib.foldlAttrs + ( + acc: name: vals: + acc + + '' + [language.${name}.grammar.source.local] + path = "${vals.parser}" + [language.${name}.grammar] + compile = "cc" + compile_args = ["-c", "-fpic", "../scanner.c", "../parser.c", "-I", ".."] + compile_flags = ["-O3"] + link = "cc" + link_args = ["-shared", "-fpic", "scanner.o", "parser.o", "-o", "typescript.so"] + link_flags = ["-O3"] + [language.${name}.queries.source.local] + path = "${vals.queries}" + [language.${name}.queries] + path = "${vals.queries}" + '' + ) + "" + { + nix = { + parser = tree-sitter-nix + "/parser"; + queries = tree-sitter-nix + "/queries"; + }; + + scss = { + parser = tree-sitter-scss + "/parser"; + queries = tree-sitter-scss + "/queries"; + }; + css = { + parser = tree-sitter-css + "/parser"; + queries = tree-sitter-css + "/queries"; + }; + + javascript = { + parser = tree-sitter-javascript + "/parser"; + queries = tree-sitter-javascript + "/queries"; + }; + typescript = { + parser = + tree-sitter-typescript.overrideAttrs (old: { + src = fetchFromGitHub { + owner = "tree-sitter"; + repo = "tree-sitter-typescript"; + rev = "b1bf4825d9eaa0f3bdeb1e52f099533328acfbdf"; + hash = "sha256-oZKit8kScXcOptmT2ckywL5JlAVe+wuwhuj6ThEI5OQ="; + }; + }) + + "/parser"; + queries = kts-src + "/runtime/queries/typescript"; + }; + }; +} diff --git a/user/kakoune/kakrc b/user/kakoune/kakrc new file mode 100644 index 0000000..d80b6de --- /dev/null +++ b/user/kakoune/kakrc @@ -0,0 +1,20 @@ +# {{@@ header() @@}} +# _ __ _ +# | |/ /__ _| | _____ _ _ _ __ ___ +# | ' // _` | |/ / _ \| | | | '_ \ / _ \ +# | . \ (_| | < (_) | |_| | | | | __/ +# |_|\_\__,_|_|\_\___/ \__,_|_| |_|\___| + + +set global scrolloff 10,20 +set global autoreload yes +set global startup_info_version 20200901 + +source "%val{config}/rc/plug.kak" +source "%val{config}/rc/keys.kak" +source "%val{config}/rc/usermode.kak" +source "%val{config}/rc/git-mode.kak" +source "%val{config}/rc/hooks.kak" +source "%val{config}/rc/filetypes.kak" +source "%val{config}/rc/indent.kak" +source "%val{config}/colors.kak" diff --git a/user/kakoune/keys.kak b/user/kakoune/keys.kak new file mode 100644 index 0000000..8b32e1d --- /dev/null +++ b/user/kakoune/keys.kak @@ -0,0 +1,39 @@ +# {{@@ header() @@}} + +# For colemak, this is pretty confortable, C-n = down, C-u = up +map global normal 10k +map global normal 10j + +# alt i makes searches case insensitive +map global prompt '(?i)' + +###################################################### +# Emacs-like insert +###################################################### + +map global insert "h" +map global insert "l" + +map global insert "b" +map global insert "w" + +map global insert "gi" +map global insert "ghgl" +map global insert "bd" + + +###################################################### +# Other insert binds +###################################################### + +map global insert "" +map global insert "" + + +###################################################### +# Objects +###################################################### + +map global object m %{c^[=|]{4\,}[^\n]*\n,^[=|]{4\,}[^\n]*\n} -docstring 'git conflict markers' +map global object M %{c^{4\,}[^\n]*\n,^{4\,}[^\n]*\n} -docstring 'git conflict' + diff --git a/user/kakoune/lsp-config.kak b/user/kakoune/lsp-config.kak new file mode 100644 index 0000000..132151b --- /dev/null +++ b/user/kakoune/lsp-config.kak @@ -0,0 +1,62 @@ +try %{ + eval %sh{kak-lsp --kakoune -s $kak_session} # Not needed if you load it with plug.kak. +} + +map global normal ': lsp-rename-prompt' +set global lsp_hover_max_lines 10 +set global lsp_auto_highlight_references true +set global lsp_inlay_diagnostic_sign "●" +set global lsp_diagnostic_line_error_sign "●" + +hook global BufCreate .* %{try lsp-enable} + +define-command -override -hidden lsp-next-placeholder-bind %{ + map global normal ': try lsp-snippets-select-next-placeholders catch %{ execute-keys -with-hooks tab> }' -docstring 'Select next snippet placeholder' + map global insert ': try lsp-snippets-select-next-placeholders catch %{ execute-keys -with-hooks tab> }' -docstring 'Select next snippet placeholder' +} +lsp-next-placeholder-bind +map global insert ": lsp-code-action-sync Fill" + +define-command -override -hidden lsp-enable-decals %{ + lsp-inlay-diagnostics-enable global + lsp-inlay-hints-enable global +} + +define-command -override -hidden lsp-disable-decals %{ + lsp-inlay-diagnostics-disable global + lsp-inlay-hints-disable global +} +try lsp-enable-decals + +hook global ModeChange '.*:insert:normal' %{lsp-enable-decals} +hook global ModeChange '.*:normal:insert' %{lsp-disable-decals} + +hook global WinSetOption filetype=(c|cpp|rust) %{ + hook window -group semantic-tokens BufReload .* lsp-semantic-tokens + hook window -group semantic-tokens NormalIdle .* lsp-semantic-tokens + hook window -group semantic-tokens InsertIdle .* lsp-semantic-tokens + hook -once -always window WinSetOption filetype=.* %{ + remove-hooks window semantic-tokens + } + decl -hidden -docstring "Timestamp of the last check" int last_modified + hook window RawKey .* %{ + eval %sh{ + if [ "${kak_opt_last_modified}" != "${kak_timestamp}" ]; then + echo "unset-option buffer lsp_inlay_diagnostics" + echo "unset-option buffer lsp_inlay_hints" + fi + } + set current last_modified %val{timestamp} + } +} + +declare-option -hidden str modeline_progress "" +define-command -hidden -params 6 -override lsp-handle-progress %{ + set global modeline_progress %sh{ + if ! "$6"; then + echo "$2${5:+" ($5%)"}${4:+": $4"}" + fi + } +} + +set global modelinefmt "%%opt{modeline_progress} %opt{modelinefmt}" diff --git a/user/kakoune/rofi-commands.kak b/user/kakoune/rofi-commands.kak new file mode 100644 index 0000000..1022e49 --- /dev/null +++ b/user/kakoune/rofi-commands.kak @@ -0,0 +1,46 @@ +define-command -override -hidden find_file \ +%{ evaluate-commands %sh{ + for line in `rofi -sort -show file-browser-extended -file-browser-depth 0 -file-browser-no-descend -file-browser-stdout -p "File: "`; do + echo "edit '$line'" + done +} } + +define-command -override -hidden find_delete \ +%{ nop %sh{ + rofi -sort -show file-browser-extended -file-browser-depth 0 -file-browser-no-descend -file-browser-stdout | xargs -r trash +} } + +define-command -override -hidden find_git_file \ +%{ evaluate-commands %sh{ + for line in `git ls-files | rofi -sort -show file-browser-extended -file-browser-depth 0 -file-browser-no-descend -file-browser-stdout -file-browser-stdin`; do + echo "edit -existing '$line'" + done +} } + +define-command -override -hidden find_git_modified \ +%{ evaluate-commands %sh{ + for line in `git status --porcelain | sd '^.. ' ''| rofi -sort -show file-browser-extended -file-browser-no-descend -file-browser-stdout -file-browser-stdin`; do + echo "edit -existing '$line'" + done +} } + +define-command -override -hidden find_dir \ +%{ cd %sh{ + for line in `fd --strip-cwd-prefix -Htd | rofi -sort -show file-browser-extended -file-browser-no-descend -file-browser-stdout -file-browser-stdin`; do + echo "edit '$line'" + done +} } + +define-command -override -hidden find_buffer \ +%{ evaluate-commands %sh{ + for line in `printf "%s\n" $kak_buflist | wdmenu -i`; do + echo "buffer '$line'" + done +} } + +define-command -override -hidden tree \ +%{ evaluate-commands %sh{ + for line in `rofi -sort -show file-browser-extended -file-browser-stdout`; do + echo "edit '$line'" + done +} } diff --git a/user/kakoune/usermode.kak b/user/kakoune/usermode.kak new file mode 100644 index 0000000..c1855a2 --- /dev/null +++ b/user/kakoune/usermode.kak @@ -0,0 +1,138 @@ +try %{ + # declare-user-mode surround + declare-user-mode find +} + +map global user 'w' ': w' -docstring 'write buffer' +map global user 'u' ': config-source' -docstring 'source configuration' +map global user 'g' ': enter-user-mode lsp' -docstring 'lsp mode' +map global user 'z' ':zoxide ' -docstring 'zoxide' +map global user 'n' ': new' -docstring 'new window' + +map global user 'e' 'x|emmet@' -docstring 'process line with emmet' +map global user 'm' ': try format-buffer catch lsp-formatting-sync' -docstring 'format document' +map global user 'M' ': try lsp-range-formatting-sync catch format-selections' -docstring 'format selection' + +map global user 'c' ': comment-line' -docstring 'comment line' +map global user 'C' '_: comment-block' -docstring 'comment block' +map global user '=' 'kghyjghihRgi' -docstring 'Copy previous line indentation ' + +map global user "s" ': enter-user-mode mirror' -docstring 'mirror mode' + +map global user 'p' '! wl-paste -n' -docstring 'clipboard paste' +map global user 'P' 'j! wl-paste -n' -docstring 'clipboard paste on next line' +map global user 'R' '"_d! wl-paste -n ' -docstring 'clipboard replace' +map global user 'y' ': copy-file-path' -docstring 'register name to clipboard' + +map global user 'b' ': find_buffer' -docstring 'switch buffer' + +map global user 'l' ': lsp-enable-decals' -docstring 'LSP enable decals' +map global user 'L' ': lsp-disable-decals' -docstring 'LSP disable decals' + +map global user 'f' ': enter-user-mode find' -docstring 'find mode' +map global find 't' ': tree' -docstring 'file tree' +map global find 'f' ': find_file' -docstring 'file' +map global find 'l' ': find_line' -docstring 'jump to line' +map global find 'r' ': find_ripgrep' -docstring 'ripgrep all file' +map global find 'g' ': find_git_file' -docstring 'git files' +map global find 'm' ': find_git_modified' -docstring 'git modified files' +map global find 'c' ': find_dir' -docstring 'change dir' +map global find 'd' ': find_delete' -docstring 'file to delete' + +map global user 'S' ': find_spell' -docstring 'pick language for spellchecking' + +define-command -override -hidden find_spell \ +%{ evaluate-commands %sh{ + for line in `aspell dump dicts | wdmenu -i -p "Language: "`; do + echo "spell '$line'" + done +} } + +define-command -override -hidden find_file \ +%{ evaluate-commands %sh{ + for line in `fd --strip-cwd-prefix -tf -HE .git | wdmenu -i -p "File: "`; do + echo "edit '$line'" + done +} } + +define-command -override -hidden find_delete \ +%{ nop %sh{ + fd --strip-cwd-prefix -H -E .git -t f | wdmenu -i | xargs -r trash +} } + +define-command -override -hidden find_git_file \ +%{ evaluate-commands %sh{ + for line in `git ls-files | wdmenu -i`; do + echo "edit -existing '$line'" + done +} } + +define-command -override -hidden find_git_modified \ +%{ evaluate-commands %sh{ + for line in `git status --porcelain | sd '^.. ' ''| wdmenu -i`; do + echo "edit -existing '$line'" + done +} } + +define-command -override -hidden find_dir \ +%{ cd %sh{ + for line in `fd --strip-cwd-prefix -Htd | wdmenu -i`; do + echo "edit '$line'" + done +} } + +define-command -override -hidden find_buffer \ +%{ evaluate-commands %sh{ + for line in `printf "%s\n" $kak_buflist | wdmenu -i`; do + echo "buffer '$line'" + done +} } + +define-command -override -hidden find_ripgrep \ +%{ evaluate-commands %sh{ + patter=$( wdmenu -i -p "Regex") + rg --column -n "$patter" | wdmenu -i | + perl -ne 'print "edit \"$1\" \"$2\" \"$3\" " if /(.+):(\d+):(\d+):/' +} } + +define-command -override -hidden find_line \ +%{ evaluate-commands -save-regs a %{ + execute-keys %{Z%"ayz} + execute-keys %sh{ + line=$( + printf "%s\n" "$kak_reg_a" | + nl -ba -w1 | + wdmenu -i -p "Line" | + cut -f1 + ) + test -n "$line" && echo "${line}gx" + } +} } + +define-command -override -hidden tree \ +%{ evaluate-commands %sh{ + file=`mktemp` + terminal --class file_picker -e ranger --selectfile="$kak_buffile" --choosefiles="$file" + for line in `cat "$file"`; do + echo "edit '$line'" + done + rm "$file" +} } + + +define-command -override -params .. \ +-shell-script-candidates 'zoxide query -l' \ +zoxide %{ + cd %sh{ zoxide query -- "$@" || echo "$@" } + echo %sh{ pwd | sed "s|$HOME|~|" } +} + +define-command -override config-source %{ + source "%val{config}/kakrc" +} + +define-command -override copy-file-path %{ + nop %sh{ { + wl-copy $kak_reg_percent + } >/dev/null 2>&1 { goto_file_relative(-1) } + { goto_file_relative(1); } + { goto_file_relative(-1) } + { goto_file_relative(1); } + + ${lib.concatStrings (make_direction_binds [ + "left" + "up" + "right" + "down" + ])} + + ${key.tabL} { goto_file_relative(-1) } + ${key.tabR} { goto_file_relative(1); } + + ${key.insertMode} { toggle_info_box() } + d { send_keys(6) } + y { send_keys(8) } + + ${if (key.layout == "colemak") then "\n t { toggle_scale_mode(0) }\n " else ""} + + # vim: ft=ini + ''; + }; + home.packages = with pkgs; [ pqiv ]; +} diff --git a/user/ranger/colorscheme.py b/user/ranger/colorscheme.py new file mode 100644 index 0000000..8f4fbfe --- /dev/null +++ b/user/ranger/colorscheme.py @@ -0,0 +1,186 @@ +# This file is part of ranger, the console file manager. +# License: GNU GPL version 3, see the file "AUTHORS" for details. + +from __future__ import (absolute_import, division, print_function) + +from ranger.gui.colorscheme import ColorScheme +from ranger.gui.color import ( + black, blue, cyan, green, magenta, red, white, yellow, default, + normal, bold, reverse, dim, BRIGHT, + default_colors, +) + + +class Default(ColorScheme): + progress_bar_color = blue + + def use(self, context): # pylint: disable=too-many-branches,too-many-statements + fg, bg, attr = default_colors + + if context.reset: + return default_colors + + elif context.in_browser: + if context.selected: + attr = reverse + else: + attr = normal + if context.empty or context.error: + bg = red + if context.border: + fg = default + if context.media: + if context.image: + fg = yellow + else: + fg = magenta + if context.container: + fg = red + if context.directory: + attr |= bold + fg = red + # fg += BRIGHT + elif context.executable and not \ + any((context.media, context.container, + context.fifo, context.socket)): + attr |= bold + fg = green + # fg += BRIGHT + if context.socket: + attr |= bold + fg = magenta + fg += BRIGHT + if context.fifo or context.device: + fg = yellow + if context.device: + attr |= bold + fg += BRIGHT + if context.link: + fg = cyan if context.good else magenta + if context.tag_marker and not context.selected: + attr |= bold + if fg in (red, magenta): + fg = white + else: + fg = red + fg += BRIGHT + if not context.selected: + fg = default + attr &= ~bold + if not context.selected and (context.cut or context.copied): + attr |= bold + fg = black + fg += BRIGHT + # If the terminal doesn't support bright colors, use dim white + # instead of black. + if BRIGHT == 0: + attr |= dim + fg = white + if context.main_column: + # Doubling up with BRIGHT here causes issues because it's + # additive not idempotent. + if context.selected: + attr |= bold + if context.marked: + attr |= bold + fg = yellow + if context.badinfo: + if attr & reverse: + bg = magenta + else: + fg = magenta + + if context.inactive_pane: + fg = cyan + + elif context.in_titlebar: + if context.hostname: + fg = red + elif context.directory: + fg = green + elif context.tab: + if context.good: + bg = green + elif context.link: + fg = cyan + attr |= bold + + elif context.in_statusbar: + if context.permissions: + if context.good: + fg = cyan + elif context.bad: + fg = magenta + if context.marked: + attr |= bold | reverse + fg = yellow + fg += BRIGHT + if context.frozen: + attr |= bold | reverse + fg = cyan + fg += BRIGHT + if context.message: + if context.bad: + attr |= bold + fg = red + fg += BRIGHT + if context.loaded: + bg = self.progress_bar_color + if context.vcsinfo: + fg = blue + attr &= ~bold + if context.vcscommit: + fg = yellow + attr &= ~bold + if context.vcsdate: + fg = cyan + attr &= ~bold + + if context.text: + if context.highlight: + attr |= reverse + + if context.in_taskview: + if context.title: + fg = blue + + if context.selected: + attr |= reverse + + if context.loaded: + if context.selected: + fg = self.progress_bar_color + else: + bg = self.progress_bar_color + + if context.vcsfile and not context.selected: + attr &= ~bold + if context.vcsconflict: + fg = magenta + elif context.vcsuntracked: + fg = cyan + elif context.vcschanged: + fg = red + elif context.vcsunknown: + fg = red + elif context.vcsstaged: + fg = green + elif context.vcssync: + fg = green + elif context.vcsignored: + fg = default + + elif context.vcsremote and not context.selected: + attr &= ~bold + if context.vcssync or context.vcsnone: + fg = green + elif context.vcsbehind: + fg = red + elif context.vcsahead: + fg = blue + elif context.vcsdiverged: + fg = magenta + elif context.vcsunknown: + fg = red + + return fg, bg, attr diff --git a/user/ranger/default.nix b/user/ranger/default.nix new file mode 100644 index 0000000..4b97170 --- /dev/null +++ b/user/ranger/default.nix @@ -0,0 +1,28 @@ +{ + config, + pkgs, + lib, + inputs, + ... +}: +{ + xdg.configFile = { + "ranger/rc.conf".source = ./rc.conf; + "ranger/rifle.conf".source = ./rifle.conf; + "ranger/scope.sh".source = ./scope.sh; + "ranger/colorschemes/mycolorscheme.py".source = ./colorscheme.py; + "ranger/plugins/ranger_devicons".source = inputs.ranger-icons; + }; + home.packages = with pkgs; [ + ranger + xdg-utils + wl-clipboard + + highlight # syntax highlight + poppler_utils # pdf preview + ffmpeg # audio preview + ffmpegthumbnailer # video preview + fontforge # font preview + imagemagick + ]; +} diff --git a/user/ranger/rc.conf b/user/ranger/rc.conf new file mode 100644 index 0000000..3936f36 --- /dev/null +++ b/user/ranger/rc.conf @@ -0,0 +1,644 @@ +# {{@@ header() @@}} +# _ __ __ _ _ __ __ _ ___ _ __ +# | '__/ _` | '_ \ / _` |/ _ \ '__| +# | | | (_| | | | | (_| | __/ | +# |_| \__,_|_| |_|\__, |\___|_| +# |___/ + +# == Options{{{ + +# Use miller columns which show multiple levels of the hierarchy +set viewmode miller + +# How many columns are there, and what are their relative widths? +set column_ratios 2,4,2 + +# Which files should be hidden? (regular expression) +set hidden_filter ^\.|\.(?:pyc|pyo|bak|swp)$|^lost\+found$|^__(py)?cache__$ + +# Show hidden files? You can toggle this by typing 'zh' +set show_hidden false + +# Ask for a confirmation when running the "delete" command? +# Valid values are "always", "never", "multiple" (default) +# With "multiple", ranger will ask only if you delete multiple files at once. +set confirm_on_delete multiple + +# Use non-default path for file preview script? +# ranger ships with scope.sh, a script that calls external programs (see +# README.md for dependencies) to preview images, archives, etc. +set preview_script ~/.config/ranger/scope.sh + +# Use the external preview script or display simple plain text or image previews? +set use_preview_script true + +# Automatically count files in the directory, even before entering them? +set automatically_count_files true + +# Open all images in this directory when running certain image viewers +# like feh or sxiv? You can still open selected files by marking them. +set open_all_images true + +# Be aware of version control systems and display information. +set vcs_aware true + +# State of the four backends git, hg, bzr, svn. The possible states are +# disabled, local (only show local info), enabled (show local and remote +# information). +set vcs_backend_git enabled +set vcs_backend_hg disabled +set vcs_backend_bzr disabled +set vcs_backend_svn disabled + +# set preview_images true +# set preview_images_method sixel + +# Use a unicode "..." character to mark cut-off filenames? +set unicode_ellipsis false + +# Show dotfiles in the bookmark preview box? +set show_hidden_bookmarks true + +# Which colorscheme to use? These colorschemes are available by default: +# default, jungle, snow, solarized +set colorscheme mycolorscheme + +# Preview files on the rightmost column? +# And collapse (shrink) the last column if there is nothing to preview? +set preview_files true +set preview_directories true +set collapse_preview true + +# Save the console history on exit? +set save_console_history true + +# Draw the status bar on top of the browser window (default: bottom) +set status_bar_on_top false + +# Draw a progress bar in the status bar which displays the average state of all +# currently running tasks which support progress bars? +set draw_progress_bar_in_status_bar true + +# Draw borders around columns? (separators, outline, both, or none) +# Separators are vertical lines between columns. +# Outline draws a box around all the columns. +# Both combines the two. +set draw_borders none + +# Display the directory name in tabs? +set dirname_in_tabs true + +# Enable the mouse support? +set mouse_enabled true + +# Display the file size in the main column or status bar? +# set display_size_in_main_column true +set display_size_in_status_bar true + +# Display the free disk space in the status bar? +set display_free_space_in_status_bar true + +# Display files tags in all columns or only in main column? +set display_tags_in_all_columns true + +# Set a title for the window? +set update_title false + +# Set the title to "ranger" in the tmux program? +set update_tmux_title true + +# Shorten the title if it gets long? The number defines how many +# directories are displayed at once, 0 turns off this feature. +set shorten_title 3 + +# Show hostname in titlebar? +set hostname_in_titlebar true + +# Abbreviate $HOME with ~ in the titlebar (first line) of ranger? +set tilde_in_titlebar true + +# How many directory-changes or console-commands should be kept in history? +set max_history_size 20 +set max_console_history_size 50 + +# Try to keep so much space between the top/bottom border when scrolling: +set scroll_offset 8 + +# Flush the input after each key hit? (Noticeable when ranger lags) +set flushinput true + +# Padding on the right when there's no preview? +# This allows you to click into the space to run the file. +set padding_right true + +# Save bookmarks (used with mX and `X) instantly? +# This helps to synchronize bookmarks between multiple ranger +# instances but leads to *slight* performance loss. +# When false, bookmarks are saved when ranger is exited. +set autosave_bookmarks true + +# Save the "`" bookmark to disk. This can be used to switch to the last +# directory by typing "``". +set save_backtick_bookmark true + +# You can display the "real" cumulative size of directories by using the +# command :get_cumulative_size or typing "dc". The size is expensive to +# calculate and will not be updated automatically. You can choose +# to update it automatically though by turning on this option: +set autoupdate_cumulative_size false + +# Turning this on makes sense for screen readers: +set show_cursor false + +# One of: size, natural, basename, atime, ctime, mtime, type, random +set sort natural + +# Additional sorting options +set sort_reverse false +set sort_case_insensitive true +set sort_directories_first true +set sort_unicode false + +# Enable this if key combinations with the Alt Key don't work for you. +# (Especially on xterm) +set xterm_alt_key false + +# Whether to include bookmarks in cd command +set cd_bookmarks true + +# Changes case sensitivity for the cd command tab completion +set cd_tab_case sensitive + +# Use fuzzy tab completion with the "cd" command. For example, +# ":cd /u/lo/b" expands to ":cd /usr/local/bin". +set cd_tab_fuzzy false + +# Avoid previewing files larger than this size, in bytes. Use a value of 0 to +# disable this feature. +set preview_max_size 0 + +# The key hint lists up to this size have their sublists expanded. +# Otherwise the submaps are replaced with "...". +set hint_collapse_threshold 10 + +# Add the highlighted file to the path in the titlebar +set show_selection_in_titlebar true + +# The delay that ranger idly waits for user input, in milliseconds, with a +# resolution of 100ms. Lower delay reduces lag between directory updates but +# increases CPU load. +set idle_delay 2000 + +# When the metadata manager module looks for metadata, should it only look for +# a ".metadata.json" file in the current directory, or do a deep search and +# check all directories above the current one as well? +set metadata_deep_search false + +# Clear all existing filters when leaving a directory +set clear_filters_on_dir_change false + +# Disable displaying line numbers in main column. +# Possible values: false, absolute, relative. +set line_numbers relative + +# When line_numbers=relative show the absolute line number in the +# current line. +set relative_current_zero false + +# Start line numbers from 1 instead of 0 +set one_indexed false + +# Save tabs on exit +set save_tabs_on_exit false + +# Enable scroll wrapping - moving down while on the last item will wrap around to +# the top and vice versa. +set wrap_scroll true + +# Set the global_inode_type_filter to nothing. Possible options: d, f and l for +# directories, files and symlinks respectively. +set global_inode_type_filter + +# This setting allows to freeze the list of files to save I/O bandwidth. It +# should be 'false' during start-up, but you can toggle it by pressing F. +set freeze_files false +# }}} +# == Local Options{{{ +# +setlocal path=~/downloads sort mtime +# }}} +# == Command Aliases in the Console{{{ +# =================================================================== + +alias e edit +alias q quit +alias q! quit! +alias qa quitall +alias qa! quitall! +alias qall quitall +alias qall! quitall! +alias setl setlocal + +alias filter scout -prts +alias find scout -aets +alias mark scout -mr +alias unmark scout -Mr +alias search scout -rs +alias search_inc scout -rts +alias travel scout -aefklst +# }}} +# == Define keys for the browser{{{ +# =================================================================== + +# Basic +map Q quitall! +map q quit +copymap q ZZ ZQ + +map R reload_cwd +map F set freeze_files! +map reset +map redraw_window +map abort +map change_mode normal +map ~ set viewmode! + +map ? help +map W display_log +map w taskview_open +map X shell $SHELL + +map : console +map ; console +map ! console shell%space +map @ console -p6 shell %%s +map # console shell -p%space +map s console shell%space +map r chain draw_possible_programs; console open_with%%space +map f console find%space +map cd console cd%space + +map chain console; eval fm.ui.console.history_move(-1) + +# Change the line mode +map Mf linemode filename +map Mi linemode fileinfo +map Mm linemode mtime +map Mp linemode permissions +map Ms linemode sizemtime +map Mt linemode metatitle + +# Tagging / Marking +map t tag_toggle +map ut tag_remove +map " tag_toggle tag=%any +map mark_files toggle=True +map v mark_files all=True toggle=True +map uv mark_files all=True val=False +map b bulkrename +map V toggle_visual_mode +map uV toggle_visual_mode reverse=True + +# For the nostalgics: Midnight Commander bindings +map help +map rename_append +map display_file +map edit +map copy +map cut +map console mkdir%space +map console delete +map exit + +# In case you work on a keyboard with dvorak layout +map move up=1 +map move down=1 +map move left=1 +map move right=1 +map move to=0 +map move to=-1 +map move down=1 pages=True +map move up=1 pages=True +map move right=1 +#map console delete +map console touch%space + +# VIM-like +copymap n +copymap i +copymap e +copymap o +copymap gg +copymap G +copymap +copymap + +map T move down=0.5 pages=True +map N move up=0.5 pages=True +copymap T +copymap N + +# Jumping around +map H history_go -1 +map S history_go 1 +map ] move_parent 1 +map [ move_parent -1 +map } traverse +map { traverse_backwards +map ) jump_non + +map gh cd ~ +map ge cd /etc +map gu cd /usr +map gd cd /dev +map gl cd -r . +map gL cd -r %f +map go cd /opt +map gv cd /var +map gm cd /media +map gi eval fm.cd('/run/media/' + os.getenv('USER')) +map gM cd /mnt +map gs cd /srv +map gp cd /tmp +map gr cd / +map gR eval fm.cd(ranger.RANGERDIR) +map g/ cd / +map g? cd /usr/share/doc/ranger + +# External Programs +map E edit +map du shell -p du --max-depth=1 -h --apparent-size +map dU shell -p du --max-depth=1 -h --apparent-size | sort -rh +map yp yank path +map yd yank dir +map yn yank name +map y. yank name_without_extension + +# Filesystem Operations +map = chmod + +map cw console rename%space +map a rename_append +map A eval fm.open_console('rename ' + fm.thisfile.relative_path.replace("%", "%%")) +map I eval fm.open_console('rename ' + fm.thisfile.relative_path.replace("%", "%%"), position=7) + +map pp paste +map po paste overwrite=True +map pP paste append=True +map pO paste overwrite=True append=True +map pl paste_symlink relative=False +map pL paste_symlink relative=True +map phl paste_hardlink +map pht paste_hardlinked_subtree + +map D console delete + +map dd cut +map ud uncut +map da cut mode=add +map dr cut mode=remove +map dt cut mode=toggle + +map yy copy +map uy uncut +map ya copy mode=add +map yr copy mode=remove +map yt copy mode=toggle + +# Temporary workarounds +map dgg eval fm.cut(dirarg=dict(to=0), narg=quantifier) +map dG eval fm.cut(dirarg=dict(to=-1), narg=quantifier) +map dj eval fm.cut(dirarg=dict(down=1), narg=quantifier) +map dk eval fm.cut(dirarg=dict(up=1), narg=quantifier) +map ygg eval fm.copy(dirarg=dict(to=0), narg=quantifier) +map yG eval fm.copy(dirarg=dict(to=-1), narg=quantifier) +map yj eval fm.copy(dirarg=dict(down=1), narg=quantifier) +map yk eval fm.copy(dirarg=dict(up=1), narg=quantifier) + +# Searching +map / console search%space +map l search_next +map L search_next forward=False +map ct search_next order=tag +map cs search_next order=size +map ci search_next order=mimetype +map cc search_next order=ctime +map cm search_next order=mtime +map ca search_next order=atime + +# Tabs +map tab_new +map tab_close +map tab_move 1 +map tab_move -1 +map tab_move 1 +map tab_move -1 +map gt tab_move 1 +map gT tab_move -1 +map gn tab_new +map gc tab_close +map uq tab_restore +map tab_open 1 +map tab_open 2 +map tab_open 3 +map tab_open 4 +map tab_open 5 +map tab_open 6 +map tab_open 7 +map tab_open 8 +map tab_open 9 +map tab_shift 1 +map tab_shift -1 + +# Sorting +map sr set sort_reverse! +map sz set sort=random +map ss chain set sort=size; set sort_reverse=False +map sb chain set sort=basename; set sort_reverse=False +map sn chain set sort=natural; set sort_reverse=False +map sm chain set sort=mtime; set sort_reverse=False +map sc chain set sort=ctime; set sort_reverse=False +map sa chain set sort=atime; set sort_reverse=False +map st chain set sort=type; set sort_reverse=False +map se chain set sort=extension; set sort_reverse=False + +map sS chain set sort=size; set sort_reverse=True +map sB chain set sort=basename; set sort_reverse=True +map sN chain set sort=natural; set sort_reverse=True +map sM chain set sort=mtime; set sort_reverse=True +map sC chain set sort=ctime; set sort_reverse=True +map sA chain set sort=atime; set sort_reverse=True +map sT chain set sort=type; set sort_reverse=True +map sE chain set sort=extension; set sort_reverse=True + +map dc get_cumulative_size + +# Settings +map zc set collapse_preview! +map zd set sort_directories_first! +map zh set show_hidden! +map set show_hidden! +copymap +copymap +map zI set flushinput! +map zi set preview_images! +map zm set mouse_enabled! +map zp set preview_files! +map zP set preview_directories! +map zs set sort_case_insensitive! +map zu set autoupdate_cumulative_size! +map zv set use_preview_script! +map zf console filter%space +copymap zf zz + +# Filter stack +map .n console filter_stack add name%space +map .m console filter_stack add mime%space +map .d filter_stack add type d +map .f filter_stack add type f +map .l filter_stack add type l +map .| filter_stack add or +map .& filter_stack add and +map .! filter_stack add not +map .r console filter_stack rotate +map .c filter_stack clear +map .* filter_stack decompose +map .p filter_stack pop +map .. filter_stack show + +# Bookmarks +map ` enter_bookmark %any +map ' enter_bookmark %any +map m set_bookmark %any +map um unset_bookmark %any + +map m draw_bookmarks +copymap m um ` ' + +# Generate all the chmod bindings with some python help: +eval for arg in "rwxXst": cmd("map +u{0} shell -f chmod u+{0} %s".format(arg)) +eval for arg in "rwxXst": cmd("map +g{0} shell -f chmod g+{0} %s".format(arg)) +eval for arg in "rwxXst": cmd("map +o{0} shell -f chmod o+{0} %s".format(arg)) +eval for arg in "rwxXst": cmd("map +a{0} shell -f chmod a+{0} %s".format(arg)) +eval for arg in "rwxXst": cmd("map +{0} shell -f chmod u+{0} %s".format(arg)) + +eval for arg in "rwxXst": cmd("map -u{0} shell -f chmod u-{0} %s".format(arg)) +eval for arg in "rwxXst": cmd("map -g{0} shell -f chmod g-{0} %s".format(arg)) +eval for arg in "rwxXst": cmd("map -o{0} shell -f chmod o-{0} %s".format(arg)) +eval for arg in "rwxXst": cmd("map -a{0} shell -f chmod a-{0} %s".format(arg)) +eval for arg in "rwxXst": cmd("map -{0} shell -f chmod u-{0} %s".format(arg)) +# }}} +# Define keys for the console{{{ +# + +# Basic +# +cmap eval fm.ui.console.tab() +cmap eval fm.ui.console.tab(-1) +cmap eval fm.ui.console.close() +cmap eval fm.ui.console.execute() +cmap redraw_window + +copycmap +copycmap + +# Move around +# +cmap eval fm.ui.console.history_move(-1) +cmap eval fm.ui.console.history_move(1) +cmap eval fm.ui.console.move(left=1) +cmap eval fm.ui.console.move(right=1) +cmap eval fm.ui.console.move(right=0, absolute=True) +cmap eval fm.ui.console.move(right=-1, absolute=True) +cmap eval fm.ui.console.move_word(left=1) +cmap eval fm.ui.console.move_word(right=1) + +copycmap +copycmap + +# Line Editing +# +cmap eval fm.ui.console.delete(-1) +cmap eval fm.ui.console.delete(0) +cmap eval fm.ui.console.delete_word() +cmap eval fm.ui.console.delete_word(backward=False) +cmap eval fm.ui.console.delete_rest(1) +cmap eval fm.ui.console.delete_rest(-1) +cmap eval fm.ui.console.paste() + +# Note: There are multiple ways to express backspaces. (code 263) +# and (code 127). To be sure, use both. +copycmap + +# This special expression allows typing in numerals: +cmap false +# }}} +# Pager Keybindings {{{ + +# Movement +pmap pager_move down=1 +pmap pager_move up=1 +pmap pager_move left=4 +pmap pager_move right=4 +pmap pager_move to=0 +pmap pager_move to=-1 +pmap pager_move down=1.0 pages=True +pmap pager_move up=1.0 pages=True +pmap pager_move down=0.5 pages=True +pmap pager_move up=0.5 pages=True + +copypmap n +copypmap t +copypmap h +copypmap s +copypmap g +copypmap G +copypmap d +copypmap u +copypmap l f +copypmap p b +# }}} +# Basic{{{ +pmap redraw_window +pmap pager_close +copypmap q Q i +pmap E edit_file +# }}} +# Taskview Keybindings + +# Movement{{{ +tmap taskview_move up=1 +tmap taskview_move down=1 +tmap taskview_move to=0 +tmap taskview_move to=-1 +tmap taskview_move down=1.0 pages=True +tmap taskview_move up=1.0 pages=True +tmap taskview_move down=0.5 pages=True +tmap taskview_move up=0.5 pages=True + +copytmap n +copytmap t +copytmap g +copytmap G +copytmap u +copytmap n f +copytmap p b +# }}} +# Changing priority and deleting tasks{{{ +tmap T eval -q fm.ui.taskview.task_move(-1) +tmap N eval -q fm.ui.taskview.task_move(0) +tmap dd eval -q fm.ui.taskview.task_remove() +tmap eval -q fm.ui.taskview.task_move(-1) +tmap eval -q fm.ui.taskview.task_move(0) +tmap eval -q fm.ui.taskview.task_remove() +# }}} +# Basic +tmap redraw_window +tmap taskview_close +copytmap q Q w + +# a plugin that adds file glyphs / icon support to Ranger: +# https://github.com/alexanderjeurissen/ranger_devicons +default_linemode devicons + +# vim: commentstring=#\ %s diff --git a/user/ranger/rifle.conf b/user/ranger/rifle.conf new file mode 100644 index 0000000..9178c89 --- /dev/null +++ b/user/ranger/rifle.conf @@ -0,0 +1,301 @@ +# vim: ft=cfg +# +# This is the configuration file of "rifle", ranger's file executor/opener. +# Each line consists of conditions and a command. For each line the conditions +# are checked and if they are met, the respective command is run. +# +# Syntax: +# , , ... = command +# +# The command can contain these environment variables: +# $1-$9 | The n-th selected file +# $@ | All selected files +# +# If you use the special command "ask", rifle will ask you what program to run. +# +# Prefixing a condition with "!" will negate its result. +# These conditions are currently supported: +# match | The regexp matches $1 +# ext | The regexp matches the extension of $1 +# mime | The regexp matches the mime type of $1 +# name | The regexp matches the basename of $1 +# path | The regexp matches the absolute path of $1 +# has | The program is installed (i.e. located in $PATH) +# env | The environment variable "variable" is non-empty +# file | $1 is a file +# directory | $1 is a directory +# number | change the number of this command to n +# terminal | stdin, stderr and stdout are connected to a terminal +# X | A graphical environment is available (darwin, Xorg, or Wayland) +# +# There are also pseudo-conditions which have a "side effect": +# flag | Change how the program is run. See below. +# label