diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..118156b --- /dev/null +++ b/flake.lock @@ -0,0 +1,726 @@ +{ + "nodes": { + "dwarffs": { + "inputs": { + "nix": "nix", + "nixpkgs": [ + "dwarffs", + "nix", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1662486847, + "narHash": "sha256-HBgQB8jzmpBTHAdPfCtLnxVhHSzI3XtSfcMW2TZ0KN8=", + "owner": "edolstra", + "repo": "dwarffs", + "rev": "1f850df9c932acb95da2f31b576a8f6c7c188376", + "type": "github" + }, + "original": { + "owner": "edolstra", + "repo": "dwarffs", + "type": "github" + } + }, + "emacs": { + "flake": false, + "locked": { + "lastModified": 1683396233, + "narHash": "sha256-VzEk0WxSyjcQuLbTHKqLFxpuokKQ8vj07h56GZoRhoE=", + "owner": "~magic_rb", + "repo": "emacs", + "rev": "ec8eac076be23e42828e3a95cead31f1a6fbac33", + "type": "sourcehut" + }, + "original": { + "owner": "~magic_rb", + "repo": "emacs", + "type": "sourcehut" + } + }, + "flake-compat": { + "flake": false, + "locked": { + "lastModified": 1673956053, + "narHash": "sha256-4gtG9iQuiKITOjNQQeQIpoIB6b16fm+504Ch3sNKLd8=", + "owner": "edolstra", + "repo": "flake-compat", + "rev": "35bb57c0c8d8b62bbfd284272c928ceb64ddbde9", + "type": "github" + }, + "original": { + "owner": "edolstra", + "repo": "flake-compat", + "type": "github" + } + }, + "flake-compat_2": { + "flake": false, + "locked": { + "lastModified": 1673956053, + "narHash": "sha256-4gtG9iQuiKITOjNQQeQIpoIB6b16fm+504Ch3sNKLd8=", + "owner": "edolstra", + "repo": "flake-compat", + "rev": "35bb57c0c8d8b62bbfd284272c928ceb64ddbde9", + "type": "github" + }, + "original": { + "owner": "edolstra", + "repo": "flake-compat", + "type": "github" + } + }, + "flake-parts": { + "inputs": { + "nixpkgs-lib": "nixpkgs-lib" + }, + "locked": { + "lastModified": 1685457039, + "narHash": "sha256-bEFtQm+YyLxQjKQAaBHJyPN1z2wbhBnr2g1NJWSYjwM=", + "owner": "hercules-ci", + "repo": "flake-parts", + "rev": "80717d11615b6f42d1ad2e18ead51193fc15de69", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "flake-parts", + "type": "github" + } + }, + "flake-parts_2": { + "inputs": { + "nixpkgs-lib": "nixpkgs-lib_2" + }, + "locked": { + "lastModified": 1678379998, + "narHash": "sha256-TZdfNqftHhDuIFwBcN9MUThx5sQXCTeZk9je5byPKRw=", + "owner": "hercules-ci", + "repo": "flake-parts", + "rev": "c13d60b89adea3dc20704c045ec4d50dd964d447", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "flake-parts", + "type": "github" + } + }, + "flake-utils": { + "inputs": { + "systems": "systems" + }, + "locked": { + "lastModified": 1681202837, + "narHash": "sha256-H+Rh19JDwRtpVPAWp64F+rlEtxUWBAQW28eAi3SRSzg=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "cfacdce06f30d2b68473a46042957675eebb3401", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "flake-utils_2": { + "inputs": { + "systems": "systems_2" + }, + "locked": { + "lastModified": 1681202837, + "narHash": "sha256-H+Rh19JDwRtpVPAWp64F+rlEtxUWBAQW28eAi3SRSzg=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "cfacdce06f30d2b68473a46042957675eebb3401", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "flake-utils_3": { + "locked": { + "lastModified": 1667395993, + "narHash": "sha256-nuEHfE/LcWyuSWnS8t12N1wc105Qtau+/OdUAjtQ0rA=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "5aed5285a952e0b949eb3ba02c12fa4fcfef535f", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "gitignore": { + "inputs": { + "nixpkgs": [ + "tuxedo-rs", + "pre-commit-hooks", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1660459072, + "narHash": "sha256-8DFJjXG8zqoONA1vXtgeKXy68KdJL5UaXR8NtVMUbx8=", + "owner": "hercules-ci", + "repo": "gitignore.nix", + "rev": "a20de23b925fd8264fd7fad6454652e142fd7f73", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "gitignore.nix", + "type": "github" + } + }, + "home-manager": { + "inputs": { + "nixpkgs": "nixpkgs_2" + }, + "locked": { + "lastModified": 1685438474, + "narHash": "sha256-qQLHbg3mHYgWA3ngvWgWIdsirVkYA0StzKR3Qi72uWg=", + "owner": "nix-community", + "repo": "home-manager", + "rev": "9f82227b64245c273d98dd02dedd44fc7576041e", + "type": "github" + }, + "original": { + "owner": "nix-community", + "ref": "master", + "repo": "home-manager", + "type": "github" + } + }, + "ical2org": { + "flake": false, + "locked": { + "lastModified": 1663312032, + "narHash": "sha256-EjfvyYicmF1dNL2sDaldha/G1bZCb9s+HP83hCTvpI8=", + "ref": "refs/heads/master", + "rev": "fa262ef8e763c745fa11acacddf1c79ade0127c2", + "revCount": 89, + "type": "git", + "url": "https://git.sr.ht/~magic_rb/ical2orgpy" + }, + "original": { + "type": "git", + "url": "https://git.sr.ht/~magic_rb/ical2orgpy" + } + }, + "lowdown-src": { + "flake": false, + "locked": { + "lastModified": 1633514407, + "narHash": "sha256-Dw32tiMjdK9t3ETl5fzGrutQTzh2rufgZV4A/BbxuD4=", + "owner": "kristapsdz", + "repo": "lowdown", + "rev": "d2c2b44ff6c27b936ec27358a2653caaef8f73b8", + "type": "github" + }, + "original": { + "owner": "kristapsdz", + "repo": "lowdown", + "type": "github" + } + }, + "nil": { + "inputs": { + "flake-utils": "flake-utils", + "nixpkgs": "nixpkgs_3", + "rust-overlay": "rust-overlay" + }, + "locked": { + "lastModified": 1685439709, + "narHash": "sha256-CZ0kT8Mxv09Sf47h97s7xdBXO0PDTFOEZdQA6nfw1Eg=", + "owner": "oxalica", + "repo": "nil", + "rev": "0158d58d47abecd7f5f4e67c06365ff77bbedbc7", + "type": "github" + }, + "original": { + "owner": "oxalica", + "repo": "nil", + "type": "github" + } + }, + "nix": { + "inputs": { + "lowdown-src": "lowdown-src", + "nixpkgs": "nixpkgs", + "nixpkgs-regression": "nixpkgs-regression" + }, + "locked": { + "lastModified": 1656108215, + "narHash": "sha256-RzgcfbXxNWtt4BeJ/rPzHxR+l+wCfiauN4XTVnRLiy0=", + "owner": "NixOS", + "repo": "nix", + "rev": "586fa707fca207dbd12e49800691390249bdcd03", + "type": "github" + }, + "original": { + "id": "nix", + "type": "indirect" + } + }, + "nixinate": { + "inputs": { + "nixpkgs": "nixpkgs_4" + }, + "locked": { + "lastModified": 1682599469, + "narHash": "sha256-BXptkIWvU6RyNb9V0FWK64hpXp+s7UqEUALkZLQZWyk=", + "owner": "MagicRB", + "repo": "nixinate", + "rev": "dedba33b205866e620424db58842900cb5afae2c", + "type": "github" + }, + "original": { + "owner": "MagicRB", + "repo": "nixinate", + "type": "github" + } + }, + "nixng": { + "inputs": { + "nixpkgs": "nixpkgs_5" + }, + "locked": { + "lastModified": 1684005067, + "narHash": "sha256-mUNHQcmUSM02FNrOa/ri06TO6eh5zpw8GiOUvugKfYU=", + "owner": "nix-community", + "repo": "NixNG", + "rev": "e5c3b6a5685d75fe2e55ddf7828f739ef599b68a", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "NixNG", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1653988320, + "narHash": "sha256-ZaqFFsSDipZ6KVqriwM34T739+KLYJvNmCWzErjAg7c=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "2fa57ed190fd6c7c746319444f34b5917666e5c1", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-22.05-small", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-hashicorp": { + "locked": { + "lastModified": 1681635962, + "narHash": "sha256-cRoieDmJoT2O2u7TWDDGyGew+Z+bZ3n/GMHOXIpjPWM=", + "owner": "~magic_rb", + "repo": "nixpkgs", + "rev": "11c39a5eb9d943ab5557de1af08d7e7153e8e9b3", + "type": "sourcehut" + }, + "original": { + "owner": "~magic_rb", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "sourcehut" + } + }, + "nixpkgs-lib": { + "locked": { + "dir": "lib", + "lastModified": 1682879489, + "narHash": "sha256-sASwo8gBt7JDnOOstnps90K1wxmVfyhsTPPNTGBPjjg=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "da45bf6ec7bbcc5d1e14d3795c025199f28e0de0", + "type": "github" + }, + "original": { + "dir": "lib", + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-lib_2": { + "locked": { + "dir": "lib", + "lastModified": 1678375444, + "narHash": "sha256-XIgHfGvjFvZQ8hrkfocanCDxMefc/77rXeHvYdzBMc8=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "130fa0baaa2b93ec45523fdcde942f6844ee9f6e", + "type": "github" + }, + "original": { + "dir": "lib", + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-regression": { + "locked": { + "lastModified": 1643052045, + "narHash": "sha256-uGJ0VXIhWKGXxkeNnq4TvV3CIOkUJ3PAoLZ3HMzNVMw=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "215d4d0fd80ca5163643b03a33fde804a29cc1e2", + "type": "github" + }, + "original": { + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "215d4d0fd80ca5163643b03a33fde804a29cc1e2", + "type": "github" + } + }, + "nixpkgs-stable": { + "locked": { + "lastModified": 1678872516, + "narHash": "sha256-/E1YwtMtFAu2KUQKV/1+KFuReYPANM2Rzehk84VxVoc=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "9b8e5abb18324c7fe9f07cb100c3cd4a29cda8b8", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-22.11", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_2": { + "locked": { + "lastModified": 1684570954, + "narHash": "sha256-FX5y4Sm87RWwfu9PI71XFvuRpZLowh00FQpIJ1WfXqE=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "3005f20ce0aaa58169cdee57c8aa12e5f1b6e1b3", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_3": { + "locked": { + "lastModified": 1682929865, + "narHash": "sha256-jxVrgnf5QNjO+XoxDxUWtN2G5xyJSGZ5SWDQFxMuHxc=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "f2e9a130461950270f87630b11132323706b4d91", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_4": { + "locked": { + "lastModified": 1653060744, + "narHash": "sha256-kfRusllRumpt33J1hPV+CeCCylCXEU7e0gn2/cIM7cY=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "dfd82985c273aac6eced03625f454b334daae2e8", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_5": { + "locked": { + "lastModified": 1668984258, + "narHash": "sha256-0gDMJ2T3qf58xgcSbYoXiRGUkPWmKyr5C3vcathWhKs=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "cf63ade6f74bbc9d2a017290f1b2e33e8fbfa70a", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-22.05", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_6": { + "locked": { + "lastModified": 1685383865, + "narHash": "sha256-3uQytfnotO6QJv3r04ajSXbEFMII0dUtw0uqYlZ4dbk=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "5e871d8aa6f57cc8e0dc087d1c5013f6e212b4ce", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_7": { + "locked": { + "lastModified": 1676569297, + "narHash": "sha256-2n4C4H3/U+3YbDrQB6xIw7AaLdFISCCFwOkcETAigqU=", + "path": "/nix/store/qhj65h4klgmnkblfly0apznnl3qdir6x-source", + "rev": "ac1f5b72a9e95873d1de0233fddcb56f99884b37", + "type": "path" + }, + "original": { + "id": "nixpkgs", + "type": "indirect" + } + }, + "pre-commit-hooks": { + "inputs": { + "flake-compat": "flake-compat_2", + "flake-utils": "flake-utils_3", + "gitignore": "gitignore", + "nixpkgs": [ + "tuxedo-rs", + "nixpkgs" + ], + "nixpkgs-stable": "nixpkgs-stable" + }, + "locked": { + "lastModified": 1682326782, + "narHash": "sha256-wj7p7iEwQXAfTZ6QokAe0dMbpQk5u7ympDnaiPvbv1w=", + "owner": "cachix", + "repo": "pre-commit-hooks.nix", + "rev": "56cd2d47a9c937be98ab225cf014b450f1533cdb", + "type": "github" + }, + "original": { + "owner": "cachix", + "repo": "pre-commit-hooks.nix", + "type": "github" + } + }, + "root": { + "inputs": { + "dwarffs": "dwarffs", + "emacs": "emacs", + "flake-parts": "flake-parts", + "home-manager": "home-manager", + "ical2org": "ical2org", + "nil": "nil", + "nixinate": "nixinate", + "nixng": "nixng", + "nixpkgs": "nixpkgs_6", + "nixpkgs-hashicorp": "nixpkgs-hashicorp", + "secret": "secret", + "tuxedo-nixos": "tuxedo-nixos", + "tuxedo-rs": "tuxedo-rs", + "udp-over-tcp": "udp-over-tcp", + "uterranix": "uterranix", + "vtermModule": "vtermModule" + } + }, + "rust-overlay": { + "inputs": { + "flake-utils": [ + "nil", + "flake-utils" + ], + "nixpkgs": [ + "nil", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1682907601, + "narHash": "sha256-FfUAYvRJ+6s9WWjXNPdRzuuvAeu2VHIXIbUkPJr4t14=", + "owner": "oxalica", + "repo": "rust-overlay", + "rev": "5eaff055dd57128c53ae373dc96af944f5849daa", + "type": "github" + }, + "original": { + "owner": "oxalica", + "repo": "rust-overlay", + "type": "github" + } + }, + "secret": { + "flake": false, + "locked": { + "lastModified": 1636145225, + "narHash": "sha256-pQpattmS9VmO3ZIQUFn66az8GSmB4IvYhTTCFn6SUmo=", + "path": "/var/empty", + "type": "path" + }, + "original": { + "path": "/var/empty", + "type": "path" + } + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "systems_2": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "terranix": { + "flake": false, + "locked": { + "lastModified": 1676043131, + "narHash": "sha256-xA3vUk86nFoDkYmW+bOgX/hTWWDdgumsJMlYE7iumgQ=", + "owner": "terranix", + "repo": "terranix", + "rev": "ac98723a6c66fce3f91b0e8cbf8911430736f130", + "type": "github" + }, + "original": { + "owner": "terranix", + "repo": "terranix", + "type": "github" + } + }, + "tuxedo-nixos": { + "inputs": { + "flake-compat": "flake-compat", + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1685384046, + "narHash": "sha256-FJNQ93vlzIc0+CKsRGEBA3wdElPP2G8VSFV8U2jyhJA=", + "owner": "blitz", + "repo": "tuxedo-nixos", + "rev": "3002821d13ff9b011a411f420d2aac36a394c433", + "type": "github" + }, + "original": { + "owner": "blitz", + "repo": "tuxedo-nixos", + "type": "github" + } + }, + "tuxedo-rs": { + "inputs": { + "flake-utils": "flake-utils_2", + "nixpkgs": [ + "nixpkgs" + ], + "pre-commit-hooks": "pre-commit-hooks" + }, + "locked": { + "lastModified": 1685392049, + "narHash": "sha256-2xRDeE5qITA8SGKiN6GQwHazz8OyfN42C0sZfum0AdQ=", + "owner": "AaronErhardt", + "repo": "tuxedo-rs", + "rev": "21db8da9a7a003ef6dec30dd09b4ffe401fa7430", + "type": "github" + }, + "original": { + "owner": "AaronErhardt", + "repo": "tuxedo-rs", + "type": "github" + } + }, + "udp-over-tcp": { + "flake": false, + "locked": { + "lastModified": 1677594708, + "narHash": "sha256-5PeaM7/zhux1UdlaKpnQ2yIdmFy1n2weV/ux9lSRha4=", + "owner": "mullvad", + "repo": "udp-over-tcp", + "rev": "87936ac29b68b902565955f138ab02294bcc8593", + "type": "github" + }, + "original": { + "owner": "mullvad", + "repo": "udp-over-tcp", + "type": "github" + } + }, + "uterranix": { + "inputs": { + "flake-parts": "flake-parts_2", + "nixpkgs": "nixpkgs_7", + "terranix": "terranix" + }, + "locked": { + "lastModified": 1680122738, + "narHash": "sha256-Dvb6ZpRSPt5G6VkHzNOqCNRyHD7J9AdFYgPfHEHi7BU=", + "path": "/home/main/uterranix", + "type": "path" + }, + "original": { + "path": "/home/main/uterranix", + "type": "path" + } + }, + "vtermModule": { + "flake": false, + "locked": { + "lastModified": 1681705456, + "narHash": "sha256-1+AbPtyl1dS73WTMrIUduyWeM4cOiD3CI7d0Ic3jpVw=", + "owner": "akermu", + "repo": "emacs-libvterm", + "rev": "94e2b0b2b4a750e7907dacd5b4c0584900846dd1", + "type": "github" + }, + "original": { + "owner": "akermu", + "repo": "emacs-libvterm", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..db11488 --- /dev/null +++ b/flake.nix @@ -0,0 +1,73 @@ +# SPDX-FileCopyrightText: 2022 Richard Brežák +# +# SPDX-License-Identifier: LGPL-3.0-or-later +{ + inputs = { + nixpkgs.url = "github:NixOS/nixpkgs?ref=nixos-unstable"; + nixpkgs-hashicorp.url = "sourcehut:~magic_rb/nixpkgs?ref=nixos-unstable"; + nixinate.url = "github:MagicRB/nixinate"; + home-manager.url = "github:nix-community/home-manager?ref=master"; + nixng.url = "github:nix-community/NixNG"; + flake-parts.url = "github:hercules-ci/flake-parts"; + nil.url = "github:oxalica/nil"; + uterranix.url = "path:///home/main/uterranix"; + dwarffs.url = "github:edolstra/dwarffs"; + + tuxedo-rs.url = "github:AaronErhardt/tuxedo-rs"; + tuxedo-rs.inputs.nixpkgs.follows = "nixpkgs"; + + tuxedo-nixos.url = "github:blitz/tuxedo-nixos"; + tuxedo-nixos.inputs.nixpkgs.follows = "nixpkgs"; + + emacs.url = "sourcehut:~magic_rb/emacs"; + emacs.flake = false; + + vtermModule.url = "github:akermu/emacs-libvterm"; + vtermModule.flake = false; + + secret.url = "path:///var/empty"; + secret.flake = false; + + ical2org.url = "git+https://git.sr.ht/~magic_rb/ical2orgpy"; + ical2org.flake = false; + + udp-over-tcp.url = "github:mullvad/udp-over-tcp"; + udp-over-tcp.flake = false; + }; + + outputs = inputs@{ flake-parts, self, ... }: + flake-parts.lib.mkFlake { inherit inputs; } ({ config, ... }: { + imports = [ + nixos/systems/omen + nixos/systems/heater + nixos/systems/toothpick + nixos/systems/liveusb + + overlays/udp-over-tcp.nix + overlays/emacsclient-remote + overlays/magic-screenshot + overlays/emacs-rofi + overlays/tree-sitter-grammars.nix + overlays/emacs-master-nativecomp + ]; + + flake.nixosModules = { + hashicorp = nixos/modules/hashicorp.nix; + }; + + flake.apps = inputs.nixpkgs.lib.genAttrs config.systems (system: { + nixinate = (inputs.nixinate.nixinate.${system} self).nixinate; + }); + + flake.patches = { + hashicorp-nomad.revert-change-consul-si-tokens-to-be-local = patches/0001-Revert-Change-consul-SI-tokens-to-be-local.patch; + hashicorp-nomad.add-nix-integration = patches/0001-Add-Nix-integration.patch; + }; + + systems = [ + "x86_64-linux" + "armv8-linux" + "riscv64-linux" + ]; + }); +} diff --git a/home-manager/modules/bash/bash_profile b/home-manager/modules/bash/bash_profile new file mode 100644 index 0000000..9f2d5cf --- /dev/null +++ b/home-manager/modules/bash/bash_profile @@ -0,0 +1,7 @@ +#!/usr/bin/env bash + +# SPDX-FileCopyrightText: 2022 Richard Brežák +# +# SPDX-License-Identifier: LGPL-3.0-or-later + +source $HOME/.bashrc diff --git a/home-manager/modules/bash/bashrc b/home-manager/modules/bash/bashrc new file mode 100644 index 0000000..6ccdb53 --- /dev/null +++ b/home-manager/modules/bash/bashrc @@ -0,0 +1,138 @@ +#!/usr/bin/env bash + +# SPDX-FileCopyrightText: 2022 Richard Brežák +# +# SPDX-License-Identifier: LGPL-3.0-or-later + +[[ -e /etc/profile.d/nix.sh ]] && . /etc/profile.d/nix.sh + +# If not running interactively, don't do anything +[[ $- != *i* ]] && return + +[[ $DISPLAY ]] && shopt -s checkwinsize + +[ -r /usr/share/bash-completion/bash_completion ] && . /usr/share/bash-completion/bash_completion + +## Enable color on grep +alias grep='grep --color=auto' + +## Replace ls and cat with exa and bat respectively +alias ls='@exa@/bin/exa' +alias cat='@bat@/bin/bat' + +if [ -z "${SHLVL_INIT+x}" ]; then + export SHLVL_INIT=1 SHLVL=1 +fi + + +if [ "$SHLVL" = 1 ]; then + export PS1="\u@\[\e[37m\]\h\[\e[m\]:\[\e[32m\]\w\[\e[m\]\[\e[31m\]\\$\[\e[m\] " +else + export PS1="$SHLVL: \u@\[\e[37m\]\h\[\e[m\]:\[\e[32m\]\w\[\e[m\]\[\e[31m\]\\$\[\e[m\] " +fi + +emacsclient() { + if [[ -e "$HOME/.ssh/emacs-server" ]] && \ + nc -Uz "$HOME/.ssh/emacs-server" >/dev/null 2>&1 && \ + [[ ! -z ${INSIDE_EMACS+x} ]] ; then + params=() + sudo=0 + nowait=0 + + host=$(echo $SSH_CONNECTION | cut -d' ' -f3) + port=$(echo $SSH_CONNECTION | cut -d' ' -f4) + + for p in "${@}"; do + if [[ "${p}" == "-s" || "${p}" == "--sudo" ]]; then + sudo=1 + elif [[ "${p}" == "-n" || "${p}" == "--no-wait" ]]; then + params+=( "-nowait" ) + else + if [[ ${sudo} -eq 1 ]]; then + params+=( "-file /ssh:${USER}@${host}#${port}|sudo::"$(realpath -m "${p}") ) + else + params+=( "-file /ssh:${USER}@${host}#${port}:"$(realpath "${p}") ) + fi + fi + done + + if [[ ${nowait} -eq 0 ]] ; then + printf 'Waiting for Emacs...\n' + fi + + echo "${params[@]}" | nc -U "$HOME/.ssh/emacs-server" >/dev/null 2>&1 + else + sudo=0 + args=() + for p in "${@}"; do + if [[ "${p}" == "-s" || "${p}" == "--sudo" ]]; then + sudo=1 + else + args+=( "${p}" ) + fi + done + + if [[ ${sudo} -eq 1 ]]; then + echo env emacsclient "/sudo::${args[0]}" "${args[@]:1}" + env emacsclient "/sudo::${args[0]}" "${args[@]:1}" + else + env emacsclient "${@}" + fi + fi +} + +alias e='emacsclient' +alias E='emacsclient -s' + + +## Set prompt + +export EDITOR="emacsclient" +export BROWSER="firefox-nightly" + +## Clear scrollback for vterm +if [[ "$INSIDE_EMACS" = 'vterm' ]]; then + function clear(){ + vterm_printf "51;Evterm-clear-scrollback"; + tput clear; + } +fi + +if [[ "$INSIDE_EMACS" = 'vterm' ]] \ + && [[ -n ${EMACS_VTERM_PATH} ]] \ + && [[ -f ${EMACS_VTERM_PATH}/etc/emacs-vterm-bash.sh ]]; then + source ${EMACS_VTERM_PATH}/etc/emacs-vterm-bash.sh +fi + +eval "$(direnv hook bash)" + +alias zlist="zfs list -r -o name,used,avail,refer,compression,compressratio,recordsize,snapdir,sharenfs,mountpoint" + +function loadenv() +{ + function passhead() + { + pass $1 | tail -n +2 + } + + export \ + $(passhead Infrastructure/Nomad) \ + $(passhead Infrastructure/Vault) \ + $(passhead Infrastructure/Consul) \ + $(passhead Infrastructure/Influx) +} + +function yaml2nix() +{ + input_file="$1" + output_file="$2" + + if [ "${input_file}" = "${output_file}" ] ; then + remarshal -if yaml -of json -i "${input_file}" -o /dev/stdout | nix eval --impure --expr 'builtins.fromJSON (builtins.readFile "/dev/stdin")' > "${input_file}.tmp" + mv "${input_file}.tmp" "${output_file}" + else + remarshal -if yaml -of json -i "${input_file}" -o /dev/stdout | nix eval --impure --expr 'builtins.fromJSON (builtins.readFile "/dev/stdin")' > "${output_file}" + fi + + nixfmt "${output_file}" +} diff --git a/home-manager/modules/bash/default.nix b/home-manager/modules/bash/default.nix new file mode 100644 index 0000000..fc5f104 --- /dev/null +++ b/home-manager/modules/bash/default.nix @@ -0,0 +1,15 @@ +{ pkgs, ... }: +{ + programs.direnv.enable = true; + programs.direnv.nix-direnv.enable = true; + + home.file.".bash_profile".source = ./bash_profile; + home.file.".bashrc".source = pkgs.writeSubstitutedFile { + name = ".bashrc"; + file = ./bashrc; + substitutes = { + "exa" = "${pkgs.exa}"; + "bat" = "${pkgs.bat}"; + }; + }; +} diff --git a/home-manager/modules/default.nix b/home-manager/modules/default.nix new file mode 100644 index 0000000..1c4f482 --- /dev/null +++ b/home-manager/modules/default.nix @@ -0,0 +1,4 @@ +{ ... }: +{ + +} diff --git a/home-manager/modules/dunst/default.nix b/home-manager/modules/dunst/default.nix new file mode 100644 index 0000000..46d1246 --- /dev/null +++ b/home-manager/modules/dunst/default.nix @@ -0,0 +1,20 @@ +{ pkgs, ... }: +{ + home.file.".config/dunstrc".source = ./dunstrc; + + systemd.user.services.dunst = { + Unit = { + Description = "Dunst notification daemon"; + After = [ "graphical-session-pre.target" ]; + PartOf = [ "graphical-session.target" ]; + }; + + Service = { + Type = "dbus"; + BusName = "org.freedesktop.Notifications"; + ExecStart = "${pkgs.dunst}/bin/dunst -config ~/.config/dunstrc"; + }; + + Install = { WantedBy = [ "graphical-session.target" ]; }; + }; +} diff --git a/home-manager/modules/dunst/dunstrc b/home-manager/modules/dunst/dunstrc new file mode 100644 index 0000000..65c58a4 --- /dev/null +++ b/home-manager/modules/dunst/dunstrc @@ -0,0 +1,464 @@ +# -*- mode: conf -*- + +# SPDX-FileCopyrightText: 2022 Richard Brežák +# +# SPDX-License-Identifier: LGPL-3.0-or-later +# See dunst(5) for all configuration options + +[global] + ### Display ### + + # Which monitor should the notifications be displayed on. + monitor = 0 + + # Display notification on focused monitor. Possible modes are: + # mouse: follow mouse pointer + # keyboard: follow window with keyboard focus + # none: don't follow anything + # + # "keyboard" needs a window manager that exports the + # _NET_ACTIVE_WINDOW property. + # This should be the case for almost all modern window managers. + # + # If this option is set to mouse or keyboard, the monitor option + # will be ignored. + follow = none + + ### Geometry ### + + # dynamic width from 0 to 300 + # width = (0, 300) + # constant width of 300 + width = 300 + + # The maximum height of a single notification, excluding the frame. + height = 50 + + # Position the notification in the top right corner + origin = top-right + + # Offset from the origin + offset = 0x15 + + # Scale factor. It is auto-detected if value is 0. + scale = 0 + + # Maximum number of notification (0 means no limit) + notification_limit = 20 + + ### Progress bar ### + + # Turn on the progess bar. It appears when a progress hint is passed with + # for example dunstify -h int:value:12 + progress_bar = true + + # Set the progress bar height. This includes the frame, so make sure + # it's at least twice as big as the frame width. + progress_bar_height = 10 + + # Set the frame width of the progress bar + progress_bar_frame_width = 1 + + # Set the minimum width for the progress bar + progress_bar_min_width = 150 + + # Set the maximum width for the progress bar + progress_bar_max_width = 300 + + # Corner radius for the progress bar. 0 disables rounded corners. + progress_bar_corner_radius = 0 + + # Corner radius for the icon image. + icon_corner_radius = 0 + + # Show how many messages are currently hidden (because of + # notification_limit). + indicate_hidden = yes + + # The transparency of the window. Range: [0; 100]. + # This option will only work if a compositing window manager is + # present (e.g. xcompmgr, compiz, etc.). (X11 only) + transparency = 0 + + # Draw a line of "separator_height" pixel height between two + # notifications. + # Set to 0 to disable. + # If gap_size is greater than 0, this setting will be ignored. + separator_height = 1 + + # Padding between text and separator. + padding = 1 + + # Horizontal padding. + horizontal_padding = 4 + + # Padding between text and icon. + text_icon_padding = 0 + + # Defines width in pixels of frame around the notification window. + # Set to 0 to disable. + frame_width = 1 + + # Defines color of the frame around the notification window. + frame_color = "#555555" + + # Size of gap to display between notifications - requires a compositor. + # If value is greater than 0, separator_height will be ignored and a border + # of size frame_width will be drawn around each notification instead. + # Click events on gaps do not currently propagate to applications below. + gap_size = 0 + + # Define a color for the separator. + # possible values are: + # * auto: dunst tries to find a color fitting to the background; + # * foreground: use the same color as the foreground; + # * frame: use the same color as the frame; + # * anything else will be interpreted as a X color. + separator_color = frame + + # Sort messages by urgency. + sort = yes + + # Don't remove messages, if the user is idle (no mouse or keyboard input) + # for longer than idle_threshold seconds. + # Set to 0 to disable. + # A client can set the 'transient' hint to bypass this. See the rules + # section for how to disable this if necessary + # idle_threshold = 120 + + ### Text ### + + font = Fixed 10 + + # The spacing between lines. If the height is smaller than the + # font height, it will get raised to the font height. + line_height = 0 + + # Possible values are: + # full: Allow a small subset of html markup in notifications: + # bold + # italic + # strikethrough + # underline + # + # For a complete reference see + # . + # + # strip: This setting is provided for compatibility with some broken + # clients that send markup even though it's not enabled on the + # server. Dunst will try to strip the markup but the parsing is + # simplistic so using this option outside of matching rules for + # specific applications *IS GREATLY DISCOURAGED*. + # + # no: Disable markup parsing, incoming notifications will be treated as + # plain text. Dunst will not advertise that it has the body-markup + # capability if this is set as a global setting. + # + # It's important to note that markup inside the format option will be parsed + # regardless of what this is set to. + markup = full + + # The format of the message. Possible variables are: + # %a appname + # %s summary + # %b body + # %i iconname (including its path) + # %I iconname (without its path) + # %p progress value if set ([ 0%] to [100%]) or nothing + # %n progress value if set without any extra characters + # %% Literal % + # Markup is allowed + format = "%a: %s\n%b" + + # Alignment of message text. + # Possible values are "left", "center" and "right". + alignment = left + + # Vertical alignment of message text and icon. + # Possible values are "top", "center" and "bottom". + vertical_alignment = center + + # Show age of message if message is older than show_age_threshold + # seconds. + # Set to -1 to disable. + show_age_threshold = 60 + + # Specify where to make an ellipsis in long lines. + # Possible values are "start", "middle" and "end". + ellipsize = middle + + # Ignore newlines '\n' in notifications. + ignore_newline = no + + # Stack together notifications with the same content + stack_duplicates = true + + # Hide the count of stacked notifications with the same content + hide_duplicate_count = false + + # Display indicators for URLs (U) and actions (A). + show_indicators = yes + + ### Icons ### + + # Recursive icon lookup. You can set a single theme, instead of having to + # define all lookup paths. + enable_recursive_icon_lookup = true + + # Set icon theme (only used for recursive icon lookup) + icon_theme = Adwaita + # You can also set multiple icon themes, with the leftmost one being used first. + # icon_theme = "Adwaita, breeze" + + # Align icons left/right/top/off + icon_position = off + + # Scale small icons up to this size, set to 0 to disable. Helpful + # for e.g. small files or high-dpi screens. In case of conflict, + # max_icon_size takes precedence over this. + min_icon_size = 32 + + # Scale larger icons down to this size, set to 0 to disable + max_icon_size = 128 + + # Paths to default icons (only neccesary when not using recursive icon lookup) + icon_path = /usr/share/icons/gnome/16x16/status/:/usr/share/icons/gnome/16x16/devices/ + + ### History ### + + # Should a notification popped up from history be sticky or timeout + # as if it would normally do. + sticky_history = yes + + # Maximum amount of notifications kept in history + history_length = 20 + + ### Misc/Advanced ### + + # dmenu path. + dmenu = /usr/bin/dmenu -p dunst: + + # Browser for opening urls in context menu. + browser = /usr/bin/xdg-open + + # Always run rule-defined scripts, even if the notification is suppressed + always_run_script = true + + # Define the title of the windows spawned by dunst + title = Dunst + + # Define the class of the windows spawned by dunst + class = Dunst + + # Define the corner radius of the notification window + # in pixel size. If the radius is 0, you have no rounded + # corners. + # The radius will be automatically lowered if it exceeds half of the + # notification height to avoid clipping text and/or icons. + corner_radius = 0 + + # Ignore the dbus closeNotification message. + # Useful to enforce the timeout set by dunst configuration. Without this + # parameter, an application may close the notification sent before the + # user defined timeout. + ignore_dbusclose = false + + ### Wayland ### + # These settings are Wayland-specific. They have no effect when using X11 + + # Uncomment this if you want to let notications appear under fullscreen + # applications (default: overlay) + # layer = top + + # Set this to true to use X11 output on Wayland. + force_xwayland = false + + ### Legacy + + # Use the Xinerama extension instead of RandR for multi-monitor support. + # This setting is provided for compatibility with older nVidia drivers that + # do not support RandR and using it on systems that support RandR is highly + # discouraged. + # + # By enabling this setting dunst will not be able to detect when a monitor + # is connected or disconnected which might break follow mode if the screen + # layout changes. + force_xinerama = false + + ### mouse + + # Defines list of actions for each mouse event + # Possible values are: + # * none: Don't do anything. + # * do_action: Invoke the action determined by the action_name rule. If there is no + # such action, open the context menu. + # * open_url: If the notification has exactly one url, open it. If there are multiple + # ones, open the context menu. + # * close_current: Close current notification. + # * close_all: Close all notifications. + # * context: Open context menu for the notification. + # * context_all: Open context menu for all notifications. + # These values can be strung together for each mouse event, and + # will be executed in sequence. + mouse_left_click = close_current + mouse_middle_click = do_action, close_current + mouse_right_click = close_all + +# Experimental features that may or may not work correctly. Do not expect them +# to have a consistent behaviour across releases. +[experimental] + # Calculate the dpi to use on a per-monitor basis. + # If this setting is enabled the Xft.dpi value will be ignored and instead + # dunst will attempt to calculate an appropriate dpi value for each monitor + # using the resolution and physical size. This might be useful in setups + # where there are multiple screens with very different dpi values. + per_monitor_dpi = false + + +[urgency_low] + # IMPORTANT: colors have to be defined in quotation marks. + # Otherwise the "#" and following would be interpreted as a comment. + background = "#000000" + foreground = "#FFFFFF" + timeout = 10 + # Icon for notifications with low urgency, uncomment to enable + #default_icon = /path/to/icon + +[urgency_normal] + background = "#000000" + foreground = "#FFFFFF" + timeout = 10 + # Icon for notifications with normal urgency, uncomment to enable + #default_icon = /path/to/icon + +[urgency_critical] + background = "#000000" + foreground = "#FFFFFF" + frame_color = "#FF0000" + timeout = 0 + # Icon for notifications with critical urgency, uncomment to enable + #default_icon = /path/to/icon + +# Every section that isn't one of the above is interpreted as a rules to +# override settings for certain messages. +# +# Messages can be matched by +# appname (discouraged, see desktop_entry) +# body +# category +# desktop_entry +# icon +# match_transient +# msg_urgency +# stack_tag +# summary +# +# and you can override the +# background +# foreground +# format +# frame_color +# fullscreen +# new_icon +# set_stack_tag +# set_transient +# set_category +# timeout +# urgency +# icon_position +# skip_display +# history_ignore +# action_name +# word_wrap +# ellipsize +# alignment +# hide_text +# +# Shell-like globbing will get expanded. +# +# Instead of the appname filter, it's recommended to use the desktop_entry filter. +# GLib based applications export their desktop-entry name. In comparison to the appname, +# the desktop-entry won't get localized. +# +# SCRIPTING +# You can specify a script that gets run when the rule matches by +# setting the "script" option. +# The script will be called as follows: +# script appname summary body icon urgency +# where urgency can be "LOW", "NORMAL" or "CRITICAL". +# +# NOTE: It might be helpful to run dunst -print in a terminal in order +# to find fitting options for rules. + +# Disable the transient hint so that idle_threshold cannot be bypassed from the +# client +#[transient_disable] +# match_transient = yes +# set_transient = no +# +# Make the handling of transient notifications more strict by making them not +# be placed in history. +#[transient_history_ignore] +# match_transient = yes +# history_ignore = yes + +# fullscreen values +# show: show the notifications, regardless if there is a fullscreen window opened +# delay: displays the new notification, if there is no fullscreen window active +# If the notification is already drawn, it won't get undrawn. +# pushback: same as delay, but when switching into fullscreen, the notification will get +# withdrawn from screen again and will get delayed like a new notification +#[fullscreen_delay_everything] +# fullscreen = delay +#[fullscreen_show_critical] +# msg_urgency = critical +# fullscreen = show + +#[espeak] +# summary = "*" +# script = dunst_espeak.sh + +#[script-test] +# summary = "*script*" +# script = dunst_test.sh + +#[ignore] +# # This notification will not be displayed +# summary = "foobar" +# skip_display = true + +#[history-ignore] +# # This notification will not be saved in history +# summary = "foobar" +# history_ignore = yes + +#[skip-display] +# # This notification will not be displayed, but will be included in the history +# summary = "foobar" +# skip_display = yes + +#[signed_on] +# appname = Pidgin +# summary = "*signed on*" +# urgency = low +# +#[signed_off] +# appname = Pidgin +# summary = *signed off* +# urgency = low +# +#[says] +# appname = Pidgin +# summary = *says* +# urgency = critical +# +#[twitter] +# appname = Pidgin +# summary = *twitter.com* +# urgency = normal +# +#[stack-volumes] +# appname = "some_volume_notifiers" +# set_stack_tag = "volume" +# +# vim: ft=cfg diff --git a/home-manager/modules/emacs/.emacs b/home-manager/modules/emacs/.emacs new file mode 100755 index 0000000..a38e199 --- /dev/null +++ b/home-manager/modules/emacs/.emacs @@ -0,0 +1,139 @@ +; SPDX-FileCopyrightText: 2022 Richard Brežák +; +; SPDX-License-Identifier: LGPL-3.0-or-later + +;;; package --- Summary + +;;; Commentary: + + +;;; Code: + +(defvar bootstrap-version) +(let ((bootstrap-file + (expand-file-name "straight/repos/straight.el/bootstrap.el" user-emacs-directory)) + (bootstrap-version 5)) + (unless (file-exists-p bootstrap-file) + (with-current-buffer + (url-retrieve-synchronously + "https://raw.githubusercontent.com/raxod502/straight.el/develop/install.el" + 'silent 'inhibit-cookies) + (goto-char (point-max)) + (eval-print-last-sexp))) + (load bootstrap-file nil 'nomessage)) + +(custom-set-variables + ;; custom-set-variables was added by Custom. + ;; If you edit it by hand, you could mess it up, so be careful. + ;; Your init file should contain only one such instance. + ;; If there is more than one, they won't work right. + '(auth-source-save-behavior nil) + '(custom-enabled-themes '()) + '(custom-safe-themes + '("2f1518e906a8b60fac943d02ad415f1d8b3933a5a7f75e307e6e9a26ef5bf570" default)) + '(package-selected-packages + '())) +(custom-set-faces + ;; custom-set-faces was added by Custom. + ;; If you edit it by hand, you could mess it up, so be careful. + ;; Your init file should contain only one such instance. + ;; If there is more than one, they won't work right. + ) + +(setq backup-directory-alist `(("." . "~/.emacs.d/saves"))) +(setq vc-follow-symlinks t) + +(add-to-list 'load-path "~/.emacs.d/lisp/") +(add-to-list 'load-path "~/.emacs.d/lisp/org-task-dump") +(add-to-list 'load-path "~/.emacs.d/vterm-module/lib") +(add-to-list 'exec-path "~/.emacs.d/profile/bin") +(setenv "PATH" (concat "~/.emacs.d/profile/bin:" (getenv "PATH"))) + +(straight-use-package 'use-package) +(straight-thaw-versions) + +;; load general early for now +(use-package general + :straight t) + +(use-package org + :straight t) + +(defun magic_rb/org-transclusion-babel-load (&optional narrowed) + "Call `org-babel-load-file` on all transcludes in the current file." + (interactive "P") + (save-restriction + (let ((marker (move-marker (make-marker) (point))) + (load-link (lambda () + (let* ((keyword-plist (org-transclusion-keyword-string-to-plist)) + (link (org-transclusion-wrap-path-to-link + (plist-get keyword-plist :link))) + + (link-raw (org-element-property :raw-link link)) + (link-type (org-element-property :type link))) + (when (string-equal link-type "id") + (message "RB Loading: %s" (org-id-find-id-file link-raw)) + (org-babel-load-file (org-id-find-id-file link-raw))))))) + (unless narrowed (widen)) + (goto-char (point-min)) + + ;; Handle inactive transclusions + (let ((regexp "^[ \t]*#\\+TRANSCLUDE:")) + (while (re-search-forward regexp nil t) + ;; Don't transclude if within a transclusion to avoid infinite + ;; recursion + (unless (or (org-transclusion-within-transclusion-p) + (plist-get (org-transclusion-keyword-string-to-plist) + :disable-auto)) + (funcall load-link)))) + + ;; Handle active transclusions + (while (setq match (text-property-search-forward 'org-transclusion-type)) + (goto-char (prop-match-beginning match)) + (org-transclusion-remove) + (funcall load-link) + (org-transclusion-add)) + + (goto-char marker) + (move-marker marker nil) ; point nowhere for GC + t))) + +(require 'cl-lib) + +(use-package org-roam + :straight t + :demand t + :init + (setq org-roam-v2-ack t + org-roam-directory "~/roam")) + +(defvar magic_rb/org-init-files + (cl-concatenate + 'list + (directory-files "~/.emacs.d/org" t "\\.org$") + (seq-map #'car + (org-roam-db-query + [:select [nodes:file] + :from tags + :left-join nodes + :on (= tags:node-id nodes:id) + :where (like tag (quote "%\"emacs-load\""))]))) + "List of org files, which should be tangled and loaded.") + +(defvar magic_rb/org-el-init-files + (cl-map 'list + (lambda (file) (concat (file-name-sans-extension file) ".el")) + magic_rb/org-init-files) + "List of generated elisp files from magic_rb/org-init-files.") + +(defun magic_rb/delete-file-maybe (file) + "If FILE exists, delete it." + (when (file-exists-p file) + (delete-file file))) + +(mapc #'magic_rb/delete-file-maybe magic_rb/org-el-init-files) +(mapc #'org-babel-load-file magic_rb/org-init-files) + + +(provide '.emacs) +;;; .emacs ends here diff --git a/home-manager/modules/emacs/.emacs.d/.keep b/home-manager/modules/emacs/.emacs.d/.keep new file mode 100644 index 0000000..e69de29 diff --git a/home-manager/modules/emacs/.emacs.d/lisp/.keep b/home-manager/modules/emacs/.emacs.d/lisp/.keep new file mode 100644 index 0000000..e69de29 diff --git a/home-manager/modules/emacs/.emacs.d/lisp/auxmenu.el b/home-manager/modules/emacs/.emacs.d/lisp/auxmenu.el new file mode 100644 index 0000000..2357be6 --- /dev/null +++ b/home-manager/modules/emacs/.emacs.d/lisp/auxmenu.el @@ -0,0 +1,36 @@ +;;; package --- Summary: +;;; Commentary: +;;; Code: + +(defvar auxmenu-frame-alist nil) + +(defun auxmenu-popup-frame (prompt collection display width height &rest args) + "" + (let ((frame (alist-get display auxmenu-frame-alist))) + (when (equal frame nil) + (when (equal display nil) + (error "Must specify display")) + + (push `(,display . ,(make-frame + `((minibuffer . only) + (name . "emacs-completing-read-float") + (unsplittable . t) + (no-other-frame . t) + (width . ,width) + (height . ,height) + (display . ,display) + (left . 0.5) + (top . 0.5)))) + auxmenu-frame-alist) + (setq frame (alist-get display auxmenu-frame-alist))) + (make-frame-visible frame) + (raise-frame frame) + (with-selected-frame frame + (unwind-protect + (let ((selection (apply #'completing-read prompt collection args))) + (make-frame-invisible frame) + selection) + (make-frame-invisible frame))))) + +(provide 'auxmenu) +;;; auxmenu.el ends here diff --git a/home-manager/modules/emacs/.emacs.d/lisp/man-preview.el b/home-manager/modules/emacs/.emacs.d/lisp/man-preview.el new file mode 100644 index 0000000..05f1835 --- /dev/null +++ b/home-manager/modules/emacs/.emacs.d/lisp/man-preview.el @@ -0,0 +1,305 @@ +;;; man-preview.el --- preview nroff man file source + +; Copyright 2008, 2009, 2010, 2011, 2013, 2015 Kevin Ryde +; SPDX-FileCopyrightText: 2022 Richard Brežák +; +; SPDX-License-Identifier: LGPL-3.0-or-later + +;; man-preview.el is free software; you can redistribute it and/or modify it +;; under the terms of the GNU General Public License as published by the +;; Free Software Foundation; either version 3, or (at your option) any later +;; version. +;; +;; man-preview.el is distributed in the hope that it will be useful, but +;; WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +;; Public License for more details. +;; +;; You can get a copy of the GNU General Public License online at +;; . + + +;;; Commentary: + +;; M-x man-preview displays a formatted preview of man nroff source using +;; "man -l". The best feature is that when re-previewing the same file or +;; buffer the existing position in the preview is preserved, so if you've +;; changed the source only a little you should still be quite close to where +;; you were in the preview, to see how the change has come out. +;; +;; M-x man with "-l filename" does almost the same as this, but depends on +;; having a disk copy of a buffer, so can't work out of tar-mode members +;; etc. + +;;; Emacsen: +;; +;; Designed for Emacs 21 and up. Works in XEmacs 21. + +;;; Install: +;; +;; Put man-preview.el in one of your `load-path' directories, and to make +;; M-x man-preview available add to your .emacs +;; +;; (autoload 'man-preview "man-preview" nil t) +;; +;; You can also bind it to a key, for example f8 in nroff-mode, +;; +;; (eval-after-load "nroff-mode" +;; '(define-key nroff-mode-map [f8] 'man-preview)) +;; +;; There's an autoload cookie for `man-preview' if you install via +;; `M-x package-install' or know `update-file-autoloads'. Then bind it to a +;; key as desired. + +;;; History: +;; +;; Version 1 - the first version +;; Version 2 - break out the save-display and errorfile bits for clarity +;; Version 3 - xemacs21 switch-to-buffer-other-window only takes one arg +;; Version 4 - tighter compilation-find-file hack +;; Version 5 - use pipe rather than pty for subprocess +;; Version 6 - delete errors window when no errors +;; Version 7 - undo defadvice on unload-feature +;; Version 8 - express dependency on 'advice +;; Version 9 - compilation-find-file args by number, so not depend on names +;; Version 10 - macros not needed after byte compiling + +;;; Code: + +(require 'man) + +;; Explicit dependency on advice.el since `man-preview-unload-function' +;; needs `ad-find-advice' macro when running not byte compiled, and that +;; macro is not autoloaded. +(require 'advice) + +;; xemacs compatibility +(eval-and-compile + (defalias 'man-preview--make-temp-file + (if (eval-when-compile (fboundp 'make-temp-file)) + 'make-temp-file ;; emacs + ;; xemacs21 + (autoload 'mm-make-temp-file "mm-util") ;; from gnus + 'mm-make-temp-file))) + + +(defconst man-preview-buffer "*man-preview*" + "The name of the buffer for `man-preview' output.") + +(defconst man-preview-error-buffer "*man-preview-errors*" + "The name of the buffer for `man-preview' error messages.") + +(defvar man-preview-origin nil + "The name of the input buffer being displayed in `man-preview-buffer'.") + +(eval-when-compile + (defmacro man-preview--with-saved-display-position (&rest body) + "An internal part of man-preview.el. +This macro does not exist when running byte compiled. + +Save `window-start' and point positions as line/column. +The use of line/column means BODY can erase and rewrite the +buffer contents." + ;; (declare (debug t)) ;; emacs22,xemacs21, or 'cl + `(let ((point-column (current-column)) + (point-line (count-lines (point-min) (line-beginning-position))) + (window-line (count-lines (point-min) (window-start)))) + ,@body + + (goto-char (point-min)) (forward-line window-line) + ;; Don't let window-start be the very end of the buffer, since that + ;; would leave it completely blank. + (if (= (point) (point-max)) + (forward-line -1)) + (set-window-start (selected-window) (point)) + (goto-char (point-min)) (forward-line point-line) + (move-to-column point-column)))) + +(eval-when-compile + (defmacro man-preview--with-errorfile (&rest body) + "An internal part of man-preview.el. +This macro does not exist when running byte compiled. +Create an `errorfile' for use by the BODY forms. +An `unwind-protect' ensures the file is removed no matter what +BODY does." + ;; (declare (debug t)) ;; emacs22,xemacs21, or 'cl + `(let ((errorfile (man-preview--make-temp-file "man-preview-"))) + (unwind-protect + (progn ,@body) + (delete-file errorfile))))) + +;;;###autoload +(defun man-preview () + "Preview man page nroff source in the current buffer. +The buffer is put through \"man -l\" and the formatted result +displayed in a buffer. + +Errors from man or nroff are shown in a `compilation-mode' buffer +and `next-error' (\\[next-error]) can step through them to see +the offending parts of the source. + +------ +For reference, the non-ascii situation is roughly as follows. + +Traditionally roff input is supposed to be ascii with various +escape directives for further characters and inked accenting to +be rendered on the phototypesetter. Groff (version 1.18) takes +8-bit input, as latin-1 by default but in principle configurable. +It doesn't, however, have a utf8 input mode, so that should be +avoided (though it can operate on unicode chars internally if +given by escape directives). + +man-db 2.5 (October 2007) and up can convert input codings to +latin1 for groff, from a charset given either with an Emacs style +\"coding:\" cookie in the file, or a subdir name like +/usr/share/man/fr.UTF-8/man1, or guessing the content bytes. The +coding cookie is probably best for `man-preview' (since it only +sends to man's stdin, there's no subdir name for man to follow). + +On the output side groff can be asked to produce either latin1 or +utf8 (though how well it matches up inked overprinting to output +chars is another matter). + +In any case `man-preview' sends per `buffer-file-coding-system', +the same as if man was run directly on the file. Output from man +is requested as -Tlatin1 if the input coding is latin-1, or +-Tutf8 for anything else (and if the running Emacs has utf-8). + +------ +The man-preview home page is +URL `http://user42.tuxfamily.org/man-preview/index.html'" + + (interactive) + + ;; Zap existing `man-preview-error-buffer'. + ;; Turn off any compilation-mode there so that mode won't attempt to parse + ;; the contents (until later when they've been variously munged). + (with-current-buffer (get-buffer-create man-preview-error-buffer) + (fundamental-mode) + (setq buffer-read-only nil) + (erase-buffer)) + + (let ((origin-buffer (current-buffer)) + (T-option "-Tlatin1") + (T-coding 'iso-8859-1) + (directory default-directory)) + + ;; Running man with either "-Tlatin1" or "-Tutf8" makes it print + ;; overstrikes and underscores for bold and italics, which + ;; `Man-fontify-manpage' (below) crunches into fontification. + ;; + ;; It might be that those -T options make man-db 2.5 lose its input + ;; charset detection ("manconv"), though it seems ok with 2.5.2. + ;; + (when (and (not (eq buffer-file-coding-system 'iso-8859-1)) + (memq 'utf-8 (coding-system-list))) + (setq T-option "-Tutf8") + (setq T-coding 'utf-8)) + + (switch-to-buffer man-preview-buffer) + (setq buffer-read-only nil) + + ;; default-directory set from the source buffer, so that find-file or + ;; whatever offers the same default as the source buffer. This is + ;; inherited on initial creation of the preview buffer, but has to be + ;; set explicitly when previewing a new source buffer with a different + ;; default-directory. + (setq default-directory directory) + + ;; if previewing a different buffer then erase here so as not to restore + ;; point+window position into a completely different document + (if (not (equal man-preview-origin (buffer-name origin-buffer))) + (erase-buffer)) + (setq man-preview-origin (buffer-name origin-buffer)) + + (man-preview--with-errorfile ;; compilation output + (man-preview--with-saved-display-position + (erase-buffer) + + (with-current-buffer origin-buffer + (let ((coding-system-for-write buffer-file-coding-system) + (coding-system-for-read T-coding) + (process-connection-type nil)) ;; pipe + (call-process-region (point-min) (point-max) "man" + nil ;; don't delete input + (list man-preview-buffer errorfile) + nil ;; don't redisplay + T-option "-l" "-"))) + + ;; show errors in a window, but only if there are any + (save-selected-window + (with-current-buffer man-preview-error-buffer + (insert-file-contents errorfile) + + ;; emacs21 compilation regexps don't like "" as a + ;; filename, so mung that (which is easier than adding to the + ;; patterns) + (goto-char (point-min)) + (while (re-search-forward "^:" nil t) + (replace-match "standardinput:" t t)) + + (if (= (point-min) (point-max)) + (progn + ;; No errors, kill buffer and window. Killing the window + ;; prevents something unrelated showing in a small window + ;; which can be annoying for buffer cycling etc. + (delete-windows-on (current-buffer)) + (kill-buffer nil)) + + ;; emacs21 ignores the first two lines of a compilation-mode + ;; buffer, so add in dummies + (goto-char (point-min)) + (insert "man-preview\n\n") + + ;; switch to display error buffer + (let ((existing-window (get-buffer-window (current-buffer)))) + (condition-case nil + ;; emacs two args + (switch-to-buffer-other-window (current-buffer) + t) ;; no-record + (error + ;; xemacs one arg + (switch-to-buffer-other-window (current-buffer)))) + ;; if newly displaying an error window then shrink to what's + ;; needed, don't want a half screen if there's only a couple + ;; of lines + (if (not existing-window) + (shrink-window-if-larger-than-buffer + (get-buffer-window (current-buffer))))) + (compilation-mode)))) + + (if (eval-when-compile (fboundp 'Man-mode)) + ;; emacs21 and emacs22 + (progn + (Man-fontify-manpage) + (Man-mode)) + ;; xemacs21 + (Manual-nuke-nroff-bs) + (Manual-mode)))))) + +(defadvice compilation-find-file (around man-preview activate) + "Use `man-preview-origin' buffer for its man/nroff errors." + + ;; args: (compilation-find-file MARKER FILENAME DIRECTORY &rest FORMATS) + (if (let ((marker (ad-get-arg 0)) + (filename (ad-get-arg 1))) + (and (equal filename + "standardinput") + (equal (buffer-name (marker-buffer marker)) + man-preview-error-buffer))) + (setq ad-return-value man-preview-origin) + ad-do-it)) + +(defun man-preview-unload-function () + "Remove defadvice from `compilation-find-file'. +This is called by `unload-feature'." + (when (ad-find-advice 'compilation-find-file 'around 'man-preview) + (ad-remove-advice 'compilation-find-file 'around 'man-preview) + (ad-activate 'compilation-find-file)) + nil) ;; and do normal unload-feature actions too + +;; LocalWords: roff groff Groff nroff latin Tlatin Tutf db subdir usr fr stdin filename ascii utf unicode codings charset + +(provide 'man-preview) + +;;; man-preview.el ends here diff --git a/home-manager/modules/emacs/.emacs.d/lisp/org-alert.el b/home-manager/modules/emacs/.emacs.d/lisp/org-alert.el new file mode 100644 index 0000000..2ab37b5 --- /dev/null +++ b/home-manager/modules/emacs/.emacs.d/lisp/org-alert.el @@ -0,0 +1,125 @@ +;;; org-alert.el --- Notify org deadlines via notify-send + +; Copyright (C) 2015 Stephen Pegoraro +; SPDX-FileCopyrightText: 2022 Richard Brežák +; +; SPDX-License-Identifier: LGPL-3.0-or-later + +;; Author: Stephen Pegoraro +;; Version: 0.1.0 +;; Package-Requires: ((s "1.10.0") (dash "2.11.0") (alert "1.2")) +;; Keywords: org, org-mode, notify, notifications, calendar +;; URL: https://github.com/groksteve/org-alert + +;; This program is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see . + +;;; Commentary: + +;; This package provides functions to display system notifications for +;; any org-mode deadlines that are due in your agenda. To perform a +;; one-shot check call (org-alert-deadlines). To enable repeated +;; checking call (org-alert-enable) and to disable call +;; (org-alert-disable). You can set the checking interval by changing +;; the org-alert-interval variable to the number of seconds you'd +;; like. + + +;;; Code: + +(require 's) +(require 'dash) +(require 'org-agenda) + + +(defvar org-alert-interval 300 + "Interval in seconds to recheck and display deadlines.") + + +(defvar org-alert-notification-title "*org*" + "Title to be sent with notify-send.") + +(defvar org-alert-headline-regexp "\\(Sched.+:.+\\|Deadline:.+\\)" + "Regexp for headlines to search in agenda buffer.") + +(defun org-alert--strip-prefix (headline) + "Remove the scheduled/deadline prefix from HEADLINE." + (replace-regexp-in-string ".*:\s+" "" headline)) + + +(defun org-alert--unique-headlines (regexp agenda) + "Return unique headlines from the results of REGEXP in AGENDA." + (let ((matches (-distinct (-flatten (s-match-strings-all regexp agenda))))) + (--map (org-alert--strip-prefix it) matches))) + + +(defun org-alert--get-headlines () + "Return the current org agenda as text only." + (with-temp-buffer + (let ((org-agenda-sticky nil) + (org-agenda-buffer-tmp-name (buffer-name))) + (ignore-errors (org-agenda-list 1)) + (org-alert--unique-headlines org-alert-headline-regexp + (buffer-substring-no-properties (point-min) (point-max)))))) + + +(defun org-alert--headline-complete? (headline) + "Return whether HEADLINE has been completed." + (--any? (s-starts-with? it headline) org-done-keywords-for-agenda)) + + +(defun org-alert--filter-active (deadlines) + "Remove any completed headings from the provided DEADLINES." + (-remove 'org-alert--headline-complete? deadlines)) + + +(defun org-alert--strip-states (deadlines) + "Remove the todo states from DEADLINES." + (--map (s-trim (s-chop-prefixes org-todo-keywords-for-agenda it)) deadlines)) + + +(defun org-alert-check () + "Check for active, due deadlines and initiate notifications." + (interactive) + ;; avoid interrupting current command. + (unless (minibufferp) + (save-window-excursion + (save-excursion + (save-restriction + (let ((active (org-alert--filter-active (org-alert--get-headlines)))) + (dolist (dl (org-alert--strip-states active)) + (notifications-notify :title dl)))))) + (when (get-buffer org-agenda-buffer-name) + (ignore-errors + (with-current-buffer org-agenda-buffer-name + (org-agenda-redo t)))))) + + +(defun org-alert-enable () + "Enable the notification timer. Cancels existing timer if running." + (interactive) + (org-alert-disable) + (run-at-time 0 org-alert-interval 'org-alert-check)) + + +(defun org-alert-disable () + "Cancel the running notification timer." + (interactive) + (dolist (timer timer-list) + (if (eq (elt timer 5) 'org-alert-check) + (cancel-timer timer)))) + + + +(provide 'org-alert) +;;; org-alert.el ends here diff --git a/home-manager/modules/emacs/.emacs.d/lisp/org-task-dump/COPYING b/home-manager/modules/emacs/.emacs.d/lisp/org-task-dump/COPYING new file mode 100644 index 0000000..0164265 --- /dev/null +++ b/home-manager/modules/emacs/.emacs.d/lisp/org-task-dump/COPYING @@ -0,0 +1,341 @@ +As per https://www.c0t0d0s0.de/otdl/otdl.html. + + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. diff --git a/home-manager/modules/emacs/.emacs.d/lisp/org-task-dump/org-task-dump-logs-as-csv.el b/home-manager/modules/emacs/.emacs.d/lisp/org-task-dump/org-task-dump-logs-as-csv.el new file mode 100644 index 0000000..cbedf90 --- /dev/null +++ b/home-manager/modules/emacs/.emacs.d/lisp/org-task-dump/org-task-dump-logs-as-csv.el @@ -0,0 +1,26 @@ +;; +;; $Id: org-task-dump-logs-as-csv.el,v 196a830a575e 2016/04/16 15:26:31 pkgs $ +;; + + +(load "org-task-dump-logs.el") + +(defun hmw/csv-formatter(log-entry) + "Format a 3-tuple into comma separated values." + (insert (format "%s,%s,%s\n" (car log-entry) + (cadr log-entry) + (mapconcat 'identity (cddr log-entry) " ")))) + +(defun hmw/org-task-dump-logs-as-csv(csv-file-name &optional with-header) + "Generate a CSV file of the state changes of a given task. The +data is saved in CSV-FILE-NAME. An optional CSV file header can +be generated by calling this function with the prefix argument or +by setting the optional WITH-HEADER parameter." + (interactive "FSave as CSV file: \nP") + (let ((log-entries (hmw/org-task-retrieve-logs))) + (with-temp-buffer + (if with-header (insert "FromState,ToState,Timestamp\n")) + (mapc (lambda(e)(hmw/csv-formatter e)) (cdr log-entries)) + (write-file csv-file-name)))) + +(provide 'org-task-dump-logs-as-csv) diff --git a/home-manager/modules/emacs/.emacs.d/lisp/org-task-dump/org-task-dump-logs.el b/home-manager/modules/emacs/.emacs.d/lisp/org-task-dump/org-task-dump-logs.el new file mode 100644 index 0000000..5107704 --- /dev/null +++ b/home-manager/modules/emacs/.emacs.d/lisp/org-task-dump/org-task-dump-logs.el @@ -0,0 +1,52 @@ +;; +;; $Id: org-task-dump-logs.el,v 1a9aa8013f28 2016/04/18 10:20:04 pkgs $ +;; + + +(defun hmw/org-task-retrieve-logs(&optional date-formatter pom) + "Retrieve all state change notes for a given task and return +them as a list of 3-tuples. Each tuple consists of the old state, +the new state and the timestamp of the state change. The +timestamp is formatted by the optional function DATE-FORMATTER. + +The very first element of the returned list is not a 3-tuple, but a +string holding the heading of the processed task. + +Optionally the point can be set to POM programmatically." + (save-excursion + (unless date-formatter (setq date-formatter 'identity)) + (if pom (goto-char pom)) + (org-back-to-heading t) + (let* ((end (org-entry-end-position)) + (reversed org-log-states-order-reversed) + (search (if reversed 're-search-forward 're-search-backward)) + (limit (if reversed end (point))) + (re (format + "^[ \t]*-[ \t]+\\(?:State \"%s\"\s+from\s+\"%s\".*%s%s\\)" + org-todo-regexp + org-todo-regexp + org-ts-regexp-inactive + (let ((value (cdr (assq 'done org-log-note-headings)))) + (if (not value) "" + (concat "\\|" + (org-replace-escapes + (regexp-quote value) + `(("%d" . ,org-ts-regexp-inactive) + ("%D" . ,org-ts-regexp) + ("%s" . "\"\\S-+\"") + ("%S" . "\"\\S-+\"") + ("%t" . ,org-ts-regexp-inactive) + ("%T" . ,org-ts-regexp) + ("%u" . ".*?") + ("%U" . ".*?")))))))) + log-entries) + (unless reversed (goto-char end)) + (while (funcall search re limit t) + (push (list (org-match-string-no-properties 2) + (org-match-string-no-properties 1) + (funcall date-formatter (org-match-string-no-properties 3))) + log-entries)) + (push (org-no-properties (org-get-heading)) log-entries) + log-entries))) + +(provide 'org-task-dump-logs) diff --git a/home-manager/modules/emacs/.emacs.d/lisp/org-task-dump/org-task-generate-calendar-view.el b/home-manager/modules/emacs/.emacs.d/lisp/org-task-dump/org-task-generate-calendar-view.el new file mode 100644 index 0000000..8ea5e1e --- /dev/null +++ b/home-manager/modules/emacs/.emacs.d/lisp/org-task-dump/org-task-generate-calendar-view.el @@ -0,0 +1,103 @@ +;; +;; $Id: org-task-generate-calendar-view.el,v 08890e87177e 2016/04/18 10:24:19 pkgs $ +;; + + +(load "org-task-dump-logs.el") +(load "org-task-svg.el") + +(defun hmw/generate-calendar-view(file-name year heading statechanges) + "Generate a calendar view for the given YEAR and colours the dates +according to the given STATECHANGES. The view is annotated with a +HEADING and a legend. It is saved in FILE-NAME in SVG format. + +If the list contains several state changes for a given date, CANCELLED has precedence over DONE over OPEN." + (with-temp-buffer + (hmw/svg-header 650 170) + (hmw/svg-text 10 20 (format "Statistics for %s for %s" heading year)) + + ;; Month names + (let ((xpos 40) + (ypos 40)) + (dotimes (i 12) + (hmw/svg-text xpos ypos (elt calendar-month-abbrev-array i)) + (setq xpos (+ 40 (* (ceiling (/ (calendar-day-number (list (+ 2 i) 1 year)) 7.0)) 11))))) + + ;; Day names + (let ((xpos 10) + (ypos 60)) + (dotimes (i 7) + (hmw/svg-text xpos ypos (elt calendar-day-abbrev-array + (% (+ i calendar-week-start-day) 7))) + (setq ypos (+ ypos 11)))) + + ;; Boxes + (let ((xpos 40) + (ypos 50) + (colour) + (el) + (free (% (+ (calendar-day-of-week (list 1 1 year)) 6) 7))) + + (setq ypos (+ ypos (* free 11))) + (dotimes (i (calendar-day-number (list 12 31 year))) + (setq els (cl-remove-if-not (lambda (e) (equal (elt e 2) (1+ i))) statechanges)) + + (setq el + (car + (or + (cl-remove-if-not (lambda (e) (equal (elt e 1) "CANCELLED")) els) + (cl-remove-if-not (lambda (e) (equal (elt e 1) "DONE")) els) + (cl-remove-if-not (lambda (e) (equal (elt e 1) "OPEN")) els)))) + + (cond + ((equal el nil) + (hmw/svg-rect xpos ypos 10 10 "#646464")) + + ((equal (elt el 1) "OPEN") + (hmw/svg-rect xpos ypos 10 10 "#0000ff")) + + ((equal (elt el 1) "DONE") + (hmw/svg-rect xpos ypos 10 10 "#00ff00")) + + ((equal (elt el 1) "CANCELLED") + (hmw/svg-rect xpos ypos 10 10 "#ff0000"))) + + ;; Jump to the next column + (if (= (% (+ free 1 i) 7) 0) + (progn + (setq ypos 50) + (setq xpos (+ xpos 11))) + (setq ypos (+ ypos 11))))) + + ;; Legend + (hmw/svg-text 10 150 "OPEN") + (hmw/svg-rect 45 141 10 10 "#0000ff") + (hmw/svg-text 70 150 "DONE") + (hmw/svg-rect 105 141 10 10 "#00ff00") + (hmw/svg-text 130 150 "CANCELLED") + (hmw/svg-rect 195 141 10 10 "#ff0000") + + (hmw/svg-footer) + (write-file file-name))) + + +(defun hmw/date-formatter(d year) + "Converts a date D in ORG date format into the day number. As a side + effect all dates that are not in YEAR are filtered." + (let ((date (org-date-to-gregorian d))) + (if (equal (elt date 2) year) + (calendar-day-number date) + nil))) + + +(defun hmw/org-task-generate-calendar-view(svg-file-name year) + "Generate a calendar view of the state changes of a given task. The + calendar view is generated for YEAR and saved in SVG-FILE-NAME in + SVG format." + (interactive "FSave as SVG file: \nnGenerate view for year (YYYY): ") + (let ((log-entries (hmw/org-task-retrieve-logs + (lambda (d) (hmw/date-formatter d year))))) + (hmw/generate-calendar-view svg-file-name year + (car log-entries) (cdr log-entries)))) + +(provide 'org-task-generate-calendar-view) diff --git a/home-manager/modules/emacs/.emacs.d/lisp/org-task-dump/org-task-svg.el b/home-manager/modules/emacs/.emacs.d/lisp/org-task-dump/org-task-svg.el new file mode 100644 index 0000000..f26ead4 --- /dev/null +++ b/home-manager/modules/emacs/.emacs.d/lisp/org-task-dump/org-task-svg.el @@ -0,0 +1,42 @@ +;; +;; $Id: svg.el,v f0c325fe1142 2016/04/16 12:48:31 pkgs $ +;; + + +(defun hmw/svg-header (width height) + (insert (format " + + " width height))) + + +(defun hmw/svg-footer () + (insert "\n \n")) + + +(defun hmw/svg-text(x y str) + (insert (format " + + %s + " x y str))) + + +(defun hmw/svg-line(x1 y1 x2 y2) + (insert (format " + " x1 y1 x2 y2))) + + +(defun hmw/svg-rect(x y width height col) + (insert (format " + " x y height width col))) + +(provide 'org-task-svg) diff --git a/home-manager/modules/emacs/.emacs.d/lisp/ytplay.el b/home-manager/modules/emacs/.emacs.d/lisp/ytplay.el new file mode 100644 index 0000000..1360494 --- /dev/null +++ b/home-manager/modules/emacs/.emacs.d/lisp/ytplay.el @@ -0,0 +1,107 @@ +; SPDX-FileCopyrightText: 2022 Richard Brežák +; +; SPDX-License-Identifier: LGPL-3.0-or-later + +;; -*- lexical-binding: t -*- +;;; ytplay.el --- search for and play a YT video + +;;; Commentary: + +(require 'cl-lib) + +(defvar ytplay-youtube-dl-commmad "/nix/store/g0656rl1hplb6w35xs6nc79r6rdm8gzp-python3.8-youtube-dl-2020.12.22/bin/youtube-dl") + +(defvar ytplay-process nil) +(defvar ytplay-buffer (get-buffer-create " yt-play process buffer")) +(defvar ytplay-callback nil) +(defvar ytplay-fail-callback nil) + +(defvar ytplay-command-queue (list)) + +(defun ytplay--run-yt-dl (args callback fail-callback) + (if (or ytplay-callback ytplay-process ytplay-fail-callback) + (push (list args callback fail-callback) ytplay-command-queue) + (setq ytplay-callback callback) + (setq ytplay-fail-callback fail-callback) + (with-current-buffer ytplay-buffer (erase-buffer)) + (let ((command (append (list ytplay-youtube-dl-commmad) args))) + (setq ytplay-process + (make-process + :name "youtube-dl" + :command command + :buffer ytplay-buffer + :sentinel 'ytplay--sentinel))))) + +(defun ytplay--sentinel (process event) + (let ((result (string-trim (with-current-buffer ytplay-buffer (buffer-string)))) + (callback ytplay-callback) + (fail-callback ytplay-fail-callback) + (event (string-trim event))) + (with-current-buffer ytplay-buffer (erase-buffer)) + (setq ytplay-process nil) + (setq ytplay-callback nil) + (setq ytplay-fail-callback nil) + (if (string-equal event "finished") + (funcall callback result) + (funcall fail-callback))) + (when-let ((command (pop ytplay-command-queue))) + (ytplay--run-yt-dl (nth 0 command) (nth 1 command) (nth 2 command)))) + +(defun ytplay--run-yt-dl-seq (args-list callback) + (let ((acc (list)) + (target-count (length args-list)) + (completed 0)) + (cl-loop for args in args-list + do (ytplay--run-yt-dl + args + (lambda (results) + (setq completed (+ completed 1)) + (push results acc) + (when (eq target-count completed) (funcall callback acc))) + (lambda () + (setq completed (+ completed 1)) + (when (eq target-count completed) (funcall callback acc))))))) + +(defun ytplay--reset () + (interactive) + (setq ytplay-process nil) + (setq ytplay-buffer (get-buffer-create " yt-play process buffer")) + (setq ytplay-callback nil) + (setq ytplay-fail-callback nil) + (setq ytplay-command-queue (list))) + +;; (defun ytplay--ivy-builder (acc rest) +;; (if-let ((vid-id (pop rest))) +;; (ytplay--run-yt-dl +;; (list "--get-title" "--" vid-id) +;; (lambda (results vid-id acc rest) +;; (push `(,(string-trim results) . ,vid-id) acc) +;; (ytplay--ivy-builder acc rest))) +;; (let ((vid-id (completing-read "Select a result: " acc))) +;; ))) + +;; (results (split-string results)) + +(defun ytplay--ivy-callback (vid-ids) + (let* ((vid-ids (split-string vid-ids)) + (sequence (cl-loop for vid-id in vid-ids + collect (list "--get-title" "--" vid-id)))) + (ytplay--run-yt-dl-seq + sequence + (lambda (titles) + (let* ((videos (cl-pairlis titles vid-ids)) + (vid-id (completing-read "Select a result: " videos))) + (make-process + :name "xdg-open" + :command (list + "xdg-open" + (format + "https://www.youtube.com/watch?v=%s" + (cdr (assoc vid-id videos)))))))))) + +(defun ytplay-search (search-term) + (interactive "MSearch term: ") + (ytplay--run-yt-dl + (list (format "ytsearch10:%s" search-term) "--get-id") + 'ytplay--ivy-callback + (lambda () (message "ytplay.el failure!")))) diff --git a/home-manager/modules/emacs/.emacs.d/org/base.org b/home-manager/modules/emacs/.emacs.d/org/base.org new file mode 100644 index 0000000..b980a68 --- /dev/null +++ b/home-manager/modules/emacs/.emacs.d/org/base.org @@ -0,0 +1,414 @@ +# SPDX-FileCopyrightText: 2022 Richard Brežák +# +# SPDX-License-Identifier: LGPL-3.0-or-later + +#+STARTUP: content +#+TITLE: Magic_RB's Emacs configuration + +* Stuff That Needs Work +** TODO Spell checking +** TODO Calc mode +** TODO Org Agenda +*** Make it work on my phone +** TODO Org Roam +** TODO org-evil moving stuff, left, right with M-j M-; instead of M-h M-l +** Org Web Tools +https://github.com/alphapapa/org-web-tools +* Stuff + +#+NAME: base +#+BEGIN_SRC emacs-lisp + (use-package pdf-tools + :straight t + :hook (('TeX-mode-hook . visual-line-mode)) + :config + ;; initialise + (pdf-tools-install) + (setq TeX-PDF-mode 1) + ;; open pdfs scaled to fit page + (setq-default pdf-view-display-size 'fit-page) + ;; automatically annotate highlights + (setq pdf-annot-activate-created-annotations t)) +#+END_SRC + +Enable =all-the-icons=, it's used by =treemacs= and =doom-modeline=. + +#+BEGIN_SRC emacs-lisp + (use-package all-the-icons + :straight t) +#+END_SRC + +Set ispell program to hunspell, this is very much a TODO, since the spelling configuration is rather minimal at this +point in time. + +#+BEGIN_SRC emacs-lisp + (setq ispell-program-name "hunspell") +#+END_SRC + +Fetch the ~SSH_AUTH_PATH~ from ~.profile~. + +#+BEGIN_SRC emacs-lisp + (setenv "SSH_AUTH_SOCK" (shell-command-to-string ". ~/.profile && printf $SSH_AUTH_SOCK")) +#+END_SRC + +* Language +** Nix Expression Language + +Enable ~nix-mode~. + +#+begin_src emacs-lisp + (use-package lsp-nix + :no-require t + :after (lsp-mode) + :custom + (lsp-nix-nil-formatter ["nixpkgs-fmt"])) + + (use-package nix-mode + :hook (nix-mode . lsp-deferred) + :ensure t) +#+end_src + +** HashiCorp +*** HashiCorp Configuration Language + +#+BEGIN_SRC emacs-lisp + (use-package hcl-mode + :straight t) +#+END_SRC + +*** Terraform Configuration Language + +#+BEGIN_SRC emacs-lisp + (use-package terraform-mode + :straight t) +#+END_SRC + +** YAML Configuration Language + +Enable ~yaml-mode~. + +#+BEGIN_SRC emacs-lisp + (use-package yaml-mode + :straight t + :mode ("\\.yml\\'" . yaml-mode) + :mode ("\\.yaml\\'" . yaml-mode)) +#+END_SRC + +** Dockerfile Configuration Language + +Enable ~dockerfile-mode~ + +#+BEGIN_SRC emacs-lisp + (use-package dockerfile-mode + :straight t + :mode ("Dockerfile\\'" . dockerfile-mode)) +#+END_SRC + +** SCAD Programming Language + +Enable ~scad-mode~ + +#+BEGIN_SRC emacs-lisp + (use-package scad-mode + :straight t) +#+END_SRC + +** Rust Programming Language + +Enable ~rustic~ and more feature-full alternative to ~rust-mode~, actually a rather distant fork of it. +Also hook ~lsp-mode~ on it. + +#+NAME: rust +#+BEGIN_SRC emacs-lisp + (use-package rustic + :straight t + :hook (rustic-mode . lsp-mode) + :mode ("\\.rs\\'" . rustic-mode)) +#+END_SRC +* LSP +** envrc + +Enable ~envrc~, which changes ENVs on a per buffer basis. + +#+BEGIN_SRC emacs-lisp + (use-package envrc + :straight t + :init + (envrc-global-mode)) +#+END_SRC + +** lsp-mode + +Increase GC threshold to avoid random freezes on garbage collection. + +#+NAME: gc-cons-threshold +#+BEGIN_SRC emacs-lisp :tangle no + (setq gc-cons-threshold 100000000) +#+END_SRC + +Increase the amount of data Emacs reads from a process in one go, default is 4KB, but some LSP servers produce responses up to 3MB. + +#+NAME: read-process-output-max +#+BEGIN_SRC emacs-lisp :tangle no + (setq read-process-output-max (* (* 1024 1024) 3)) +#+END_SRC + +Switch completion provider to =capf=, even though it should be the default, but just to make sure it. =company-lsp= +is what =lsp-mode= switched away from. + +#+NAME: lsp-completion-provider +#+BEGIN_SRC emacs-lisp :tangle no + (setq lsp-completion-provider :capf) +#+END_SRC + +Set the minimum delay between LSP refreshes, should help with performance when typing really fast. + +#+NAME: lsp-idle-delay +#+BEGIN_SRC emacs-lisp :tangle no + (setq lsp-idle-delay 0.500) ;; adjust me +#+END_SRC + +Setup rustic to prefer ~rust-analyzer~ instead of ~rls~ and also don't format on save, it's really annoying. + +#+NAME: lsp-rustic +#+BEGIN_SRC emacs-lisp :tangle no + (setq rustic-lsp-server 'rust-analyzer) + (setq rustic-compile-command "cargo build") + (setq rustic-format-trigger nil);'on-save +#+END_SRC + +Enable inline type hints and disable chaining and parameter hints for Rust. + +#+NAME: lsp-rust-analyzer +#+BEGIN_SRC emacs-lisp :tangle no + (setq lsp-rust-analyzer-display-chaining-hints nil) + (setq lsp-rust-analyzer-display-parameter-hints nil) + (setq lsp-rust-analyzer-server-display-inlay-hints t) +#+END_SRC + +Finally enable ~lsp-mode~. + +#+BEGIN_SRC emacs-lisp :noweb yes + (use-package lsp-mode + :straight t + :after (envrc) + :config + (setq lsp-prefer-flymake nil) + (setq lsp-ui-doc-enable nil) + :config + <> + ;; <> + + <> + <> + <> + ;; <> + <> + <>) +#+END_SRC + +** lsp-pyright + +Enable ~lsp-pyright~, the best Python language server, all of them are a bit lackluster, this one is the best +option. + +#+BEGIN_SRC emacs-lisp + (use-package lsp-pyright + :straight t + :hook (python-mode . lsp)) +#+END_SRC + +** lsp-ui + +Enable ~lsp-ui~, it adds doc frames, code actions at the side and other cool things, some of them are annoying and +need disabling. + +#+BEGIN_SRC emacs-lisp + (use-package lsp-ui + :straight t + :after (company-box) + :config + ;; disable focus on mouse over + (push '(no-accept-focus . t) lsp-ui-doc-frame-parameters) + (push '(no-accept-focus . t) company-box-frame-parameters) + + (add-to-list 'lsp-ui-doc-frame-parameters '(no-accept-focus . t)) + (add-to-list 'company-box-frame-parameters '(no-accept-focus . t)) + (setq mouse-autoselect-window nil)) +#+END_SRC + +** flycheck + +Enable ~flycheck~ for in-buffer hints and errors and warning and things. + +#+BEGIN_SRC emacs-lisp + (use-package flycheck + :straight t + :init (global-flycheck-mode)) +#+END_SRC + +** origami + +Enable ~origami~. It allows one to fold and unfold a section with =zc= and =zo= in ~evil-mode~. Hook it on both ~conf-mode~ and ~prog-mode~; + +#+BEGIN_SRC emacs-lisp + (use-package origami + :straight t + :hook ((prog-mode . origami-mode) + (conf-mode . origami-mode))) +#+END_SRC + +Enable ~origami-lsp~. Some LSP servers specify these folding ranges and this package makes ~origami~ understand that +and work with it. + +#+BEGIN_SRC emacs-lisp + (use-package lsp-origami + :straight t + :hook (lsp-after-open-hook lsp-origami-try-enable)) +#+END_SRC + +* hledger + +For hledger, it's possible to use =ledger-mode= instead of =hledger-mode=. We'll see how it goes. It does require some convincing though. + +#+BEGIN_SRC emacs-lisp + (use-package ledger-mode + :straight t + :config + (setq ledger-binary-path "hledger") + (setq ledger-mode-should-check-version nil) + (add-to-list 'auto-mode-alist '("\\.\\(h?ledger\\|journal\\|j\\)$" . ledger-mode)) + (setq ledger-report-balance + (list "bal" (concat ledger-binary-path " --strict -f %(ledger-file) bal"))) + + (setq ledger-report-reg + (list "reg" (concat ledger-binary-path " --strict -f %(ledger-file) reg"))) + + (setq ledger-report-payee + (list "payee" (concat ledger-binary-path " --strict -f %(ledger-file) reg @%(payee)"))) + + (setq ledger-report-account + (list "account" (concat ledger-binary-path " --strict -f %(ledger-file) reg %(account)"))) + + (setq ledger-reports + (list ledger-report-balance + ledger-report-reg + ledger-report-payee + ledger-report-account))) +#+END_SRC + +* Projectile + +Enable ~projectile~. + +#+BEGIN_SRC emacs-lisp + (use-package projectile + :straight t + :config + (projectile-mode +1) + (define-key projectile-mode-map (kbd "C-c p") 'projectile-command-map)) +#+END_SRC + +* Random Bits and Bobs + +Set keystrokes echo to something really low, it's useful to know what you're typing. + +#+BEGIN_SRC emacs-lisp + (setq echo-keystrokes 0.01) +#+END_SRC + +Set default major mode to org mode, it's much more useful than fundamental. + +#+BEGIN_SRC emacs-lisp + (setq-default major-mode 'org-mode) +#+END_SRC + +Delete files by moving to trash. + +#+BEGIN_SRC emacs-lisp + (setq-default delete-by-moving-to-trash t) +#+END_SRC + +Equalize windows after split. + +#+BEGIN_SRC emacs-lisp + (setq-default window-combination-resize t) +#+END_SRC + +Increase undo limit to 80MB and enable fine undo, Evil will no longer chunk all edits in =INSERT= mode into one big +undo blob. + +#+BEGIN_SRC emacs-lisp + (setq undo-limit 80000000 + evil-want-fine-undo t) +#+END_SRC + +For now, don't autosave. Because editing on remote disks, not TRAMP, but just NFS or CIFS, becomes extremely painful. + +#+BEGIN_SRC emacs-lisp :tangle no + (setq auto-save-default t) +#+END_SRC + +Enable line numbers for both programming buffers (Rust, C, and such) and configuration buffers (Nix, Yaml, Json, and +such) and Org mode. + +#+BEGIN_SRC emacs-lisp + (add-hook 'conf-mode-hook 'display-line-numbers-mode) + (add-hook 'prog-mode-hook 'display-line-numbers-mode) +#+END_SRC + +Improve scrolling by: +1. disabling acceleration +2. making it so that the window under the pointer is scroller no matter the focused window +3. changing default scroll amount to 5 lines and 1 when shift is pressed + + #+BEGIN_SRC emacs-lisp + (setq mouse-wheel-scroll-amount '(5 ((shift) . 1))) + (setq mouse-wheel-progressive-speed nil) + (setq mouse-wheel-follow-mouse 't) + #+END_SRC + + Enable perentheses highlighting and pairing. + + #+BEGIN_SRC emacs-lisp + (show-paren-mode 1) + (electric-pair-mode) + #+END_SRC + + Set fill colum, horizontal indicator, for both =fill-paragraph=(=M-q=) and the visual horizontal indicator. + + #+BEGIN_SRC emacs-lisp + (setq-default display-fill-column-indicator-column 120 + fill-column 120) + #+END_SRC + + Start Emacs server, unless it's already running. Starting a new Emacs instance while debugging and getting an error + about a server already running can be a bit annoying. + + #+BEGIN_SRC emacs-lisp + (load "server") + (unless (server-running-p) (server-start)) + #+END_SRC + + #+BEGIN_SRC emacs-lisp + (setq backup-directory-alist + `(("." . ,(concat user-emacs-directory "backups")))) + #+END_SRC + +** Windows + +As [[https://github.com/tecosaur/][tecosaur]] has it in his [[https://tecosaur.github.io/emacs-config/config.html#windows][configuration]], I was to be asked which window to should be brought up when I split a +window in Emacs. So create a new advice which will run after evil split commands and brings up the buffer selector. + +#+BEGIN_SRC emacs-lisp + (defadvice evil-window-vsplit (after activate compile) + (counsel-switch-buffer)) + (defadvice evil-window-split (after activate compile) + (counsel-switch-buffer)) +#+END_SRC + +** PGTK neo2 fix +#+BEGIN_SRC emacs-lisp + (put 'none 'modifier-value 0) + (setq x-hyper-keysym 'none) +#+END_SRC diff --git a/home-manager/modules/emacs/default.nix b/home-manager/modules/emacs/default.nix new file mode 100644 index 0000000..585e4bb --- /dev/null +++ b/home-manager/modules/emacs/default.nix @@ -0,0 +1,75 @@ +{ pkgs, config, lib, secret, inputs', ... }: +{ + home.packages = with pkgs; [ + (makeDesktopItem { + name = "Org-Protocol"; + exec = "emacsclient %u"; + comment = "Org protocol"; + desktopName = "org-protocol"; + type = "Application"; + mimeTypes = ["x-scheme-handler/org-protocol"]; + }) + (iosevka-bin.override {variant = "aile";}) + (iosevka-bin.override {variant = "etoile";}) + (iosevka-bin.override {variant = "";}) + emacs-all-the-icons-fonts + + emacs-master-nativecomp + ]; + + systemd.user.services.emacs = { + Unit = { + Description = "Emacs, the extensible editor"; + After = [ "graphical-session-pre.target" ]; + PartOf = [ "graphical-session.target" ]; + }; + + Service = { + Type = "simple"; + ExecStart = ''/bin/sh -l -c "emacs --fg-daemon"''; + }; + + Install = { WantedBy = [ "graphical-session.target" ]; }; + }; + + home.file = { + ".emacs".source = ./.emacs; + ".mbsyncrc".source = secret.emacs.mbsyncrc or ./.; + ".emacs.d/org" = { + source = ./.emacs.d/org; + recursive = true; + }; + ".emacs.d/lisp" = { + source = ./.emacs.d/lisp; + recursive = true; + }; + ".emacs.d/mu4e-contexts".source = secret.emacs.mu4eContexts or ./.; + ".emacs.d/tree-sitter".source = pkgs.tree-sitter-grammars; + ".emacs.d/vterm-module".source = pkgs.stdenv.mkDerivation { + name = "vterm-emacs"; + src = inputs'.vtermModule; + buildInputs = with pkgs; [cmake libtool glib.dev libvterm-neovim]; + cmakeFlags = [ + "-DEMACS_SOURCE=${inputs'.emacs}" + "-DUSE_SYSTEM_LIBVTERM=ON" + ]; + installPhase = '' + mkdir -p $out/lib + install ../vterm-module.so $out/lib + ''; + }; + ".emacs.d/profile".source = pkgs.buildEnv { + name = "emacs-env"; + paths = with pkgs; [ + cmake + ninja + gnumake + gcc + mu + ripgrep + fd + isync + ]; + }; + }; +} diff --git a/home-manager/modules/emacs/straight-versions.el b/home-manager/modules/emacs/straight-versions.el new file mode 100644 index 0000000..71b07d5 --- /dev/null +++ b/home-manager/modules/emacs/straight-versions.el @@ -0,0 +1,104 @@ +(("ace-window" . "77115afc1b0b9f633084cf7479c767988106c196") + ("alert" . "c762380ff71c429faf47552a83605b2578656380") + ("all-the-icons.el" . "f75c1130b72c718bfaf18b56c445c4b58efc714f") + ("avy" . "be612110cb116a38b8603df367942e2bb3d9bdbe") + ("cape" . "db3059af52718c7f55485ef183bdad3e40f58df9") + ("cfrs" . "f3a21f237b2a54e6b9f8a420a9da42b4f0a63121") + ("clang-format" . "e48ff8ae18dc7ab6118c1f6752deb48cb1fc83ac") + ("compat" . "b3b18044f9ca99a53ade91794226d71968b3e14f") + ("consult" . "aadb912e126a143c60e6ece92b163a7356bd4730") + ("corfu" . "2e066448df9cc8b16e75f3bc22e6fb5a8d1c065d") + ("dash.el" . "96eaba028ac069ea0e5cc70de15b0229126a054a") + ("dirvish" . "4b63cd2e5ba994f8e674388db7035de1a8f0343f") + ("dockerfile-mode" . "52c6c00da1d31c0b6c29c74335b3af63ed6bf06c") + ("doom-modeline" . "3612082bc5cba712c07860ce37865f938beb9002") + ("el-get" . "22c83206bab10100fdee03cb2d5b97c8c24eff0e") + ("el-secretario" . "93f9b1bd2e381354a6ae799fed3e4a8313f24e11") + ("elisp" . "3497ffd763cadcc1f507aae88c3c7a84007ccfbd") + ("emacs-elixir" . "7641373f0563cab67cc5459c34534a8176b5e676") + ("emacs-hcl-mode" . "751b79247f326ab52e00032e805775c37ad9f080") + ("emacs-libvterm" . "94e2b0b2b4a750e7907dacd5b4c0584900846dd1") + ("emacs-which-key" . "bd34ede7bf77ad3988330b37207f3978e7342c79") + ("emacsmirror-mirror" . "606c3dcfc57ee47a9969b4d9f3d87408f14ebffb") + ("emacsql" . "64012261f65fcdd7ea137d1973ef051af1dced42") + ("embark" . "10ac6b7260c82e3a59a33ea93e7027692b228e5f") + ("ement.el" . "5be1e0700288fea0762b4fc9311e0b05d6c78cc0") + ("envrc" . "15af96080772af415a56b680acdd7d2010a68ffa") + ("epl" . "78ab7a85c08222cd15582a298a364774e3282ce6") + ("f.el" . "af7d37c619010b576fd22b50c62c71ff33093f3c") + ("flycheck" . "5f2ef177cb21ae8b73714575802beef04abd0f5e") + ("flycheck-posframe" . "19896b922c76a0f460bf3fe8d8ebc2f9ac9028d8") + ("general.el" . "7ce8db297e3de258ec43802269438ac7f1918707") + ("gntp.el" . "767571135e2c0985944017dc59b0be79af222ef5") + ("gnu-elpa-mirror" . "eda4c968f0400750e17a013bb80832088dab12d1") + ("go-mode.el" . "166dfb1e090233c4609a50c2ec9f57f113c1da72") + ("haskell-mode" . "20d4e2300302a9af673e82d0185d3f489bfb0f59") + ("hercules" . "557da39878d0637395fdded91243b340c37eff7b") + ("ht.el" . "3c1677f1bf2ded2ab07edffb7d17def5d2b5b6f6") + ("hydra" . "317e1de33086637579a7aeb60f77ed0405bf359b") + ("inheritenv" . "2102ed2d105a5c9f366cb6503d04794600985598") + ("js2-mode" . "7d928272bc311b1dd6f38d3f6365c18153e28636") + ("ledger-mode" . "7bed9b468bf7d2cd4dafa30b067bb576263f8e0c") + ("let-alist" . "021fc10df2e44faba4728d849ee767cf890aa51a") + ("log4e" . "737d275eac28dbdfb0b26d28e99da148bfce9d16") + ("lsp-haskell" . "3249cde75fb411f95fe173c222b848182fd0b752") + ("lsp-mode" . "cf30718ed5128753565452f476385dac1f7821d6") + ("lsp-origami" . "7df9c91a309aa4229bec41f109920b37c4197618") + ("lsp-pyright" . "54a2acddfdd7c3d31cb804a042305a3c6e60cf81") + ("lsp-python-ms" . "f8e7c4bcaefbc3fd96e1ca53d17589be0403b828") + ("lsp-ui" . "295d8984da06a745b0a36c56e28ce915bc389adb") + ("magit" . "6067f92c0195616707b25e23c2d4c0dd81928fd8") + ("map" . "a0e501aede34f183a8baa5d3d41610a3ffa1728e") + ("marginalia" . "3ddd2b7fa09e1e84112749ffbdcb6bd8900bfc26") + ("markdown-mode" . "5d98592fe516748034d8baf92d7c0ba045e1f87a") + ("melpa" . "86ca8d06599c8d7d9067ce92ae5dde3b122f6796") + ("meow" . "07ccf112fc1a56ddd96cfc39967957be7dc8dd5f") + ("mu4e-alert" . "3c9af8c7994df0a1a4f0703552ea3beffb485ace") + ("nongnu-elpa" . "0120f3dfe80cffe0c3016080d9205d12be3b741d") + ("openscad" . "31670fc8bbde97f47f050f1837de093ecee89e1e") + ("orderless" . "e6784026717a8a6a7dcd0bf31fd3414f148c542e") + ("org" . "080710797ad25e76c4556d2b03cc0aa5313cd187") + ("org-ql" . "2c098540cab6a0ee7d82abe2327d524a171edd1e") + ("org-roam" . "5c06471c3a11348342719fd9011486455adeb701") + ("org-super-agenda" . "f4f528985397c833c870967884b013cf91a1da4a") + ("origami.el" . "e558710a975e8511b9386edc81cd6bdd0a5bda74") + ("ov" . "c5b9aa4e1b00d702eb2caedd61c69a22a5fa1fab") + ("password-store" . "28cec11f1dbe6c4273d30370af45b69c9f408386") + ("pdf-tools" . "7ff6293a25baaae65651b3e1c54b61208279a7ef") + ("peg" . "5d4ed356ca89acdf52a3e7e7f8e2408b808552c4") + ("persist" . "c10835478d9f916534a07fad0174d497adf85729") + ("pfuture" . "19b53aebbc0f2da31de6326c495038901bffb73c") + ("pkg-info" . "76ba7415480687d05a4353b27fea2ae02b8d9d61") + ("plz" . "205e8284340ff10bc7a8468f8af0c50eb0e97c60") + ("popper" . "e3991202234e4dc10dbfae8e13b27c590dd52fb5") + ("posframe" . "3b97dc180b03498103cfcc7f44e64150df440bf0") + ("project" . "33511939473551b5cfa42de9a12d606b3d60a2cf") + ("projectile" . "271007c6611fcb08ddd326d7de9727c2ad5ef265") + ("racket-mode" . "c2fe266c18bb6e55a13c7ba795b0a5f7372b6c13") + ("rjsx-mode" . "b697fe4d92cc84fa99a7bcb476f815935ea0d919") + ("rust-mode" . "e443ccf2884028d3b6cc550ff20e7c92dadccb68") + ("rustic" . "39423d1cf4fa054c36bf9577356451f4c06ee148") + ("s.el" . "dda84d38fffdaf0c9b12837b504b402af910d01d") + ("shackle" . "f1467db75a8fa5d51c676181fb308ccbf7b05e6f") + ("shrink-path.el" . "c14882c8599aec79a6e8ef2d06454254bb3e1e41") + ("spinner" . "634529bb3173e09b37499f636de70abf29d9fa8a") + ("straight.el" . "039e5c9a9b5c00749602afb41341e9e77ba09429") + ("svg-lib" . "31085bbf247f0467e2f6af948085610248fce6c5") + ("tablist" . "faab7a035ef2258cc4ea2182f67e3aedab7e2af9") + ("taxy" . "b222226f9e1057490150c1a8a98e8b471df88302") + ("taxy-magit-section" . "00e1e41341cbc71fcc8f4d4c98b2cc5c371c4f54") + ("tempel" . "94afb9b916a711c56f23183da93a103338e9f84e") + ("terraform-mode" . "56f19abae95afb7e13e48ec3e6aeba3820d31307") + ("transient" . "af7fe42bd46e24ca7852e73bd1691015c5bd2151") + ("treemacs" . "983ea5a66801a5c1f6e32e3d515bd48761677ac6") + ("ts.el" . "552936017cfdec89f7fc20c254ae6b37c3f22c5b") + ("typescript.el" . "4fcb4594819caf472ae42ea068a1c7795cf07f46") + ("use-package" . "a6e856418d2ebd053b34e0ab2fda328abeba731c") + ("vertico" . "dd8eb3aa3d0d048cc0e1bc455f42a12a4162f5bb") + ("vulpea" . "f4d3448b6ccdb314c5fe3defea66e750e1371a10") + ("web-mode" . "57856ba64b9382811b35df0d9ab0a24aede0c1f0") + ("with-editor" . "df74385b455cd7687232ad189acfea16cb44dd04") + ("xref" . "420511e20187d0c6c8680c0e63ae8810f84dee00") + ("xterm-color" . "2ad407c651e90fff2ea85d17bf074cee2c022912") + ("yaml-mode" . "b153150e0e77b4ec462d741cdb16956c6ae270d6")) +:gamma diff --git a/home-manager/modules/keynav/default.nix b/home-manager/modules/keynav/default.nix new file mode 100644 index 0000000..fab3fc5 --- /dev/null +++ b/home-manager/modules/keynav/default.nix @@ -0,0 +1,20 @@ +{ pkgs, ... }: +{ + home.file.".keynavrc".source = ./keynavrc; + + systemd.user.services.keynav = { + Unit = { + Description = "keynav"; + After = [ "graphical-session-pre.target" ]; + PartOf = [ "graphical-session.target" ]; + }; + + Service = { + ExecStart = "${pkgs.keynav}/bin/keynav"; + RestartSec = 3; + Restart = "always"; + }; + + Install = { WantedBy = [ "graphical-session.target" ]; }; + }; +} diff --git a/home-manager/modules/keynav/keynavrc b/home-manager/modules/keynav/keynavrc new file mode 100644 index 0000000..501525f --- /dev/null +++ b/home-manager/modules/keynav/keynavrc @@ -0,0 +1,32 @@ +# -*- mode: text -*- + +# SPDX-FileCopyrightText: 2022 Richard Brežák +# +# SPDX-License-Identifier: LGPL-3.0-or-later + +clear +ctrl+s start, grid 3x3 +Escape end +u end + +g warp, click 1, end +c warp, click 3, end +d warp, click 4 +b warp, click 5 +l warp, end + + +t move-left +r move-up +n move-down +s move-right + +period cell-select 1x1 +o cell-select 2x1 +comma cell-select 3x1 +a cell-select 1x2 +e cell-select 2x2 +i cell-select 3x2 +q cell-select 1x3 +adiaeresis cell-select 2x3 +udiaeresis cell-select 3x3 diff --git a/home-manager/modules/lightlocker/default.nix b/home-manager/modules/lightlocker/default.nix new file mode 100644 index 0000000..cdcd17f --- /dev/null +++ b/home-manager/modules/lightlocker/default.nix @@ -0,0 +1,17 @@ +{ pkgs, lib, ... }: +{ + systemd.user.services.light-locker = { + Unit = { + Description = "LightLocker screen locker"; + After = [ "graphical-session-pre.target" ]; + PartOf = [ "graphical-session.target" ]; + }; + + Service = { + Type = "simple"; + ExecStart = ''/bin/sh -l -c "${lib.getExe pkgs.lightlocker} --lock-on-suspend"''; + }; + + Install = { WantedBy = [ "graphical-session.target" ]; }; + }; +} diff --git a/home-manager/modules/pantalaimon.nix b/home-manager/modules/pantalaimon.nix new file mode 100644 index 0000000..13ee3d2 --- /dev/null +++ b/home-manager/modules/pantalaimon.nix @@ -0,0 +1,23 @@ +{ ... }: +{ + services.pantalaimon = { + enable = true; + settings = + { + Default = + { + LogLevel = "Info"; + SSL = true; + }; + local-matrix = + { + Homeserver = "https://matrix.redalder.org"; + ListenAddress = "127.0.0.1"; + ListenPort = 8008; + UseKeyring = false; + IgnoreVerification = true; + SSL = false; + }; + }; + }; +} diff --git a/home-manager/modules/picom/default.nix b/home-manager/modules/picom/default.nix new file mode 100644 index 0000000..705604b --- /dev/null +++ b/home-manager/modules/picom/default.nix @@ -0,0 +1,18 @@ +{ pkgs, lib, ... }: +{ + home.file.".config/picom.conf".source = ./picom.conf; + systemd.user.services.picom = { + Unit = { + Description = "Picom compositor"; + After = [ "graphical-session-pre.target" ]; + PartOf = [ "graphical-session.target" ]; + }; + + Service = { + Type = "simple"; + ExecStart = ''/bin/sh -l -c "${lib.getExe pkgs.picom} --config ~/.config/picom.conf"''; + }; + + Install = { WantedBy = [ "graphical-session.target" ]; }; + }; +} diff --git a/home-manager/modules/picom/picom.conf b/home-manager/modules/picom/picom.conf new file mode 100644 index 0000000..b783144 --- /dev/null +++ b/home-manager/modules/picom/picom.conf @@ -0,0 +1,238 @@ +# SPDX-FileCopyrightText: 2022 Richard Brežák +# +# SPDX-License-Identifier: LGPL-3.0-or-later + +# Thank you code_nomad: http://9m.no/ꪯ鵞 +# and Arch Wiki contributors: https://wiki.archlinux.org/index.php/Compton + +################################# +# +# Backend +# +################################# + +# Backend to use: "xrender" or "glx". +# GLX backend is typically much faster but depends on a sane driver. +backend = "glx"; + +################################# +# +# GLX backend +# +################################# + +glx-no-stencil = true; + +# GLX backend: Copy unmodified regions from front buffer instead of redrawing them all. +# My tests with nvidia-drivers show a 10% decrease in performance when the whole screen is modified, +# but a 20% increase when only 1/4 is. +# My tests on nouveau show terrible slowdown. +glx-copy-from-front = false; + +# GLX backend: Use MESA_copy_sub_buffer to do partial screen update. +# My tests on nouveau shows a 200% performance boost when only 1/4 of the screen is updated. +# May break VSync and is not available on some drivers. +# Overrides --glx-copy-from-front. +# glx-use-copysubbuffermesa = true; + +# GLX backend: Avoid rebinding pixmap on window damage. +# Probably could improve performance on rapid window content changes, but is known to break things on some drivers (LLVMpipe). +# Recommended if it works. +# glx-no-rebind-pixmap = true; + +# GLX backend: GLX buffer swap method we assume. +# Could be undefined (0), copy (1), exchange (2), 3-6, or buffer-age (-1). +# undefined is the slowest and the safest, and the default value. +# copy is fastest, but may fail on some drivers, +# 2-6 are gradually slower but safer (6 is still faster than 0). +# Usually, double buffer means 2, triple buffer means 3. +# buffer-age means auto-detect using GLX_EXT_buffer_age, supported by some drivers. +# Useless with --glx-use-copysubbuffermesa. +# Partially breaks --resize-damage. +# Defaults to undefined. +#glx-swap-method = "undefined"; + +################################# +# +# Shadows +# +################################# + +# Enabled client-side shadows on windows. +shadow = true; +# The blur radius for shadows. (default 12) +shadow-radius = 5; +# The left offset for shadows. (default -15) +shadow-offset-x = -5; +# The top offset for shadows. (default -15) +shadow-offset-y = -5; +# The translucency for shadows. (default .75) +shadow-opacity = 0.5; + +# Set if you want different colour shadows +# shadow-red = 0.0; +# shadow-green = 0.0; +# shadow-blue = 0.0; + +# The shadow exclude options are helpful if you have shadows enabled. Due to the way picom draws its shadows, certain applications will have visual glitches +# (most applications are fine, only apps that do weird things with xshapes or argb are affected). +# This list includes all the affected apps I found in my testing. The "! name~=''" part excludes shadows on any "Unknown" windows, this prevents a visual glitch with the XFWM alt tab switcher. +shadow-exclude = [ + "! name~=''", + "name = 'Notification'", + "name = 'Plank'", + "name = 'Docky'", + "name = 'Kupfer'", + "name = 'xfce4-notifyd'", + "name *= 'VLC'", + "name *= 'compton'", + "name *= 'picom'", + "name *= 'Chromium'", + "name *= 'Chrome'", + "class_g = 'Firefox' && argb", + "class_g = 'Conky'", + "class_g = 'Kupfer'", + "class_g = 'Synapse'", + "class_g ?= 'Notify-osd'", + "class_g ?= 'Cairo-dock'", + "class_g ?= 'Xfce4-notifyd'", + "class_g ?= 'Xfce4-power-manager'", + "_GTK_FRAME_EXTENTS@:c", + "_NET_WM_STATE@:32a *= '_NET_WM_STATE_HIDDEN'" +]; +# Avoid drawing shadow on all shaped windows (see also: --detect-rounded-corners) +shadow-ignore-shaped = false; + +################################# +# +# Opacity +# +################################# + +inactive-opacity = 1; +active-opacity = 1; +frame-opacity = 1; +inactive-opacity-override = false; + +# Dim inactive windows. (0.0 - 1.0) +# inactive-dim = 0.2; +# Do not let dimness adjust based on window opacity. +# inactive-dim-fixed = true; +# Blur background of transparent windows. Bad performance with X Render backend. GLX backend is preferred. +blur-background = true; +# Blur background of opaque windows with transparent frames as well. +# blur-background-frame = true; +# Do not let blur radius adjust based on window opacity. +blur-background-fixed = false; +blur-background-exclude = [ + "window_type = 'dock'", + "window_type = 'desktop'" +]; + +blur: +{ + method = "kernel"; + size = 50; + deviation = 5.0; +}; + +################################# +# +# Fading +# +################################# + +# Fade windows during opacity changes. +fading = false; +# The time between steps in a fade in milliseconds. (default 10). +fade-delta = 4; +# Opacity change between steps while fading in. (default 0.028). +fade-in-step = 0.03; +# Opacity change between steps while fading out. (default 0.03). +fade-out-step = 0.03; +# Fade windows in/out when opening/closing +# no-fading-openclose = true; + +# Specify a list of conditions of windows that should not be faded. +fade-exclude = [ ]; + +################################# +# +# Other +# +################################# + +# Try to detect WM windows and mark them as active. +mark-wmwin-focused = true; +# Mark all non-WM but override-redirect windows active (e.g. menus). +mark-ovredir-focused = true; +# Use EWMH _NET_WM_ACTIVE_WINDOW to determine which window is focused instead of using FocusIn/Out events. +# Usually more reliable but depends on a EWMH-compliant WM. +use-ewmh-active-win = true; +# Detect rounded corners and treat them as rectangular when --shadow-ignore-shaped is on. +detect-rounded-corners = true; + +# Detect _NET_WM_OPACITY on client windows, useful for window managers not passing _NET_WM_OPACITY of client windows to frame windows. +# This prevents opacity being ignored for some apps. +# For example without this enabled my xfce4-notifyd is 100% opacity no matter what. +detect-client-opacity = true; + +# Specify refresh rate of the screen. +# If not specified or 0, picom will try detecting this with X RandR extension. +refresh-rate = 0; + +# Vertical synchronization: match the refresh rate of the monitor +vsync = true; + +# Enable DBE painting mode, intended to use with VSync to (hopefully) eliminate tearing. +# Reported to have no effect, though. +dbe = false; + +# Limit picom to repaint at most once every 1 / refresh_rate second to boost performance. +# This should not be used with --vsync drm/opengl/opengl-oml as they essentially does --sw-opti's job already, +# unless you wish to specify a lower refresh rate than the actual value. +#sw-opti = true; + +# Unredirect all windows if a full-screen opaque window is detected, to maximize performance for full-screen windows, like games. +# Known to cause flickering when redirecting/unredirecting windows. +unredir-if-possible = false; + +# Specify a list of conditions of windows that should always be considered focused. +focus-exclude = [ ]; + +# Use WM_TRANSIENT_FOR to group windows, and consider windows in the same group focused at the same time. +detect-transient = true; +# Use WM_CLIENT_LEADER to group windows, and consider windows in the same group focused at the same time. +# WM_TRANSIENT_FOR has higher priority if --detect-transient is enabled, too. +detect-client-leader = true; + +################################# +# +# Window type settings +# +################################# + +wintypes: +{ + tooltip = + { + # fade: Fade the particular type of windows. + fade = true; + # shadow: Give those windows shadow + shadow = false; + # opacity: Default opacity for the type of windows. + opacity = 0.85; + # focus: Whether to always consider windows of this type focused. + focus = true; + }; +}; + +###################### +# +# XSync +# See: https://github.com/yshui/picom/commit/b18d46bcbdc35a3b5620d817dd46fbc76485c20d +# +###################### + +# Use X Sync fence to sync clients' draw calls. Needed on nvidia-drivers with GLX backend for some users. +xrender-sync-fence = true; diff --git a/home-manager/modules/profiles/alacritty.yaml b/home-manager/modules/profiles/alacritty.yaml new file mode 100644 index 0000000..a3bdf9c --- /dev/null +++ b/home-manager/modules/profiles/alacritty.yaml @@ -0,0 +1,537 @@ +# SPDX-FileCopyrightText: 2022 Richard Brežák +# +# SPDX-License-Identifier: LGPL-3.0-or-later + +# Configuration for Alacritty, the GPU enhanced terminal emulator. + +# Any items in the `env` entry below will be added as +# environment variables. Some entries may override variables +# set by alacritty itself. +env: + # TERM variable + # + # This value is used to set the `$TERM` environment variable for + # each instance of Alacritty. If it is not present, alacritty will + # check the local terminfo database and use `alacritty` if it is + # available, otherwise `xterm-256color` is used. + # TERM: rxvt-unicode-256color + TERM: xterm-256color + +#window: + # Window dimensions (changes require restart) + # + # Specified in number of columns/lines, not pixels. + # If both are `0`, this setting is ignored. + #dimensions: + # columns: 0 + # lines: 0 + + # Window position (changes require restart) + # + # Specified in number of pixels. + # If the position is not set, the window manager will handle the placement. + #position: + # x: 0 + # y: 0 + + # Window padding (changes require restart) + # + # Blank space added around the window in pixels. This padding is scaled + # by DPI and the specified value is always added at both opposing sides. + #padding: + # x: 0 + # y: 0 + + # Spread additional padding evenly around the terminal content. + #dynamic_padding: false + + # Window decorations + # + # Values for `decorations`: + # - full: Borders and title bar + # - none: Neither borders nor title bar + # + # Values for `decorations` (macOS only): + # - transparent: Title bar, transparent background and title bar buttons + # - buttonless: Title bar, transparent background, but no title bar buttons + #decorations: full + + # Startup Mode (changes require restart) + # + # Values for `startup_mode`: + # - Windowed + # - Maximized + # - Fullscreen + # + # Values for `startup_mode` (macOS only): + # - SimpleFullscreen + #startup_mode: Windowed + + # Window title + #title: Alacritty + + # Window class (Linux/BSD only): + #class: + # Application instance name + #instance: Alacritty + # General application class + #general: Alacritty + + # GTK theme variant (Linux/BSD only) + # + # Override the variant of the GTK theme. Commonly supported values are `dark` and `light`. + # Set this to `None` to use the default theme variant. + #gtk_theme_variant: None + +#scrolling: + # Maximum number of lines in the scrollback buffer. + # Specifying '0' will disable scrolling. + #history: 10000 + + # Number of lines the viewport will move for every line scrolled when + # scrollback is enabled (history > 0). + #multiplier: 3 + +# Font configuration +font: + # Normal (roman) font face + normal: + # Font family + # + # Default: + # - (macOS) Menlo + # - (Linux/BSD) monospace + # - (Windows) Consolas + family: SourceCodePro + + # The `style` can be specified to pick a specific face. + style: Regular + + # Bold font face + bold: + # Font family + # + # If the bold family is not specified, it will fall back to the + # value specified for the normal font. + family: SourceCodePro + + # The `style` can be specified to pick a specific face. + style: Bold + + # Italic font face + italic: + # Font family + # + # If the italic family is not specified, it will fall back to the + # value specified for the normal font. + family: SourceCodePro + + # The `style` can be specified to pick a specific face. + style: Italic + + # Bold italic font face + bold_italic: + # Font family + # + # If the bold italic family is not specified, it will fall back to the + # value specified for the normal font. + family: SourceCodePro + + # The `style` can be specified to pick a specific face. + style: Bold Italic + + # Point size + size: 10.0 + + # Offset is the extra space around each character. `offset.y` can be thought of + # as modifying the line spacing, and `offset.x` as modifying the letter spacing. + #offset: + # x: 0 + # y: 0 + + # Glyph offset determines the locations of the glyphs within their cells with + # the default being at the bottom. Increasing `x` moves the glyph to the right, + # increasing `y` moves the glyph upwards. + #glyph_offset: + # x: 0 + # y: 0 + + # Thin stroke font rendering (macOS only) + # + # Thin strokes are suitable for retina displays, but for non-retina screens + # it is recommended to set `use_thin_strokes` to `false` + # + # macOS >= 10.14.x: + # + # If the font quality on non-retina display looks bad then set + # `use_thin_strokes` to `true` and enable font smoothing by running the + # following command: + # `defaults write -g CGFontRenderingFontSmoothingDisabled -bool NO` + # + # This is a global setting and will require a log out or restart to take + # effect. + #use_thin_strokes: true + +# If `true`, bold text is drawn using the bright color variants. +#draw_bold_text_with_bright_colors: false + +# Theme: modus-operandi +# Description: Alacritty port of modus-operandi (Modus themes for Emacs) +# Author: Protesilaos Stavrou, +colors: + primary: + background: '#ffffff' + foreground: '#000000' + normal: + black: '#000000' + red: '#a60000' + green: '#005e00' + yellow: '#813e00' + blue: '#0031a9' + magenta: '#721045' + cyan: '#00538b' + white: '#bfbfbf' + bright: + black: '#595959' + red: '#972500' + green: '#315b00' + yellow: '#70480f' + blue: '#2544bb' + magenta: '#5317ac' + cyan: '#005a5f' + white: '#ffffff' + + # Dim colors + # + # If the dim colors are not set, they will be calculated automatically based + # on the `normal` colors. + #dim: + # black: '#000000' + # red: '#8c3336' + # green: '#7a8530' + # yellow: '#97822e' + # blue: '#506d8f' + # magenta: '#80638e' + # cyan: '#497e7a' + # white: '#9a9a9a' + + # Indexed Colors + # + # The indexed colors include all colors from 16 to 256. + # When these are not set, they're filled with sensible defaults. + # + # Example: + # `- { index: 16, color: '#ff00ff' }` + # + #indexed_colors: [] + +# Visual Bell +# +# Any time the BEL code is received, Alacritty "rings" the visual bell. Once +# rung, the terminal background will be set to white and transition back to the +# default background color. You can control the rate of this transition by +# setting the `duration` property (represented in milliseconds). You can also +# configure the transition function by setting the `animation` property. +# +# Values for `animation`: +# - Ease +# - EaseOut +# - EaseOutSine +# - EaseOutQuad +# - EaseOutCubic +# - EaseOutQuart +# - EaseOutQuint +# - EaseOutExpo +# - EaseOutCirc +# - Linear +# +# Specifying a `duration` of `0` will disable the visual bell. +#visual_bell: +# animation: EaseOutExpo +# duration: 0 +# color: '#ffffff' + +# Background opacity +# +# Window opacity as a floating point number from `0.0` to `1.0`. +# The value `0.0` is completely transparent and `1.0` is opaque. +background_opacity: 0.9 + +#selection: + #semantic_escape_chars: ",│`|:\"' ()[]{}<>\t" + + # When set to `true`, selected text will be copied to the primary clipboard. + #save_to_clipboard: false + +# Allow terminal applications to change Alacritty's window title. +#dynamic_title: true + +#cursor: + # Cursor style + # + # Values for `style`: + # - ▇ Block + # - _ Underline + # - | Beam + #style: Block + + # If this is `true`, the cursor will be rendered as a hollow box when the + # window is not focused. + #unfocused_hollow: true + +# Live config reload (changes require restart) +#live_config_reload: true + +# Shell +# +# You can set `shell.program` to the path of your favorite shell, e.g. `/bin/fish`. +# Entries in `shell.args` are passed unmodified as arguments to the shell. +# +# Default: +# - (macOS) /bin/bash --login +# - (Linux/BSD) user login shell +# - (Windows) powershell +#shell: +# program: /bin/bash +# args: +# - --login + +# Startup directory +# +# Directory the shell is started in. If this is unset, or `None`, the working +# directory of the parent process will be used. +#working_directory: None + +# WinPTY backend (Windows only) +# +# Alacritty defaults to using the newer ConPTY backend if it is available, +# since it resolves a lot of bugs and is quite a bit faster. If it is not +# available, the the WinPTY backend will be used instead. +# +# Setting this option to `true` makes Alacritty use the legacy WinPTY backend, +# even if the ConPTY backend is available. +#winpty_backend: false + +# Send ESC (\x1b) before characters when alt is pressed. +#alt_send_esc: true + +#mouse: + # Click settings + # + # The `double_click` and `triple_click` settings control the time + # alacritty should wait for accepting multiple clicks as one double + # or triple click. + #double_click: { threshold: 300 } + #triple_click: { threshold: 300 } + + # If this is `true`, the cursor is temporarily hidden when typing. + #hide_when_typing: false + + #url: + # URL launcher + # + # This program is executed when clicking on a text which is recognized as a URL. + # The URL is always added to the command as the last parameter. + # + # When set to `None`, URL launching will be disabled completely. + # + # Default: + # - (macOS) open + # - (Linux/BSD) xdg-open + # - (Windows) explorer + #launcher: + # program: xdg-open + # args: [] + + # URL modifiers + # + # These are the modifiers that need to be held down for opening URLs when clicking + # on them. The available modifiers are documented in the key binding section. + #modifiers: None + +# Mouse bindings +# +# Mouse bindings are specified as a list of objects, much like the key +# bindings further below. +# +# To trigger mouse bindings when an application running within Alacritty captures the mouse, the +# `Shift` modifier is automatically added as a requirement. +# +# Each mouse binding will specify a: +# +# - `mouse`: +# +# - Middle +# - Left +# - Right +# - Numeric identifier such as `5` +# +# - `action` (see key bindings) +# +# And optionally: +# +# - `mods` (see key bindings) +#mouse_bindings: +# - { mouse: Middle, action: PasteSelection } + +# Key bindings +# +# Key bindings are specified as a list of objects. For example, this is the +# default paste binding: +# +# `- { key: V, mods: Control|Shift, action: Paste }` +# +# Each key binding will specify a: +# +# - `key`: Identifier of the key pressed +# +# - A-Z +# - F1-F24 +# - Key0-Key9 +# +# A full list with available key codes can be found here: +# https://docs.rs/glutin/*/glutin/event/enum.VirtualKeyCode.html#variants +# +# Instead of using the name of the keys, the `key` field also supports using +# the scancode of the desired key. Scancodes have to be specified as a +# decimal number. This command will allow you to display the hex scancodes +# for certain keys: +# +# `showkey --scancodes`. +# +# Then exactly one of: +# +# - `chars`: Send a byte sequence to the running application +# +# The `chars` field writes the specified string to the terminal. This makes +# it possible to pass escape sequences. To find escape codes for bindings +# like `PageUp` (`"\x1b[5~"`), you can run the command `showkey -a` outside +# of tmux. Note that applications use terminfo to map escape sequences back +# to keys. It is therefore required to update the terminfo when changing an +# escape sequence. +# +# - `action`: Execute a predefined action +# +# - Copy +# - Paste +# - PasteSelection +# - IncreaseFontSize +# - DecreaseFontSize +# - ResetFontSize +# - ScrollPageUp +# - ScrollPageDown +# - ScrollLineUp +# - ScrollLineDown +# - ScrollToTop +# - ScrollToBottom +# - ClearHistory +# - Hide +# - Minimize +# - Quit +# - ToggleFullscreen +# - SpawnNewInstance +# - ClearLogNotice +# - ReceiveChar +# - None +# +# (macOS only): +# - ToggleSimpleFullscreen: Enters fullscreen without occupying another space +# +# - `command`: Fork and execute a specified command plus arguments +# +# The `command` field must be a map containing a `program` string and an +# `args` array of command line parameter strings. For example: +# `{ program: "alacritty", args: ["-e", "vttest"] }` +# +# And optionally: +# +# - `mods`: Key modifiers to filter binding actions +# +# - Command +# - Control +# - Option +# - Super +# - Shift +# - Alt +# +# Multiple `mods` can be combined using `|` like this: +# `mods: Control|Shift`. +# Whitespace and capitalization are relevant and must match the example. +# +# - `mode`: Indicate a binding for only specific terminal reported modes +# +# This is mainly used to send applications the correct escape sequences +# when in different modes. +# +# - AppCursor +# - AppKeypad +# - Alt +# +# A `~` operator can be used before a mode to apply the binding whenever +# the mode is *not* active, e.g. `~Alt`. +# +# Bindings are always filled by default, but will be replaced when a new +# binding with the same triggers is defined. To unset a default binding, it can +# be mapped to the `ReceiveChar` action. Alternatively, you can use `None` for +# a no-op if you do not wish to receive input characters for that binding. +# +# If the same trigger is assigned to multiple actions, all of them are executed +# at once. +#key_bindings: + # (Windows, Linux, and BSD only) + #- { key: V, mods: Control|Shift, action: Paste } + #- { key: C, mods: Control|Shift, action: Copy } + #- { key: Insert, mods: Shift, action: PasteSelection } + #- { key: Key0, mods: Control, action: ResetFontSize } + #- { key: Equals, mods: Control, action: IncreaseFontSize } + #- { key: Add, mods: Control, action: IncreaseFontSize } + #- { key: Subtract, mods: Control, action: DecreaseFontSize } + #- { key: Minus, mods: Control, action: DecreaseFontSize } + + # (Windows only) + #- { key: Return, mods: Alt, action: ToggleFullscreen } + + # (macOS only) + #- { key: Key0, mods: Command, action: ResetFontSize } + #- { key: Equals, mods: Command, action: IncreaseFontSize } + #- { key: Add, mods: Command, action: IncreaseFontSize } + #- { key: Minus, mods: Command, action: DecreaseFontSize } + #- { key: K, mods: Command, action: ClearHistory } + #- { key: K, mods: Command, chars: "\x0c" } + #- { key: V, mods: Command, action: Paste } + #- { key: C, mods: Command, action: Copy } + #- { key: H, mods: Command, action: Hide } + #- { key: M, mods: Command, action: Minimize } + #- { key: Q, mods: Command, action: Quit } + #- { key: W, mods: Command, action: Quit } + #- { key: F, mods: Command|Control, action: ToggleFullscreen } + + #- { key: Paste, action: Paste } + #- { key: Copy, action: Copy } + #- { key: L, mods: Control, action: ClearLogNotice } + #- { key: L, mods: Control, chars: "\x0c" } + #- { key: PageUp, mods: Shift, action: ScrollPageUp, mode: ~Alt } + #- { key: PageDown, mods: Shift, action: ScrollPageDown, mode: ~Alt } + #- { key: Home, mods: Shift, action: ScrollToTop, mode: ~Alt } + #- { key: End, mods: Shift, action: ScrollToBottom, mode: ~Alt } + +#debug: + # Display the time it takes to redraw each frame. + #render_timer: false + + # Keep the log file after quitting Alacritty. + #persistent_logging: false + + # Log level + # + # Values for `log_level`: + # - None + # - Error + # - Warn + # - Info + # - Debug + # - Trace + #log_level: Warn + + # Print all received window events. + #print_events: false diff --git a/home-manager/modules/profiles/server.nix b/home-manager/modules/profiles/server.nix new file mode 100644 index 0000000..027668e --- /dev/null +++ b/home-manager/modules/profiles/server.nix @@ -0,0 +1,10 @@ +{ config, pkgs, lib, ... }: +let + inherit (lib) + ; +in +{ + imports = [ + ../bash + ]; +} diff --git a/home-manager/modules/profiles/workstation.nix b/home-manager/modules/profiles/workstation.nix new file mode 100644 index 0000000..d0ac0ff --- /dev/null +++ b/home-manager/modules/profiles/workstation.nix @@ -0,0 +1,112 @@ +{ config, pkgs, lib, ... }: +let + inherit (lib) + concatStringsSep + getExe + flip; + + combineWines = wines: + pkgs.stdenv.mkDerivation { + pname = "wine-combined"; + version = "unknown"; + + dontFetch = true; + dontUnpack = true; + dontBuild = true; + + installPhase = + '' + mkdir -p $out/bin + '' + + + (concatStringsSep "\n" + (flip map wines + (wine: '' + ln -s ${getExe wine} $out/bin/${wine.pname} + '') + )); + }; +in +{ + imports = [ + ../picom + ../dunst + ../keynav + ../lightlocker + ../bash + ../emacs + ../xmonad + ../pantalaimon.nix + ../ssh.nix + ]; + + programs.librewolf = { + enable = true; + settings = { + "webgl.disabled" = false; + }; + }; + + xsession.enable = true; + home.keyboard = null; + + services.redshift = { + enable = true; + dawnTime = "6:00-6:05"; + duskTime = "21:00-21:05"; + }; + + home.packages = with pkgs; [ + prismlauncher + + dejavu_fonts + alacritty + gimp + obs-studio + mpv + slack + schildichat-desktop + armcord + pavucontrol + + # GPG + gnupg + pass + yubikey-manager + + # wine + winetricks + (combineWines [ wineWowPackages.staging ]) + + # 3d printing + openscad + freecad + + cura + super-slicer + + inkscape + + # command line programs + emacsclient-remote + zip + unzip + unrar + git + htop + lm_sensors + cryptsetup + + magic-screenshot + emacs-rofi + libnotify + playerctl + ]; + + + home.file.".config/alacritty/alacritty.yaml".source = ./alacritty.yaml; + home.file.".gpg-agent.conf".text = '' + enable-ssh-support + pinentry-program ${pkgs.pinentry.gtk2}/bin/pinentry + ''; +} diff --git a/home-manager/modules/ssh.nix b/home-manager/modules/ssh.nix new file mode 100644 index 0000000..6f33477 --- /dev/null +++ b/home-manager/modules/ssh.nix @@ -0,0 +1,26 @@ +{ config, ... }: +{ + programs.ssh = { + enable = true; + + controlMaster = "auto"; + controlPath = "~/.ssh/controlmasters/%r@%h:%p"; + controlPersist = "300s"; + serverAliveInterval = 30; + matchBlocks = { + "Host *redalder.org 10.64.1.* 10.64.0.*".extraOptions = { + ExitOnForwardFailure = "yes"; + SendEnv = "INSIDE_EMACS"; + RemoteForward = "/home/main/.ssh/emacs-server /run/user/1000/emacs/server"; + }; + }; + }; + + home.activation."ssh-controlmasters" = config.lib.dag.entryAfter ["writeBoundary"] '' + mkdir -p ~/.ssh/controlmasters + ''; + + home.file.".profile".text = '' + export SSH_AUTH_SOCK=$(gpgconf --list-dirs agent-ssh-socket) + ''; +} diff --git a/home-manager/modules/xmonad/default.nix b/home-manager/modules/xmonad/default.nix new file mode 100644 index 0000000..6fc7e83 --- /dev/null +++ b/home-manager/modules/xmonad/default.nix @@ -0,0 +1,103 @@ +{ pkgs, lib, ... }: +{ + home.file.".xmonad/xmonad.hs".source = pkgs.writeSubstitutedFile { + name = "xmonad.hs"; + file = ./xmonad.hs; + substitutes = { + "lightLockerCommand" = "${pkgs.lightlocker}/bin/light-locker-command"; + "brightnessctl" = lib.getExe pkgs.brightnessctl; + "playerctl" = lib.getExe pkgs.playerctl; + "dmenu_run" = "${pkgs.dmenu}/bin/dmenu_run"; + "polybar" = pkgs.writeShellScript "polybar" + '' + monitors=$(polybar --list-monitors | cut -f 1 -d':') + MONITOR=''${monitors[$1]} ${lib.getExe pkgs.polybarFull} -c ${./polybar.ini} top + ''; + "reload" = pkgs.writeShellScript "xmonad-reload" + '' + ${lib.getExe pkgs.libnotify} -t 5000 "recompiling xmonad" + + if xmonad --recompile + then + ${lib.getExe pkgs.libnotify} -t 5000 "compilation succeeded" + xmonad --restart + else + ${lib.getExe pkgs.libnotify} -t 5000 "compilation failed" + fi + ''; + "toggle_touchpad" = pkgs.writeShellScript "toggle-touchpad" + '' + read TPdevice <<< $( xinput | sed -nre '/TouchPad|Touchpad/s/.*id=([0-9]*).*/\1/p' ) + state=$( xinput list-props "$TPdevice" | grep "Device Enabled" | grep -o "[01]$" ) + + if [ "$state" -eq '1' ];then + xinput --disable "$TPdevice" && notify-send -i emblem-nowrite "Touchpad" "Disabled" + else + xinput --enable "$TPdevice" && notify-send -i emblem-nowrite "Touchpad" "Enabled" + fi + ''; + "auxmenu" = pkgs.writeShellScript "auxmenu" + '' + export SUDO_ASKPASS=${pkgs.x11_ssh_askpass}/libexec/x11-ssh-askpass + + _options="toggle-mic\ntoggle-wifi\ntoggle-bluetooth\nscreenshot-all\nscreenshot-select\nscreenshot-focused\nsuspend\nreboot\nkexec\npoweroff\nlogout\nnmtui" + + _option="$(echo -e $_options | emacs-rofi "command: " 90 30 | awk '{print $1}' | tr -d '\r\n')" + if [ ''${#_option} -gt 0 ] + then + case $_option in + toggle-mic) + wpctl set-mute @DEFAULT_AUDIO_SOURCE@ toggle + ;; + toggle-wifi) + if [ "$(nmcli radio wifi)" = "enabled" ] + then + nmcli radio wifi off + else + nmcli radio wifi on + fi + ;; + toggle-bluetooth) + if [ "$(nmcli radio wifi)" = "enabled" ] + then + nmcli radio wifi off + else + nmcli radio wifi on + fi + ;; + screenshot-all) + ${lib.getExe pkgs.magic-screenshot} screen + ;; + screenshot-select) + ${lib.getExe pkgs.magic-screenshot} select + ;; + screenshot-focused) + ${lib.getExe pkgs.magic-screenshot} focused + ;; + suspend) + systemctl suspend + ;; + reboot) + systemctl reboot + ;; + poweroff) + systemctl poweroff + ;; + kexec) + sudo -A kexec -l /run/current-system/kernel --initrd=/run/current-system/initrd --reuse-cmdline + systemctl kexec + ;; + logout) + loginctl terminate-session $XDG_SESSION_ID + ;; + nmtui) + alacritty -e nmtui + ;; + *) + ;; + esac + fi + ''; + }; + }; +} diff --git a/home-manager/modules/xmonad/polybar.ini b/home-manager/modules/xmonad/polybar.ini new file mode 100644 index 0000000..0abc1d3 --- /dev/null +++ b/home-manager/modules/xmonad/polybar.ini @@ -0,0 +1,184 @@ +[colors] +background = #282A2E +background-alt = #373B41 +foreground = #C5C8C6 +primary = #F0C674 +secondary = #8ABEB7 +alert = #A54242 +disabled = #707880 + +[bar/top] +monitor = ${env:MONITOR:} +height = 10pt + +font-0 = Fixed;2 + +modules-left = battery backlight xworkspaces +modules-right = filesystem pulseaudio memory cpu wlan eth xkeyboard date + +module-margin = 1 + +separator = | +separator-foreground = ${colors.disabled} + +border-size = 1pt +border-color = #222222 + +enable-ipc = true + +tray-position = right + +[module/battery] +type = internal/battery + +full-at = 100 + +# format-low once this charge percentage is reached +# Default: 10 +# New in version 3.6.0 +low-at = 20 + +# Use the following command to list batteries and adapters: +# $ ls -1 /sys/class/power_supply/ +battery = BAT0 +adapter = ADP1 + +# If an inotify event haven't been reported in this many +# seconds, manually poll for new values. +# +# Needed as a fallback for systems that don't report events +# on sysfs/procfs. +# +# Disable polling by setting the interval to 0. +# +# Default: 5 +poll-interval = 5 + +format-low = +label-low = %{F#FF0000}! %percentage% + +label-charging = %{F#F0C674}c%{F-} %percentage%% +label-discharging = %{F#F0C674}d%{F-} %percentage%% +label-full = %{F#F0C674}-%{F-} %percentage%% + +[module/backlight] +type = internal/backlight + +# Use the following command to list available cards: +# $ ls -1 /sys/class/backlight/ +card = intel_backlight + +label = %{F#F0C674}b%{F-} %percentage%% + +# Use the `/sys/class/backlight/.../actual-brightness` file +# rather than the regular `brightness` file. +# Defaults to true unless the specified card is an amdgpu backlight. +# New in version 3.6.0 +use-actual-brightness = true + +[module/xworkspaces] +type = internal/xworkspaces + +label-active = %name% +label-active-background = ${colors.background-alt} +label-active-underline= ${colors.primary} +label-active-padding = 1 + +label-occupied = %name% +label-occupied-padding = 1 + +label-urgent = %name% +label-urgent-background = ${colors.alert} +label-urgent-padding = 1 + +label-empty = +# label-empty-foreground = ${colors.disabled} +# label-empty-padding = 1 + +pin-workspaces = true + +enable-click = false +enable-scroll = false + +[module/filesystem] +type = internal/fs +interval = 25 + +mount-0 = / +mount-1 = /nix/store +mount-2 = /home + +label-mounted = %{F#F0C674}%mountpoint%%{F-} %used% + +label-unmounted = %mountpoint% not mounted +label-unmounted-foreground = ${colors.disabled} + +[module/pulseaudio] +type = internal/pulseaudio + +format-volume-prefix = "VOL " +format-volume-prefix-foreground = ${colors.primary} +format-volume = + +label-volume = %percentage%% + +label-muted = muted +label-muted-foreground = ${colors.disabled} + +interval = 0 + +[module/xkeyboard] +type = internal/xkeyboard +blacklist-0 = num lock + +label-layout = %icon% +label-layout-foreground = ${colors.primary} + +label-indicator-on = +label-indicator-off = + +layout-icon-default = some-icon +layout-icon-0 = de;koy;koy +layout-icon-1 = us;us +layout-icon-2 = mine;mine;mine +layout-icon-3 = de;neo;neo + +[module/memory] +type = internal/memory +interval = 2 +format-prefix = "RAM " +format-prefix-foreground = ${colors.primary} +label = %percentage_used:2%% + +[module/cpu] +type = internal/cpu +interval = 2 +format-prefix = "CPU " +format-prefix-foreground = ${colors.primary} +label = %percentage-cores:2% + +[network-base] +type = internal/network +interval = 5 +format-connected = +format-disconnected = +label-disconnected = %{F#F0C674}%ifname%%{F#707880} disconnected + +[module/wlan] +inherit = network-base +interface-type = wireless +label-connected = %{F#F0C674}%ifname%%{F-} %essid% %local_ip% %{F#707880},%{F-} %upspeed% %downspeed% + +[module/eth] +inherit = network-base +interface-type = wired +label-connected = %{F#F0C674}%ifname%%{F-} %local_ip% %{F#707880},%{F-} %upspeed% %downspeed% + +[module/date] +type = internal/date +interval = 1 + +date = %Y-%m-%d %H:%M:%S + +label = %date% +label-foreground = ${colors.primary} diff --git a/home-manager/modules/xmonad/xmonad.hs b/home-manager/modules/xmonad/xmonad.hs new file mode 100644 index 0000000..a69e25e --- /dev/null +++ b/home-manager/modules/xmonad/xmonad.hs @@ -0,0 +1,368 @@ +-- SPDX-FileCopyrightText: 2022 Richard Brežák +-- +-- SPDX-License-Identifier: LGPL-3.0-or-later + +-- +-- xmonad example config file. +-- +-- A template showing all available configuration hooks, +-- and how to override the defaults in your own xmonad.hs conf file. +-- +-- Normally, you'd only override those defaults you care about. +-- + +import XMonad +import Data.Monoid +import Data.Maybe +import Data.Function +import Data.Functor +import System.Exit +import XMonad.Util.EZConfig +import XMonad.Util.SpawnOnce +import XMonad.Util.WindowProperties +import XMonad.Hooks.ManageDocks +import XMonad.Hooks.EwmhDesktops + +import XMonad.Layout.BinarySpacePartition +import XMonad.Layout.Tabbed +import XMonad.Layout.NoBorders +import XMonad.Util.WorkspaceCompare +import XMonad.Hooks.DynamicLog +import XMonad.Hooks.StatusBar +import XMonad.Actions.UpdatePointer +import XMonad.Actions.FloatKeys + +import Control.Monad + +import qualified XMonad.StackSet as W +import qualified Data.Map as M + + +myTerminal = "xterm" +myFocusFollowsMouse = True +myClickJustFocuses = False +-- > workspaces = ["web", "irc", "code" ] ++ map show [4..9] +myWorkspaces = map show ([1..9] ++ [0]) + +toggleFloat = withFocused (\windowId -> do + { floats <- gets (W.floating . windowset); + if windowId `M.member` floats + then withFocused $ windows . W.sink + else float windowId }) + +modm :: KeyMask +modm = mod4Mask + +------------------------------------------------------------------------ +-- Key bindings. Add, modify or remove key bindings here. +-- +myKeymap c = + -- launch a terminal + [ ("M-S-", spawn "alacritty") + + -- launch dmenu + , ("M-e", spawn "@dmenu_run@") + + -- close focused window + , ("M-S-q", io (exitWith ExitSuccess)) + + -- Rotate through the available layout algorithms + , ("M-", sendMessage NextLayout) + + -- Reset the layouts on the current workspace to default + -- , ("M-S-Space", setLayout $ XMonad.layoutHook c) + + -- Resize viewed windows to the correct size + , ("M-b", refresh) + + -- Move focus to the next window + , ("M-", windows W.focusDown) + + -- Move focus to the next window + , ("M-n", windows W.focusDown) + + -- Move focus to the previous window + , ("M-r", windows W.focusUp) + + -- Move focus to the master window + , ("M-p", windows W.focusMaster) + + -- Swap the focused window and the master window + , ("M-", windows W.swapMaster) + + -- Swap the focused window with the next window + , ("M-S-n", windows W.swapDown) + + -- Swap the focused window with the previous window + , ("M-S-r", windows W.swapUp) + + -- Shrink the master area + , ("M-t", sendMessage Shrink) + + -- Expand the master area + , ("M-s", sendMessage Expand) + + -- Push window back into tiling + , ("M-y", toggleFloat) + + -- Increment the number of windows in the master area + , ("M-w", sendMessage (IncMasterN 1)) + + -- Deincrement the number of windows in the master area + , ("M-m", sendMessage (IncMasterN (-1))) + + -- , ("M-b", spawn ("pkill xmobar && " ++ xmobarCmd)) + , ("", spawn "sleep 0.1 ; @screenshot@ select") + , ("S-", spawn "@screenshot@ screen && sleep 0.1 && @notify@ -t 5000 \"snap\"") + , ("C-S-", spawn "@screenshot@ focused && sleep 0.1 && @notify@ -t 5000 \"snap\"") + + -- Toggle the status bar gap + -- Use this binding with avoidStruts from Hooks.ManageDocks. + -- See also the statusBar function from Hooks.DynamicLog. + -- + , ("M-b", sendMessage ToggleStruts) + + -- Quit xmonad + , ("M-S-k", kill) + + -- Restart xmonad + , ("M-k", spawn "@reload@") + + -- float keys + , ("M-g", withFocused (keysResizeWindow (-10, 0) (0, 0))) + , ("M-c", withFocused (keysResizeWindow ( 0, 10) (0, 0))) + , ("M-l", withFocused (keysResizeWindow ( 0,-10) (0, 0))) + , ("M-ß", withFocused (keysResizeWindow ( 10, 0) (0, 0))) + , ("M-S-g", withFocused (xMoveWindow (-10, 0))) + , ("M-S-c", withFocused (xMoveWindow ( 0, 10))) + , ("M-S-l", withFocused (xMoveWindow ( 0,-10))) + , ("M-S-ß", withFocused (xMoveWindow ( 10, 0))) + + , ("M-z", spawn "@lightLockerCommand@ --lock") + + , ("" , spawn "wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle") + , ("" , spawn "wpctl set-volume -l 1.5 @DEFAULT_AUDIO_SINK@ 5%+") + , ("" , spawn "wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%-") + , ("" , spawn "@brightnessctl@ set +5%") + , ("" , spawn "@brightnessctl@ set 5%-") + + , ("" , spawn "@notify@ -t 5000 \"Music: Play\"" >> spawn "@playerctl@ play-pause") + , ("" , spawn "@notify@ -t 5000 \"Music: Stop\"" >> spawn "@playerctl@ stop") + , ("" , spawn "@notify@ -t 5000 \"Music: Prev\"" >> spawn "@playerctl@ previous") + , ("" , spawn "@notify@ -t 5000 \"Music: Next\"" >> spawn "@playerctl@ next") + + , ("" , spawn "@toggle_touchpad@") + + , ("M-", spawn "@auxmenu@") + ] + ++ + + -- + -- mod-[1..9], Switch to workspace N + -- mod-shift-[1..9], Move client to workspace N + -- + [("M-" ++ m ++ [k], windows $ f i) + | (i, k) <- zip (XMonad.workspaces c) "1234567890" + , (f, m) <- [(W.view, ""), (W.shift, "S-")]] + ++ + + -- + -- mod-{w,e,r}, Switch to physical/Xinerama screens 1, 2, or 3 + -- mod-shift-{w,e,r}, Move client to screen 1, 2, or 3 + -- + [("M-"++m++[key], screenWorkspace sc >>= flip whenJust (windows . f)) + | (key, sc) <- zip ".o," [0..] + , (f, m) <- [(W.view, ""), (W.shift, "S-")]] + where + xMoveWindow + :: (Position, Position) + -> Window + -> X () + xMoveWindow (x, y) w = withDisplay (\d -> do + (_, ox, oy, _, _, _, _) <- io $ getGeometry d w + io $ moveWindow d w (ox + x) (oy + y)) + + +------------------------------------------------------------------------ +-- Mouse bindings: default actions bound to mouse events +-- +myMouseBindings (XConfig {XMonad.modMask = modm}) = M.fromList $ + + -- mod-button1, Set the window to floating mode and move by dragging + [ ((modm, button1), (\w -> focus w >> mouseMoveWindow w + >> windows W.shiftMaster)) + + -- mod-button2, Raise the window to the top of the stack + , ((modm, button2), (\w -> focus w >> windows W.shiftMaster)) + + -- mod-button3, Set the window to floating mode and resize by dragging + , ((modm, button3), (\w -> focus w >> mouseResizeWindow w + >> windows W.shiftMaster)) + + -- you may also bind events to the mouse scroll wheel (button4 and button5) + ] + +------------------------------------------------------------------------ +-- Layouts: + +-- You can specify and transform your layouts by modifying these values. +-- If you change layout bindings be sure to use 'mod-shift-space' after +-- restarting (with 'mod-q') to reset your layout state to the new +-- defaults, as xmonad preserves your old layout settings by default. +-- +-- The available layouts. Note that each layout is separated by |||, +-- which denotes layout choice. +-- +myLayout = smartBorders tiled ||| smartBorders simpleTabbed ||| smartBorders emptyBSP ||| noBorders Full + where + -- default tiling algorithm partitions the screen into two panes + tiled = Tall nmaster delta ratio + + -- The default number of windows in the master pane + nmaster = 1 + + -- Default proportion of screen occupied by master pane + ratio = 1/2 + + -- Percent of screen to increment by when resizing panes + delta = 3/100 + +myPP = def + { ppLayout = const "" -- Don't show the layout name + , ppSort = getSortByXineramaRule -- Sort left/right screens on the left, non-empty workspaces after those + , ppTitle = const "" -- Don't show the focused window's title + , ppTitleSanitize = const "" -- Also about window's title + , ppVisible = wrap "(" ")" -- Non-focused (but still visible) screen + } + +spawnBar :: ScreenId -> IO StatusBarConfig +spawnBar screen = pure $ statusBarPropTo "_XMONAD_LOG" ("@polybar@ " <> (show (fromIntegral screen :: Int))) (pure myPP) + +------------------------------------------------------------------------ +-- Now run xmonad with all the defaults we set up. + +-- Run xmonad with the settings you specify. No need to modify this. +-- +-- main = xmonad $ ewmh $ docks $ defaults +main = do + pure defaults <&> dynamicSBs spawnBar <&> docks >>= xmonad + +getNetWMState :: Window -> X [Atom] +getNetWMState w = do + atom <- getAtom "_NET_WM_STATE" + map fromIntegral . fromMaybe [] <$> getProp32 atom w + + +hasNetWMState :: String -> Query Bool +hasNetWMState state = do + window <- ask + wmstate <- liftX $ getNetWMState window + atom <- liftX $ getAtom state + return $ elem atom wmstate + +-- A structure containing your configuration settings, overriding +-- fields in the default config. Any you don't override, will +-- use the defaults defined in xmonad/XMonad/Config.hs +-- +-- No need to modify this. +-- +defaults = let + c = def { + -- simple stuff + terminal = myTerminal, + focusFollowsMouse = myFocusFollowsMouse, + clickJustFocuses = myClickJustFocuses, + modMask = modm, + workspaces = myWorkspaces, + + -- key bindings + -- keys = myKeys, + mouseBindings = myMouseBindings, + + -- hooks, layouts + layoutHook = avoidStruts $ myLayout, + + -- To find the property name associated with a program, use + -- > xprop | grep WM_CLASS + -- and click on the client you're interested in. + -- + -- To match on the WM_NAME, you can use 'title' in the same way that + -- 'className' and 'resource' are used below. + manageHook = manageDocks <+> composeAll + [ title =? "emacs-completing-read-float" --> doFloat + , hasNetWMState "_NET_WM_STATE_ABOVE" --> doFloat + -- , hasNetWMState "_NET_WM_STATE_STICKY" --> doF copyToAll + -- , className =? "Gimp" --> doFloat + -- , resource =? "desktop_window" --> doIgnore + -- , resource =? "kdesktop" --> doIgnore + ], + + logHook = + updatePointer (0.5, 0.5) (1, 1), + + -- XMonad.Layout.PerWorkspace + startupHook = do + spawnOnce "@dunst@ -config .config/dunstrcs" + spawnOnce "@picom@ --config .config/picom.conf --experimental-backends" + spawnOnce "@keynav@" + spawnOnce "@lightLocker@ --lock-on-suspend", + + -- Looks + focusedBorderColor = "#5c5c5c", + normalBorderColor = "#222222", + borderWidth = 4 + } + in additionalKeysP c (myKeymap c) + & flip additionalKeys [ ((mod1Mask, xK_v), return ()) ] + & ewmh + +-- | Finally, a copy of the default bindings in simple textual tabular format. +help :: String +help = unlines ["The default modifier key is 'alt'. Default keybindings:", + "", + "-- launching and killing programs", + "mod-Shift-Enter Launch xterminal", + "mod-p Launch dmenu", + "mod-Shift-p Launch gmrun", + "mod-Shift-c Close/kill the focused window", + "mod-Space Rotate through the available layout algorithms", + "mod-Shift-Space Reset the layouts on the current workSpace to default", + "mod-n Resize/refresh viewed windows to the correct size", + "", + "-- move focus up or down the window stack", + "mod-Tab Move focus to the next window", + "mod-Shift-Tab Move focus to the previous window", + "mod-j Move focus to the next window", + "mod-k Move focus to the previous window", + "mod-m Move focus to the master window", + "", + "-- modifying the window order", + "mod-Return Swap the focused window and the master window", + "mod-Shift-j Swap the focused window with the next window", + "mod-Shift-k Swap the focused window with the previous window", + "", + "-- resizing the master/slave ratio", + "mod-h Shrink the master area", + "mod-l Expand the master area", + "", + "-- floating layer support", + "mod-t Push window back into tiling; unfloat and re-tile it", + "", + "-- increase or decrease number of windows in the master area", + "mod-comma (mod-,) Increment the number of windows in the master area", + "mod-period (mod-.) Deincrement the number of windows in the master area", + "", + "-- quit, or restart", + "mod-Shift-q Quit xmonad", + "mod-q Restart xmonad", + "mod-[1..9] Switch to workSpace N", + "", + "-- Workspaces & screens", + "mod-Shift-[1..9] Move client to workspace N", + "mod-{w,e,r} Switch to physical/Xinerama screens 1, 2, or 3", + "mod-Shift-{w,e,r} Move client to screen 1, 2, or 3", + "", + "-- Mouse bindings: default actions bound to mouse events", + "mod-button1 Set the window to floating mode and move by dragging", + "mod-button2 Raise the window to the top of the stack", + "mod-button3 Set the window to floating mode and resize by dragging"] diff --git a/nixos/common/mine.xkb b/nixos/common/mine.xkb new file mode 100644 index 0000000..0512909 --- /dev/null +++ b/nixos/common/mine.xkb @@ -0,0 +1,81 @@ +// Bei einem Hochströmen sollte der nächste Abschnitt zu symbols/de hinzugefügt werden +// und im unteren Teil mine(mine_base) durch de(mine_base) ersetzt werden + +partial alphanumeric_keys +xkb_symbols "mine_base" { + include "de(neo_base)" + + + key.type[Group1] = "EIGHT_LEVEL_LEVEL_FIVE_LOCK"; + key { [ comma, endash, NoSymbol, U03F1, NoSymbol, NoSymbol, U21D2, NoSymbol ] }; + key { [ period, enfilledcircbullet, NoSymbol, U03D1, NoSymbol, NoSymbol, U21A6, NoSymbol ] }; + + + key.type[Group1] = "EIGHT_LEVEL_ALPHABETIC_LEVEL_FIVE_LOCK"; + key { [ j, J, NoSymbol, Greek_theta, NoSymbol, NoSymbol, Greek_THETA, NoSymbol ] }; + key { [ l, L, NoSymbol, Greek_lambda, NoSymbol, NoSymbol, Greek_LAMBDA, NoSymbol ] }; + key { [ u, U, NoSymbol, NoSymbol, NoSymbol, NoSymbol, includedin, NoSymbol ] }; + key { [ a, A, NoSymbol, Greek_alpha, NoSymbol, NoSymbol, U2200, NoSymbol ] }; + key { [ q, Q, NoSymbol, U03D5, NoSymbol, NoSymbol, U211A, NoSymbol ] }; + key { [ w, W, NoSymbol, Greek_omega, NoSymbol, NoSymbol, Greek_OMEGA, NoSymbol ] }; + key { [ b, B, NoSymbol, Greek_beta, NoSymbol, NoSymbol, U21D0, NoSymbol ] }; + key { [ d, D, NoSymbol, Greek_delta, NoSymbol, NoSymbol, Greek_DELTA, NoSymbol ] }; + key { [ g, G, NoSymbol, Greek_gamma, NoSymbol, NoSymbol, Greek_GAMMA, NoSymbol ] }; + key { [ y, Y, NoSymbol, Greek_upsilon, NoSymbol, NoSymbol, nabla, NoSymbol ] }; + // AD11 receives symbol from neo AC11 in layers 3 and from neo AD11 in layer 4 + key { [ z, Z, at, Greek_zeta, U2212, NoSymbol, U2124, NoSymbol ] }; + // AD12 recieves symbol from neo AD11 in layers 3 and from neo AB10 in layer 4 + key { [ ssharp, U1E9E, U017F, Greek_finalsmallsigma, semicolon, NoSymbol, jot, NoSymbol ] }; + + key { [ c, C, NoSymbol, Greek_chi, NoSymbol, NoSymbol, U2102, NoSymbol ] }; + key { [ r, R, NoSymbol, Greek_rho, NoSymbol, NoSymbol, U211D, NoSymbol ] }; + key { [ i, I, NoSymbol, Greek_iota, NoSymbol, NoSymbol, integral, NoSymbol ] }; + key { [ e, E, NoSymbol, Greek_epsilon, NoSymbol, NoSymbol, U2203, NoSymbol ] }; + key { [ o, O, NoSymbol, Greek_omicron, NoSymbol, NoSymbol, elementof, NoSymbol ] }; + key { [ m, M, NoSymbol, Greek_mu, NoSymbol, NoSymbol, ifonlyif, NoSymbol ] }; + key { [ n, N, NoSymbol, Greek_nu, NoSymbol, NoSymbol, U2115, NoSymbol ] }; + key { [ t, T, NoSymbol, Greek_tau, NoSymbol, NoSymbol, partialderivative, NoSymbol ] }; + key { [ s, S, NoSymbol, Greek_sigma, NoSymbol, NoSymbol, Greek_SIGMA, NoSymbol ] }; + key { [ h, H, NoSymbol, Greek_psi, NoSymbol, NoSymbol, Greek_PSI, NoSymbol ] }; + + key.type[Group1] = "EIGHT_LEVEL_LEVEL_FIVE_LOCK"; + // AC12 recieves symbols from neo AD12 + key { [ dead_acute, dead_tilde, dead_stroke, dead_psili, dead_doubleacute, NoSymbol, dead_breve, NoSymbol ] }; + + key.type[Group1] = "EIGHT_LEVEL_ALPHABETIC_LEVEL_FIVE_LOCK"; + key { [ v, V, NoSymbol, NoSymbol, NoSymbol, NoSymbol, radical, NoSymbol ] }; + key { [ x, X, NoSymbol, Greek_xi, NoSymbol, NoSymbol, Greek_XI, NoSymbol ] }; + key { [ udiaeresis, Udiaeresis, NoSymbol, NoSymbol, NoSymbol, NoSymbol, union, NoSymbol ] }; + key { [ adiaeresis, Adiaeresis, NoSymbol, Greek_eta, NoSymbol, NoSymbol, U2135, NoSymbol ] }; + key { [ odiaeresis, Odiaeresis, NoSymbol, U03F5, NoSymbol, NoSymbol, intersection, NoSymbol ] }; + key { [ p, P, NoSymbol, Greek_pi, NoSymbol, NoSymbol, Greek_PI, NoSymbol ] }; + key { [ f, F, NoSymbol, Greek_phi, NoSymbol, NoSymbol, Greek_PHI, NoSymbol ] }; + // AB10 receives symbol from neo AC11 in layer 4 + key { [ k, K, NoSymbol, Greek_kappa, period, KP_Decimal, multiply, NoSymbol ] }; +}; + +default partial alphanumeric_keys modifier_keys keypad_keys +xkb_symbols "mine" { + + include "mine(mine_base)" + + name[Group1]= "German (Mine)"; + + include "shift(both_capslock)" + include "level3(caps_switch)" + include "mine(ac11_switch)" + include "level5(lsgt_switch_lock)" + include "level5(ralt_switch_lock)" +}; + +// Bei einem Hochströmen sollte der nächste Abschnitt zu symbols/level3 hinzugefügt werden +// und mine(ac11_switch) durch level3(ac11_switch) +// The Backslash key (while pressed) chooses the third shift level. +partial modifier_keys +xkb_symbols "ac11_switch" { + key { + type[Group1]="ONE_LEVEL", + symbols[Group1] = [ ISO_Level3_Shift ] + }; +}; + diff --git a/nixos/common/nixpkgs.nix b/nixos/common/nixpkgs.nix new file mode 100644 index 0000000..836fc51 --- /dev/null +++ b/nixos/common/nixpkgs.nix @@ -0,0 +1,17 @@ +{ inputs', lib, ... }: +let + inherit (lib) + flip + mapAttrs; +in +{ + nix.registry = + flip mapAttrs inputs' + ( + n: flake: {inherit flake;} + ); + nix.settings = { + experimental-features = [ "flakes" "nix-command" ]; + }; + nixpkgs.config.allowUnfree = true; +} diff --git a/nixos/common/qwerty_neo.xkb b/nixos/common/qwerty_neo.xkb new file mode 100644 index 0000000..6f43a78 --- /dev/null +++ b/nixos/common/qwerty_neo.xkb @@ -0,0 +1,265 @@ +// SPDX-FileCopyrightText: 2022 Richard Brežák +// +// SPDX-License-Identifier: LGPL-3.0-or-later + +// # QWERTY/Neo 2 +// +// This is a custom keyboard layout that combines regular German QWERTY (mostly +// letters of the first 2 levels) with the upper levels of Neo 2. It is +// especially useful if you do lots of programming, but don’t want to lose the +// letters peculiar to the German layout (ä, ö, u, etc.). I use this layout +// with vim where it has proven to be quite useful. +// +// ## How this layout was created +// +// - I took the original "neo_base" layout, defined in +// /usr/share/X11/xkb/symbols/de +// - and modified it to include the standard QWERTY layout for the first +// 2 levels. +// +// The QWERTY layout is built up of the following sections: +// +// - "de(basic)", defined in /usr/share/X11/xkb/symbols/de. +// It includes "kpdl(comma)" and "level3(ralt_switch)", both of which are not +// necessary as Neo 2 takes care of the respective keys, +// - "latin(type4)", defined in /usr/share/X11/xkb/symbols/latin. +// It includes "latin(basic)". +// +// The end result is mostly identical to Neo 2 except for the letters and a few +// other keys that have different mappings in either "de(basic)", +// "latin(type4)", or "latin(basic)". The changes to Neo 2’s default mappings +// can be found at the end of the layout. +// +// ## Installation +// +// Append the contents of this file to /usr/share/X11/xkb/symbols/de. You can +// use `cat qwerty_neo | sudo tee -a /usr/share/X11/xkb/symbols/de >/dev/null` +// to do that. +// +// Add the following tag to /usr/share/X11/xkb/rules/evdev.xml (e. g. after the +// tag that configures Neo 2). +// +// ``` +// +// +// qwerty_neo +// German (QWERTY/Neo 2) +// +// +// ``` +// +// On Ubuntu, you will likely have to reinstall this layout after an upgrade to +// a new version of the OS (e. g. after an update from 17.04 to 17.10). +// +// ## Usage +// +// Use it with `setxkbmap de qwerty_neo` or select the layout in your desktop +// environment. +// +partial alphanumeric_keys modifier_keys keypad_keys +xkb_symbols "qwerty_neo" { + + // Levels in Neo jargon + // -------------------------------------------------------------- + // Ebene 1: normal + // Ebene 2: Shift + // Ebene 3: Mod3 + // Ebene 4: Mod4 (for marking something use Shift + Mod4) + // Ebene 5: Shift + Mod3 + // Ebene 6: Mod3 + Mod4 + // Compose (not a level): Mod3 + Tab + // Feststelltaste (Capslock): Shift + Shift + // Mod4-Lock: Mod4 + Mod4 + // Mod4-Lock: Shift + Mod3 + Tab + + // Legend + // =============== + // Levels in Xkbmap jargon to be found here in the definitions. + // These are the levels used, and Xorg's translations: + // -------------------------------------------------------------- + // Xorg: Level1 Level2 Level3 Level4 Level5 Level6 Level7 Level8 + // Neo: Ebene1 Ebene2 Ebene3 Ebene5 Ebene4 Pseudo-Ebene Ebene6 ??? + // Keys (Neo): None Shift Mod3 Mod3 + Shift Mod4 Mod4 + Shift Mod3 + Mod4 Mod3 + Mod4 + Shift + + + // Alphanumeric-keys + // =============== + key.type[Group1] = "EIGHT_LEVEL"; + + // Tab as Multi_key (Compose) + // -------------------------------------------------------------- + key { [ Tab, ISO_Left_Tab, Multi_key, ISO_Level5_Lock, NoSymbol, NoSymbol, NoSymbol, ISO_Level5_Lock ] }; + + + // Number row + // -------------------------------------------------------------- + key { [ dead_circumflex, dead_caron, U21BB, U02DE, dead_abovedot, Pointer_EnableKeys, dead_belowdot, NoSymbol ] }; + + key { [ 1, degree, onesuperior, onesubscript, ordfeminine, NoSymbol, notsign, NoSymbol ] }; + key { [ 2, section, twosuperior, twosubscript, masculine, NoSymbol, logicalor, NoSymbol ] }; + key { [ 3, U2113, threesuperior, threesubscript, numerosign, NoSymbol, logicaland, NoSymbol ] }; + key { [ 4, guillemotright, U203A, femalesymbol, NoSymbol, NoSymbol, U22A5, NoSymbol ] }; + key { [ 5, guillemotleft, U2039, malesymbol, periodcentered, NoSymbol, U2221, NoSymbol ] }; + key { [ 6, dollar, cent, U26A5, sterling, NoSymbol, U2225, NoSymbol ] }; + + key { [ 7, EuroSign, yen, U03F0, currency, NoSymbol, rightarrow, NoSymbol ] }; + key { [ 8, doublelowquotemark, singlelowquotemark, U27E8, Tab, ISO_Left_Tab, U221E, NoSymbol ] }; + key { [ 9, leftdoublequotemark, leftsinglequotemark, U27E9, KP_Divide, KP_Divide, variation, NoSymbol ] }; + key { [ 0, rightdoublequotemark, rightsinglequotemark, zerosubscript, KP_Multiply, KP_Multiply, emptyset, NoSymbol ] }; + + key { [ minus, emdash, NoSymbol, U2011, KP_Subtract, KP_Subtract, hyphen, NoSymbol ] }; + key { [ dead_grave, dead_cedilla, dead_abovering, dead_dasia, dead_diaeresis, NoSymbol, dead_macron, NoSymbol ] }; + + // Top row + // -------------------------------------------------------------- + key.type[Group1] = "EIGHT_LEVEL_SEMIALPHABETIC"; + key { [ x, X, ellipsis, Greek_xi, Prior, Prior, Greek_XI, NoSymbol ] }; + key { [ v, V, underscore, NoSymbol, BackSpace, BackSpace, radical, NoSymbol ] }; + key { [ l, L, bracketleft, Greek_lambda, Up, Up, Greek_LAMBDA, NoSymbol ] }; + key { [ c, C, bracketright, Greek_chi, Delete, Delete, U2102, NoSymbol ] }; + key { [ w, W, asciicircum, Greek_omega, Next, Next, Greek_OMEGA, NoSymbol ] }; + + key { [ k, K, exclam, Greek_kappa, exclamdown, NoSymbol, multiply, NoSymbol ] }; + key { [ h, H, less, Greek_psi, KP_7, KP_7, Greek_PSI, NoSymbol ] }; + key { [ g, G, greater, Greek_gamma, KP_8, KP_8, Greek_GAMMA, NoSymbol ] }; + key { [ f, F, equal, Greek_phi, KP_9, KP_9, Greek_PHI, NoSymbol ] }; + key { [ q, Q, ampersand, U03D5, KP_Add, KP_Add, U211A, NoSymbol ] }; + + key { [ ssharp, U1E9E, U017F, Greek_finalsmallsigma, U2212, NoSymbol, jot, NoSymbol ] }; + + key.type[Group1] = "EIGHT_LEVEL"; + key { [ dead_acute, dead_tilde, dead_stroke, dead_psili, dead_doubleacute, NoSymbol, dead_breve, NoSymbol ] }; + + // Middle row + // -------------------------------------------------------------- + key.type[Group1] = "EIGHT_LEVEL_SEMIALPHABETIC"; + key { [ u, U, backslash, NoSymbol, Home, Home, includedin, NoSymbol ] }; + key { [ i, I, slash, Greek_iota, Left, Left, integral, NoSymbol ] }; + key { [ a, A, braceleft, Greek_alpha, Down, Down, U2200, NoSymbol ] }; + key { [ e, E, braceright, Greek_epsilon, Right, Right, U2203, NoSymbol ] }; + key { [ o, O, asterisk, Greek_omicron, End, End, elementof, NoSymbol ] }; + + key { [ s, S, question, Greek_sigma, questiondown, NoSymbol, Greek_SIGMA, NoSymbol ] }; + key { [ n, N, parenleft, Greek_nu, KP_4, KP_4, U2115, NoSymbol ] }; + key { [ r, R, parenright, Greek_rho, KP_5, KP_5, U211D, NoSymbol ] }; + key { [ t, T, minus, Greek_tau, KP_6, KP_6, partialderivative, NoSymbol ] }; + key { [ d, D, colon, Greek_delta, KP_Separator, comma, Greek_DELTA, NoSymbol ] }; + + key { [ y, Y, at, Greek_upsilon, period, KP_Decimal, nabla, NoSymbol ] }; + + // Bottom row + // -------------------------------------------------------------- + key { [ udiaeresis, Udiaeresis, numbersign, NoSymbol, Escape, Escape, union, NoSymbol ] }; + key { [ odiaeresis, Odiaeresis, dollar, U03F5, Tab, Tab, intersection, NoSymbol ] }; + key { [ adiaeresis, Adiaeresis, bar, Greek_eta, Insert, Insert, U2135, NoSymbol ] }; + key { [ p, P, asciitilde, Greek_pi, Return, Return, Greek_PI, NoSymbol ] }; + key { [ z, Z, grave, Greek_zeta, Undo, Redo, U2124, NoSymbol ] }; + + key { [ b, B, plus, Greek_beta, colon, NoSymbol, U21D0, NoSymbol ] }; + key { [ m, M, percent, Greek_mu, KP_1, KP_1, ifonlyif, NoSymbol ] }; + key.type[Group1] = "EIGHT_LEVEL"; + key { [ comma, endash, quotedbl, U03F1, KP_2, KP_2, U21D2, NoSymbol ] }; + key { [ period, enfilledcircbullet, apostrophe, U03D1, KP_3, KP_3, U21A6, NoSymbol ] }; + key.type[Group1] = "EIGHT_LEVEL_SEMIALPHABETIC"; + key { [ j, J, semicolon, Greek_theta, semicolon, NoSymbol, Greek_THETA, NoSymbol ] }; + key.type[Group1] = "EIGHT_LEVEL"; + + // Space key + // -------------------------------------------------------------- + key { [ space, space, space, nobreakspace, KP_0, KP_0, U202F, NoSymbol ] }; + + + // Keypad-keys + // =============== + + // The former Numlock key: + key { [ Tab, ISO_Left_Tab, equal, approxeq, notequal, Pointer_EnableKeys, identical, NoSymbol ] }; + + // Topmost row + // -------------------------------------------------------------- + key { [ KP_Divide, KP_Divide, division, U2300, U2215, NoSymbol, U2223, NoSymbol ] }; + key { [ KP_Multiply, KP_Multiply, U22C5, U2299, multiply, NoSymbol, U2297, NoSymbol ] }; + key { [ KP_Subtract, KP_Subtract, U2212, U2296, U2216, NoSymbol, U2238, NoSymbol ] }; + + // Top row + // -------------------------------------------------------------- + key { [ KP_7, U2714, U2195, U226A, KP_Home, KP_Home, upstile, NoSymbol ] }; + key { [ KP_8, U2718, uparrow, intersection, KP_Up, KP_Up, U22C2, NoSymbol ] }; + key { [ KP_9, dagger, U20D7, U226B, KP_Prior, KP_Prior, U2309, NoSymbol ] }; + key { [ KP_Add, KP_Add, plusminus, U2295, U2213, NoSymbol, U2214, NoSymbol ] }; + + // Middle row + // -------------------------------------------------------------- + key { [ KP_4, club, leftarrow, includedin, KP_Left, KP_Left, U2286, NoSymbol ] }; + key { [ KP_5, EuroSign, colon, U22B6, KP_Begin, KP_Begin, U22B7, NoSymbol ] }; + key { [ KP_6, U2023, rightarrow, includes, KP_Right, KP_Right, U2287, NoSymbol ] }; + + // Bottom row + // -------------------------------------------------------------- + key { [ KP_1, diamond, U2194, lessthanequal, KP_End, KP_End, downstile, NoSymbol ] }; + key { [ KP_2, heart, downarrow, union, KP_Down, KP_Down, U22C3, NoSymbol ] }; + key { [ KP_3, U2660, U21CC, greaterthanequal, KP_Next, KP_Next, U230B, NoSymbol ] }; + key { [ KP_Enter, KP_Enter, KP_Enter, KP_Enter, KP_Enter, KP_Enter, KP_Enter, NoSymbol ] }; + key { [ KP_Equal, NoSymbol, NoSymbol, NoSymbol, NoSymbol, NoSymbol, NoSymbol, NoSymbol ] }; + + // Bottommost row + // -------------------------------------------------------------- + key { [ KP_0, U2423, percent, U2030, KP_Insert, KP_Insert, U25A1, NoSymbol ] }; + key { [ KP_Separator, period, comma, minutes, KP_Delete, KP_Delete, seconds, NoSymbol ] }; + + // The above is the full Neo 2 layout. What follows are the customizations + // that make most of the letters of a standard German layout available. + + // latin(basic) + + + key { [ q, Q ] }; + key { [ w, W ] }; + key { [ e, E ] }; + key { [ r, R ] }; + key { [ t, T ] }; + key { [ y, Y ] }; + key { [ u, U ] }; + key { [ i, I ] }; + key { [ o, O ] }; + key { [ p, P ] }; + key { [udiaeresis, Udiaeresis ] }; + + key { [ a, A ] }; + key { [ s, S ] }; + key { [ d, D ] }; + key { [ f, F ] }; + key { [ g, G ] }; + key { [ h, H ] }; + key { [ j, J ] }; + key { [ k, K ] }; + key { [ l, L ] }; + key { [ colon, semicolon ] }; + key { [apostrophe, quotedbl ] }; + + + key { [ z, Z ] }; + key { [ x, X ] }; + key { [ c, C ] }; + key { [ v, V ] }; + key { [ b, B ] }; + key { [ n, N ] }; + key { [ m, M ] }; + key { [ slash, backslash, question, questiondown ] }; + + // latin(type4) + + // Modified to have minus and emdash where you would find minus on a QWERTY + // layout. + // Neo 2: key { [ j, J ] } + // Neo 2: key { [ minus, emdash ] } + key { [plus, equal ] }; + + name[Group1]="German (QWERTY/Neo 2)"; + + include "shift(both_capslock)" + include "level3(caps_switch)" + include "level5(lsgt_switch)" + include "level5(ralt_switch)" + +}; diff --git a/nixos/common/remote_access.nix b/nixos/common/remote_access.nix new file mode 100644 index 0000000..1fbea6e --- /dev/null +++ b/nixos/common/remote_access.nix @@ -0,0 +1,24 @@ +# SPDX-FileCopyrightText: 2022 Richard Brežák +# +# SPDX-License-Identifier: LGPL-3.0-or-later +{ + lib, + ... +}: +let + inherit (lib) + singleton; +in +{ + nix.settings.trusted-users = singleton "@wheel"; + + services.openssh = { + enable = true; + settings = { + PasswordAuthentication = false; + PermitRootLogin = "no"; + AcceptEnv = "INSIDE_EMACS"; + StreamLocalBindUnlink = true; + }; + }; +} diff --git a/nixos/common/sound.nix b/nixos/common/sound.nix new file mode 100644 index 0000000..30f691c --- /dev/null +++ b/nixos/common/sound.nix @@ -0,0 +1,14 @@ +{ secret, ... }: +{ + security.rtkit.enable = true; + services.pipewire = { + enable = true; + + wireplumber.enable = true; + + alsa.enable = true; + alsa.support32Bit = true; + jack.enable = true; + pulse.enable = true; + }; +} diff --git a/nixos/common/steam.nix b/nixos/common/steam.nix new file mode 100644 index 0000000..916e23c --- /dev/null +++ b/nixos/common/steam.nix @@ -0,0 +1,18 @@ +{ pkgs, lib, ... }: +{ + programs.gamemode.enable = true; + + environment.systemPackages = [ + pkgs.mangohud + ]; + + programs.steam = { + enable = true; + remotePlay.openFirewall = true; + }; + + services.udev.extraRules = '' + ACTION=="add", SUBSYSTEM=="block", ENV{ID_PART_ENTRY_UUID}=="a7588d17-2c04-4bb7-8c10-b2aaeed1826c" RUN{program}+="${pkgs.systemd}/bin/systemd-mount --no-block $devnode /media/steam_library" + ACTION=="remove", SUBSYSTEM=="block", ENV{ID_PART_ENTRY_UUID}=="a7588d17-2c04-4bb7-8c10-b2aaeed1826c" RUN{program}+="${pkgs.systemd}/bin/systemctl stop media-steam_library.mount" + ''; +} diff --git a/nixos/common/users.nix b/nixos/common/users.nix new file mode 100644 index 0000000..91de664 --- /dev/null +++ b/nixos/common/users.nix @@ -0,0 +1,24 @@ +{ secret, ... }: +{ + users = { + mutableUsers = false; + + users.root.hashedPassword = secret.passwordHashes.main or ""; + users.main = { + isNormalUser = true; + home = "/home/main"; + hashedPassword = secret.passwordHashes.main or ""; + description = "main"; + + uid = 1000; + + extraGroups = ["wheel" "audio"]; + + openssh.authorizedKeys.keys = ["ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFVkFvalffJ/SMjJGG3WPiqCqFygnWzhGUaeALBIoCsJ (none)"]; + }; + + groups.main = { + gid = 1000; + }; + }; +} diff --git a/nixos/common/xserver.nix b/nixos/common/xserver.nix new file mode 100644 index 0000000..a73c9d9 --- /dev/null +++ b/nixos/common/xserver.nix @@ -0,0 +1,47 @@ +{ pkgs, lib, ... }: +let + inherit (lib) + getExe; +in +{ + services.xserver = { + enable = true; + + windowManager = { + xmonad.enable = true; + xmonad.enableContribAndExtras = true; + }; + + displayManager = { + lightdm.enable = true; + defaultSession = "none+xmonad"; + }; + + libinput = { + enable = true; + }; + + layout = "de,de,mine,us"; + xkbVariant = "koy,neo_qwerty,mine,"; + xkbOptions = "ctrl:swap_lalt_lctl_lwin, altwin:menu_win, grp:sclk_toggle"; + + extraLayouts."neo_qwerty" = { + description = "QWERTY neo2 layout."; + languages = ["de"]; + symbolsFile = ./qwerty_neo.xkb; + }; + + extraLayouts."mine" = { + description = "mine neo layout."; + languages = ["de"]; + symbolsFile = ./mine.xkb; + }; + }; + + hardware = { + opengl.enable = true; + opengl.driSupport32Bit = true; + }; + + console.useXkbConfig = true; +} diff --git a/nixos/modules/hashicorp.nix b/nixos/modules/hashicorp.nix new file mode 100644 index 0000000..c7a104d --- /dev/null +++ b/nixos/modules/hashicorp.nix @@ -0,0 +1,174 @@ +{ config, pkgs, lib, ... }: +with lib; +let + format = pkgs.formats.json { }; + + hashiServiceModule = + { config, ... }: + let + cfg' = config; + in + { + options = { + enable = mkEnableOption "Enable HashiCorp service"; + + package = mkOption { + type = with types; + package; + }; + + settings = mkOption { + type = format.type; + default = {}; + }; + + settingsFile = mkOption { + type = with types; + path; + default = format.generate "${cfg'.package.pname}.json" cfg'.settings; + }; + + command = mkOption { + type = with types; + str; + default = + let + switch = + { "nomad" = "agent"; + "vault" = "server"; + "vault-bin" = "server"; + "consul" = "agent"; + }; + in switch.${cfg'.package.pname} or ""; + }; + + extraSettingsPaths = mkOption { + type = with types; + listOf path; + default = []; + }; + + extraPluginPaths = mkOption { + type = with types; + listOf path; + default = []; + }; + + extraArguments = mkOption { + type = with types; + listOf str; + default = []; + }; + + extraPackages = mkOption { + type = with types; + listOf package; + default = with pkgs; + let + switch = + { "nomad" = [ coreutils iproute2 iptables ]; + "vault" = [ ]; + "vault-bin" = [ ]; + "consul" = [ ]; + }; + in + switch.${cfg'.package.pname} or []; + }; + + dynamic = mkOption { + type = with types; + nullOr package; + default = null; + }; + }; + }; + + cfg = config.services.hashicorp; +in +{ + options.services.hashicorp = mkOption { + type = with types; + attrsOf (submodule hashiServiceModule); + default = {}; + }; + + config.environment.etc = flip mapAttrs' (filterAttrs (_: v: v.enable) cfg) + (name: value: + nameValuePair + "${name}.d/main.json" + { source = value.settingsFile; } + ); + + config.systemd.services = zipAttrsWith (const head) + [ (flip mapAttrs' (filterAttrs (_: v: v.enable) cfg) + (name: value: + let + configOpt = + let + switch = + { "nomad" = "--config"; + "consul" = "--config-file"; + "vault" = "--config"; + "vault-bin" = "--config"; + }; + in + switch.${value.package.pname} or ""; + in + nameValuePair + ("hashicorp-" + name) + { description = name; + + wantedBy = [ "multi-user.target" ]; + wants = [ "network-online.target" ]; + after = [ "network-online.target" ]; + + path = value.extraPackages; + + restartIfChanged = false; + + serviceConfig = + { ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID"; + ExecStart = "${value.package}/bin/${value.package.meta.mainProgram or value.package.pname} ${value.command} " + + (optionalString (value.package.pname != "vault" || value.command != "agent") "${configOpt}=/etc/${name}.d ") + + "${concatMapStringsSep " " (v: "${configOpt}=${v}") value.extraSettingsPaths} " + + "${concatMapStringsSep " " (v: "--plugin-dir=${v}/bin") value.extraPluginPaths} " + + (optionalString (value.package.pname == "vault" && value.command == "agent") "${configOpt}=/etc/${name}.d/main.json ") + + "${concatStringsSep " " value.extraArguments} "; + + KillMode = "process"; + KillSignal = "SIGINT"; + LimitNOFILE = 65536; + LimitNPROC = "infinity"; + OOMScoreAdjust = -1000; + Restart = "always"; + RestartSec = 2; + TasksMax = "infinity"; + + StateDirectory = value.package.pname; + }; + } + )) + (flip mapAttrs' (filterAttrs (_: v: v.enable && v.dynamic != null) cfg) + (name: value: + nameValuePair + ("hashicorp-${name}-dynamic") + { description = name; + + wantedBy = [ "hashicorp-${name}.service" ]; + wants = [ "network-online.target" ]; + after = [ "network-online.target" ]; + before = [ "hashicorp-${name}.service" ]; + + path = value.extraPackages; + + restartIfChanged = true; + + serviceConfig = + { ExecStart = value.dynamic; + RemainAfterExit = true; + Type = "oneshot"; + }; + } + )) + ]; +} diff --git a/nixos/systems/heater/default.nix b/nixos/systems/heater/default.nix new file mode 100644 index 0000000..71ddba9 --- /dev/null +++ b/nixos/systems/heater/default.nix @@ -0,0 +1,58 @@ +# SPDX-FileCopyrightText: 2022 Richard Brežák +# +# SPDX-License-Identifier: LGPL-3.0-or-later +{ inputs, lib, config, secret, ... }: +let + inherit (lib) + flip + mapAttrs + singleton; + + config' = config; +in +{ + flake.nixosConfigurations.heater = inputs.nixpkgs.lib.nixosSystem { + system = "x86_64-linux"; + + specialArgs = { + config' = config'; + inputs' = inputs; + secret = + if builtins.pathExists "${inputs.secret}/default.nix" then + import inputs.secret { inherit lib; } + else + {}; + }; + modules = singleton + ({ pkgs, config, ... }: + { + imports = [ + ./xserver.nix + ../../common/steam.nix + ./grub.nix + ./networking.nix + ./filesystems.nix + ./hardware.nix + ./users.nix + ./nixpkgs.nix + ../../common/sound.nix + ]; + + _module.args.nixinate = { + host = secret.network.ips.heater or ""; + sshUser = "main"; + buildOn = "local"; + substituteOnTarget = true; + hermetic = false; + nixOptions = [ + "--override-input secret path://$HOME/dotfiles/secret" + ]; + }; + + services.fwupd.enable = true; + + time.timeZone = "Europe/Amsterdam"; + system.stateVersion = "20.09"; + }); + }; +} diff --git a/nixos/systems/heater/filesystems.nix b/nixos/systems/heater/filesystems.nix new file mode 100644 index 0000000..0948d91 --- /dev/null +++ b/nixos/systems/heater/filesystems.nix @@ -0,0 +1,79 @@ +{ secret, ... }: +let + nfsOptions = [ + "noauto" + "X-mount.mkdir" + "x-systemd.device-timeout=10" + "timeo=14" + "soft" + "noatime" + "x-systemd.after=wireguard-wg0.target" + "x-systemd.wants=wireguard-wg0.target" + ]; + + blowholeAddress = secret.network.ips.blowhole.dns or ""; +in +{ + fileSystems = { + "/" = { + device = "heater-zpool/local/root"; + fsType = "zfs"; + }; + + "/nix" = { + device = "heater-zpool/local/nix"; + fsType = "zfs"; + }; + + "/home" = { + device = "heater-zpool/safe/home"; + fsType = "zfs"; + }; + + "/var/lib/nomad" = { + device = "heater-zpool/persist/nomad"; + fsType = "zfs"; + }; + + "/var/lib/syncthing" = { + device = "heater-zpool/persist/syncthing"; + fsType = "zfs"; + }; + + "/etc/vault-agent" = { + device = "heater-zpool/persist/vault-agent"; + fsType = "zfs"; + }; + + "/boot" = { + device = "/dev/disk/by-uuid/5e590840-9e62-4231-8ac5-e6a27325254d"; + fsType = "ext4"; + }; + + "/boot/EFI" = { + device = "/dev/disk/by-uuid/D381-9D12"; + fsType = "vfat"; + }; + + "/mnt/cartman" = { + device = "${blowholeAddress}:/mnt/cartman"; + fsType = "nfs"; + options = nfsOptions; + }; + + "/mnt/kyle" = { + device = "${blowholeAddress}:/mnt/kyle"; + fsType = "nfs"; + options = nfsOptions; + + }; + + "/mnt/stan" = { + device = "${blowholeAddress}:/mnt/stan"; + fsType = "nfs"; + options = nfsOptions; + }; + }; + + swapDevices = []; +} diff --git a/nixos/systems/heater/grub.nix b/nixos/systems/heater/grub.nix new file mode 100644 index 0000000..1c7c68c --- /dev/null +++ b/nixos/systems/heater/grub.nix @@ -0,0 +1,14 @@ +{ pkgs, lib, ... }: +{ + boot.loader = { + systemd-boot.enable = false; + efi.canTouchEfiVariables = true; + efi.efiSysMountPoint = "/boot/EFI"; + + grub = { + enable = true; + efiSupport = true; + devices = [ "nodev" ]; + }; + }; +} diff --git a/nixos/systems/heater/hardware.nix b/nixos/systems/heater/hardware.nix new file mode 100644 index 0000000..fa55677 --- /dev/null +++ b/nixos/systems/heater/hardware.nix @@ -0,0 +1,44 @@ +# SPDX-FileCopyrightText: 2022 Richard Brežák +# +# SPDX-License-Identifier: LGPL-3.0-or-later +{ pkgs, lib, ... }: +let + inherit (lib) + singleton; + + kernelPackages = pkgs.linuxKernel.packages.linux_6_1; +in +{ + boot = { + initrd.availableKernelModules = [ + "xhci_pci" + "ahci" + "usbhid" + "usb_storage" + "sd_mod" + "nvme" + ]; + + initrd.kernelModules = []; + kernelModules = ["i2c-dev" "kvm-amd"]; + + kernelParams = [ + "zfs.zfs_arc_max=8589934592" + "zfs.zfs_arc_sys_free=3221225472" + ]; + kernelPackages = kernelPackages; + + zfs.enableUnstable = true; + supportedFilesystems = singleton "zfs"; + }; + + hardware.enableRedistributableFirmware = true; + hardware.nvidia.package = kernelPackages.nvidia_x11_beta; + + hardware.nvidia = { + nvidiaPersistenced = true; + powerManagement.enable = true; + + modesetting.enable = true; + }; +} diff --git a/nixos/systems/heater/networking.nix b/nixos/systems/heater/networking.nix new file mode 100644 index 0000000..8498b07 --- /dev/null +++ b/nixos/systems/heater/networking.nix @@ -0,0 +1,9 @@ +{ pkgs, lib, inputs', secret, ... }: +{ + networking = { + hostName = "heater"; + useDHCP = false; + interfaces.enp3s0.useDHCP = true; + hostId = "3457b383"; + }; +} diff --git a/nixos/systems/heater/nixpkgs.nix b/nixos/systems/heater/nixpkgs.nix new file mode 100644 index 0000000..75e6780 --- /dev/null +++ b/nixos/systems/heater/nixpkgs.nix @@ -0,0 +1,19 @@ +{ inputs', config', ... }: +{ + imports = [ + ../../common/nixpkgs.nix + ]; + + nixpkgs.overlays = + (with config'.flake.overlays; [ + emacsclient-remote + magic-screenshot + emacs-rofi + tree-sitter-grammars + emacs-master-nativecomp + ]) + ++ + (with inputs'.nixng.overlays; [ + default + ]); +} diff --git a/nixos/systems/heater/users.nix b/nixos/systems/heater/users.nix new file mode 100644 index 0000000..97f95f0 --- /dev/null +++ b/nixos/systems/heater/users.nix @@ -0,0 +1,19 @@ +{ config', inputs', secret, ... }: +{ + imports = [ + inputs'.home-manager.nixosModules.default + ../../common/users.nix + ]; + + home-manager.useGlobalPkgs = true; + home-manager.extraSpecialArgs = { + config' = config'; + inputs' = inputs'; + secret = secret; + }; + home-manager.users.main = { + imports = [ (inputs'.self + "/home-manager/modules/profiles/workstation.nix") ]; + + home.stateVersion = "21.05"; + }; +} diff --git a/nixos/systems/heater/xserver.nix b/nixos/systems/heater/xserver.nix new file mode 100644 index 0000000..59a6468 --- /dev/null +++ b/nixos/systems/heater/xserver.nix @@ -0,0 +1,12 @@ +{ pkgs, lib, ... }: +let + inherit (lib) + getExe; +in +{ + imports = [ + ../../common/xserver.nix + ]; + + services.xserver.videoDrivers = [ "nvidia" ]; +} diff --git a/nixos/systems/liveusb/default.nix b/nixos/systems/liveusb/default.nix new file mode 100644 index 0000000..9e3ea7b --- /dev/null +++ b/nixos/systems/liveusb/default.nix @@ -0,0 +1,61 @@ +# SPDX-FileCopyrightText: 2022 Richard Brežák +# +# SPDX-License-Identifier: LGPL-3.0-or-later +{ inputs, lib, config, ... }: +let + inherit (lib) + flip + mapAttrs + singleton; + + config' = config; +in +{ + flake.nixosConfigurations.liveusb = inputs.nixpkgs.lib.nixosSystem { + system = "x86_64-linux"; + + specialArgs = { + config' = config'; + inputs' = inputs; + secret = + if builtins.pathExists "${inputs.secret}/default.nix" then + import inputs.secret { inherit lib; } + else + {}; + }; + + modules = singleton + ({ pkgs, config, ... }: + { + imports = [ + "${inputs.nixpkgs}/nixos/modules/installer/cd-dvd/installation-cd-graphical-base.nix" + ../../common/nixpkgs.nix + ]; + + isoImage.edition = "xfce"; + + services.xserver.videoDrivers = [ "nvidia" ]; + + boot.supportedFilesystems = singleton "zfs"; + + boot.kernelPackages = pkgs.linuxKernel.packages.linux_6_1; + boot.kernelParams = [ + "nvidia.NVreg_EnableS0ixPowerManagement=1" + "nvidia.NVreg_S0ixPowerManagementVideoMemoryThreshold=2048" + ]; + + hardware.nvidia = { + powerManagement.enable = true; + package = config.boot.kernelPackages.nvidia_x11_beta; + }; + + services.xserver = { + desktopManager = { + xterm.enable = false; + xfce.enable = true; + }; + displayManager.defaultSession = "xfce"; + }; + }); + }; +} diff --git a/nixos/systems/omen/0001-Revert-nvme-pci-avoid-the-deepest-sleep-state-on-Kin.patch b/nixos/systems/omen/0001-Revert-nvme-pci-avoid-the-deepest-sleep-state-on-Kin.patch new file mode 100644 index 0000000..12b58d8 --- /dev/null +++ b/nixos/systems/omen/0001-Revert-nvme-pci-avoid-the-deepest-sleep-state-on-Kin.patch @@ -0,0 +1,16 @@ +diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c +index 492f319eb..587f054f0 100644 +--- a/drivers/nvme/host/pci.c ++++ b/drivers/nvme/host/pci.c +@@ -3400,10 +3400,6 @@ static const struct pci_device_id nvme_id_table[] = { + .driver_data = NVME_QUIRK_DISABLE_WRITE_ZEROES, }, + { PCI_DEVICE(0x1cc4, 0x6302), /* UMIS RPJTJ256MGE1QDY 256G */ + .driver_data = NVME_QUIRK_DISABLE_WRITE_ZEROES, }, +- { PCI_DEVICE(0x2646, 0x2262), /* KINGSTON SKC2000 NVMe SSD */ +- .driver_data = NVME_QUIRK_NO_DEEPEST_PS, }, +- { PCI_DEVICE(0x2646, 0x2263), /* KINGSTON A2000 NVMe SSD */ +- .driver_data = NVME_QUIRK_NO_DEEPEST_PS, }, + { PCI_DEVICE(0x2646, 0x5018), /* KINGSTON OM8SFP4xxxxP OS21012 NVMe SSD */ + .driver_data = NVME_QUIRK_DISABLE_WRITE_ZEROES, }, + { PCI_DEVICE(0x2646, 0x5016), /* KINGSTON OM3PGP4xxxxP OS21011 NVMe SSD */ + diff --git a/nixos/systems/omen/default.nix b/nixos/systems/omen/default.nix new file mode 100644 index 0000000..3d953fd --- /dev/null +++ b/nixos/systems/omen/default.nix @@ -0,0 +1,78 @@ +# SPDX-FileCopyrightText: 2022 Richard Brežák +# +# SPDX-License-Identifier: LGPL-3.0-or-later +{ inputs, lib, config, secret, ... }: +let + inherit (lib) + flip + mapAttrs + singleton; + + config' = config; +in +{ + flake.nixosConfigurations.omen = inputs.nixpkgs.lib.nixosSystem { + system = "x86_64-linux"; + + specialArgs = { + config' = config'; + inputs' = inputs; + secret = + if builtins.pathExists "${inputs.secret}/default.nix" then + import inputs.secret { inherit lib; } + else + {}; + }; + + modules = singleton + ({ pkgs, config, ... }: + { + imports = [ + ./xserver.nix + ./udp2tcp.nix + ../../common/steam.nix + ./grub.nix + ./networking.nix + ./filesystems.nix + ./hardware.nix + ./users.nix + ./nixpkgs.nix + ../../common/sound.nix + + inputs.dwarffs.nixosModules.dwarffs + ]; + + _module.args.nixinate = { + host = secret.network.ips.omen.vpn or ""; + sshUser = "main"; + buildOn = "local"; + substituteOnTarget = true; + hermetic = false; + nixOptions = [ + "--override-input secret path://$HOME/dotfiles/secret" + ]; + }; + + services.fwupd.enable = true; + + services.syncthing = { + enable = true; + user = "main"; + group = "main"; + }; + + services.sshd.enable = true; + + # Makes QEMU recompile https://github.com/NixOS/nixpkgs/issues/221056 + # boot.binfmt.emulatedSystems = [ + # "aarch64-linux" + # "riscv64-linux" + # ]; + + time.timeZone = "Europe/Amsterdam"; + system.stateVersion = "20.09"; + + virtualisation.podman.enable = true; + }); + }; +} diff --git a/nixos/systems/omen/filesystems.nix b/nixos/systems/omen/filesystems.nix new file mode 100644 index 0000000..4427baa --- /dev/null +++ b/nixos/systems/omen/filesystems.nix @@ -0,0 +1,71 @@ +{ secret, ... }: +let + nfsOptions = [ + "noauto" + "X-mount.mkdir" + "x-systemd.device-timeout=10" + "timeo=14" + "soft" + "noatime" + "x-systemd.after=wireguard-wg0.target" + "x-systemd.wants=wireguard-wg0.target" + ]; + + blowholeAddress = secret.network.ips.blowhole.dns or ""; +in +{ + fileSystems = { + "/" = { + device = "omen-ssd/local/root"; + fsType = "zfs"; + }; + "/nix" = { + device = "omen-ssd/local/nix"; + fsType = "zfs"; + }; + "/home" = { + device = "omen-ssd/safe/home"; + fsType = "zfs"; + }; + + "/boot" = { + device = "/dev/disk/by-uuid/078c1885-5e0c-4bb8-bec3-5bf40785f5cd"; + fsType = "ext4"; + }; + "/boot/EFI" = { + device = "/dev/disk/by-uuid/6F1E-8B1B"; + fsType = "vfat"; + }; + + "/var/lib/secrets" = { + device = "omen-ssd/local/secrets"; + fsType = "zfs"; + }; + + "/mnt/net/kyle" = { + fsType = "nfs"; + device = "${blowholeAddress}:/mnt/kyle"; + options = nfsOptions; + }; + "/mnt/net/cartman" = { + fsType = "nfs"; + device = "${blowholeAddress}:/mnt/cartman"; + options = nfsOptions; + }; + "/mnt/net/stan" = { + fsType = "nfs"; + device = "${blowholeAddress}:/mnt/stan"; + options = nfsOptions; + }; + "/mnt/net/getmail.d" = { + fsType = "nfs"; + device = "${blowholeAddress}:/var/nfs/getmail/getmail.d"; + options = nfsOptions; + }; + "/mnt/net/mail-configuration" = { + fsType = "nfs"; + device = "${blowholeAddress}:/var/nfs/mail-configuration"; + options = nfsOptions; + }; + }; +} diff --git a/nixos/systems/omen/grub.nix b/nixos/systems/omen/grub.nix new file mode 100644 index 0000000..1c7c68c --- /dev/null +++ b/nixos/systems/omen/grub.nix @@ -0,0 +1,14 @@ +{ pkgs, lib, ... }: +{ + boot.loader = { + systemd-boot.enable = false; + efi.canTouchEfiVariables = true; + efi.efiSysMountPoint = "/boot/EFI"; + + grub = { + enable = true; + efiSupport = true; + devices = [ "nodev" ]; + }; + }; +} diff --git a/nixos/systems/omen/hardware.nix b/nixos/systems/omen/hardware.nix new file mode 100644 index 0000000..a2f5982 --- /dev/null +++ b/nixos/systems/omen/hardware.nix @@ -0,0 +1,109 @@ +# SPDX-FileCopyrightText: 2022 Richard Brežák +# +# SPDX-License-Identifier: LGPL-3.0-or-later +{ pkgs, lib, inputs', ... }: +let + inherit (lib) + singleton + mkForce; + + kernelPackages = + pkgs.linuxKernel.packages.linux_xanmod_latest.extend (final: prev: + { + zfsUnstable = + let + unstableNix = + { callPackage + , kernel ? null + , stdenv + , linuxKernel + , ... + } @ args: + + let + stdenv' = if kernel == null then stdenv else kernel.stdenv; + in + callPackage "${inputs'.nixpkgs}/pkgs/os-specific/linux/zfs/generic.nix" args { + # check the release notes for compatible kernels + # NOTE: + # zfs-2.1.9<=x<=2.1.10 is broken with aarch64-linux-6.2 + # for future releases, please delete this condition. + kernelCompatible = kernel.kernelOlder "6.4"; + latestCompatibleLinuxPackages = linuxKernel.packages.linux_6_3; + + # this package should point to a version / git revision compatible with the latest kernel release + # IMPORTANT: Always use a tagged release candidate or commits from the + # zfs--staging branch, because this is tested by the OpenZFS + # maintainers. + version = "zfs-2.1.12"; + rev = "86783d7d92cf7a859464719a917fdff845b9a9e1"; + + sha256 = "sha256-eYUR5d4gpTrlFu6j1uL83DWL9uPGgAUDRdSEb73V5i4="; + + isUnstable = true; + }; + in + prev.callPackage unstableNix { + configFile = "kernel"; + }; + } + ); +in +{ + environment.systemPackages = [ + kernelPackages.turbostat + ]; + + hardware.cpu.intel.updateMicrocode = true; + + boot = { + initrd.availableKernelModules = [ + "xhci_pci" + "ahci" + "usb_storage" + "sr_mod" + "rtsx_pci_sdmmc" + "nvme" + "vmd" + ]; + initrd.kernelModules = []; + kernelModules = singleton "kvm-intel"; + + kernelParams = [ + "zfs.zfs_arc_max=8589934592" + "zfs.zfs_arc_sys_free=3221225472" + # "intel_pstate=active" + "nvidia.NVreg_EnableS0ixPowerManagement=1" + "nvidia.NVreg_S0ixPowerManagementVideoMemoryThreshold=2048" + # "nvme.noacpi=1" + "nvme_core.default_ps_max_latency_us=30000" + ]; + kernelPackages = kernelPackages; + kernelPatches = [ + { + name = "nvme-kingston-sleep"; + patch = ./0001-Revert-nvme-pci-avoid-the-deepest-sleep-state-on-Kin.patch; + } + ]; + + zfs.enableUnstable = true; + supportedFilesystems = singleton "zfs"; + }; + + hardware.enableRedistributableFirmware = true; + hardware.nvidia.package = kernelPackages.nvidia_x11_beta; + + hardware.tuxedo-keyboard.enable = true; + + hardware.nvidia = { + nvidiaPersistenced = true; + + powerManagement.enable = true; + powerManagement.finegrained = true; + + prime.reverseSync.enable = true; + prime.offload.enable = true; + + modesetting.enable = true; + }; +} diff --git a/nixos/systems/omen/networking.nix b/nixos/systems/omen/networking.nix new file mode 100644 index 0000000..6aefd12 --- /dev/null +++ b/nixos/systems/omen/networking.nix @@ -0,0 +1,19 @@ +{ pkgs, lib, inputs', secret, ... }: +{ + networking = { + hostName = "omen"; + useDHCP = false; + # interfaces.eno1.useDHCP = true; + hostId = "10c7ffc5"; + networkmanager.dns = "none"; + nameservers = [ "10.64.2.1" ]; + + firewall.allowedTCPPorts = [22000]; + + wireguard.interfaces."wg0" = + secret.wireguard."omen" or { privateKey = ""; }; + }; + + networking.networkmanager.enable = true; + hardware.bluetooth.enable = true; +} diff --git a/nixos/systems/omen/nixpkgs.nix b/nixos/systems/omen/nixpkgs.nix new file mode 100644 index 0000000..3761fcd --- /dev/null +++ b/nixos/systems/omen/nixpkgs.nix @@ -0,0 +1,20 @@ +{ inputs', config', config, ... }: +{ + imports = [ + ../../common/nixpkgs.nix + ]; + + nixpkgs.overlays = + (with config'.flake.overlays; [ + udp-over-tcp + emacsclient-remote + magic-screenshot + emacs-rofi + tree-sitter-grammars + emacs-master-nativecomp + ]) + ++ + (with inputs'.nixng.overlays; [ + default + ]); +} diff --git a/nixos/systems/omen/udp2tcp.nix b/nixos/systems/omen/udp2tcp.nix new file mode 100644 index 0000000..995d397 --- /dev/null +++ b/nixos/systems/omen/udp2tcp.nix @@ -0,0 +1,110 @@ +{ pkgs, lib, ... }: +let + inherit (lib) + makeBinPath; +in +{ + systemd.services.udp2tcp = { + wantedBy = [ "multi-user.target" ]; + after = [ "network.target" ]; + + path = with pkgs; [ dig.host ]; + + restartIfChanged = true; + + script = '' + ${pkgs.udp-over-tcp}/bin/udp2tcp\ + --udp-listen 127.0.0.1:6665 \ + --tcp-forward "64.225.104.221:6001" + ''; + }; + + systemd.services.udp2tcp-wake-restart = { + wantedBy = [ + "suspend.target" + "hibernate.target" + "hybrid-sleep.target" + "suspend-then-hibernate.target" + ]; + after = [ + "suspend.target" + "hibernate.target" + "hybrid-sleep.target" + "suspend-then-hibernate.target" + ]; + + script = '' + systemctl restart udp2tcp.service + ''; + }; + + networking.networkmanager.dispatcherScripts = [ + { + source = pkgs.writeShellScript "udp2tcp.sh" + '' + export PATH=${makeBinPath [ pkgs.wireguard-tools ]}:$PATH + _interface="$1" + _action="$2" + + echo "action: $_action interface: $_interface id: $CONNECTION_ID" + case "$_action" in + up) + case "$_interface" in + wlo1) + case "$CONNECTION_ID" in + VU-Campusnet) + wg set wg0 \ + peer h4g6vWjOB6RS0NbrP/Kvb2CZeutm/F+ZfDbJmEd1Dgk= \ + endpoint 127.0.0.1:6665 + systemctl restart udp2tcp.service + ;; + *) + wg set wg0 \ + peer h4g6vWjOB6RS0NbrP/Kvb2CZeutm/F+ZfDbJmEd1Dgk= \ + endpoint 64.225.104.221:6666 + systemctl stop udp2tcp.service + ;; + esac + ;; + *) + ;; + esac + ;; + down) + wg set wg0 \ + peer h4g6vWjOB6RS0NbrP/Kvb2CZeutm/F+ZfDbJmEd1Dgk= \ + endpoint 64.225.104.221:6666 + systemctl stop udp2tcp.service + ;; + *) + ;; + esac + ''; + } + { + source = pkgs.writeShellScript "nfs-mounts.sh" + '' + export PATH=${makeBinPath [ pkgs.iputils ]}:$PATH + + ping -c 1 -W 0.7 8.8.4.4 # > /dev/null 2>&1 + + if [ $? -eq 0 ] ; then + echo "Mounting network drives" + systemctl start mnt-net-kyle.mount \ + mnt-net-cartman.mount \ + mnt-net-stan.mount \ + mnt-net-getmail.d.mount \ + mnt-net-mail\\x2dconfiguration & + else + echo "Unmounting network drives" + umount -ql \ + /mnt/net/kyle \ + /mnt/net/cartman \ + /mnt/net/stan \ + /mnt/net/getmail.d \ + /mnt/net/mail-configuration & + fi + ''; + } + ]; +} diff --git a/nixos/systems/omen/users.nix b/nixos/systems/omen/users.nix new file mode 100644 index 0000000..64b482d --- /dev/null +++ b/nixos/systems/omen/users.nix @@ -0,0 +1,19 @@ +{ inputs', config', secret, ... }: +{ + imports = [ + inputs'.home-manager.nixosModules.default + ../../common/users.nix + ]; + + home-manager.useGlobalPkgs = true; + home-manager.extraSpecialArgs = { + config' = config'; + inputs' = inputs'; + secret = secret; + }; + home-manager.users.main = { + imports = [ (inputs'.self + "/home-manager/modules/profiles/workstation.nix") ]; + + home.stateVersion = "21.05"; + }; +} diff --git a/nixos/systems/omen/xserver.nix b/nixos/systems/omen/xserver.nix new file mode 100644 index 0000000..1dc9dda --- /dev/null +++ b/nixos/systems/omen/xserver.nix @@ -0,0 +1,22 @@ +{ pkgs, lib, ... }: +let + inherit (lib) + getExe; +in +{ + imports = [ + ../../common/xserver.nix + ]; + + services.xserver.videoDrivers = [ "nvidia" ]; + + services.xserver.libinput = { + touchpad.clickMethod = "clickfinger"; + touchpad.disableWhileTyping = true; + }; + + hardware.nvidia.prime = { + intelBusId = "PCI:0:2:0"; + nvidiaBusId = "PCI:1:0:0"; + }; +} diff --git a/nixos/systems/toothpick/consul.nix b/nixos/systems/toothpick/consul.nix new file mode 100644 index 0000000..9a9f982 --- /dev/null +++ b/nixos/systems/toothpick/consul.nix @@ -0,0 +1,56 @@ +{ inputs', lib, config, pkgs, secret, ... }: +let + inherit (lib) + mkForce + singleton; +in +{ + services.hashicorp.consul = { + enable = true; + + extraSettingsPaths = singleton "/run/secrets/consul.json"; + package = inputs'.nixpkgs-hashicorp.legacyPackages.${pkgs.stdenv.system}.consul; + + settings = { + datacenter = "do-1"; + data_dir = "/var/lib/consul"; + + retry_join_wan = singleton (secret.network.ips.blowhole.ip or ""); + + server = true; + + bind_addr = secret.network.ips.toothpick or ""; + client_addr = secret.network.ips.toothpick or ""; + + primary_datacenter = "homelab-1"; + + acl = { + enabled = true; + default_policy = "deny"; + enable_token_persistence = true; + enable_token_replication = true; + }; + + ports = { + http = 8500; + grpc = 8502; + }; + + ui_config.enabled = true; + + connect.enabled = true; + + # ca_file = "/var/secrets/consul-ca.crt"; + # cert_file = "" + # key_file = "" + verify_incoming = false; + verify_outgoing = false; + verify_server_hostname = false; + }; + }; + + systemd.services.hashicorp-consul.serviceConfig = { + LimitNOFILE = mkForce "infinity"; + LimitNPROC = mkForce "infinity"; + }; +} diff --git a/nixos/systems/toothpick/default.nix b/nixos/systems/toothpick/default.nix new file mode 100644 index 0000000..adcf4aa --- /dev/null +++ b/nixos/systems/toothpick/default.nix @@ -0,0 +1,65 @@ +# SPDX-FileCopyrightText: 2022 Richard Brežák +# +# SPDX-License-Identifier: LGPL-3.0-or-later +{ inputs, lib, config, ... }: +let + inherit (lib) + flip + mapAttrs + singleton; + + config' = config; +in +{ + flake.nixosConfigurations.toothpick = inputs.nixpkgs.lib.nixosSystem { + system = "x86_64-linux"; + + specialArgs = { + config' = config'; + inputs' = inputs; + secret = + if builtins.pathExists "${inputs.secret}/default.nix" then + import inputs.secret { inherit lib; } + else + {}; + }; + + modules = singleton + ({ pkgs, config, ... }: + { + imports = [ + ./consul.nix + ./nomad.nix + ./vault-agent.nix + ./u2t.nix + ./grub.nix + ./networking.nix + ./nixpkgs.nix + ./hardware.nix + ./filesystems.nix + ./users.nix + ../../common/remote_access.nix + + config'.flake.nixosModules.hashicorp + ]; + + _module.args.nixinate = { + host = "redalder.org"; + sshUser = "main"; + buildOn = "local"; + substituteOnTarget = true; + hermetic = false; + nixOptions = [ + "--override-input secret path://$HOME/dotfiles/secret" + ]; + }; + + environment.systemPackages = [ + pkgs.git + ]; + + time.timeZone = "Europe/Bratislava"; + system.stateVersion = "21.05"; + }); + }; +} diff --git a/nixos/systems/toothpick/filesystems.nix b/nixos/systems/toothpick/filesystems.nix new file mode 100644 index 0000000..e33ed48 --- /dev/null +++ b/nixos/systems/toothpick/filesystems.nix @@ -0,0 +1,7 @@ +{ ... }: +{ + fileSystems."/" = { + device = "/dev/vda1"; + fsType = "ext4"; + }; +} diff --git a/nixos/systems/toothpick/grub.nix b/nixos/systems/toothpick/grub.nix new file mode 100644 index 0000000..65e7d56 --- /dev/null +++ b/nixos/systems/toothpick/grub.nix @@ -0,0 +1,9 @@ +{ pkgs, lib, ... }: +{ + boot.loader.grub = { + enable = true; + device = "/dev/vda"; + version = 2; + efiSupport = false; + }; +} diff --git a/nixos/systems/toothpick/hardware.nix b/nixos/systems/toothpick/hardware.nix new file mode 100644 index 0000000..851e51b --- /dev/null +++ b/nixos/systems/toothpick/hardware.nix @@ -0,0 +1,8 @@ +{ inputs', ... }: +{ + imports = [ + (inputs'.nixpkgs + "/nixos/modules/profiles/qemu-guest.nix") + ]; + + boot.initrd.kernelModules = ["nvme"]; +} diff --git a/nixos/systems/toothpick/networking.nix b/nixos/systems/toothpick/networking.nix new file mode 100644 index 0000000..c00eba8 --- /dev/null +++ b/nixos/systems/toothpick/networking.nix @@ -0,0 +1,132 @@ +{ pkgs, lib, secret, ... }: +let + inherit (lib) + getExe; +in +{ + boot.kernel.sysctl = {"net.ipv4.ip_forward" = "1";}; + + # https://github.com/NixOS/nixpkgs/issues/76671 + # the rpc.statd daemon is not running when not mounting any nfs filesystems on boot + # and can't be manually started... + boot.supportedFilesystems = [ "nfs" ]; + services.rpcbind.enable = true; + + networking = { + hostName = "toothpick"; + + nameservers = [ + (secret.network.ips.blowhole.ip or "") + "93.184.77.2" + "67.207.67.3" + ]; + + wireguard = { + enable = true; + interfaces."wg0" = + { + postSetup = '' + ${getExe pkgs.iptables} -I FORWARD -i wg0 -o wg0 -j ACCEPT + ''; + + postShutdown = '' + ${getExe pkgs.iptables} -D FORWARD -i wg0 -o wg0 -j ACCEPT + ''; + } + // secret.wireguard."toothpick" or { privateKey = ""; }; + }; + + defaultGateway = "64.225.96.1"; + defaultGateway6 = ""; + dhcpcd.enable = false; + usePredictableInterfaceNames = lib.mkForce false; + + firewall = { + extraCommands = '' + iptables -P FORWARD DROP + ''; + + interfaces."eth0" = { + allowedTCPPorts = [ + 80 + 443 + 6001 + ]; + allowedUDPPorts = [ + 6666 + ]; + }; + + interfaces."nomad" = { + allowedTCPPorts = [ + 8500 + ]; + }; + + interfaces."wg0" = { + allowedTCPPorts = [ + ## Consul + 8600 # DNS + 8500 # HTTP + 8502 # gRPC + 8300 # server + 8301 # LAN serf + 8302 # WAN serf + 4646 # Nomad + 4647 + 4648 + 10000 + ]; + allowedTCPPortRanges = [ + { + from = 21000; + to = 21255; + } + ]; + allowedUDPPorts = [ + ## Consul + 8600 # DNS + 8301 # LAN serf + 8302 # WAN serf + ]; + allowedUDPPortRanges = [ + { + from = 21000; + to = 21255; + } + ]; + }; + }; + + interfaces = { + eth0 = { + ipv4.addresses = [ + { + address = "64.225.104.221"; + prefixLength = 20; + } + { + address = "10.19.0.6"; + prefixLength = 16; + } + ]; + ipv6.addresses = [ + { + address = "fe80::8ce0:84ff:fefb:f981"; + prefixLength = 64; + } + ]; + ipv4.routes = [ + { + address = "64.225.96.1"; + prefixLength = 32; + } + ]; + }; + }; + }; + + services.udev.extraRules = '' + ATTR{address}=="8e:e0:84:fb:f9:81", NAME="eth0" + ''; +} diff --git a/nixos/systems/toothpick/nixpkgs.nix b/nixos/systems/toothpick/nixpkgs.nix new file mode 100644 index 0000000..fe5d3bc --- /dev/null +++ b/nixos/systems/toothpick/nixpkgs.nix @@ -0,0 +1,16 @@ +{ inputs', config', ... }: +{ + imports = [ + ../../common/nixpkgs.nix + ]; + + nixpkgs.overlays = + (with config'.flake.overlays; [ + udp-over-tcp + emacsclient-remote + ]) + ++ + (with inputs'.nixng.overlays; [ + default + ]); +} diff --git a/nixos/systems/toothpick/nomad.nix b/nixos/systems/toothpick/nomad.nix new file mode 100644 index 0000000..6395b22 --- /dev/null +++ b/nixos/systems/toothpick/nomad.nix @@ -0,0 +1,132 @@ +{ lib, config, config', pkgs, inputs', secret, ... }: +{ + services.hashicorp.nomad = { + enable = true; + + extraPackages = with pkgs; [ + coreutils + iproute2 + iptables + consul + glibc + config.nix.package + git + ]; + extraSettingsPaths = [ + "/run/secrets/nomad.json" + ]; + package = inputs'.nixpkgs-hashicorp.legacyPackages.${pkgs.stdenv.system}.nomad_1_5.overrideAttrs (old: + { + patches = with config'.flake.patches; [ + hashicorp-nomad.revert-change-consul-si-tokens-to-be-local + hashicorp-nomad.add-nix-integration + ]; + }); + + settings = { + server.enabled = true; + + tls = { + # http = false # true + # rpc = true + + # ca_file = "nomad-ca.pem" + # cert_file = "client.pem" + # key_file = "client-key.pem" + + # verify_server_hostname = true + # verify_https_client = true + }; + + vault = { + enabled = true; + address = "https://${secret.network.ips.vault.dns or ""}:8200"; + allow_unauthenticated = true; + create_from_role = "nomad-cluster"; + }; + + consul = { + address = "${secret.network.ips.toothpick or ""}:8500"; + auto_advertise = true; + server_auto_join = true; + client_auto_join = true; + }; + + acl.enabled = true; + + client = { + cni_path = "${pkgs.cni-plugins}/bin"; + + options = { + "docker.privileged.enabled" = "true"; + }; + + host_network."default" = { + cidr = secret.network.ips.toothpick or "" + "/32"; + }; + + host_network."private" = { + cidr = secret.network.ips.toothpick or "" + "/32"; + }; + + host_network."mesh" = { + cidr = secret.network.ips.toothpick or "" + "/32"; + }; + + network_interface = "wg0"; + + host_network."public" = { + cidr = "64.225.104.221/32"; + reserved_ports = "22"; + }; + + enabled = true; + }; + + plugin."docker" = { + config = { + allow_caps = [ + "CHOWN" + "DAC_OVERRIDE" + "FSETID" + "FOWNER" + "MKNOD" + "NET_RAW" + "SETGID" + "SETUID" + "SETFCAP" + "SETPCAP" + "NET_BIND_SERVICE" + "SYS_CHROOT" + "KILL" + "AUDIT_WRITE" + "SYS_ADMIN" + ]; + allow_privileged = true; + extra_labels = [ + "job_name" + "job_id" + "task_group_name" + "task_name" + "namespace" + "node_name" + "node_id" + ]; + }; + }; + + bind_addr = secret.network.ips.toothpick or ""; + disable_update_check = true; + data_dir = "/var/lib/nomad"; + + server.authoritative_region = "homelab-1"; + datacenter = "do-1"; + region = "do-1"; + }; + }; + + virtualisation.docker.enable = true; + virtualisation.docker.daemon.settings.dns = [ + (secret.network.ips.blowhole or "") + ]; +} diff --git a/nixos/systems/toothpick/u2t.nix b/nixos/systems/toothpick/u2t.nix new file mode 100644 index 0000000..26a8869 --- /dev/null +++ b/nixos/systems/toothpick/u2t.nix @@ -0,0 +1,18 @@ +{ pkgs, ... }: +{ + systemd.services.udp2tcp = { + wantedBy = [ "multi-user.target" ]; + after = [ "network.target" ]; + + restartIfChanged = true; + + path = with pkgs; [ dig.host ]; + + script = '' + ${pkgs.udp-over-tcp}/bin/tcp2udp\ + --tcp-listen 127.0.0.1:6001 \ + --tcp-listen "$(host redalder.org | sed -e 's/.* //'):6001" \ + --udp-forward 127.0.0.1:6666 + ''; + }; +} diff --git a/nixos/systems/toothpick/users.nix b/nixos/systems/toothpick/users.nix new file mode 100644 index 0000000..b863bde --- /dev/null +++ b/nixos/systems/toothpick/users.nix @@ -0,0 +1,19 @@ +{ inputs', config', secret, ... }: +{ + imports = [ + inputs'.home-manager.nixosModules.default + ../../common/users.nix + ]; + + home-manager.useGlobalPkgs = true; + home-manager.extraSpecialArgs = { + config' = config'; + inputs' = inputs'; + secret = secret; + }; + home-manager.users.main = { + imports = [ (inputs'.self + "/home-manager/modules/profiles/server.nix") ]; + + home.stateVersion = "22.05"; + }; +} diff --git a/nixos/systems/toothpick/vault-agent.nix b/nixos/systems/toothpick/vault-agent.nix new file mode 100644 index 0000000..77c93dd --- /dev/null +++ b/nixos/systems/toothpick/vault-agent.nix @@ -0,0 +1,93 @@ +{ config, lib, pkgs, secret, inputs', ... }: +let + inherit (lib) + singleton; +in +{ + services.hashicorp.vault-agent = { + enable = true; + package = inputs'.nixpkgs-hashicorp.legacyPackages.${pkgs.stdenv.system}.vault; + + command = "agent"; + + extraPackages = with pkgs; [ + sudo + getent + ]; + + settings = { + vault = { + address = "https://${secret.network.ips.vault.dns or ""}:8200"; + retry.num_retries = 5; + }; + + auto_auth.method = singleton + { + "approle" = { + mount_path = "auth/approle"; + config = + { + role_id_file_path = "/var/secrets/approle.roleid"; + secret_id_file_path = "/var/secrets/approle.secretid"; + remove_secret_id_file_after_reading = false; + }; + }; + }; + + sink = singleton + { + "file" = { + type = "file"; + config.path = "/run/secrets/vault-token"; + }; + }; + + template = [ + { + source = pkgs.writeText "consul.json.vtmpl" + '' + { + "encrypt": "{{ with secret "kv/data/do-1/toothpick/consul/encryption_key" }}{{ or .Data.data.key "" }}{{ end }}", + "acl": { + "tokens": { + "agent": "{{ with secret "kv/data/do-1/toothpick/consul/agent_token" }}{{ or .Data.data.secret "" }}{{ end }}", + "replication": "{{ with secret "kv/data/do-1/toothpick/consul/replication_token" }}{{ or .Data.data.secret "" }}{{ end }}", + "default": "{{ with secret "kv/data/do-1/toothpick/consul/anonymous_token" }}{{ or .Data.data.secret "" }}{{ end }}" + } + } + } + ''; + destination = "/run/secrets/consul.json"; + command = pkgs.writeShellScript "consul-command" + '' + sudo systemctl try-reload-or-restart hashicorp-consul.service + ''; + } + { + source = pkgs.writeText "nomad.json.vtmpl" + '' + { + "server": { + "encrypt": "{{ with secret "kv/data/do-1/toothpick/nomad/encryption_key" }}{{ or .Data.data.key "" }}{{ end }}" + }, + "acl": { + "replication_token": "{{ with secret "kv/data/do-1/toothpick/nomad/replication_token" }}{{ or .Data.data.secret "" }}{{ end }}" + }, + "vault": { + "token": "{{ with secret "kv/data/do-1/toothpick/nomad/vault_token" }}{{ or .Data.data.secret "" }}{{ end }}" + }, + "consul": { + "token": "{{ with secret "kv/data/do-1/toothpick/nomad/consul_token" }}{{ or .Data.data.secret "" }}{{ end }}" + } + } + ''; + destination = "/run/secrets/nomad.json"; + command = pkgs.writeShellScript "nomad-command" + '' + sudo systemctl try-reload-or-restart hashicorp-nomad.service + ''; + } + ]; + }; + }; +} diff --git a/overlays/emacs-master-nativecomp/default.nix b/overlays/emacs-master-nativecomp/default.nix new file mode 100644 index 0000000..2014439 --- /dev/null +++ b/overlays/emacs-master-nativecomp/default.nix @@ -0,0 +1,44 @@ +{ inputs, ... }: +{ + flake.overlays.emacs-master-nativecomp = final: prev: + { + emacs-master-nativecomp = + let + emacs-master = import (inputs.nixpkgs + "/pkgs/applications/editors/emacs/generic.nix") { + version = "30"; + versionModifier = "-nativecomp"; + sha256 = null; + }; + emacs-master-package = (prev.callPackage emacs-master { + libXaw = prev.xorg.libXaw; + gconf = null; + alsa-lib = prev.alsa-lib; + acl = prev.acl; + gpm = null; + + # disable MacOS junk + AppKit = null; + Carbon = null; + Cocoa = null; + IOKit = null; + OSAKit = null; + Quartz = null; + QuartzCore = null; + WebKit = null; + ImageCaptureCore = null; + GSS = null; + ImageIO = null; + sigtool = null; + }).overrideAttrs (old: + { + src = inputs.emacs; + } + ); + in + emacs-master-package.override { + withSQLite3 = true; + nativeComp = true; + withWebP = true; + }; + }; +} diff --git a/overlays/emacs-rofi/default.nix b/overlays/emacs-rofi/default.nix new file mode 100644 index 0000000..53951e2 --- /dev/null +++ b/overlays/emacs-rofi/default.nix @@ -0,0 +1,9 @@ +# SPDX-FileCopyrightText: 2022 Richard Brežák +# +# SPDX-License-Identifier: LGPL-3.0-or-later +{ + flake.overlays.emacs-rofi = + final: prev: { + emacs-rofi = final.writeShellScriptBin "emacs-rofi" (builtins.readFile ./emacs-rofi); + }; +} diff --git a/overlays/emacs-rofi/emacs-rofi b/overlays/emacs-rofi/emacs-rofi new file mode 100644 index 0000000..1877814 --- /dev/null +++ b/overlays/emacs-rofi/emacs-rofi @@ -0,0 +1,9 @@ +# -*- mode: shell-script; -*- +# SPDX-FileCopyrightText: 2022 Richard Brežák +# +# SPDX-License-Identifier: LGPL-3.0-or-later + +tmp=$(mktemp) +tee > $tmp +emacs -Q --batch --eval $"(progn (require 'server) (princ (format \"%s\\n\" (server-eval-at \"server\" '(completing-read-frame-popup-file \"$1\" \"$tmp\" \"$DISPLAY\" $2 $3)))))" +rm $tmp diff --git a/overlays/emacsclient-remote/default.nix b/overlays/emacsclient-remote/default.nix new file mode 100644 index 0000000..53b1b50 --- /dev/null +++ b/overlays/emacsclient-remote/default.nix @@ -0,0 +1,9 @@ +{ inputs, ... }: +{ + flake.overlays.emacsclient-remote = + final: prev: { + emacsclient-remote = prev.writeShellScriptBin + "emacsclient-remote" + (builtins.readFile ./emacsclient-remote); + }; +} diff --git a/overlays/emacsclient-remote/emacsclient-remote b/overlays/emacsclient-remote/emacsclient-remote new file mode 100644 index 0000000..6ae74df --- /dev/null +++ b/overlays/emacsclient-remote/emacsclient-remote @@ -0,0 +1,49 @@ +#!/bin/bash + +# SPDX-FileCopyrightText: 2022 Richard Brežák +# +# SPDX-License-Identifier: LGPL-3.0-or-later + +# Open file on a remote Emacs server. +# https://andy.wordpress.com/2013/01/03/automatic-emacsclient/ with added sudo. + +params=() +sudo=0 +local=0 + +host=$(echo $SSH_CONNECTION | cut -d' ' -f3) +port=$(echo $SSH_CONNECTION | cut -d' ' -f4) + +for p in "${@}"; do + if [[ "${p}" == "-n" ]]; then + params+=( "${p}" ) + elif [[ "${p}" == "-c" ]]; then + params+=( "${p}" ) + elif [[ "${p:0:1}" == "+" ]]; then + params+=( "${p}" ) + elif [[ "${p}" == "--sudo" ]]; then + sudo=1 + elif [[ "${p}" == "--local" ]]; then + # Use local server, for use with --sudo. + local=1 + else + # Setting field separator to newline so that filenames with spaces will + # not be split up into 2 array elements. + OLDIFS=${IFS} + IFS=$'\n' + + if [[ $(id -u) -eq 0 || ${sudo} -eq 1 ]]; then + if [[ ${local} -eq 0 ]]; then + params+=( "/ssh:${USER}@${host}#${port}|sudo::"$(realpath -m "${p}") ) + else + params+=( "/sudo:localhost:"$(realpath -m "${p}") ) + fi + else + params+=( "/ssh:${USER}@${host}#${port}:"$(realpath "${p}") ) + fi + + IFS=${OLDIFS} + fi +done + +"emacsclient-$(uname -m)" -s ~/.ssh/emacs-server "${params[@]}" diff --git a/overlays/magic-screenshot/default.nix b/overlays/magic-screenshot/default.nix new file mode 100644 index 0000000..d42924d --- /dev/null +++ b/overlays/magic-screenshot/default.nix @@ -0,0 +1,13 @@ +{ inputs, ... }: +{ + flake.overlays.magic-screenshot = + final: prev: { + magic-screenshot = final.writeSubstitutedShellScriptBin { + name = "screenshot"; + file = ./screenshot; + substitutes = with prev; { + inherit busybox scrot xclip; + }; + }; + }; +} diff --git a/overlays/magic-screenshot/screenshot b/overlays/magic-screenshot/screenshot new file mode 100644 index 0000000..3eb584c --- /dev/null +++ b/overlays/magic-screenshot/screenshot @@ -0,0 +1,20 @@ +# -*- mode: shell-script; -*- +# SPDX-FileCopyrightText: 2022 Richard Brežák +# +# SPDX-License-Identifier: LGPL-3.0-or-later + +export PATH=@scrot@/bin:@xclip@/bin:@busybox@/bin + +OPT="${1:-screen}" + +case "$OPT" in + screen) + scrot '/tmp/%F_%T_$wx$h.png' -e 'mkdir -p ~/screenshot/ ; mv $f ~/screenshot ; xclip -selection clipboard -target image/png -i ~/screenshot/`basename $f`' + ;; + select) + scrot '/tmp/%F_%T_$wx$h.png' -f -s -e 'mkdir -p ~/screenshot/ ; mv $f ~/screenshot ; xclip -selection clipboard -target image/png -i ~/screenshot/`basename $f`' + ;; + focused) + scrot '/tmp/%F_%T_$wx$h.png' -f -e 'mkdir -p ~/screenshot/ ; mv $f ~/screenshot ; xclip -selection clipboard -target image/png -i ~/screenshot/`basename $f`' + ;; +esac diff --git a/overlays/tree-sitter-grammars.nix b/overlays/tree-sitter-grammars.nix new file mode 100644 index 0000000..070a9f6 --- /dev/null +++ b/overlays/tree-sitter-grammars.nix @@ -0,0 +1,25 @@ +# SPDX-FileCopyrightText: 2022 Richard Brežák +# +# SPDX-License-Identifier: LGPL-3.0-or-later +{ lib, ... }: +let + inherit (lib) + strings + flip; +in +{ + flake.overlays.tree-sitter-grammars = + final: prev: { + tree-sitter-grammars = prev.linkFarm "grammars" + (flip map (builtins.attrValues prev.tree-sitter.builtGrammars) + (drv: + let + name = strings.getName drv; + in + { + name = "lib${strings.removeSuffix "-grammar" name}.so"; + path = "${drv}/parser"; + } + )); + }; +} diff --git a/overlays/udp-over-tcp.nix b/overlays/udp-over-tcp.nix new file mode 100644 index 0000000..527428e --- /dev/null +++ b/overlays/udp-over-tcp.nix @@ -0,0 +1,19 @@ +{ inputs, ... }: +{ + flake.overlays.udp-over-tcp = + final: prev: { + udp-over-tcp = + prev.rustPlatform.buildRustPackage { + pname = "udp-over-tcp"; + version = "v0.2.0"; + + src = inputs.udp-over-tcp; + + buildFeatures = [ "clap" ]; + cargoBuildFlags = [ "--bin" "udp2tcp" "--bin" "tcp2udp" ]; + + cargoSha256 = "sha256-b8Q1f1KrCGKe4yySBTCn4bCkg9aL2nu/vMoAY6Kispo="; + verifyCargoDeps = true; + }; + }; +} diff --git a/patches/0001-Add-Nix-integration.patch b/patches/0001-Add-Nix-integration.patch new file mode 100644 index 0000000..442287d --- /dev/null +++ b/patches/0001-Add-Nix-integration.patch @@ -0,0 +1,287 @@ +From ce5fb5686e7d54f51dc15aeb1ef4ec08d5635740 Mon Sep 17 00:00:00 2001 +From: main +Date: Tue, 25 Oct 2022 17:22:50 +0200 +Subject: [PATCH] Add Nix integration + +Signed-off-by: main +--- + drivers/docker/config.go | 19 ++++++- + drivers/docker/driver.go | 52 +++++++++++++++++-- + drivers/docker/nix.go | 109 +++++++++++++++++++++++++++++++++++++++ + 3 files changed, 176 insertions(+), 4 deletions(-) + create mode 100644 drivers/docker/nix.go + +diff --git a/drivers/docker/config.go b/drivers/docker/config.go +index 40d98966a..9aa26458f 100644 +--- a/drivers/docker/config.go ++++ b/drivers/docker/config.go +@@ -108,6 +108,10 @@ func PluginLoader(opts map[string]string) (map[string]interface{}, error) { + conf["nvidia_runtime"] = v + } + ++ if v, ok := opts["docker.gcroots_dir"]; ok { ++ conf["gcroots_dir"] = v ++ } ++ + return conf, nil + } + +@@ -281,6 +285,11 @@ var ( + hclspec.NewLiteral(`"5m"`), + ), + ++ "gcroots_dir": hclspec.NewDefault( ++ hclspec.NewAttr("gcroots_dir", "string", false), ++ hclspec.NewLiteral(`"/nix/var/nix/gcroots/nomad-docker"`), ++ ), ++ + // the duration that the driver will wait for activity from the Docker engine during an image pull + // before canceling the request + "pull_activity_timeout": hclspec.NewDefault( +@@ -327,7 +336,7 @@ var ( + // taskConfigSpec is the hcl specification for the driver config section of + // a task within a job. It is returned in the TaskConfigSchema RPC + taskConfigSpec = hclspec.NewObject(map[string]*hclspec.Spec{ +- "image": hclspec.NewAttr("image", "string", true), ++ "image": hclspec.NewAttr("image", "string", false), + "advertise_ipv6_address": hclspec.NewAttr("advertise_ipv6_address", "bool", false), + "args": hclspec.NewAttr("args", "list(string)", false), + "auth": hclspec.NewBlock("auth", false, hclspec.NewObject(map[string]*hclspec.Spec{ +@@ -402,6 +411,9 @@ var ( + "volumes": hclspec.NewAttr("volumes", "list(string)", false), + "volume_driver": hclspec.NewAttr("volume_driver", "string", false), + "work_dir": hclspec.NewAttr("work_dir", "string", false), ++ ++ "nix_flake_ref": hclspec.NewAttr("nix_flake_ref", "string", false), ++ "nix_flake_sha": hclspec.NewAttr("nix_flake_sha", "string", false), + }) + + // driverCapabilities represents the RPC response for what features are +@@ -474,6 +486,9 @@ type TaskConfig struct { + VolumeDriver string `codec:"volume_driver"` + WorkDir string `codec:"work_dir"` + ++ NixFlakeRef string `codec:"nix_flake_ref"` ++ NixFlakeSha string `codec:"nix_flake_sha"` ++ + // MountsList supports the pre-1.0 mounts array syntax + MountsList []DockerMount `codec:"mounts"` + } +@@ -642,6 +657,8 @@ type DriverConfig struct { + ExtraLabels []string `codec:"extra_labels"` + Logging LoggingConfig `codec:"logging"` + ++ GCRootsDir string `codec:"gcroots_dir"` ++ + AllowRuntimesList []string `codec:"allow_runtimes"` + allowRuntimes map[string]struct{} `codec:"-"` + } +diff --git a/drivers/docker/driver.go b/drivers/docker/driver.go +index 0aa993845..812952fad 100644 +--- a/drivers/docker/driver.go ++++ b/drivers/docker/driver.go +@@ -14,6 +14,7 @@ import ( + "strings" + "sync" + "time" ++ "os/exec" + + docker "github.com/fsouza/go-dockerclient" + "github.com/hashicorp/consul-template/signals" +@@ -254,7 +255,7 @@ func (d *Driver) StartTask(cfg *drivers.TaskConfig) (*drivers.TaskHandle, *drive + return nil, nil, fmt.Errorf("failed to decode driver config: %v", err) + } + +- if driverConfig.Image == "" { ++ if driverConfig.Image == "" && !(driverConfig.NixFlakeRef != "" && driverConfig.NixFlakeSha != "") { + return nil, nil, fmt.Errorf("image name required for docker driver") + } + +@@ -269,6 +270,47 @@ func (d *Driver) StartTask(cfg *drivers.TaskConfig) (*drivers.TaskHandle, *drive + return nil, nil, fmt.Errorf("Failed to connect to docker daemon: %s", err) + } + ++ if driverConfig.NixFlakeRef != "" && driverConfig.NixFlakeSha != "" { ++ driverConfig.Image = "magicrb/nix-container-base@sha256:01f199486f5b0e3c90411d700436395f21154f8234b6dfa86eb224eb5b6ad43b"; ++ ++ nixExecutable, err := exec.LookPath("nix") ++ if err != nil { ++ return nil, nil, fmt.Errorf("failed to find `nix` executable") ++ } ++ ++ err = NixBuildFlake(nixExecutable, driverConfig.NixFlakeRef, driverConfig.NixFlakeSha) ++ if err != nil { ++ return nil, nil, err ++ } ++ ++ deps, err := NixGetDeps(nixExecutable, driverConfig.NixFlakeRef) ++ if err != nil { ++ return nil, nil, err ++ } ++ ++ for _, dep := range deps { ++ var mount DockerMount ++ mount.Type = "bind" ++ mount.Target = dep; ++ mount.Source = dep; ++ mount.ReadOnly = true; ++ ++ driverConfig.Mounts = append(driverConfig.Mounts, mount); ++ } ++ ++ storePath, err := NixGetStorePath(nixExecutable, driverConfig.NixFlakeRef) ++ if err != nil { ++ return nil, nil, err ++ } ++ ++ driverConfig.Entrypoint[0] = storePath + "/" + driverConfig.Entrypoint[0] ++ ++ os.Symlink(storePath, GetGCRoot(d.config.GCRootsDir, cfg.Name, cfg.AllocID)) ++ } ++ if (driverConfig.NixFlakeRef != "") != (driverConfig.NixFlakeSha != "") { ++ d.logger.Warn("one of either nix_flake_ref or nix_flake_sha is not set", "container_id", cfg.ID, "nix_flake_ref", driverConfig.NixFlakeRef, "nix_flake_sha", driverConfig.NixFlakeSha) ++ } ++ + id, err := d.createImage(cfg, &driverConfig, client) + if err != nil { + return nil, nil, err +@@ -1263,7 +1305,7 @@ func (d *Driver) toDockerMount(m *DockerMount, task *drivers.TaskConfig) (*docke + + // paths inside alloc dir are always allowed as they mount within + // a container, and treated as relative to task dir +- if !d.config.Volumes.Enabled && !isParentPath(task.AllocDir, hm.Source) { ++ if !d.config.Volumes.Enabled && !isParentPath(task.AllocDir, hm.Source) && !isParentPath("/nix/store", hm.Source) { + return nil, fmt.Errorf( + "volumes are not enabled; cannot mount host path: %q %q", + hm.Source, task.AllocDir) +@@ -1425,7 +1467,11 @@ func (d *Driver) StopTask(taskID string, timeout time.Duration, signal string) e + return drivers.ErrTaskNotFound + } + +- return h.Kill(timeout, signal) ++ err := h.Kill(timeout, signal) ++ ++ os.Remove(GetGCRoot(d.config.GCRootsDir, h.task.Name, h.task.AllocID)) ++ ++ return err + } + + func (d *Driver) DestroyTask(taskID string, force bool) error { +diff --git a/drivers/docker/nix.go b/drivers/docker/nix.go +new file mode 100644 +index 000000000..426cc51fd +--- /dev/null ++++ b/drivers/docker/nix.go +@@ -0,0 +1,109 @@ ++package docker ++ ++import ( ++ "fmt" ++ "os/exec" ++ "strings" ++ "encoding/json" ++) ++ ++func NixGetDeps(executable string, flakeRef string) ([]string, error) { ++ nixDepsCmd := &exec.Cmd { ++ Path: executable, ++ Args: []string{ ++ executable, ++ "path-info", ++ "-r", ++ flakeRef, ++ }, ++ } ++ res, err := nixDepsCmd.Output() ++ if err != nil { ++ return nil, fmt.Errorf("failed to get dependencies of built flake-ref %s", flakeRef) ++ } ++ deps := strings.Split(strings.Trim(string(res), " \n"), "\n") ++ ++ return deps, nil ++} ++ ++func NixBuildFlake(executable string, flakeRef string, flakeSha string) error { ++ ++ flakeHost := strings.Split(flakeRef, "#") ++ ++ if len(flakeHost) != 2 { ++ return fmt.Errorf("Invalid flake ref.") ++ } ++ ++ nixShaCmd := &exec.Cmd { ++ Path: executable, ++ Args: []string{ ++ executable, ++ "flake", ++ "metadata", ++ "--json", ++ flakeHost[0], ++ }, ++ } ++ nixSha, err := nixShaCmd.Output() ++ if err != nil { ++ return fmt.Errorf("failed to get sha for flake-ref %s with %s:\n %s", flakeRef, err, string(nixSha)) ++ } ++ ++ var shaJson map[string]interface{} ++ err = json.Unmarshal(nixSha, &shaJson) ++ ++ if err != nil { ++ return fmt.Errorf("failed to parse json %s", err) ++ } ++ ++ lockedVal, ok := shaJson["locked"].(map[string]interface{}) ++ if !ok { ++ return fmt.Errorf("failed to parse `nix flake metadata` output") ++ } ++ fetchedSha, ok := lockedVal["narHash"].(string) ++ if !ok { ++ return fmt.Errorf("failed to parse `nix flake metadata` output") ++ } ++ ++ if string(fetchedSha) != flakeSha { ++ return fmt.Errorf("pinned flake sha doesn't match: \"%s\" != \"%s\"", flakeSha, fetchedSha) ++ } ++ ++ nixBuildCmd := &exec.Cmd { ++ Path: executable, ++ Args: []string{ ++ executable, ++ "build", ++ "--no-link", ++ flakeRef, ++ }, ++ } ++ res, err := nixBuildCmd.Output() ++ if err != nil { ++ return fmt.Errorf("failed to build flake-ref %s with %s:\n %s", flakeRef, err, string(res)) ++ } ++ ++ return nil ++} ++ ++func NixGetStorePath(executable string, flakeRef string) (string, error) { ++ nixEvalCmd := exec.Cmd { ++ Path: executable, ++ Args: []string{ ++ executable, ++ "eval", ++ "--raw", ++ flakeRef + ".outPath", ++ }, ++ } ++ ++ storePath, err := nixEvalCmd.Output() ++ if err != nil { ++ return "", fmt.Errorf("failed to get store path of %s", flakeRef) ++ } ++ return string(storePath), nil ++} ++ ++func GetGCRoot(gcRootsDir string, containerName string, allocationId string) string { ++ return fmt.Sprintf("%s/%s-%s", gcRootsDir, containerName, allocationId) ++} +-- +2.37.1 + diff --git a/patches/0001-Revert-Change-consul-SI-tokens-to-be-local.patch b/patches/0001-Revert-Change-consul-SI-tokens-to-be-local.patch new file mode 100644 index 0000000..f10f6f6 --- /dev/null +++ b/patches/0001-Revert-Change-consul-SI-tokens-to-be-local.patch @@ -0,0 +1,25 @@ +From ba55d4ee4e05fd7b5c885ad91132a333651c80e1 Mon Sep 17 00:00:00 2001 +From: main +Date: Sat, 30 Jul 2022 15:48:33 +0200 +Subject: [PATCH] Revert "Change consul SI tokens to be local" + +This reverts commit 7bfb482b1ef3a1bf0138c2f9e00700466127c3fc. +--- + nomad/consul.go | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/nomad/consul.go b/nomad/consul.go +index 7eac19ff8..3c238a8c8 100644 +--- a/nomad/consul.go ++++ b/nomad/consul.go +@@ -290,7 +290,6 @@ func (c *consulACLsAPI) CreateToken(ctx context.Context, sir ServiceIdentityRequ + Description: sir.Description(), + ServiceIdentities: []*api.ACLServiceIdentity{{ServiceName: service}}, + Namespace: sir.ConsulNamespace, +- Local: true, + } + + // Ensure we are under our rate limit. +-- +2.36.1 +