44 Commits

Author SHA1 Message Date
Smaug123
3efd22bc6b Update flake 2024-12-15 09:59:02 +00:00
Patrick Stevens
3bfb4e7ec5 Freeze tty (#101) 2024-12-13 09:27:45 +00:00
Patrick Stevens
d857f7ab9f Screenshots (#100) 2024-11-29 19:05:10 +00:00
Patrick Stevens
cb3c993507 Fix sway on Earthworm (#99) 2024-11-29 09:41:46 +00:00
Patrick Stevens
14f21cb172 Fix shutdown menu (#98) 2024-11-29 09:35:39 +00:00
Patrick Stevens
02f757bf57 Fix pavucontrol (#96) 2024-11-24 12:47:27 +00:00
Patrick Stevens
6d3804a5ee Start tmux automatically (#95) 2024-11-20 18:29:59 +00:00
Patrick Stevens
6c3bdcc4b2 AMD GPU on capybara (#94) 2024-11-20 18:23:01 +00:00
Patrick Stevens
2123c53980 Bump flake again (#93) 2024-11-14 23:40:40 +00:00
Patrick Stevens
7f712faf2c Bump flake (#92) 2024-11-14 23:31:22 +00:00
Patrick Stevens
5b8b64b0a2 Keepassxc broken on aarch64-darwin (#91) 2024-11-14 23:26:55 +00:00
Patrick Stevens
73efe7a18c Add golang (#90) 2024-10-26 08:25:43 +00:00
Patrick Stevens
f6dd2e686a Add gopls (#89) 2024-10-26 08:20:48 +00:00
Patrick Stevens
df071387b2 Pipewire on Capybara (#88) 2024-10-23 21:00:06 +00:00
Patrick Stevens
f83285dec2 Use Waybar (#87) 2024-10-21 23:23:29 +00:00
Patrick Stevens
9fbcd75842 Use pinentry-curses (#86) 2024-10-21 23:28:21 +01:00
Patrick Stevens
52c08e4183 Fix Earthworm key (#84) 2024-10-21 23:23:37 +01:00
Patrick Stevens
fd1452cc8f Fix tmux after macOS upgrade (#83) 2024-10-20 10:05:03 +01:00
dependabot[bot]
8e7abf90c2 Bump cachix/install-nix-action from 29 to 30 (#82)
Bumps [cachix/install-nix-action](https://github.com/cachix/install-nix-action) from 29 to 30.
- [Release notes](https://github.com/cachix/install-nix-action/releases)
- [Commits](https://github.com/cachix/install-nix-action/compare/v29...v30)

---
updated-dependencies:
- dependency-name: cachix/install-nix-action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-10-07 09:14:14 +01:00
dependabot[bot]
8d888029bd Bump cachix/install-nix-action from V28 to 29 (#81) 2024-09-30 08:36:19 +01:00
Patrick Stevens
d891582dfe Add regular Nix store optimisation (#80) 2024-09-20 21:37:30 +00:00
Patrick Stevens
fa88755137 Fix mail and Git repo syncing on darwin (#79) 2024-09-20 21:42:08 +01:00
Patrick Stevens
544fc635eb Install pip (#78) 2024-09-20 20:36:06 +00:00
Patrick Stevens
6a493ab214 Delete ltex, it sticks around consuming loads of CPU (#77) 2024-09-20 20:32:54 +00:00
Patrick Stevens
86b6269229 Disable auto-optimise on Darwin (#76) 2024-09-20 18:37:42 +00:00
dependabot[bot]
89e1aa4d7e Bump cachix/install-nix-action from V27 to 28 (#75)
Bumps [cachix/install-nix-action](https://github.com/cachix/install-nix-action) from V27 to 28. This release includes the previously tagged commit.
- [Release notes](https://github.com/cachix/install-nix-action/releases)
- [Commits](https://github.com/cachix/install-nix-action/compare/V27...V28)

---
updated-dependencies:
- dependency-name: cachix/install-nix-action
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-09-16 10:26:24 +01:00
Patrick Stevens
76dbd82446 Add Rider and nvidia drivers (#73) 2024-09-08 21:25:33 +01:00
Patrick Stevens
ceaead9b63 Some Linux fixes (#72) 2024-09-08 16:45:20 +00:00
Patrick Stevens
88f4111744 Move Capybara to AMD (#71) 2024-09-08 17:31:33 +01:00
Patrick Stevens
3ae9cebd58 Bump nixpkgs and fix some nvim stuff (#70) 2024-08-28 20:00:31 +01:00
Patrick Stevens
5c872e2c4a Add some more stuff (#69) 2024-08-19 22:38:06 +00:00
Patrick Stevens
ede76d2bc2 Update flake (breaks ;; in which-key) (#67) 2024-08-06 20:14:01 +01:00
Patrick Stevens
19e8024a13 Add NuGet upgrade shortcut in neovim (#66) 2024-07-23 17:27:55 +01:00
Patrick Stevens
43c7842fac Fix required checks (#65) 2024-07-14 11:11:32 +01:00
Patrick Stevens
df22898e58 Add clangd (#64) 2024-07-14 11:08:36 +01:00
Patrick Stevens
ad9621acd3 Bump Nixpkgs (#63) 2024-06-29 19:53:49 +01:00
Patrick Stevens
dec7aff312 Bump Nixpkgs (#62) 2024-06-29 10:08:48 +01:00
Patrick Stevens
9649e2e37b Add .NET project filetypes in nvim (#61) 2024-05-31 20:33:33 +00:00
Patrick Stevens
162b58abc4 Difftastic as Git diff tool (#60) 2024-05-27 17:03:47 +00:00
Patrick Stevens
29d80dec16 Neovim non nightly (#59) 2024-05-27 16:55:10 +00:00
dependabot[bot]
1fc72d0288 Bump cachix/install-nix-action from 26 to 27 (#58)
Bumps [cachix/install-nix-action](https://github.com/cachix/install-nix-action) from 26 to 27.
- [Release notes](https://github.com/cachix/install-nix-action/releases)
- [Commits](https://github.com/cachix/install-nix-action/compare/v26...V27)

---
updated-dependencies:
- dependency-name: cachix/install-nix-action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-05-20 08:24:50 +01:00
Patrick Stevens
8752e0a720 Update Ionide (#57) 2024-05-03 23:10:38 +00:00
Patrick Stevens
cde0abe5d9 Add calendar backup job (#56) 2024-04-28 21:42:54 +00:00
Patrick Stevens
5536c97493 Qualify path to cat (#55) 2024-04-28 21:40:55 +00:00
27 changed files with 1521 additions and 597 deletions

View File

@@ -13,14 +13,16 @@ jobs:
- name: "Checkout"
uses: "actions/checkout@v4"
- name: "Install Nix"
uses: "cachix/install-nix-action@v26"
uses: "cachix/install-nix-action@v30"
with: { "extra_nix_config": "access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}" }
- name: "Check flake"
run: "nix flake check --all-systems"
all-required-checks-complete:
if: ${{ always() }}
runs-on: "ubuntu-latest"
steps:
- run: "echo \"All required checks complete.\""
needs:
- "flake-check"
- uses: Smaug123/all-required-checks-complete-action@05b40a8c47ef0b175ea326e9abb09802cb67b44e
with:
needs-context: ${{ toJSON(needs) }}
needs: [ "flake-check" ]

View File

@@ -53,7 +53,58 @@ in {
serviceConfig = {
KeepAlive = false;
UserName = "patrick";
StartInterval = 60;
# Refresh token is 60min long, so do this more often than that!
StartInterval = 30;
RunAtLoad = true;
};
};
backup-calendar = {
command = ''${pkgs.bash}/bin/bash -c "mkdir -p '/Users/patrick/Library/Application Support/RadicaleBackups' && if [ ! -d '/Users/patrick/Library/Application Support/RadicaleBackups/.git' ] ; then ${pkgs.git}/bin/git clone root@patrickstevens.co.uk:/preserve/radicale/data/.git '/Users/patrick/Library/Application Support/RadicaleBackups' >/tmp/radicale.out.log 2>/tmp/radicale.err.log; fi && ${pkgs.git}/bin/git --git-dir '/Users/patrick/Library/Application Support/RadicaleBackups/.git' --work-tree '/Users/patrick/Library/Application Support/RadicaleBackups/' pull 2>>/tmp/radicale.err.log"'';
serviceConfig = {
KeepAlive = false;
UserName = "patrick";
StartInterval = 3600;
RunAtLoad = true;
};
};
sync-nixpkgs = {
command = ''${pkgs.bash}/bin/bash -c "if [ -d /Users/patrick/Documents/GitHub/nixpkgs ] ; then ${pkgs.git}/bin/git --git-dir /Users/patrick/Documents/GitHub/nixpkgs/.git --work-tree '/Users/patrick/Documents/GitHub/nixpkgs/' fetch origin ; fi"'';
serviceConfig = {
KeepAlive = false;
UserName = "patrick";
StartInterval = 36000;
RunAtLoad = true;
};
};
sync-dotnet-api-docs = {
command = ''${pkgs.bash}/bin/bash -c "if [ -d /Users/patrick/Documents/GitHub/dotnet-api-docs ] ; then ${pkgs.git}/bin/git --git-dir /Users/patrick/Documents/GitHub/dotnet-api-docs/.git --work-tree '/Users/patrick/Documents/GitHub/dotnet-api-docs' fetch origin ; fi"'';
serviceConfig = {
KeepAlive = false;
UserName = "patrick";
StartInterval = 36000;
RunAtLoad = true;
};
};
sync-dotnet-docs = {
command = ''${pkgs.bash}/bin/bash -c "if [ -d /Users/patrick/Documents/GitHub/dotnet-docs ] ; then ${pkgs.git}/bin/git --git-dir /Users/patrick/Documents/GitHub/dotnet-docs/.git --work-tree '/Users/patrick/Documents/GitHub/dotnet-docs' fetch origin ; fi"'';
serviceConfig = {
KeepAlive = false;
UserName = "patrick";
StartInterval = 36000;
RunAtLoad = true;
};
};
nix-store-optimise = {
command = ''${pkgs.nix}/bin/nix store optimise'';
serviceConfig = {
KeepAlive = false;
UserName = "patrick";
StartInterval = 72000;
RunAtLoad = true;
};
};
@@ -67,8 +118,9 @@ in {
# Sandbox causes failure: https://github.com/NixOS/nix/issues/4119
nix.settings.sandbox = false;
# Optimising store leads to transient build failures https://github.com/NixOS/nix/issues/7273
nix.extraOptions = ''
auto-optimise-store = true
auto-optimise-store = false
experimental-features = nix-command flakes
extra-experimental-features = ca-derivations
max-jobs = auto # Allow building multiple derivations in parallel

244
flake.lock generated
View File

@@ -7,11 +7,11 @@
"rust-overlay": "rust-overlay"
},
"locked": {
"lastModified": 1712279577,
"narHash": "sha256-Bwn4rmQi2L2iX6g3ycQMA4baE3zgPHAO0xPBpr2T4/k=",
"lastModified": 1733377410,
"narHash": "sha256-tZ9JEAaHIs3TPdRZeZzHsnJmUilkcnVaUTvyprbRb1A=",
"owner": "tpwrules",
"repo": "nixos-apple-silicon",
"rev": "d47afc3f0f8b3078c818da8609c41340af61a2ec",
"rev": "e8c07c3ae199b55a8c1c35a7c067c5cef9c7e929",
"type": "github"
},
"original": {
@@ -27,11 +27,11 @@
]
},
"locked": {
"lastModified": 1711763326,
"narHash": "sha256-sXcesZWKXFlEQ8oyGHnfk4xc9f2Ip0X/+YZOq3sKviI=",
"lastModified": 1733570843,
"narHash": "sha256-sQJAxY1TYWD1UyibN/FnN97paTFuwBw3Vp3DNCyKsMk=",
"owner": "lnl7",
"repo": "nix-darwin",
"rev": "36524adc31566655f2f4d55ad6b875fb5c1a4083",
"rev": "a35b08d09efda83625bef267eb24347b446c80b8",
"type": "github"
},
"original": {
@@ -43,18 +43,17 @@
},
"emacs": {
"inputs": {
"flake-utils": "flake-utils",
"nixpkgs": [
"nixpkgs"
],
"nixpkgs-stable": "nixpkgs-stable"
},
"locked": {
"lastModified": 1712941527,
"narHash": "sha256-wD9XQFGW0qzRW1YHj6oklCHzgKNxjwS0tZ/hFGgiHX4=",
"lastModified": 1734253225,
"narHash": "sha256-LnBb8SyY+WGmBtnQ9XmbpKPoGjOrf89T//xQsKZhJzE=",
"owner": "nix-community",
"repo": "emacs-overlay",
"rev": "9f4406718ada7af83892e17355ef7fd202c20897",
"rev": "d6353ce807b7845ffec114d234c90ece44c39122",
"type": "github"
},
"original": {
@@ -78,86 +77,10 @@
"type": "github"
}
},
"flake-compat_2": {
"flake": false,
"locked": {
"lastModified": 1696426674,
"narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=",
"owner": "edolstra",
"repo": "flake-compat",
"rev": "0f9255e01c2351cc7d116c072cb317785dd33b33",
"type": "github"
},
"original": {
"owner": "edolstra",
"repo": "flake-compat",
"type": "github"
}
},
"flake-parts": {
"inputs": {
"nixpkgs-lib": [
"neovim-nightly",
"nixpkgs"
]
},
"locked": {
"lastModified": 1712014858,
"narHash": "sha256-sB4SWl2lX95bExY2gMFG5HIzvva5AVMJd4Igm+GpZNw=",
"owner": "hercules-ci",
"repo": "flake-parts",
"rev": "9126214d0a59633752a136528f5f3b9aa8565b7d",
"type": "github"
},
"original": {
"owner": "hercules-ci",
"repo": "flake-parts",
"type": "github"
}
},
"flake-parts_2": {
"inputs": {
"nixpkgs-lib": [
"neovim-nightly",
"hercules-ci-effects",
"nixpkgs"
]
},
"locked": {
"lastModified": 1709336216,
"narHash": "sha256-Dt/wOWeW6Sqm11Yh+2+t0dfEWxoMxGBvv3JpIocFl9E=",
"owner": "hercules-ci",
"repo": "flake-parts",
"rev": "f7b3c975cf067e56e7cda6cb098ebe3fb4d74ca2",
"type": "github"
},
"original": {
"id": "flake-parts",
"type": "indirect"
}
},
"flake-utils": {
"inputs": {
"systems": "systems"
},
"locked": {
"lastModified": 1710146030,
"narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"flake-utils_2": {
"inputs": {
"systems": "systems_2"
},
"locked": {
"lastModified": 1701680307,
"narHash": "sha256-kAuep2h5ajznlPMD9rnQyffWG8EM/C73lejGofXvdM8=",
@@ -172,46 +95,6 @@
"type": "github"
}
},
"flake-utils_3": {
"inputs": {
"systems": "systems_3"
},
"locked": {
"lastModified": 1701680307,
"narHash": "sha256-kAuep2h5ajznlPMD9rnQyffWG8EM/C73lejGofXvdM8=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "4022d587cbbfd70fe950c1e2083a02621806a725",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"hercules-ci-effects": {
"inputs": {
"flake-parts": "flake-parts_2",
"nixpkgs": [
"neovim-nightly",
"nixpkgs"
]
},
"locked": {
"lastModified": 1710478346,
"narHash": "sha256-Xjf8BdnQG0tLhPMlqQdwCIjOp7Teox0DP3N/jjyiGM4=",
"owner": "hercules-ci",
"repo": "hercules-ci-effects",
"rev": "64e7763d72c1e4c1e5e6472640615b6ae2d40fbf",
"type": "github"
},
"original": {
"owner": "hercules-ci",
"repo": "hercules-ci-effects",
"type": "github"
}
},
"home-manager": {
"inputs": {
"nixpkgs": [
@@ -219,11 +102,11 @@
]
},
"locked": {
"lastModified": 1712759992,
"narHash": "sha256-2APpO3ZW4idlgtlb8hB04u/rmIcKA8O7pYqxF66xbNY=",
"lastModified": 1734093295,
"narHash": "sha256-hSwgGpcZtdDsk1dnzA0xj5cNaHgN9A99hRF/mxMtwS4=",
"owner": "nix-community",
"repo": "home-manager",
"rev": "31357486b0ef6f4e161e002b6893eeb4fafc3ca9",
"rev": "66c5d8b62818ec4c1edb3e941f55ef78df8141a8",
"type": "github"
},
"original": {
@@ -244,93 +127,45 @@
"url": "https://huggingface.co/ggerganov/whisper.cpp/resolve/main/ggml-large-v3.bin?download=true"
}
},
"neovim-flake": {
"inputs": {
"flake-utils": "flake-utils_2",
"nixpkgs": [
"neovim-nightly",
"nixpkgs"
]
},
"locked": {
"dir": "contrib",
"lastModified": 1712877603,
"narHash": "sha256-8JesAgnsv1bD+xHNoqefz0Gv243wSiCKnzh4rhZLopU=",
"owner": "neovim",
"repo": "neovim",
"rev": "18ee9f9e7dbbc9709ee9c1572870b4ad31443569",
"type": "github"
},
"original": {
"dir": "contrib",
"owner": "neovim",
"repo": "neovim",
"type": "github"
}
},
"neovim-nightly": {
"inputs": {
"flake-compat": "flake-compat_2",
"flake-parts": "flake-parts",
"hercules-ci-effects": "hercules-ci-effects",
"neovim-flake": "neovim-flake",
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1712880226,
"narHash": "sha256-2CGLzsFft8zF/gEY4qDN0uAjRCWUqvNJ9yV118NlzTg=",
"owner": "nix-community",
"repo": "neovim-nightly-overlay",
"rev": "58d367a1924bf0d02bcc5bd2c5af8ac97f178381",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "neovim-nightly-overlay",
"type": "github"
}
},
"nixpkgs": {
"locked": {
"lastModified": 1712163089,
"narHash": "sha256-Um+8kTIrC19vD4/lUCN9/cU9kcOsD1O1m+axJqQPyMM=",
"lastModified": 1733212471,
"narHash": "sha256-M1+uCoV5igihRfcUKrr1riygbe73/dzNnzPsmaLCmpo=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "fd281bd6b7d3e32ddfa399853946f782553163b5",
"rev": "55d15ad12a74eb7d4646254e13638ad0c4128776",
"type": "github"
},
"original": {
"owner": "nixos",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"rev": "fd281bd6b7d3e32ddfa399853946f782553163b5",
"type": "github"
}
},
"nixpkgs-stable": {
"locked": {
"lastModified": 1712741485,
"narHash": "sha256-bCs0+MSTra80oXAsnM6Oq62WsirOIaijQ/BbUY59tR4=",
"lastModified": 1734083684,
"narHash": "sha256-5fNndbndxSx5d+C/D0p/VF32xDiJCJzyOqorOYW4JEo=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "b2cf36f43f9ef2ded5711b30b1f393ac423d8f72",
"rev": "314e12ba369ccdb9b352a4db26ff419f7c49fa84",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-23.11",
"ref": "nixos-24.11",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs_2": {
"locked": {
"lastModified": 1712849433,
"narHash": "sha256-flQtf/ZPJgkLY/So3Fd+dGilw2DKIsiwgMEn7BbBHL0=",
"lastModified": 1733935885,
"narHash": "sha256-xyiHLs6KJ1fxeGmcCxKjJE4yJknVJxbC8Y/ZRYyC8WE=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "f173d0881eff3b21ebb29a2ef8bedbc106c86ea5",
"rev": "5a48e3c2e435e95103d56590188cfed7b70e108c",
"type": "github"
},
"original": {
@@ -361,7 +196,6 @@
"darwin": "darwin",
"emacs": "emacs",
"home-manager": "home-manager",
"neovim-nightly": "neovim-nightly",
"nixpkgs": "nixpkgs_2",
"whisper": "whisper"
}
@@ -397,39 +231,9 @@
"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"
}
},
"systems_3": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
},
"whisper": {
"inputs": {
"flake-utils": "flake-utils_3",
"flake-utils": "flake-utils",
"model": "model",
"nixpkgs": "nixpkgs_3"
},

View File

@@ -24,14 +24,9 @@
whisper = {
url = "github:Smaug123/whisper.cpp/nix";
};
neovim-nightly = {
url = "github:nix-community/neovim-nightly-overlay";
inputs.nixpkgs.follows = "nixpkgs";
};
};
outputs = {
neovim-nightly,
darwin,
emacs,
nixpkgs,
@@ -46,7 +41,7 @@
};
systems = ["aarch64-darwin" "aarch64-linux" "x86_64-linux"];
in let
overlays = [emacs.overlay neovim-nightly.overlay];
overlays = [emacs.overlay];
recursiveMerge = attrList: let
f = attrPath:
builtins.zipAttrsWith (n: values:
@@ -68,6 +63,10 @@
in
nixpkgs.lib.nixosSystem {
inherit system;
specialArgs = {
username = "patrick";
dotnet = pkgs.dotnet-sdk_8;
};
modules = let
args = {
nixpkgs = pkgs;
@@ -75,6 +74,7 @@
dotnet = pkgs.dotnet-sdk_8;
mbsync = import ./mbsync.nix {inherit pkgs;};
secretsPath = "/home/patrick/.secrets/";
machinename = "capybara";
};
in [
./home-manager/capybara-config.nix
@@ -100,6 +100,7 @@
dotnet = pkgs.dotnet-sdk_8;
mbsync = import ./mbsync.nix {inherit pkgs;};
secretsPath = "/home/patrick/.secrets/";
machinename = "earthworm";
};
in [
./home-manager/earthworm-config.nix
@@ -129,6 +130,7 @@
whisper = whisper.packages.${system};
mbsync = import ./mbsync.nix {inherit pkgs;};
secretsPath = "/Users/patrick/.secrets/";
machinename = "darwin";
};
in [
./darwin-configuration.nix

View File

@@ -12,9 +12,9 @@
(modulesPath + "/installer/scan/not-detected.nix")
];
boot.initrd.availableKernelModules = ["xhci_pci" "ahci" "nvme" "usb_storage" "usbhid" "sd_mod"];
boot.initrd.availableKernelModules = ["nvme" "xhci_pci" "ahci" "usb_storage" "usbhid" "sd_mod"];
boot.initrd.kernelModules = [];
boot.kernelModules = ["kvm-intel"];
boot.kernelModules = ["kvm-amd"];
boot.extraModulePackages = [];
fileSystems."/" = {
@@ -23,12 +23,21 @@
};
fileSystems."/boot" = {
device = "/dev/nvme0n1p2";
device = "/dev/disk/by-uuid/9248-31C6";
fsType = "vfat";
options = ["fmask=0022" "dmask=0022"];
};
swapDevices = [];
powerManagement.cpuFreqGovernor = lib.mkDefault "powersave";
hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
# Enables DHCP on each ethernet and wireless interface. In case of scripted networking
# (the default) this is the recommended approach. When using systemd-networkd it's
# still possible to use this option, but it's recommended to use it in conjunction
# with explicit per-interface declarations with `networking.interfaces.<interface>.useDHCP`.
networking.useDHCP = lib.mkDefault true;
# networking.interfaces.eno1.useDHCP = lib.mkDefault true;
# networking.interfaces.wlp9s0.useDHCP = lib.mkDefault true;
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
hardware.cpu.amd.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
}

View File

@@ -8,10 +8,28 @@
../hardware/capybara.nix
];
hardware.graphics = {
enable = true;
enable32Bit = true;
};
security.rtkit.enable = true;
services.pipewire = {
enable = true;
alsa.enable = true;
alsa.support32Bit = true;
pulse.enable = true;
};
boot.loader.systemd-boot.enable = true;
boot.loader.efi.canTouchEfiVariables = true;
boot.loader.grub.useOSProber = true;
boot.kernelParams = [
"video=DP-1:2560x1440@144"
"video=HDMI-A-1:1920x1080@144"
];
boot.extraModulePackages = [config.boot.kernelPackages.rtl8821au];
networking = {
@@ -38,16 +56,16 @@
};
environment.systemPackages = [
pkgs.git
pkgs.vim
pkgs.wget
pkgs.tmux
pkgs.home-manager
pkgs.firefox
pkgs.steam-run
];
environment.loginShellInit = ''
[[ "$(tty)" == /dev/tty1 ]] && sway
[[ "$(tty)" == /dev/tty1 ]] && sway --unsupported-gpu
'';
services.openssh.enable = true;

View File

@@ -3,7 +3,31 @@
../hardware/earthworm.nix
];
hardware.asahi.peripheralFirmwareDirectory = ../firmware;
hardware.asahi.peripheralFirmwareDirectory = ./../firmware;
hardware.asahi = {
useExperimentalGPUDriver = true;
experimentalGPUInstallMode = "overlay";
setupAsahiSound = true;
withRust = true;
};
hardware.graphics.enable = true;
programs.light.enable = true;
services.actkbd = {
enable = true;
bindings = [
{
keys = [225];
events = ["key"];
command = "${pkgs.light}/bin/light -A 10";
}
{
keys = [224];
events = ["key"];
command = "${pkgs.light}/bin/light -U 10";
}
];
};
boot.loader.systemd-boot.enable = true;
boot.loader.efi.canTouchEfiVariables = false;
@@ -14,6 +38,10 @@
networking = {
hostName = "earthworm";
networkmanager.enable = true;
wireless.iwd = {
enable = true;
settings.General.EnableNetworkConfiguration = true;
};
};
time.timeZone = "Europe/London";
@@ -31,10 +59,11 @@
environment.systemPackages = [
pkgs.vim
pkgs.wget
pkgs.mesa-asahi-edge
];
environment.loginShellInit = ''
[[ "$(tty)" == /dev/tty1 ]] && sway
[[ "$(tty)" == /dev/tty1 ]] && export WLR_RENDER_NO_EXPLICIT_SYNC=1 && sway
'';
services.openssh.enable = true;

View File

@@ -1,5 +1,6 @@
{
nixpkgs,
machinename,
username,
mbsync,
dotnet,
@@ -54,11 +55,18 @@
co = "checkout";
st = "status";
};
delta = {enable = true;};
difftastic.enable = true;
extraConfig = {
commit.gpgsign = true;
gpg.program = "${nixpkgs.gnupg}/bin/gpg";
user.signingkey = "7C97D679CF3BC4F9";
user.signingkey =
if machinename == "darwin"
then "7C97D679CF3BC4F9"
else if machinename == "earthworm"
then "6E8B1BA1148AD7C9"
else if machinename == "capybara"
then "AE90453E879DBCFA"
else throw "unrecognised machine name!";
core = {
autocrlf = "input";
};
@@ -125,33 +133,19 @@
};
programs.neovim = let
pynvimpp = nixpkgs.python3.pkgs.buildPythonPackage {
pname = "pynvim-pp";
version = "unstable-2024-03-24";
pyproject = true;
src = nixpkgs.fetchFromGitHub {
owner = "ms-jpq";
repo = "pynvim_pp";
rev = "34e3a027c595981886d7efd1c91071f3eaa4715d";
hash = "sha256-2+jDRJXlg9q4MN9vOhmeq4cWVJ0wp5r5xAh3G8lqgOg=";
};
nativeBuildInputs = [nixpkgs.python3.pkgs.setuptools];
propagatedBuildInputs = [nixpkgs.python3.pkgs.pynvim];
};
in let
pythonEnv = nixpkgs.python3.withPackages (ps: [
ps.pynvim
pynvimpp
ps.pyyaml
ps.std2
]);
debugPyEnv = nixpkgs.python3.withPackages (ps: [ps.debugpy]);
in {
enable = true;
plugins = [
{
plugin = nixpkgs.vimPlugins.nvim-web-devicons;
}
{
plugin = nixpkgs.vimPlugins.mini-nvim;
}
{
plugin = nixpkgs.vimPlugins.satellite-nvim;
}
{
plugin = nixpkgs.vimPlugins.nvim-lightbulb;
type = "lua";
@@ -257,59 +251,89 @@
vimAlias = true;
vimdiffAlias = true;
withPython3 = true;
extraPython3Packages = ps: [
ps.pip
ps.pynvim
ps.pynvim-pp
ps.pyyaml
ps.std2
];
withRuby = true;
extraLuaConfig = builtins.readFile ./nvim/build-utils.lua + "\n" + builtins.readFile ./nvim/dotnet.lua + "\n" + builtins.replaceStrings ["%PYTHONENV%"] ["${pythonEnv}"] (builtins.readFile ./nvim/init.lua) + "\n" + builtins.readFile ./nvim/python.lua;
package = nixpkgs.neovim-nightly;
extraLuaConfig = builtins.readFile ./nvim/build-utils.lua + "\n" + (builtins.replaceStrings ["_CURL_"] ["${nixpkgs.curl}/bin/curl"] (builtins.readFile ./nvim/dotnet.lua)) + "\n" + builtins.readFile ./nvim/init.lua + "\n" + builtins.readFile ./nvim/python.lua;
};
home.packages = [
nixpkgs.syncthing
nixpkgs.nodePackages_latest.dockerfile-language-server-nodejs
nixpkgs.nodePackages_latest.bash-language-server
nixpkgs.nodePackages_latest.vscode-json-languageserver
nixpkgs.nodePackages_latest.vscode-langservers-extracted
nixpkgs.hadolint
nixpkgs.ltex-ls
nixpkgs.yaml-language-server
nixpkgs.csharp-ls
nixpkgs.netcoredbg
nixpkgs.nil
nixpkgs.fsautocomplete
nixpkgs.keepassxc
nixpkgs.wget
nixpkgs.yt-dlp
nixpkgs.cmake
nixpkgs.gnumake
nixpkgs.gcc
nixpkgs.lldb
nixpkgs.hledger
nixpkgs.hledger-web
dotnet
nixpkgs.jitsi-meet
nixpkgs.elan
nixpkgs.coreutils-prefixed
nixpkgs.shellcheck
nixpkgs.universal-ctags
nixpkgs.asciinema
nixpkgs.git-lfs
nixpkgs.imagemagick
nixpkgs.nixpkgs-fmt
nixpkgs.lnav
nixpkgs.age
nixpkgs.nodejs
nixpkgs.nodePackages.pyright
nixpkgs.woodpecker-agent
nixpkgs.lynx
nixpkgs.alejandra
nixpkgs.ffmpeg
nixpkgs.bat
nixpkgs.pandoc
nixpkgs.fd
nixpkgs.sumneko-lua-language-server
nixpkgs.gnupg
];
home.packages =
[
nixpkgs.jq
nixpkgs.difftastic
nixpkgs.syncthing
nixpkgs.nodePackages_latest.dockerfile-language-server-nodejs
nixpkgs.nodePackages_latest.bash-language-server
nixpkgs.nodePackages_latest.vscode-json-languageserver
nixpkgs.nodePackages_latest.vscode-langservers-extracted
nixpkgs.hadolint
nixpkgs.yaml-language-server
nixpkgs.csharp-ls
nixpkgs.netcoredbg
nixpkgs.nil
nixpkgs.fsautocomplete
nixpkgs.wget
nixpkgs.yt-dlp
nixpkgs.cmake
nixpkgs.gnumake
nixpkgs.gcc
nixpkgs.lldb
nixpkgs.hledger
nixpkgs.hledger-web
dotnet
nixpkgs.elan
nixpkgs.coreutils-prefixed
nixpkgs.shellcheck
nixpkgs.universal-ctags
nixpkgs.asciinema
nixpkgs.git-lfs
nixpkgs.imagemagick
nixpkgs.nixpkgs-fmt
nixpkgs.age
nixpkgs.nodejs
nixpkgs.pyright
nixpkgs.woodpecker-agent
nixpkgs.lynx
nixpkgs.alejandra
nixpkgs.ffmpeg
nixpkgs.bat
nixpkgs.pandoc
nixpkgs.fd
nixpkgs.sumneko-lua-language-server
nixpkgs.gnupg
nixpkgs.gh
nixpkgs.clang-tools
nixpkgs.deno
nixpkgs.yazi
nixpkgs.font-awesome
nixpkgs.gopls
nixpkgs.go
]
++ (
if nixpkgs.stdenv.isLinux
then [
nixpkgs.protonmail-bridge
nixpkgs.pinentry
nixpkgs.signal-desktop
nixpkgs.keepassxc
]
else []
)
++ (
if machinename == "capybara"
then [
nixpkgs.steam-run
nixpkgs.discord
nixpkgs.anki-bin
]
else []
);
home.file.".ideavimrc".source = ./ideavimrc;
home.file.".config/yt-dlp/config".source = ./youtube-dl.conf;

View File

@@ -1,5 +1,5 @@
{nixpkgs, ...}: {
home.packages = [nixpkgs.firefox-wayland];
home.packages = [nixpkgs.firefox-wayland nixpkgs.jetbrains.rider];
nixpkgs.config.firefox.speechSynthesisSupport = true;
wayland.windowManager.sway = {
@@ -9,16 +9,196 @@
modifier = "Mod4";
terminal = "alacritty";
window = {border = 5;};
bars = [
{command = "${nixpkgs.waybar}/bin/waybar";}
];
};
extraConfig = ''
output Unknown-1 scale 2
extraConfig = builtins.replaceStrings ["@@WL-COPY@@" "@@GRIM@@" "@@SLURP@@"] ["${nixpkgs.wl-clipboard}/bin/wl-copy" "${nixpkgs.grim}/bin/grim" "${nixpkgs.slurp}/bin/slurp"] (builtins.readFile ./sway.conf);
};
programs.waybar = {
enable = true;
settings = {
"bar-0" = {
position = "bottom";
layer = "top";
height = 34;
spacing = 8;
modules-left = ["sway/workspaces" "sway/mode" "sway/scratchpad" "custom/media"];
modules-center = ["sway/window"];
modules-right = ["mpd" "idle_inhibitor" "pulseaudio" "network" "power-profiles-daemon" "cpu" "memory" "temperature" "backlight" "keyboard-state" "sway/language" "battery" "battery#bat2" "clock" "tray" "custom/power"];
"keyboard-state" = {
"numlock" = true;
"capslock" = true;
"format" = "{name} {icon}";
"format-icons" = {
"locked" = "";
"unlocked" = "";
};
};
"sway/mode" = {
"format" = "<span style=\"italic\">{}</span>";
};
"sway/scratchpad" = {
"format" = "{icon} {count}";
"show-empty" = false;
"format-icons" = ["" ""];
"tooltip" = true;
"tooltip-format" = "{app}: {title}";
};
"mpd" = {
"format" = "{stateIcon} {consumeIcon}{randomIcon}{repeatIcon}{singleIcon}{artist} - {album} - {title} ({elapsedTime:%M:%S}/{totalTime:%M:%S}) {songPosition}|{queueLength} {volume}% ";
"format-disconnected" = "Disconnected ";
"format-stopped" = "{consumeIcon}{randomIcon}{repeatIcon}{singleIcon}Stopped ";
"unknown-tag" = "N/A";
"interval" = 5;
"consume-icons" = {
"on" = " ";
};
"random-icons" = {
"off" = "<span color=\"#f53c3c\"></span> ";
"on" = " ";
};
"repeat-icons" = {
"on" = " ";
};
"single-icons" = {
"on" = "1 ";
};
"state-icons" = {
"paused" = "";
"playing" = "";
};
"tooltip-format" = "MPD (connected)";
"tooltip-format-disconnected" = "MPD (disconnected)";
};
"idle_inhibitor" = {
"format" = "{icon}";
"format-icons" = {
"activated" = "";
"deactivated" = "";
};
};
"tray" = {
"spacing" = 20;
};
"clock" = {
"tooltip-format" = "<big>{:%Y %B}</big>\n<tt><small>{calendar}</small></tt>";
"format" = "{:%Y-%m-%d %H:%M:%S}";
"interval" = 1;
};
"cpu" = {
"format" = "{usage}% ";
"tooltip" = false;
};
"memory" = {
"format" = "{}% ";
};
"temperature" = {
"critical-threshold" = 80;
"format" = "{temperatureC}°C {icon}";
"format-icons" = ["" "" ""];
};
"backlight" = {
"format" = "{percent}% {icon}";
"format-icons" = ["" "" "" "" "" "" "" "" ""];
};
"battery" = {
"states" = {
"warning" = 30;
"critical" = 15;
};
"format" = "{capacity}% {icon}";
"format-full" = "{capacity}% {icon}";
"format-charging" = "{capacity}% ";
"format-plugged" = "{capacity}% ";
"format-alt" = "{time} {icon}";
"format-icons" = ["" "" "" "" ""];
};
"battery#bat2" = {
"bat" = "BAT2";
};
"power-profiles-daemon" = {
"format" = "{icon}";
"tooltip-format" = "Power profile: {profile}\nDriver: {driver}";
"tooltip" = true;
"format-icons" = {
"default" = "";
"performance" = "";
"balanced" = "";
"power-saver" = "";
};
};
"network" = {
"format-wifi" = "{essid} ({signalStrength}%) ";
"format-ethernet" = "{bandwidthDownBytes}/{bandwidthUpBytes} ";
"interval" = 5;
"tooltip-format" = "{ifname} via {gwaddr} ";
"format-linked" = "{ifname} (No IP) ";
"format-disconnected" = "Disconnected ";
"format-alt" = "{ifname}: {ipaddr}/{cidr}";
};
"pulseaudio" = {
"format" = "{volume}% {icon} {format_source}";
"format-bluetooth" = "{volume}% {icon} {format_source}";
"format-bluetooth-muted" = " {icon} {format_source}";
"format-muted" = " {format_source}";
"format-source" = "{volume}% ";
"format-source-muted" = "";
"format-icons" = {
"headphone" = "";
"hands-free" = "";
"headset" = "";
"phone" = "";
"portable" = "";
"car" = "";
"default" = ["" "" ""];
};
"on-click" = "${nixpkgs.pavucontrol}/bin/pavucontrol";
};
"custom/media" = {
"format" = "{icon} {text}";
"return-type" = "json";
"max-length" = 40;
"format-icons" = {
"spotify" = "";
"default" = "🎜";
};
"escape" = true;
"exec" = let
python = nixpkgs.python312.withPackages (ppkgs: [ppkgs.pygobject3]);
in "${python}/bin/python ${./modules/waybar/mediaplayer.py} 2> /dev/null";
};
"custom/power" = {
"format" = " ";
"tooltip" = false;
"menu" = "on-click";
"menu-file" = ./modules/waybar/power_menu.xml;
"menu-actions" = {
"shutdown" = "shutdown now";
"reboot" = "reboot";
"suspend" = "systemctl suspend";
"hibernate" = "systemctl hibernate";
};
};
};
};
style = ''
* {
font-family: FontAwesome, Roboto, Helvetica, Arial, sans-serif;
font-size: 13px;
}
'';
};
services.swayidle = {enable = true;};
services.cbatticon = {
lowLevelPercent = 20;
iconType = "standard";
enable = true;
services.gpg-agent = {
enable = nixpkgs.stdenv.isLinux;
pinentryPackage = nixpkgs.pinentry-curses;
};
services.swayidle = {enable = true;};
}

View File

@@ -7,11 +7,13 @@
family = "FiraCode Nerd Font Mono";
};
};
terminal = {shell = "${pkgs.zsh}/bin/zsh";};
};
};
home.packages = [
pkgs.alacritty
(pkgs.nerdfonts.override {fonts = ["FiraCode" "DroidSansMono"];})
pkgs.nerd-fonts.fira-code
pkgs.nerd-fonts.droid-sans-mono
];
}

View File

@@ -75,7 +75,7 @@ in {
# Run `./mail/mutt-oauth2.py /path/to/secret --authorize --verbose` once manually,
# and that will populate /path/to/secret.
# I've left it unencrypted here; the original uses GPG to store it encrypted at rest.
passwordCommand = ''${pkgs.python3}/bin/python ${./mail/mutt-oauth2.py} ${secretsPath}/gmail.txt'';
passwordCommand = ''${pkgs.python3}/bin/python ${./mail/mutt-oauth2.py} ${secretsPath}/gmail.txt 2>/tmp/gmail-passcmd.2.txt'';
realName = "Patrick Stevens";
};
@@ -100,7 +100,7 @@ in {
create = "maildir";
};
realName = "Patrick Stevens";
passwordCommand = "cat ${secretsPath}/btinternet.txt";
passwordCommand = "${pkgs.coreutils}/bin/cat ${secretsPath}/btinternet.txt";
smtp = {
host = "mail.btinternet.com";
port = 465;
@@ -143,13 +143,16 @@ in {
passwordCommand =
# I store the ProtonMail Bridge password here.
# Extracting it from a keychain would be better.
"cat ${secretsPath}/proton.txt";
"${pkgs.coreutils}/bin/cat ${secretsPath}/proton.txt";
smtp = {
host = "127.0.0.1";
port = 1025; # 8126; if using hydroxide
tls = {enable = false;};
};
userName = address;
userName =
if pkgs.stdenv.isLinux
then builtins.head (pkgs.lib.strings.splitString "@" address)
else address;
};
programs.mbsync = {

View File

@@ -13,6 +13,7 @@
terminal = "screen-256color";
extraConfig = ''
set-option -sa terminal-features ',xterm-256color:RGB'
set -g default-command "exec ${pkgs.zsh}/bin/zsh"
'';
};
}

View File

@@ -0,0 +1,199 @@
#!/usr/bin/env python3
# MIT licenced, https://github.com/Alexays/Waybar/blob/dacecb9b265c1c7c36ee43d17526fa95f4e6596f/resources/custom_modules/mediaplayer.py
# See licence in power_menu.xml
import gi
gi.require_version("Playerctl", "2.0")
from gi.repository import Playerctl, GLib
from gi.repository.Playerctl import Player
import argparse
import logging
import sys
import signal
import gi
import json
import os
from typing import List
logger = logging.getLogger(__name__)
def signal_handler(sig, frame):
logger.info("Received signal to stop, exiting")
sys.stdout.write("\n")
sys.stdout.flush()
# loop.quit()
sys.exit(0)
class PlayerManager:
def __init__(self, selected_player=None, excluded_player=[]):
self.manager = Playerctl.PlayerManager()
self.loop = GLib.MainLoop()
self.manager.connect(
"name-appeared", lambda *args: self.on_player_appeared(*args))
self.manager.connect(
"player-vanished", lambda *args: self.on_player_vanished(*args))
signal.signal(signal.SIGINT, signal_handler)
signal.signal(signal.SIGTERM, signal_handler)
signal.signal(signal.SIGPIPE, signal.SIG_DFL)
self.selected_player = selected_player
self.excluded_player = excluded_player.split(',') if excluded_player else []
self.init_players()
def init_players(self):
for player in self.manager.props.player_names:
if player.name in self.excluded_player:
continue
if self.selected_player is not None and self.selected_player != player.name:
logger.debug(f"{player.name} is not the filtered player, skipping it")
continue
self.init_player(player)
def run(self):
logger.info("Starting main loop")
self.loop.run()
def init_player(self, player):
logger.info(f"Initialize new player: {player.name}")
player = Playerctl.Player.new_from_name(player)
player.connect("playback-status",
self.on_playback_status_changed, None)
player.connect("metadata", self.on_metadata_changed, None)
self.manager.manage_player(player)
self.on_metadata_changed(player, player.props.metadata)
def get_players(self) -> List[Player]:
return self.manager.props.players
def write_output(self, text, player):
logger.debug(f"Writing output: {text}")
output = {"text": text,
"class": "custom-" + player.props.player_name,
"alt": player.props.player_name}
sys.stdout.write(json.dumps(output) + "\n")
sys.stdout.flush()
def clear_output(self):
sys.stdout.write("\n")
sys.stdout.flush()
def on_playback_status_changed(self, player, status, _=None):
logger.debug(f"Playback status changed for player {player.props.player_name}: {status}")
self.on_metadata_changed(player, player.props.metadata)
def get_first_playing_player(self):
players = self.get_players()
logger.debug(f"Getting first playing player from {len(players)} players")
if len(players) > 0:
# if any are playing, show the first one that is playing
# reverse order, so that the most recently added ones are preferred
for player in players[::-1]:
if player.props.status == "Playing":
return player
# if none are playing, show the first one
return players[0]
else:
logger.debug("No players found")
return None
def show_most_important_player(self):
logger.debug("Showing most important player")
# show the currently playing player
# or else show the first paused player
# or else show nothing
current_player = self.get_first_playing_player()
if current_player is not None:
self.on_metadata_changed(current_player, current_player.props.metadata)
else:
self.clear_output()
def on_metadata_changed(self, player, metadata, _=None):
logger.debug(f"Metadata changed for player {player.props.player_name}")
player_name = player.props.player_name
artist = player.get_artist()
title = player.get_title()
title = title.replace("&", "&amp;")
track_info = ""
if player_name == "spotify" and "mpris:trackid" in metadata.keys() and ":ad:" in player.props.metadata["mpris:trackid"]:
track_info = "Advertisement"
elif artist is not None and title is not None:
track_info = f"{artist} - {title}"
else:
track_info = title
if track_info:
if player.props.status == "Playing":
track_info = "" + track_info
else:
track_info = "" + track_info
# only print output if no other player is playing
current_playing = self.get_first_playing_player()
if current_playing is None or current_playing.props.player_name == player.props.player_name:
self.write_output(track_info, player)
else:
logger.debug(f"Other player {current_playing.props.player_name} is playing, skipping")
def on_player_appeared(self, _, player):
logger.info(f"Player has appeared: {player.name}")
if player.name in self.excluded_player:
logger.debug(
"New player appeared, but it's in exclude player list, skipping")
return
if player is not None and (self.selected_player is None or player.name == self.selected_player):
self.init_player(player)
else:
logger.debug(
"New player appeared, but it's not the selected player, skipping")
def on_player_vanished(self, _, player):
logger.info(f"Player {player.props.player_name} has vanished")
self.show_most_important_player()
def parse_arguments():
parser = argparse.ArgumentParser()
# Increase verbosity with every occurrence of -v
parser.add_argument("-v", "--verbose", action="count", default=0)
parser.add_argument("-x", "--exclude", "- Comma-separated list of excluded player")
# Define for which player we"re listening
parser.add_argument("--player")
parser.add_argument("--enable-logging", action="store_true")
return parser.parse_args()
def main():
arguments = parse_arguments()
# Initialize logging
if arguments.enable_logging:
logfile = os.path.join(os.path.dirname(
os.path.realpath(__file__)), "media-player.log")
logging.basicConfig(filename=logfile, level=logging.DEBUG,
format="%(asctime)s %(name)s %(levelname)s:%(lineno)d %(message)s")
# Logging is set by default to WARN and higher.
# With every occurrence of -v it's lowered by one
logger.setLevel(max((3 - arguments.verbose) * 10, 0))
logger.info("Creating player manager")
if arguments.player:
logger.info(f"Filtering for player: {arguments.player}")
if arguments.exclude:
logger.info(f"Exclude player {arguments.exclude}")
player = PlayerManager(arguments.player, arguments.exclude)
player.run()
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,53 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Source: https://github.com/Alexays/Waybar/blob/dacecb9b265c1c7c36ee43d17526fa95f4e6596f/resources/custom_modules/power_menu.xml -->
<!-- MIT licence available at https://github.com/Alexays/Waybar/blob/dacecb9b265c1c7c36ee43d17526fa95f4e6596f/LICENSE
MIT License
Copyright (c) 2018 Alex
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
-->
<interface>
<object class="GtkMenu" id="menu">
<child>
<object class="GtkMenuItem" id="suspend">
<property name="label">Suspend</property>
</object>
</child>
<child>
<object class="GtkMenuItem" id="hibernate">
<property name="label">Hibernate</property>
</object>
</child>
<child>
<object class="GtkMenuItem" id="shutdown">
<property name="label">Shutdown</property>
</object>
</child>
<child>
<object class="GtkSeparatorMenuItem" id="delimiter1"/>
</child>
<child>
<object class="GtkMenuItem" id="reboot">
<property name="label">Reboot</property>
</object>
</child>
</object>
</interface>

View File

@@ -30,3 +30,9 @@ bindkey '^X^E' edit-command-line
bindkey -e
PATH="$PATH:$HOME/.cargo/bin"
if [[ -z "$TMUX" ]]; then
tmux new-session -A -s default
fi
ttyctl -f

View File

@@ -73,13 +73,14 @@ function RegisterSolution(sln_path)
end
local whichkey = require("which-key")
whichkey.register({
s = {
name = ".NET solution",
b = { BuildDotNetSolution, "Build .NET solution" },
t = { TestDotNetSolution, "Test .NET solution" },
whichkey.add({
{
"<localleader>s",
desc = ".NET solution",
},
}, { prefix = vim.api.nvim_get_var("maplocalleader"), buffer = vim.api.nvim_get_current_buf() })
{ "<localleader>sb", BuildDotNetSolution, desc = "Build .NET solution" },
{ "<localleader>st", TestDotNetSolution, desc = "Test .NET solution" },
}, { buffer = vim.api.nvim_get_current_buf() })
end
local function find_nearest_slns()
@@ -153,8 +154,612 @@ vim.api.nvim_create_autocmd({ "BufReadPost", "BufNewFile" }, {
})
vim.api.nvim_create_autocmd("FileType", {
pattern = { "fsharp", "cs" },
pattern = { "fsharp", "cs", "fsharp_project" },
callback = function()
FindAndRegisterSolution(false)
end,
})
-- For what I'm sure are reasons, Lua appears to have nothing in its standard library
---@generic K
---@generic V1
---@generic V2
---@param tbl table<K, V1>
---@param f fun(V1): V2
---@return table<K, V2>
local function map(tbl, f)
local t = {}
for k, v in pairs(tbl) do
t[k] = f(v)
end
return t
end
---@generic K
---@generic V
---@param tbl table<K, V>
---@param f fun(V1): nil
local function iter(tbl, f)
for _, v in pairs(tbl) do
f(v)
end
end
---@generic K
---@generic V
---@param tbl table<K, V>
---@param predicate fun(V): boolean
---@return boolean, V
local function find(tbl, predicate)
for _, v in pairs(tbl) do
if predicate(v) then
return true, v
end
end
return false, nil
end
---@class (exact) NuGetVersion
---@field major number
---@field minor number
---@field patch number
---@field suffix? string
local NuGetVersion = {}
---@param v NuGetVersion
---@nodiscard
---@return string
local function nuGetVersionToString(v)
local s = tostring(v.major) .. "." .. tostring(v.minor) .. "." .. tostring(v.patch)
if v.suffix then
return s .. v.suffix
else
return s
end
end
local function get_all_variables()
local variables = {}
local lines = vim.api.nvim_buf_get_lines(0, 0, -1, false)
for _, line in ipairs(lines) do
local var_name, var_value = line:match("<(%w+)>([^<]+)</(%w+)>")
if var_name and var_value then
variables[var_name] = var_value
end
end
return variables
end
local function resolve_variable(version, variables)
if version:match("^%$%((.+)%)$") then
local var_name = version:match("^%$%((.+)%)$")
return variables[var_name] or nil
end
return nil
end
---@param v string
---@nodiscard
---@return NuGetVersion
local function parse_version(v)
local variables = get_all_variables()
local major, minor, patch, pre = v:match("(%d+)%.(%d+)%.(%d+)(.*)$")
if major == nil then
local resolved = resolve_variable(v, variables)
if resolved ~= nil then
return parse_version(resolved)
end
end
-- TODO: why does this type-check if you remove the field names?
return {
major = tonumber(major) or 0,
minor = tonumber(minor) or 0,
patch = tonumber(patch) or 0,
suffix = pre or nil,
}
end
---@param a NuGetVersion
---@param b NuGetVersion
---@nodiscard
---@return boolean
local function compare_versions(a, b)
if a.major ~= b.major then
return a.major < b.major
elseif a.minor ~= b.minor then
return a.minor < b.minor
elseif a.patch ~= b.patch then
return a.patch < b.patch
elseif a.suffix and not b.suffix then
return false
elseif not a.suffix and b.suffix then
return true
else
return a.suffix < b.suffix
end
end
---@param url string
---@nodiscard
local function curl_sync(url)
local command = string.format("_CURL_ --silent --compressed --fail '%s'", url)
local response = vim.fn.system(command)
if vim.v.shell_error ~= 0 then
print("Failed to fetch " .. url)
return nil
end
local success, decoded = pcall(vim.fn.json_decode, response)
if not success then
print("Failed to decode JSON from curl at " .. url)
return nil
end
return decoded
end
---@param url string
---@param callback fun(table): nil
---@return nil
local function curl(url, callback)
local stdout = vim.uv.new_pipe(false)
local stdout_text = ""
local handle
handle, _ = vim.uv.spawn(
"_CURL_",
{ args = { "--silent", "--compressed", "--fail", url }, stdio = { nil, stdout, nil } },
vim.schedule_wrap(function(code, _)
stdout:read_stop()
stdout:close()
if handle and not handle:is_closing() then
handle:close()
end
if code ~= 0 then
print("Failed to fetch " .. url)
end
local success, decoded = pcall(vim.fn.json_decode, stdout_text)
if not success then
print("Failed to decode JSON from curl at " .. url .. "\n" .. stdout_text)
end
callback(decoded)
end)
)
vim.uv.read_start(stdout, function(err, data)
assert(not err, err)
if data then
stdout_text = stdout_text .. data
end
end)
end
local _nugetIndex
local _packageBaseAddress
---@param callback fun(): nil
local function populate_nuget_api(callback)
if _nugetIndex ~= nil then
callback()
end
local url = string.format("https://api.nuget.org/v3/index.json")
local function handle(decoded)
local default_nuget_reg = "https://api.nuget.org/v3/registration5-semver1/"
local default_base_address = "https://api.nuget.org/v3-flatcontainer/"
if not decoded then
print("Failed to fetch NuGet index; falling back to default")
_nugetIndex = default_nuget_reg
_packageBaseAddress = default_base_address
else
local resources = decoded["resources"]
if resources == nil then
print("Failed to parse: " .. decoded .. tostring(decoded))
for k, v in pairs(decoded) do
print(k .. ": " .. tostring(v))
end
callback()
return
end
local resourceSuccess, regUrl = find(resources, function(o)
return o["@type"] == "RegistrationsBaseUrl/3.6.0"
end)
if not resourceSuccess then
print("Failed to find endpoint in NuGet index; falling back to default")
_nugetIndex = default_nuget_reg
else
_nugetIndex = regUrl["@id"]
end
local baseAddrSuccess, baseAddrUrl = find(resources, function(o)
return o["@type"] == "PackageBaseAddress/3.0.0"
end)
if not baseAddrSuccess then
print("Failed to find endpoint in NuGet index; falling back to default")
_packageBaseAddress = default_base_address
else
_packageBaseAddress = baseAddrUrl["@id"]
end
end
callback()
end
curl(url, handle)
end
---@return nil
local function populate_nuget_api_sync()
if _nugetIndex ~= nil then
return
end
local url = string.format("https://api.nuget.org/v3/index.json")
local decoded = curl_sync(url)
local default_nuget_reg = "https://api.nuget.org/v3/registration5-semver1/"
local default_base_address = "https://api.nuget.org/v3-flatcontainer/"
if not decoded then
print("Failed to fetch NuGet index; falling back to default")
_nugetIndex = default_nuget_reg
_packageBaseAddress = default_base_address
else
local resources = decoded["resources"]
local resourceSuccess, regUrl = find(resources, function(o)
return o["@type"] == "RegistrationsBaseUrl/3.6.0"
end)
if not resourceSuccess then
print("Failed to find endpoint in NuGet index; falling back to default")
_nugetIndex = default_nuget_reg
else
_nugetIndex = regUrl["@id"]
end
local baseAddrSuccess, baseAddrUrl = find(resources, function(o)
return o["@type"] == "PackageBaseAddress/3.0.0"
end)
if not baseAddrSuccess then
print("Failed to find endpoint in NuGet index; falling back to default")
_packageBaseAddress = default_base_address
else
_packageBaseAddress = baseAddrUrl["@id"]
end
end
end
---@return nil
---@param callback fun(nugetIndex: string): nil
local function get_nuget_index(callback)
populate_nuget_api(function()
callback(_nugetIndex)
end)
end
---@return nil
---@param callback fun(packageBaseIndex: string): nil
local function get_package_base_addr(callback)
populate_nuget_api(function()
callback(_packageBaseAddress)
end)
end
---@return string
local function get_package_base_addr_sync()
populate_nuget_api_sync()
return _packageBaseAddress
end
local _package_versions_cache = {}
---@param package_name string
---@return NuGetVersion[]
local function get_package_versions_sync(package_name)
if _package_versions_cache[package_name] ~= nil then
return _package_versions_cache[package_name]
end
local base = get_package_base_addr_sync()
local url = base .. string.format("%s/index.json", package_name:lower())
local decoded = curl_sync(url)
if not decoded then
print("Failed to fetch package versions")
return {}
end
local versions = map(decoded.versions, parse_version)
table.sort(versions, function(a, b)
return compare_versions(b, a)
end)
_package_versions_cache[package_name] = versions
return versions
end
---@param package_name string
---@param callback fun(v: NuGetVersion[]): nil
---@return nil
local function get_package_versions(package_name, callback)
if _package_versions_cache[package_name] ~= nil then
callback(_package_versions_cache[package_name])
end
local function handle(base)
local url = base .. string.format("%s/index.json", package_name:lower())
local function handle2(decoded)
if not decoded then
print("Failed to fetch package versions")
callback({})
end
local versions = map(decoded.versions, parse_version)
table.sort(versions, function(a, b)
return compare_versions(b, a)
end)
_package_versions_cache[package_name] = versions
callback(versions)
end
curl(url, handle2)
end
get_package_base_addr(handle)
end
---@param version NuGetVersion
---@return nil
local function update_package_version(version)
local line = vim.api.nvim_get_current_line()
local new_line = line:gsub('Version="[^"]+"', string.format('Version="%s"', nuGetVersionToString(version)))
vim.api.nvim_set_current_line(new_line)
end
-- A map from package to { packageWeDependOn: version }.
--- @type table<string, table<string, string>>
local _package_dependency_cache = {}
---@param package_name string
---@param version NuGetVersion
---@param callback fun(result: table<string, string>): nil
---@return nil
local function get_package_dependencies(package_name, version, callback)
local key = package_name .. "@" .. nuGetVersionToString(version)
local cache_hit = _package_dependency_cache[key]
if cache_hit ~= nil then
callback(cache_hit)
return
end
local function handle1(index)
local url = index .. string.format("%s/%s.json", package_name:lower(), nuGetVersionToString(version):lower())
local function handle(response)
if not response then
print(
"Failed to get dependencies of "
.. package_name
.. " at version "
.. version
.. " : unsuccessful response to "
.. url
)
return
end
local entry_url = response["catalogEntry"]
local function handle2(catalog_entry)
if not catalog_entry then
print(
"Failed to get dependencies of "
.. package_name
.. " at version "
.. version
.. " : unsuccessful response to "
.. entry_url
)
return
end
local result = {}
if catalog_entry["dependencyGroups"] then
iter(catalog_entry["dependencyGroups"], function(grp)
if grp["dependencies"] then
for _, dep in pairs(grp["dependencies"]) do
result[dep["id"]] = dep["range"]
end
end
end)
end
_package_dependency_cache[key] = result
callback(result)
end
curl(entry_url, handle2)
end
curl(url, handle)
end
get_nuget_index(handle1)
end
---@return table<string, NuGetVersion>
---@nodiscard
local function get_all_package_references()
local packages = {}
local lines = vim.api.nvim_buf_get_lines(0, 0, -1, false)
for _, line in ipairs(lines) do
local package_name = line:match('PackageReference Include="([^"]+)"')
or line:match('PackageReference Update="([^"]+)"')
local version = line:match('Version="([^"]+)"')
if package_name and version then
if not packages[package_name] then
packages[package_name] = {}
end
table.insert(packages[package_name], parse_version(version))
end
end
return packages
end
function ClearNuGetDependencyCache()
for k, _ in pairs(_package_dependency_cache) do
_package_dependency_cache[k] = nil
end
end
vim.api.nvim_create_user_command("ClearNuGetDependencyCache", ClearNuGetDependencyCache, {})
function PrintNuGetDependencyCache()
for k, v in pairs(_package_dependency_cache) do
print(k .. ":")
for dep, ver in pairs(v) do
print(" " .. dep .. ": " .. ver)
end
end
end
vim.api.nvim_create_user_command("PrintNuGetDependencyCache", PrintNuGetDependencyCache, {})
local function prefetch_dependencies()
local packages = get_all_package_references()
local function process_package(package_name, versions, callback)
local count = #versions
for _, version in ipairs(versions) do
vim.schedule(function()
get_package_dependencies(package_name, version, function(_)
count = count - 1
if count == 0 then
callback()
end
end)
end)
end
end
local total_packages = 0
for _ in pairs(packages) do
total_packages = total_packages + 1
end
local processed_packages = 0
for package_name, versions in pairs(packages) do
process_package(package_name, versions, function()
local function handle(package_versions)
if package_versions then
process_package(package_name, package_versions, function()
processed_packages = processed_packages + 1
if processed_packages == total_packages then
print("All dependencies prefetched")
end
end)
else
processed_packages = processed_packages + 1
if processed_packages == total_packages then
print("All dependencies prefetched")
end
end
end
get_package_versions(package_name, handle)
end)
end
end
---@param v1 NuGetVersion
---@param v2 NuGetVersion
---@return boolean
---@nodiscard
local function nuget_versions_equal(v1, v2)
return v1.major == v2.major and v1.minor == v2.minor and v1.patch == v2.patch and v1.suffix == v2.suffix
end
vim.api.nvim_create_autocmd("FileType", {
pattern = { "fsharp_project", "csharp_project", "xml" },
callback = function()
function UpdateNuGetVersion()
local line = vim.api.nvim_get_current_line()
local package_name = line:match('PackageReference Include="([^"]+)"')
or line:match('PackageReference Update="([^"]+)"')
if not package_name then
print("No package reference found on the current line")
return
end
local current_version = parse_version(line:match('Version="([^"]+)"'))
if not current_version then
print("oh no!")
end
local package_versions = get_package_versions_sync(package_name)
if #package_versions == 0 then
print("No versions found for the package")
return
end
local pickers = require("telescope.pickers")
local finders = require("telescope.finders")
local previewers = require("telescope.previewers")
pickers
.new({}, {
prompt_title = string.format("Select version for %s", package_name),
finder = finders.new_table({
results = package_versions,
entry_maker = function(entry)
local val = nuGetVersionToString(entry)
local display_value = val
if current_version and nuget_versions_equal(entry, current_version) then
display_value = "[CURRENT] " .. val
end
return {
value = entry,
display = display_value,
ordinal = entry,
}
end,
}),
previewer = previewers.new_buffer_previewer({
define_preview = function(self, entry, _)
local bufnr = self.state.bufnr
vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, { "Loading..." })
get_package_dependencies(package_name, entry.value, function(package_dependencies)
if not package_dependencies then
vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, { "No dependencies found" })
return
end
local display = {}
table.insert(
display,
"Dependencies for "
.. package_name
.. " at version "
.. nuGetVersionToString(entry.value)
.. ":"
)
for dep, range in pairs(package_dependencies) do
table.insert(display, dep .. ": " .. range)
end
local ok, err = pcall(vim.api.nvim_buf_set_lines, bufnr, 0, -1, false, display)
if not ok then
-- If we can't set lines, the window's probably gone. Ignore.
return
end
end)
end,
}),
attach_mappings = function(_, mapping)
mapping("i", "<CR>", function(prompt_bufnr)
local selection = require("telescope.actions.state").get_selected_entry()
require("telescope.actions").close(prompt_bufnr)
update_package_version(selection.value)
end)
return true
end,
})
:find()
end
local whichkey = require("which-key")
whichkey.add({
{ "<localleader>n", desc = "NuGet" },
{ "<localleader>nu", UpdateNuGetVersion, desc = "Upgrade NuGet versions" },
}, { buffer = vim.api.nvim_get_current_buf() })
vim.schedule(prefetch_dependencies)
end,
})

View File

@@ -1,4 +1,3 @@
vim.g.python3_host_prog = "%PYTHONENV%/bin/python"
vim.opt.mouse = ""
vim.opt.history = 500
vim.opt.background = "dark"
@@ -170,8 +169,6 @@ function DisplayAllMappingsWithTelescope()
local function accumulate(tree)
tree:walk(function(node)
-- Note: we could (if desired) view all groups, because the `node.mapping` table looks like this:
-- { prefix = "g", group = true, keys = {...}}
if node.mapping then
local mapping = node.mapping
if not mapping.group then
@@ -225,66 +222,69 @@ function ToggleSpell()
vim.cmd("setlocal spell!")
end
whichkey.register({
[vim.api.nvim_get_var("maplocalleader")] = {
DisplayAllMappingsWithTelescope,
"View all mappings",
whichkey.add({
{
"<localleader><localleader>",
function()
require("which-key").show({ global = false })
end,
desc = "View all mappings",
},
m = {
p = { MarkdownPreview, "Preview Markdown in Lynx" },
d = { RemoveCarriageReturn, "Delete carriage returns from file" },
},
["j"] = {
FormatJson,
"Auto-format JSON",
},
}, { prefix = vim.api.nvim_get_var("maplocalleader") })
whichkey.register({
g = {
{ "<localleader>mp", MarkdownPreview, desc = "Preview Markdown in Lynx" },
{ "<localleader>md", RemoveCarriageReturn, desc = "Delete carriage returns from file" },
{ "<localleader>j", FormatJson, desc = "Auto-format JSON" },
})
whichkey.add({
{
"<leader>g",
function()
require("telescope.builtin").grep_string()
end,
"Find instances of text under cursor",
desc = "Find instances of text under cursor",
},
h = {
name = "Find historical...",
f = {
function()
require("telescope.builtin").oldfiles()
end,
"List previously open files",
},
c = {
function()
require("telescope.builtin").command_history()
end,
"List previously run commands",
},
s = {
function()
require("telescope.builtin").search_history()
end,
"List previously run searches",
},
{ "<leader>h", desc = "Find historical..." },
{
"<leader>hf",
function()
require("telescope.builtin").oldfiles()
end,
desc = "List previously open files",
},
m = {
{
"<leader>hc",
function()
require("telescope.builtin").command_history()
end,
desc = "List previously run commands",
},
{
"<leader>hs",
function()
require("telescope.builtin").search_history()
end,
desc = "List previously run searches",
},
{
"<leader>m",
function()
require("telescope.builtin").marks()
end,
"List marks",
desc = "List marks",
},
["cd"] = {
ChangeToCurrentDirectory,
"Switch CWD to the directory of the open buffer",
},
["ss"] = {
ToggleSpell,
"Toggle spell-checker on or off",
},
[vim.api.nvim_get_var("mapleader")] = {
{ "<leader>cd", ChangeToCurrentDirectory, desc = "Switch CWD to the directory of the open buffer" },
{ "<leader>ss", ToggleSpell, desc = "Toggle spell-checker on or off" },
{
"<leader><leader>",
function()
require("telescope.builtin").find_files()
end,
"Find files by name",
desc = "Find files by name",
},
}, { prefix = vim.api.nvim_get_var("mapleader") })
})
vim.api.nvim_create_autocmd({ "BufRead", "BufNewFile" }, {
pattern = { "Directory.Build.props", "*.fsproj", "*.csproj" },
callback = function()
vim.bo.filetype = "xml"
end,
})

View File

@@ -2,23 +2,6 @@ vim.g["fsharp#fsautocomplete_command"] = { "fsautocomplete" }
vim.g["fsharp#show_signature_on_cursor_move"] = 1
vim.g["fsharp#fsi_keymap"] = "none"
-- MASSIVE HACK - raised https://github.com/ionide/Ionide-vim/pull/78
local function captureLoadedProjects()
vim.fn.execute("redir => g:massive_hack_patrick_capture")
vim.fn.execute("call fsharp#showLoadedProjects()")
vim.fn.execute("redir END")
local output = vim.fn.eval("g:massive_hack_patrick_capture")
local projects = {}
for line in output:gmatch("[^\r\n]+") do
local project = line:gsub("^%s*-%s*", "")
table.insert(projects, project)
end
return projects
end
-- Supply nil to get all loaded F# projects and build them.
local function BuildFSharpProjects(projects)
local function on_line(data, _, context)
@@ -76,7 +59,7 @@ local function BuildFSharpProjects(projects)
end
if not projects then
projects = captureLoadedProjects()
projects = vim.fn["fsharp#getLoadedProjects"]()
end
if projects then
local total_projects = 0
@@ -107,7 +90,7 @@ vim.api.nvim_create_user_command("BuildFSharpProject", function(opts)
.new({}, {
prompt_title = "Projects",
finder = finders.new_table({
results = captureLoadedProjects(),
results = vim.fn["fsharp#getLoadedProjects"](),
}),
sorter = conf.generic_sorter({}),
attach_mappings = function(prompt_buf, _)
@@ -173,7 +156,7 @@ vim.api.nvim_create_user_command("RunFSharpProject", function(opts)
.new({}, {
prompt_title = "Projects",
finder = finders.new_table({
results = captureLoadedProjects(),
results = vim.fn["fsharp#getLoadedProjects"](),
}),
sorter = conf.generic_sorter({}),
attach_mappings = function(prompt_buf, _)
@@ -202,7 +185,7 @@ vim.api.nvim_create_user_command("PublishFSharpProject", function(opts)
.new({}, {
prompt_title = "Projects",
finder = finders.new_table({
results = captureLoadedProjects(),
results = vim.fn["fsharp#getLoadedProjects"](),
}),
sorter = conf.generic_sorter({}),
attach_mappings = function(prompt_buf, _)
@@ -223,28 +206,19 @@ vim.api.nvim_create_autocmd("FileType", {
callback = function()
local status, whichkey = pcall(require, "which-key")
if status then
whichkey.register({
f = {
name = "F#",
t = { ":call fsharp#showTooltip()<CR>", "Show F# Tooltip" },
["si"] = { ":call fsharp#toggleFsi()<CR>", "Toggle FSI (F# Interactive)" },
["sl"] = { ":call fsharp#sendLineToFsi()<cr>", "Send line to FSI (F# Interactive)" },
r = {
name = "Run F# project",
d = { ":RunFSharpProject Debug", "Run F# project in debug configuration" },
r = { ":RunFSharpProject Release", "Run F# project in release configuration" },
},
p = {
":PublishFSharpProject",
"Publish F# project",
},
b = {
"Build F# project",
a = { BuildFSharpProjects, "Build all projects" },
s = { ":BuildFSharpProject", "Build specified project" },
},
},
}, { prefix = vim.api.nvim_get_var("maplocalleader"), buffer = vim.api.nvim_get_current_buf() })
whichkey.add({
{ "<localleader>f", desc = "F#" },
{ "<localleader>ft", ":call fsharp#showTooltip()<CR>", desc = "Show F# Tooltip" },
{ "<localleader>fsi", ":call fsharp#toggleFsi()<CR>", desc = "Toggle FSI (F# Interactive)" },
{ "<localleader>fsl", ":call fsharp#sendLineToFsi()<cr>", desc = "Send line to FSI (F# Interactive)" },
{ "<localleader>fr", desc = "Run F# project" },
{ "<localleader>frd", ":RunFSharpProject Debug", desc = "Run F# project in debug configuration" },
{ "<localleader>frr", ":RunFSharpProject Release", desc = "Run F# project in release configuration" },
{ "<localleader>fp", ":PublishFSharpProject", desc = "Publish F# project" },
{ "<localleader>fb", desc = "Build F# project" },
{ "<localleader>fba", BuildFSharpProjects, desc = "Build all projects" },
{ "<localleader>fbs", ":BuildFSharpProject", desc = "Build specified project" },
}, { buffer = vim.api.nvim_get_current_buf() })
else
vim.api.nvim_set_keymap("n", "<localleader>ft", ":call fsharp#showTooltip()<CR>", { noremap = true })
vim.api.nvim_set_keymap("n", "<localleader>fsi", ":call fsharp#toggleFsi()<CR>", { noremap = true })

View File

@@ -2,16 +2,16 @@ require("lspconfig")["leanls"].setup({})
require("lean").setup({})
require("which-key").register({
l = {
i = { "<Cmd>LeanInfoviewToggle<CR>", "Toggle Lean info view" },
p = { "<Cmd>LeanInfoviewPinTogglePause<CR>", "Pause Lean info view" },
s = { "<Cmd>LeanSorryFill<CR>", "Fill open goals with sorry" },
w = { "<Cmd>LeanInfoviewEnableWidgets<CR>", "Enable Lean widgets" },
W = { "<Cmd>LeanInfoviewDisableWidgets<CR>", "Disable Lean widgets" },
["?"] = {
"<Cmd>LeanAbbreviationsReverseLookup<CR>",
"Show what Lean abbreviation produces the symbol under the cursor",
},
require("which-key").add({
{ "<localleader>l", desc = "Lean" },
{ "<localleader>li", "<Cmd>LeanInfoviewToggle<CR>", desc = "Toggle Lean info view" },
{ "<localleader>lp", "<Cmd>LeanInfoviewPinTogglePause<CR>", desc = "Pause Lean info view" },
{ "<localleader>ls", "<Cmd>LeanSorryFill<CR>", desc = "Fill open goals with sorry" },
{ "<localleader>lw", "<Cmd>LeanInfoviewEnableWidgets<CR>", desc = "Enable Lean widgets" },
{ "<localleader>lW", "<Cmd>LeanInfoviewDisableWidgets<CR>", desc = "Disable Lean widgets" },
{
"<localleader>l?",
"<Cmd>LeanAbbreviationsReverseLookup<CR>",
desc = "Show what Lean abbreviation produces the symbol under the cursor",
},
}, { prefix = vim.api.nvim_get_var("maplocalleader") })
})

View File

@@ -13,6 +13,10 @@ local schemas = {
["https://json.schemastore.org/dotnet-tools.json"] = "dotnet-tools.json",
}
require("lspconfig")["clangd"].setup({})
require("lspconfig")["gopls"].setup({})
require("lspconfig")["yamlls"].setup({
settings = {
yaml = {
@@ -41,15 +45,18 @@ require("lspconfig")["jsonls"].setup({
},
})
require("lspconfig")["denols"].setup({})
require("lspconfig")["bashls"].setup({})
require("lspconfig")["dockerls"].setup({})
require("lspconfig")["html"].setup({
capabilities = capabilities,
})
require("lspconfig")["ltex"].setup({})
require("lspconfig")["lua_ls"].setup({
on_init = function(client)
if not client.workspace_folders then
return
end
local path = client.workspace_folders[1].name
if vim.uv.fs_stat(path .. "/.luarc.json") or vim.loop.fs_stat(path .. "/.luarc.jsonc") then
return
@@ -116,15 +123,13 @@ end
do
local whichkey_status, whichkey = pcall(require, "which-key")
if whichkey_status then
whichkey.register({
l = {
name = "loclist-related commands",
p = { vim.diagnostic.goto_prev, "Go to previous entry in loclist" },
n = { vim.diagnostic.goto_next, "Go to next entry in loclist" },
l = { ToggleLocList, "Toggle loclist" },
f = { vim.diagnostic.open_float, "Open current loclist entry in floating window" },
},
}, { prefix = vim.api.nvim_get_var("mapleader") })
whichkey.add({
{ "<leader>l", desc = "loclist-related commands" },
{ "<leader>lp", vim.diagnostic.goto_prev, desc = "Go to previous entry in loclist" },
{ "<leader>ln", vim.diagnostic.goto_next, desc = "Go to next entry in loclist" },
{ "<leader>ll", ToggleLocList, desc = "Toggle loclist" },
{ "<leader>lf", vim.diagnostic.open_float, desc = "Open current loclist entry in floating window" },
})
else
vim.keymap.set("n", "<leader>lp", vim.diagnostic.goto_prev)
vim.keymap.set("n", "<leader>ln", vim.diagnostic.goto_next)
@@ -144,48 +149,44 @@ vim.api.nvim_create_autocmd("LspAttach", {
-- Buffer local mappings.
-- See `:help vim.lsp.*` for documentation on any of the below functions
whichkey.register({
g = {
name = "Go-to related commands",
D = { vim.lsp.buf.declaration, "Go to declaration" },
d = { vim.lsp.buf.definition, "Go to definition" },
i = { vim.lsp.buf.implementation, "Go to implementation" },
r = {
function()
require("telescope.builtin").lsp_references()
end,
"Find references",
},
whichkey.add({
{ "g", desc = "Go-to related commands" },
{ "gD", vim.lsp.buf.declaration, desc = "Go to declaration" },
{ "gd", vim.lsp.buf.definition, desc = "Go to definition" },
{ "gi", vim.lsp.buf.implementation, desc = "Go to implementation" },
{
"gr",
function()
require("telescope.builtin").lsp_references()
end,
desc = "Find references",
},
K = { vim.lsp.buf.hover, "Display information about symbol under cursor" },
{ "gK", vim.lsp.buf.hover, desc = "Display information about symbol under cursor" },
})
whichkey.register({
["<C-k>"] = { vim.lsp.buf.signature_help, "Display signature information about symbol under cursor" },
whichkey.add({
{ "<C-k>", vim.lsp.buf.signature_help, desc = "Display signature information about symbol under cursor" },
})
whichkey.register({
w = {
a = { vim.lsp.buf.add_workspace_folder, "Add a path to the workspace folders list" },
r = { vim.lsp.buf.add_workspace_folder, "Remove a path from the workspace folders list" },
l = {
function()
print(vim.inspect(vim.lsp.buf.list_workspace_folders()))
end,
"Show the workspace folders list",
},
whichkey.add({
{ "<leader>w", desc = "Workspace-related commands" },
{ "<leader>wa", vim.lsp.buf.add_workspace_folder, desc = "Add a path to the workspace folders list" },
{ "<leader>wr", vim.lsp.buf.add_workspace_folder, desc = "Remove a path from the workspace folders list" },
{
"<leader>wl",
function()
print(vim.inspect(vim.lsp.buf.list_workspace_folders()))
end,
desc = "Show the workspace folders list",
},
f = {
{
"<leader>f",
function()
vim.lsp.buf.format({ async = true })
end,
"Autoformat",
desc = "Autoformat",
},
c = {
a = { vim.lsp.buf.code_action, "Select a code action" },
},
r = {
n = { vim.lsp.buf.rename, "Rename variable" },
},
D = { vim.lsp.buf.type_definition, "Go to type definition" },
}, { prefix = vim.api.nvim_get_var("mapleader") })
{ "<leader>ca", vim.lsp.buf.code_action, desc = "Select a code action" },
{ "<leader>rn", vim.lsp.buf.rename, desc = "Rename variable" },
{ "<leader>D", vim.lsp.buf.type_definition, desc = "Go to type definition" },
})
end,
})

View File

@@ -2,14 +2,10 @@ require("dap-python").setup("%PYTHONENV%/bin/python")
do
local whichkey = require("which-key")
whichkey.register({
['pd'] = {
"Debugger-related commands",
t = {
"Tests",
f = { require("dap-python").test_class, "Run Python tests in the current file" },
c = { require("dap-python").test_method, "Run the Python test under the cursor" },
},
},
}, { prefix = vim.api.nvim_get_var("maplocalleader") })
whichkey.add({
{ "<localleader>pd", desc = "Debugger-related commands" },
{ "<localleader>pdt", desc = "Tests" },
{ "<localleader>pdtf", require("dap-python").test_class, desc = "Run Python tests in the current file" },
{ "<localleader>pdtc", require("dap-python").test_method, desc = "Run the Python test under the cursor" },
})
end

View File

@@ -30,37 +30,36 @@ dap.configurations.cs = {
do
local whichkey = require("which-key")
whichkey.register({
d = {
name = "Debugger-related commands",
o = { dap.step_over, "Step over" },
i = { dap.step_into, "Step into" },
c = { dap.continue, "Continue" },
C = { dap.run_last, "Run with last debug configuration" },
b = { dap.toggle_breakpoint, "Toggle breakpoint" },
r = { dap.repl.open, "Open debug repl" },
v = {
name = "Commands to view debugger state",
v = {
function()
dap_ui.hover()
end,
"View value of expression under cursor",
},
s = {
function()
dap_ui.sidebar(dap_ui.scopes).open()
end,
"View values of all variables in all scopes",
},
f = {
function()
dap_ui.sidebar(dap_ui.frames).open()
end,
"View stack frames",
},
},
t = { dap.terminate, "Terminate/stop/end debug session" },
whichkey.add({
{ "<localleader>d", desc = "Debugger-related commands" },
{ "<localleader>do", dap.step_over, desc = "Step over" },
{ "<localleader>di", dap.step_into, desc = "Step into" },
{ "<localleader>dc", dap.continue, desc = "Continue" },
{ "<localleader>dC", dap.run_last, desc = "Run with last debug configuration" },
{ "<localleader>db", dap.toggle_breakpoint, desc = "Toggle breakpoint" },
{ "<localleader>dr", dap.repl.open, desc = "Open debug repl" },
{ "<localleader>dv", desc = "Commands to view debugger state" },
{
"<localleader>dvv",
function()
dap_ui.hover()
end,
desc = "View value of expression under cursor",
},
}, { prefix = vim.api.nvim_get_var("maplocalleader") })
{
"<localleader>dvs",
function()
dap_ui.sidebar(dap_ui.scopes).open()
end,
desc = "View values of all variables in all scopes",
},
{
"<localleader>dvf",
function()
dap_ui.sidebar(dap_ui.frames).open()
end,
desc = "View stack frames",
},
{ "<localleader>dt", dap.terminate, desc = "Terminate/stop/end debug session" },
})
end

View File

@@ -55,12 +55,10 @@ end
do
local whichkey = require("which-key")
whichkey.register({
['pt'] = {
"Run Python tests",
f = { RunPythonTestsInFile, "Run Python tests in the current file" },
a = { RunAllPythonTests, "Run all Python tests" },
c = { RunPythonTestAtCursor, "Run the Python test under the cursor" },
},
}, { prefix = vim.api.nvim_get_var("maplocalleader") })
whichkey.add({
{ "<localleader>pt", desc = "Run Python tests" },
{ "<localleader>ptf", RunPythonTestsInFile, desc = "Run Python tests in the current file" },
{ "<localleader>pta", RunAllPythonTests, desc = "Run all Python tests" },
{ "<localleader>ptc", RunPythonTestAtCursor, desc = "Run the Python test under the cursor" },
})
end

View File

@@ -1,5 +1,8 @@
require("tokyonight").setup({
style = "night",
on_colors = function(colors)
colors.border = "#565f89"
end,
})
vim.cmd([[colorscheme tokyonight]])

View File

@@ -84,17 +84,16 @@ end
do
local whichkey = require("which-key")
whichkey.register({
['pv'] = {
name = "Python virtual environment-related commands",
c = { CreateVenv, "Create virtual environment" },
l = { SelectVenv, "Load virtual environment" },
o = {
function()
vim.cmd("VenvSelect")
end,
"Choose (override) new virtual environment",
},
whichkey.add({
{ "<localleader>pv", desc = "Python virtual environment-related commands" },
{ "<localleader>pvc", CreateVenv, desc = "Create virtual environment" },
{ "<localleader>pvl", SelectVenv, desc = "Load virtual environment" },
{
"<localleader>pvo",
function()
vim.cmd("VenvSelect")
end,
desc = "Choose (override) new virtual environment",
},
}, { prefix = vim.api.nvim_get_var("maplocalleader") })
})
end

View File

@@ -18,67 +18,19 @@ require("which-key").setup({
g = true, -- bindings for prefixed with g
},
},
-- add operators that will trigger motion and text object completion
-- to enable all native operators, set the preset / operators plugin above
operators = { gc = "Comments" },
key_labels = {
-- override the label used to display some keys. It doesn't effect WK in any other way.
-- For example:
-- ["<space>"] = "SPC",
-- ["<cr>"] = "RET",
-- ["<tab>"] = "TAB",
},
motions = {
count = true,
},
icons = {
breadcrumb = "»", -- symbol used in the command line area that shows your active key combo
separator = "", -- symbol used between a key and it's label
group = "+", -- symbol prepended to a group
},
popup_mappings = {
scroll_down = "<c-d>", -- binding to scroll down inside the popup
scroll_up = "<c-u>", -- binding to scroll up inside the popup
},
window = {
border = "none", -- none, single, double, shadow
position = "bottom", -- bottom, top
margin = { 1, 0, 1, 0 }, -- extra window margin [top, right, bottom, left]. When between 0 and 1, will be treated as a percentage of the screen size.
padding = { 1, 2, 1, 2 }, -- extra window padding [top, right, bottom, left]
winblend = 0, -- value between 0-100 0 for fully opaque and 100 for fully transparent
zindex = 1000, -- positive value to position WhichKey above other floating windows.
},
layout = {
height = { min = 4, max = 25 }, -- min and max height of the columns
width = { min = 20, max = 50 }, -- min and max width of the columns
spacing = 3, -- spacing between columns
align = "left", -- align columns left, center or right
},
ignore_missing = false, -- enable this to hide mappings for which you didn't specify a label
hidden = { "<silent>", "<cmd>", "<Cmd>", "<CR>", "^:", "^ ", "^call ", "^lua " }, -- hide mapping boilerplate
show_help = true, -- show a help message in the command line for using WhichKey
show_keys = true, -- show the currently pressed key and its label as a message in the command line
triggers = "auto", -- automatically setup triggers
-- triggers = {"<leader>"} -- or specifiy a list manually
-- list of triggers, where WhichKey should not wait for timeoutlen and show immediately
triggers_nowait = {
-- marks
"`",
"'",
"g`",
"g'",
-- registers
'"',
"<c-r>",
-- spelling
"z=",
},
triggers_blacklist = {
-- list of mode / prefixes that should never be hooked by WhichKey
-- this is mostly relevant for keymaps that start with a native binding
i = { "j", "k" },
v = { "j", "k" },
},
-- disable the WhichKey popup for certain buf types and file types.
-- Disabled by default for Telescope
disable = {

13
home-manager/sway.conf Normal file
View File

@@ -0,0 +1,13 @@
output Unknown-1 scale 2
input * {
xkb_layout "gb"
}
# capture all screens to clipboard
bindsym Shift+Print exec @@GRIM@@ - | @@WL-COPY@@
# capture the specified screen area to clipboard
bindsym Shift+Alt+Print exec @@GRIM@@ -g "$(@@SLURP@@)" - | @@WL-COPY@@
# capture the focused monitor to clipboard
bindsym Shift+Control+Print exec @@GRIM@@ -o $(swaymsg -t get_outputs | jq -r '.[] | select(.focused) | .name') - | @@WL-COPY@@