9 Commits

Author SHA1 Message Date
Joe Frikker c3288188bd more use-package 2026-09-16 21:39:42 -04:00
Joe Frikker a806ae81bc Switching to flake-parts 2026-09-16 21:27:37 -04:00
Joe Frikker 41bd32951d Aligning home manager and nixpkgs versions 2026-09-16 10:55:51 -04:00
Joe Frikker acc0385350 Formatting flake 2026-09-16 10:53:47 -04:00
Joe Frikker 7ecbf30138 Initial switch back to one file + config options 2026-09-16 10:46:56 -04:00
Joe Frikker 61b30f5062 Adding notion, removing postgres 2026-09-16 08:37:01 -04:00
Joe Frikker 83b70c6c81 Some unbinds 2026-09-15 16:32:54 -04:00
Joe Frikker 0ea18214a5 Fixing apheleia error on load 2026-09-14 16:35:30 -04:00
Joe Frikker 57db7a1db8 nix flake update 2026-09-14 16:35:22 -04:00
11 changed files with 2101 additions and 424 deletions
Generated
+47 -13
View File
@@ -8,11 +8,11 @@
"systems": "systems"
},
"locked": {
"lastModified": 1787189302,
"narHash": "sha256-cUM75Rob89qTxJvqVRF8GUewOriqQtLiyiy5xfd1fMM=",
"lastModified": 1789074092,
"narHash": "sha256-QCXTUbd4FuwOHO7LgJws78YTRcco4xgR8RoYgKLvd9w=",
"owner": "sadjow",
"repo": "claude-code-nix",
"rev": "8fb8cbab6345583e0b68ca7dbbbad08a0a348145",
"rev": "1f88b393ac054378c393f914dc83d08a6ef5daeb",
"type": "github"
},
"original": {
@@ -21,6 +21,24 @@
"type": "github"
}
},
"flake-parts": {
"inputs": {
"nixpkgs-lib": "nixpkgs-lib"
},
"locked": {
"lastModified": 1788450739,
"narHash": "sha256-glZLQlzIn1fXH6PazR2iUmTo7kzzyYSshrWhLS9TqCU=",
"owner": "hercules-ci",
"repo": "flake-parts",
"rev": "31729ca8cbdb4fa927b34e5f4353e6a83f39e993",
"type": "github"
},
"original": {
"owner": "hercules-ci",
"repo": "flake-parts",
"type": "github"
}
},
"home-manager": {
"inputs": {
"nixpkgs": [
@@ -28,16 +46,16 @@
]
},
"locked": {
"lastModified": 1779969295,
"narHash": "sha256-HwIJ3tOcwSMiV75L7KqJXciXR9UfT+d7rwOZMX7cTnA=",
"lastModified": 1789267039,
"narHash": "sha256-LWiBv9yAYFi2LPbUhDGHPGKYskJQjj2fw12OlyO1uQo=",
"owner": "nix-community",
"repo": "home-manager",
"rev": "61e2c9659324181e0f0ed911958c536333b1d4f6",
"rev": "ec172013fa62135f58fb58dd17ae9651e8f39727",
"type": "github"
},
"original": {
"owner": "nix-community",
"ref": "master",
"ref": "release-26.05",
"repo": "home-manager",
"type": "github"
}
@@ -49,11 +67,11 @@
]
},
"locked": {
"lastModified": 1779604987,
"narHash": "sha256-ZQ5z+fVhxYKtIFwtqGp5O0PD84BM1riASvqDaN5Xs+s=",
"lastModified": 1788680125,
"narHash": "sha256-amGSoDobwmp4CFvCn841ws2iuitus+HUJdD/gKgsrJA=",
"owner": "nix-community",
"repo": "nix-index-database",
"rev": "8fba98c80b48fa013820e0163c5096922fea4ddd",
"rev": "116ad1c2adb642405ef8916f6a94c8626f971344",
"type": "github"
},
"original": {
@@ -64,11 +82,11 @@
},
"nixpkgs": {
"locked": {
"lastModified": 1787101114,
"narHash": "sha256-gwrPcFf/rDjHPaVflbDZ040ZDmBTRj/7+s8ZmE2SaIM=",
"lastModified": 1789009968,
"narHash": "sha256-GB16oaxpsrnGNnGIE+0uYBqMRzB9X6FYDUvjvnJAYew=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "b18a4b905f8d028dc4476412e6d6891728695379",
"rev": "d58a46e3bc02d91ebe04667f8397752a749c0024",
"type": "github"
},
"original": {
@@ -78,9 +96,25 @@
"type": "github"
}
},
"nixpkgs-lib": {
"locked": {
"lastModified": 1788057806,
"narHash": "sha256-DTQSMxzDWmT0zhguthvegnVkn7CFqGCv4IHCzk5ZUpM=",
"owner": "nix-community",
"repo": "nixpkgs.lib",
"rev": "596e2e3940e09b2abbeb03f75fa1828c57fcd72c",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "nixpkgs.lib",
"type": "github"
}
},
"root": {
"inputs": {
"claude-code": "claude-code",
"flake-parts": "flake-parts",
"home-manager": "home-manager",
"nix-index-database": "nix-index-database",
"nixpkgs": "nixpkgs"
+50 -121
View File
@@ -10,7 +10,7 @@
};
home-manager = {
url = "github:nix-community/home-manager/master";
url = "github:nix-community/home-manager/release-26.05";
inputs.nixpkgs.follows = "nixpkgs";
};
# kube = {
@@ -22,137 +22,66 @@
url = "github:nix-community/nix-index-database";
inputs.nixpkgs.follows = "nixpkgs";
};
flake-parts.url = "github:hercules-ci/flake-parts";
};
outputs = { nixpkgs, home-manager, claude-code, nix-index-database, ... }:
let modules-for-system = pkgs: pkgs.stdenv.mkDerivation {
name = "home-manager-modules";
src = pkgs.lib.fileset.toSource {
root = ./.;
fileset = pkgs.lib.fileset.unions [
./home.org
outputs =
inputs@{
self,
nixpkgs,
flake-parts,
home-manager,
claude-code,
nix-index-database,
...
}:
let
pkgs-for-system =
system:
import nixpkgs {
inherit system;
config.allowUnfree = true;
overlays = [
claude-code.overlays.default
];
};
in
flake-parts.lib.mkFlake { inherit inputs; } {
imports = [
inputs.home-manager.flakeModules.home-manager
];
flake = {
homeModules.jfrikker = import ./modules/home;
homeConfigurations.redbook = home-manager.lib.homeManagerConfiguration {
pkgs = pkgs-for-system "aarch64-darwin";
modules = [
nix-index-database.homeModules.default
self.homeModules.jfrikker
(import ./home/redbook.nix)
];
};
buildPhase = ''
runHook preBuild
${pkgs.emacs}/bin/emacs --batch --eval "(require 'org)" --eval '(org-babel-tangle-file "home.org")'
runHook postBuild
'';
installPhase = ''
runHook preInstall
cp -R target $out
runHook postInstall
'';
};
in {
homeConfigurations.redbook =
let pkgs = import nixpkgs { system = "aarch64-darwin"; config.allowUnfree = true; };
modules = modules-for-system pkgs;
in home-manager.lib.homeManagerConfiguration {
inherit pkgs;
modules =
[
homeConfigurations.home = home-manager.lib.homeManagerConfiguration {
pkgs = pkgs-for-system "x86_64-linux";
modules = [
nix-index-database.homeModules.default
"${modules}/base.nix"
"${modules}/desktop.nix"
"${modules}/redbook.nix"
"${modules}/redbook-desktop.nix"
] ++
[{
home.stateVersion = "22.05";
home.username = "jfrikker";
home.homeDirectory = "/Users/jfrikker";
home.packages = [ pkgs.pinentry_mac ];
}];
extraSpecialArgs = { claude-code = claude-code.packages.aarch64-darwin.default; };
self.homeModules.jfrikker
(import ./home/home.nix)
];
};
homeConfigurations.home =
let pkgs = import nixpkgs { system = "x86_64-linux"; config.allowUnfree = true; };
modules = modules-for-system pkgs;
in home-manager.lib.homeManagerConfiguration {
inherit pkgs;
homeConfigurations.home-laptop = home-manager.lib.homeManagerConfiguration {
pkgs = pkgs-for-system "x86_64-linux";
modules = [
nix-index-database.homeModules.default
] ++
(pkgs.lib.filter
(n: pkgs.lib.strings.hasSuffix ".nix" n)
(pkgs.lib.filesystem.listFilesRecursive "${modules}/base")) ++
[{
home.stateVersion = "22.05";
home.username = "jfrikker";
home.homeDirectory = "/home/jfrikker";
}];
extraSpecialArgs = { claude-code = claude-code.packages.x86_64-linux.default; };
};
homeConfigurations.home-laptop =
let pkgs = import nixpkgs { system = "x86_64-linux"; config.allowUnfree = true; };
modules = modules-for-system pkgs;
in home-manager.lib.homeManagerConfiguration {
inherit pkgs;
modules =
[
nix-index-database.homeModules.default
] ++
(pkgs.lib.filter
(n: pkgs.lib.strings.hasSuffix ".nix" n)
(pkgs.lib.filesystem.listFilesRecursive "${modules}/base")) ++
(pkgs.lib.filter
(n: pkgs.lib.strings.hasSuffix ".nix" n)
(pkgs.lib.filesystem.listFilesRecursive "${modules}/desktop")) ++
[{
home.stateVersion = "22.05";
home.username = "jfrikker";
home.homeDirectory = "/home/jfrikker";
# home.packages = [ pkgs.pinentry ];
programs.ghostty = {
enable = true;
settings = {
font-family = "Iosevka Term Extended";
font-size = 10;
};
};
programs.foot = {
enable = true;
settings = {
main = {
font = "Iosevka Term:size=10:width=expanded";
};
};
};
home.pointerCursor = {
enable = true;
package = pkgs.vanilla-dmz;
name = "Vanilla-DMZ";
sway.enable = true;
gtk.enable = true;
};
wayland.windowManager.sway = {
enable = true;
config.modifier = "Mod4";
# config.terminal = "${pkgs.ghostty}/bin/ghostty";
config.input = {
"1452:628:bcm5974" = {
scroll_factor = "0.4";
};
};
};
programs.emacs.package = pkgs.emacs-pgtk;
}];
self.homeModules.jfrikker
(import ./home/home-laptop.nix)
];
# extraSpecialArgs = { kube = kube.packages.x86_64-linux.default; };
extraSpecialArgs = { claude-code = claude-code.packages.x86_64-linux.default; };
};
packages.x86_64-linux.default = modules-for-system nixpkgs.legacyPackages.x86_64-linux;
};
};
}
+205 -253
View File
@@ -1,40 +1,33 @@
#+PROPERTY: header-args :mkdirp yes
#+PROPERTY: header-args :mkdirp yes :noweb yes
#+PROPERTY: header-args:elisp :lexical t
* Categories
#+begin_src nix :tangle modules/home/default.nix
{lib, pkgs, config, ...}: let
inherit (lib)
mkIf
mkMerge
;
cfg = config.jfrikker;
in {
options.jfrikker = {
enable = lib.mkEnableOption "Joe Frikker's configuration";
desktop.enable = lib.mkEnableOption "Desktop (GUI) applications";
redbook.enable = lib.mkEnableOption "Redbook-specific configuration";
#+BEGIN_SRC nix :tangle target/base.nix
{lib, ...}: {
imports = lib.filter
(n: lib.strings.hasSuffix ".nix" n)
(lib.filesystem.listFilesRecursive ./base);
}
#+END_SRC
<<nix-options>>
};
#+BEGIN_SRC nix :tangle target/desktop.nix
{lib, ...}: {
imports = lib.filter
(n: lib.strings.hasSuffix ".nix" n)
(lib.filesystem.listFilesRecursive ./desktop);
config = mkIf cfg.enable (mkMerge [
<<nix-configs>>
]);
}
#+END_SRC
#+BEGIN_SRC nix :tangle target/redbook.nix
{lib, ...}: {
imports = lib.filter
(n: lib.strings.hasSuffix ".nix" n)
(lib.filesystem.listFilesRecursive ./redbook);
}
#+END_SRC
#+BEGIN_SRC nix :tangle target/redbook-desktop.nix
{lib, ...}: {
imports = lib.filter
(n: lib.strings.hasSuffix ".nix" n)
(lib.filesystem.listFilesRecursive ./redbook-desktop);
}
#+END_SRC
#+end_src
* Packages
:PROPERTIES:
:header-args:nix: :noweb-ref nix-configs
:END:
Home-manager "packages" are simply binaries that are placed on the path, without any attached
configuration. The code blocks in this section contain package lists that go under the packages
section above.
@@ -45,8 +38,7 @@ in a ~nix~ devshell I think I'd also like to use it for scripting / exploratory
so I'm installing it globally with a useful set of libraries. I should curate this somewhat
carefully so it doesn't get carried away...
#+BEGIN_SRC nix :tangle target/base/sbcl.nix
{pkgs, ...}:
#+BEGIN_SRC nix
{
home.packages = with pkgs; [
rlwrap
@@ -94,8 +86,7 @@ the name implies, allows generating and storing ~age~ keys on a Yubikey. ~rage~
~age~ when using ~age.el~, because it supports ~pinentry~. That allows it to prompt for yubikey pins
using a dialog, rather than a command line prompt.
#+BEGIN_SRC nix :tangle target/base/crypto.nix
{pkgs, ...}:
#+BEGIN_SRC nix
{
home.packages = with pkgs; [
rage
@@ -114,8 +105,7 @@ tools. They boost better speed, or simply more streamlined features.
| ~ripgrep~ | ~grep~ |
| ~xh~ | ~curl~ |
#+BEGIN_SRC nix :tangle target/base/rust-reimpls.nix
{pkgs, ...}:
#+BEGIN_SRC nix
{
home.packages = with pkgs; [
dust
@@ -124,13 +114,19 @@ tools. They boost better speed, or simply more streamlined features.
tokei
xh
];
programs.eza = {
enable = true;
enableBashIntegration = true;
enableZshIntegration = true;
icons = "auto";
};
}
#+END_SRC
[[https://ledger-cli.org/][~ledger~]] is how I manage my budget. It's a plain-text accounting tool that's really awesome.
#+BEGIN_SRC nix :tangle target/base/ledger.nix
{pkgs, ...}:
#+BEGIN_SRC nix
{
home.packages = with pkgs; [
ledger
@@ -140,11 +136,11 @@ tools. They boost better speed, or simply more streamlined features.
~nil~ is an LSP server for nix files.
#+BEGIN_SRC nix :tangle target/base/nil.nix
{pkgs, ...}:
#+BEGIN_SRC nix
{
home.packages = with pkgs; [
nil
nixfmt
];
}
#+END_SRC
@@ -153,8 +149,7 @@ tools. They boost better speed, or simply more streamlined features.
computers in the world, assuming that you have an out-of-band way to communicate a passphrase
between them. Once installed, the actual command is ~wormhole~.
#+begin_src nix :tangle target/base/magic-wormhole.nix
{pkgs, ...}:
#+begin_src nix
{
home.packages = with pkgs; [
magic-wormhole
@@ -165,23 +160,18 @@ between them. Once installed, the actual command is ~wormhole~.
These are the other programs I have installed globally. A few (like ~awscli~, ~mysql-client~, etc.)
are still Redbook-specific; ideally I'd find another way to install them.
#+BEGIN_SRC nix :tangle target/redbook/other-packages.nix
{pkgs, ...}:
{
#+BEGIN_SRC nix
(mkIf cfg.redbook.enable {
home.packages = with pkgs; [
postgresql
openssh
];
fonts.fontconfig.enable = true;
}
})
#+END_SRC
These programs require a full desktop environment:
#+BEGIN_SRC nix :tangle target/desktop/desktop-packages.nix
{pkgs, ...}:
{
#+BEGIN_SRC nix
(mkIf cfg.desktop.enable {
home.packages = with pkgs; [
google-chrome
nerd-fonts.jetbrains-mono
@@ -194,14 +184,16 @@ These programs require a full desktop environment:
proton-pass
wireshark
];
}
fonts.fontconfig.enable = true;
})
#+END_SRC
#+BEGIN_SRC nix :tangle target/redbook-desktop/desktop-packages.nix
{pkgs, ...}:
{
#+BEGIN_SRC nix
(mkIf (cfg.redbook.enable && cfg.desktop.enable) {
home.packages = with pkgs; [
linear
notion-app
(slack.overrideAttrs {
version = "4.50.143";
src = pkgs.fetchurl {
@@ -211,10 +203,14 @@ These programs require a full desktop environment:
})
teams
];
}
})
#+END_SRC
* Program Configurations
:PROPERTIES:
:header-args:nix: :noweb-ref nix-configs
:END:
This section contains applications whose config files will be generated by Home Manager. Home
Manager calls these "programs" (as opposed to "packages", which are just binaries to put on the
path).
@@ -225,7 +221,7 @@ Although Home-Manager generates config files for these programs, they don't need
configuration. I'm not sure what benefit there is to enabling ~jq~ as a Home Manager program, rather
than just as an available package, but there doesn't seem to be a downside.
#+BEGIN_SRC nix :tangle target/base/simple-programs.nix
#+BEGIN_SRC nix
{
programs = {
bash.enable = true;
@@ -244,7 +240,7 @@ than just as an available package, but there doesn't seem to be a downside.
provides syntax-highlighting versions of a few other commands. It's honestly not incredibly useful,
but still nice to have.
#+BEGIN_SRC nix :tangle target/base/bat.nix
#+BEGIN_SRC nix
{
programs.bat = {
enable = true;
@@ -255,7 +251,7 @@ but still nice to have.
** Comma
#+BEGIN_SRC nix :tangle target/base/comma.nix
#+BEGIN_SRC nix
{
programs.nix-index.enable = true;
programs.nix-index-database.comma.enable = true;
@@ -267,7 +263,7 @@ but still nice to have.
~direnv~ allows loading per-project paths as I navigate to their directories on the command line. I
leverage this with the emacs ~envrc~ package.
#+BEGIN_SRC nix :tangle target/base/direnv.nix
#+BEGIN_SRC nix
{
programs.direnv = {
enable = true;
@@ -276,27 +272,12 @@ leverage this with the emacs ~envrc~ package.
}
#+END_SRC
** Eza
~eza~ is an ~ls~ replacement that offers icons, colors, and some easier command-line options.
#+BEGIN_SRC nix :tangle target/base/eza.nix
{
programs.eza = {
enable = true;
enableBashIntegration = true;
enableZshIntegration = true;
icons = "auto";
};
}
#+END_SRC
** Fzf
~fzf~ offers a variety of fuzzy finders right from the shell. I haven't been using this, so I'll
turn it off for now.
#+BEGIN_SRC nix :tangle target/base/fzf.nix
#+BEGIN_SRC nix
{
programs.fzf = {
defaultCommand = "fd --type f";
@@ -312,7 +293,7 @@ turn it off for now.
We all know what ~git~ does.
#+BEGIN_SRC nix :tangle target/base/git.nix
#+BEGIN_SRC nix
{
programs.git = {
enable = true;
@@ -333,7 +314,7 @@ We all know what ~git~ does.
The best text editor ever? Heresy!
#+BEGIN_SRC nix :tangle target/base/helix.nix
#+BEGIN_SRC nix
{
programs.helix = {
enable = true;
@@ -411,7 +392,7 @@ The best text editor ever? Heresy!
~nh~ is an alternative frontend to home-manager and a few other nix tools that I'm trying out. It
shows what's changing when you update your config, which is nice.
#+BEGIN_SRC nix :tangle target/base/nh.nix
#+BEGIN_SRC nix
{
programs.nh = {
enable = true;
@@ -425,7 +406,7 @@ shows what's changing when you update your config, which is nice.
~starship~ gives me a nice shell prompt, mostly showing the versions of relevant software I have
installed. It's shell-agnostic, so it works with both bash and zsh.
#+BEGIN_SRC nix :tangle target/base/starship.nix
#+BEGIN_SRC nix
{
programs.starship = {
enable = true;
@@ -458,8 +439,7 @@ installed. It's shell-agnostic, so it works with both bash and zsh.
I'm using ~wezterm~ instead of ~tmux~ for now, so this is disabled, but I'm keeping the config here
in case I need it later.
#+BEGIN_SRC nix :tangle target/base/tmux.nix
{pkgs, ...}:
#+BEGIN_SRC nix
{
programs.tmux = {
baseIndex = 1;
@@ -487,14 +467,14 @@ in case I need it later.
#+END_SRC
** Wezterm
:PROPERTIES:
:header-args:lua: :tangle target/desktop/wezterm.lua
:header-args:lua: :noweb-ref wezterm-config
:END:
~wezterm~ is a fast terminal emulator and multiplexer. It is configured using lua. We'll define its
config in two blocks, so we can get lua syntax highlighting in org. First, the nix configuration:
#+BEGIN_SRC nix :tangle target/desktop/wezterm.nix
{pkgs, ...}: {
#+BEGIN_SRC nix
(mkIf cfg.desktop.enable {
programs.wezterm = {
enable = true;
extraConfig = ''
@@ -503,14 +483,20 @@ config in two blocks, so we can get lua syntax highlighting in org. First, the n
config.font_size = ${if pkgs.stdenv.isDarwin then "13.0" else "10.0"}
'' + builtins.readFile ./wezterm.lua;
};
}
})
#+END_SRC
Then the real lua config:
#+BEGIN_SRC lua
#+begin_src lua :tangle modules/home/wezterm.lua :noweb-ref nil
local config = {}
config.default_prog = { '/Users/jfrikker/.nix-profile/bin/zsh', '-l' }
<<wezterm-config>>
return config
#+end_src
#+BEGIN_SRC lua
config.font = wezterm.font 'Iosevka Term SS14'
config.font_size = 13.0
-- config.font = wezterm.font("JetBrains Mono")
@@ -700,8 +686,8 @@ Now we'll set up some keybindings:
#+END_SRC
** Kitty
#+BEGIN_SRC nix :tangle target/desktop/kitty.nix
{pkgs, ...}: {
#+BEGIN_SRC nix
(mkIf cfg.desktop.enable {
programs.kitty = {
enable = true;
font = {
@@ -722,16 +708,16 @@ Now we'll set up some keybindings:
"ctrl+9" = "goto_tab 9";
};
};
}
})
#+END_SRC
** Ghostty
Disabled until I can get it working on both linux and mac (if I want to).
#+BEGIN_SRC nix
{pkgs, ...}: {
{
programs.ghostty = {
enable = true;
enable = false;
package = pkgs.ghostty-bin;
settings = {
adjust-cell-height = "15%";
@@ -747,7 +733,7 @@ Disabled until I can get it working on both linux and mac (if I want to).
This is my default shell for now. Unfortunately, nix requires a posix-compliant shell, so bash or
zsh it is.
#+BEGIN_SRC nix :tangle target/base/zsh.nix
#+BEGIN_SRC nix
{
programs.zsh = {
enable = true;
@@ -763,8 +749,7 @@ zsh it is.
Actually, nix *really* requires ~bash~. This is a plugin that allows using zsh from nix-shell.
#+BEGIN_SRC nix :tangle target/base/zsh-nix-shell.nix
{pkgs, ...}:
#+BEGIN_SRC nix
{
programs.zsh.plugins = [
{
@@ -781,18 +766,12 @@ Actually, nix *really* requires ~bash~. This is a plugin that allows using zsh f
}
#+END_SRC
** Claude Code
#+BEGIN_SRC nix :tangle target/base/claude-code.nix
{claude-code, ...}: {
programs.claude-code = {
enable = true;
package = claude-code;
};
}
#+END_SRC
* Emacs
:PROPERTIES:
:header-args:nix: :noweb-ref nix-configs
:header-args:elisp: :tangle modules/home/emacs.el
:END:
Emacs is a huge portion of this configuration, so although it's a home-manager "program", I'm
breaking it out into its own top-level section. Many of the sections here have two code blocks: a
nix code block listing the emacs packages to include, and an elisp code block to configure them in
@@ -801,6 +780,15 @@ emacs.
We'll put the actual emacs configs into separate files, rather than into nix string literals. This
helps with a few places where nix's string interpolation was causing problems.
#+BEGIN_SRC nix
(mkIf cfg.desktop.enable {
programs.emacs = {
enable = true;
extraConfig = builtins.readFile ./emacs.el;
};
})
#+END_SRC
** Keybindings
These keybindings are scattered throughout this file, I'm collecting them all here to make it easier
to track them.
@@ -825,15 +813,11 @@ to track them.
| C-c M-g | | [[id:4F426E77-CE03-4BF8-8D1B-7791C7C02B28][Magit file dispatch]] | |
** Global Settings
:PROPERTIES:
:header-args:elisp: :tangle target/desktop/emacs-global.el
:END:
These are just some general settings that apply everywhere. First, a few packages:
#+BEGIN_SRC nix :tangle target/desktop/emacs-global.nix
#+BEGIN_SRC nix
{
programs.emacs = {
enable = true;
extraPackages = epkgs: with epkgs; [
ace-window
doom-modeline
@@ -842,7 +826,6 @@ These are just some general settings that apply everywhere. First, a few package
mixed-pitch
popper
];
extraConfig = builtins.readFile ./emacs-global.el;
};
}
#+END_SRC
@@ -971,6 +954,29 @@ repeats set up that only apply in that mode.
(savehist-mode)
#+END_SRC
Let's unbind some builtin keys that I don't use. I'm not sure if I'll replace them with anything or not, but at a minimum it'll avoid accidental keypresses and clean up which-key output.
#+begin_src elisp
(require 'bind-key)
(unbind-key "C-x RET")
(unbind-key "C-x #")
(unbind-key "C-x 5")
(unbind-key "C-x 6")
(unbind-key "C-x \\")
(unbind-key "C-x `")
(unbind-key "C-x m")
(unbind-key "C-x l")
(unbind-key "C-x i")
(unbind-key "C-x u")
(unbind-key "C-x @")
(unbind-key "C-x C-b")
(unbind-key "C-x C-d")
(unbind-key "C-x C-l")
(unbind-key "C-x C-p")
(unbind-key "C-x C-u")
(unbind-key "C-x C-z")
#+end_src
The doom modeline looks nice. I'm turning off IRC notifications, because it was slow to update (and
it would update after every command, slowing down everything). I don't need the workspace name when
I have the tab bar at the top of the window. The other settings just clear up some space, and make
@@ -988,7 +994,7 @@ Ligature mode combines character sequences like <= into a single on-screen glyph
cool, so I'm turning it on in prog mode. The enabled ligatures are font-specific, taken from [[https://github.com/mickeynp/ligature.el/wiki#jetbrains-mono][the
ligature wiki]].
#+BEGIN_SRC elisp
#+BEGIN_SRC elisp :noweb no
(ligature-set-ligatures 'prog-mode
'("--" "---" "==" "===" "!=" "!==" "=!="
"=:=" "=/=" "<=" ">=" "&&" "&&&" "&=" "++" "+++" "***" ";;" "!!"
@@ -1317,16 +1323,11 @@ content to be.
** Editing
:PROPERTIES:
:header-args:elisp: :tangle target/desktop/emacs-editing.el
:END:
This configuration affects general text editing, across all modes. First, some packages:
#+BEGIN_SRC nix :tangle target/desktop/emacs-editing.nix
#+BEGIN_SRC nix
{
programs.emacs = {
enable = true;
extraPackages = epkgs: with epkgs; [
apheleia
avy
@@ -1338,7 +1339,6 @@ This configuration affects general text editing, across all modes. First, some p
# evil-org
string-inflection
];
extraConfig = builtins.readFile ./emacs-editing.el;
};
}
#+END_SRC
@@ -1448,22 +1448,17 @@ Just "silently" wrap when searching at the bottom of a document.
Some auto-formatting stuff
#+begin_src elisp
(push '(prisma-format "prisma" "format" "--schema" filepath) apheleia-formatters)
(with-eval-after-load 'apheleia
(push '(prisma-format "prisma" "format" "--schema" filepath) apheleia-formatters))
#+end_src
** Workflow
:PROPERTIES:
:header-args:elisp: :tangle target/desktop/emacs-workflow.el
:END:
#+BEGIN_SRC nix :tangle target/desktop/emacs-workflow.nix
#+BEGIN_SRC nix
{
programs.emacs = {
enable = true;
extraPackages = epkgs: with epkgs; [
buffer-terminator
];
extraConfig = builtins.readFile ./emacs-workflow.el;
};
}
#+END_SRC
@@ -1476,14 +1471,9 @@ Some auto-formatting stuff
#+END_SRC
** Language Support
:PROPERTIES:
:header-args:elisp: :tangle target/desktop/emacs-languages.el
:END:
#+BEGIN_SRC nix :tangle target/desktop/emacs-languages.nix
#+BEGIN_SRC nix
{
programs.emacs = {
enable = true;
extraPackages = epkgs: with epkgs; [
consult-eglot
graphql-ts-mode
@@ -1545,7 +1535,6 @@ Some auto-formatting stuff
]))
yaml-pro
];
extraConfig = builtins.readFile ./emacs-languages.el;
};
}
#+END_SRC
@@ -1811,18 +1800,12 @@ for completion. That makes it really annoying to use; don't use yasnippet with e
#+END_SRC
** Envrc
:PROPERTIES:
:header-args:elisp: :tangle target/desktop/emacs-envrc.el
:END:
#+BEGIN_SRC nix :tangle target/desktop/emacs-envrc.nix
#+BEGIN_SRC nix
{
programs.emacs = {
enable = true;
extraPackages = epkgs: with epkgs; [
envrc
];
extraConfig = builtins.readFile ./emacs-envrc.el;
};
}
#+END_SRC
@@ -1833,14 +1816,9 @@ for completion. That makes it really annoying to use; don't use yasnippet with e
#+END_SRC
** Magit
:PROPERTIES:
:header-args:elisp: :tangle target/desktop/emacs-magit.el
:END:
#+BEGIN_SRC nix :tangle target/desktop/emacs-magit.nix
#+BEGIN_SRC nix
{
programs.emacs = {
enable = true;
extraPackages = epkgs: with epkgs; [
consult-gh
diff-hl
@@ -1848,7 +1826,6 @@ for completion. That makes it really annoying to use; don't use yasnippet with e
git-timemachine
magit
];
extraConfig = builtins.readFile ./emacs-magit.el;
};
}
#+END_SRC
@@ -1877,14 +1854,9 @@ for completion. That makes it really annoying to use; don't use yasnippet with e
#+END_SRC
** Vertico
:PROPERTIES:
:header-args:elisp: :tangle target/desktop/emacs-vertico.el
:END:
#+BEGIN_SRC nix :tangle target/desktop/emacs-vertico.nix
#+BEGIN_SRC nix
{
programs.emacs = {
enable = true;
extraPackages = epkgs: with epkgs; [
cape
consult
@@ -1894,7 +1866,6 @@ for completion. That makes it really annoying to use; don't use yasnippet with e
orderless
vertico
];
extraConfig = builtins.readFile ./emacs-vertico.el;
};
}
#+END_SRC
@@ -1965,57 +1936,58 @@ for completion. That makes it really annoying to use; don't use yasnippet with e
(setopt consult-narrow-key "<") ;; "C-+"
(setopt vertico-count 25)
(vertico-mode)
(use-package vertico
:custom
(vertico-count 25)
:config
(vertico-mode))
(setopt completion-styles '(orderless basic))
(marginalia-mode)
(use-package marginalia
:config
(marginalia-mode))
(setopt corfu-cycle t)
(setopt corfu-popupinfo-mode nil)
(setopt corfu-quit-at-boundary nil)
(setopt corfu-on-exact-match 'show)
(global-corfu-mode)
(use-package corfu
:custom
(corfu-cycle t)
(corfu-popupinfo-mode nil)
(corfu-quit-at-boundary nil)
(corfu-on-exact-match 'show)
:config
(global-corfu-mode))
;; (setq completion-in-region-function #'consult-completion-in-region)
(add-hook 'completion-at-point-functions 'cape-file)
(use-package cape
:custom
(add-hook 'completion-at-point-functions 'cape-file))
#+END_SRC
** Org
:PROPERTIES:
:header-args:elisp: :tangle target/desktop/emacs-org.el
:END:
#+BEGIN_SRC nix :tangle target/desktop/emacs-org.nix
#+BEGIN_SRC nix
{
programs.emacs = {
enable = true;
extraPackages = epkgs: with epkgs; [
org-modern
org-present
org-roam
ox-slack
verb
visual-fill-column
];
extraConfig = builtins.readFile ./emacs-org.el;
};
}
#+END_SRC
#+BEGIN_SRC elisp
(require 'org)
(bind-keys ("C-c A" . org-agenda)
(use-package org
:bind (("C-c A" . org-agenda)
("C-c C" . org-capture)
("C-c l" . org-id-store-link))
(setopt org-babel-load-languages '((emacs-lisp . t) (sql . t)))
(setopt org-confirm-babel-evaluate nil)
(add-hook 'org-mode-hook 'visual-line-mode)
(setopt org-link-keep-stored-after-insertion t
org-capture-templates
:custom
(org-babel-load-languages '((emacs-lisp . t) (sql . t)))
(org-confirm-babel-evaluate nil)
(org-link-keep-stored-after-insertion t)
(org-capture-templates
'(("t" "Todo" entry
(here)
"** TODO %?\n:LOGBOOK:\n- State \"TODO\" %U\n:END:\n")
@@ -2032,12 +2004,14 @@ for completion. That makes it really annoying to use; don't use yasnippet with e
"*** PROJ %?\n- State \"PROJ\" %U\n")
("pa" "Personal Next Action" entry
(file+headline "~/org/todo/personal.org.age" "Next Actions")
"*** TODO %?\n- State \"TODO\" %U\n"))
org-agenda-files '("~/org/todo/work.org" "~/org/todo/personal.org.age")
org-agenda-todo-ignore-scheduled 'future
org-agenda-tags-todo-honor-ignore-options t
org-enforce-todo-dependencies t
org-agenda-dim-blocked-tasks 'invisible)
"*** TODO %?\n- State \"TODO\" %U\n")))
(org-agenda-files '("~/org/todo/work.org" "~/org/todo/personal.org.age"))
(org-agenda-todo-ignore-scheduled 'future)
(org-agenda-tags-todo-honor-ignore-options t)
(org-enforce-todo-dependencies t)
(org-agenda-dim-blocked-tasks 'invisible)
:config
(add-hook 'org-mode-hook 'visual-line-mode)
(set-face-attribute 'org-level-1 nil :font "Iosevka Aile")
(set-face-attribute 'org-level-2 nil :font "Iosevka Aile")
(set-face-attribute 'org-level-3 nil :font "Iosevka Aile")
@@ -2045,10 +2019,11 @@ for completion. That makes it really annoying to use; don't use yasnippet with e
(set-face-attribute 'org-level-5 nil :font "Iosevka Aile")
(set-face-attribute 'org-level-6 nil :font "Iosevka Aile")
(set-face-attribute 'org-level-7 nil :font "Iosevka Aile")
(set-face-attribute 'org-level-8 nil :font "Iosevka Aile")
(set-face-attribute 'org-level-8 nil :font "Iosevka Aile"))
(defvar-local my/org-present-face-remapping-cookies nil)
(with-eval-after-load 'org-present
(use-package org-present
:config
(require 'face-remap)
(require 'visual-fill-column)
@@ -2116,24 +2091,18 @@ for completion. That makes it really annoying to use; don't use yasnippet with e
;; (org-roam-db-autosync-mode)
(use-package org-modern
:hook org-mode-hook)
:hook org-mode)
;; (define-key org-mode-map (kbd "C-c C-r") verb-command-map)
#+END_SRC
** Terminal
:PROPERTIES:
:header-args:elisp: :tangle target/desktop/emacs-terminal.el
:END:
#+BEGIN_SRC nix :tangle target/desktop/emacs-terminal.nix
#+BEGIN_SRC nix
{
programs.emacs = {
enable = true;
extraPackages = epkgs: with epkgs; [
eat
];
extraConfig = builtins.readFile ./emacs-terminal.el;
};
}
#+END_SRC
@@ -2145,23 +2114,19 @@ for completion. That makes it really annoying to use; don't use yasnippet with e
#+END_SRC
** Slack
:PROPERTIES:
:header-args:elisp: :tangle target/desktop/emacs-slack.el
:END:
#+BEGIN_SRC nix :tangle target/desktop/emacs-slack.nix
{
#+BEGIN_SRC nix
(mkIf (cfg.redbook.enable && cfg.desktop.enable) {
programs.emacs = {
enable = true;
extraPackages = epkgs: with epkgs; [
slack
ox-slack
];
extraConfig = builtins.readFile ./emacs-slack.el;
extraConfig = builtins.readFile ./slack.el;
};
}
})
#+END_SRC
#+BEGIN_SRC elisp
#+BEGIN_SRC elisp :tangle modules/home/home/slack.el :noweb-ref nil
(use-package lui
:defer t
:custom
@@ -2175,11 +2140,9 @@ for completion. That makes it really annoying to use; don't use yasnippet with e
#+END_SRC
** Ledger
#+BEGIN_SRC nix :tangle target/desktop/emacs-ledger.nix
#+BEGIN_SRC nix
{
programs.emacs = {
enable = true;
extraPackages = epkgs: with epkgs; [
ledger-mode
];
@@ -2188,18 +2151,12 @@ for completion. That makes it really annoying to use; don't use yasnippet with e
#+END_SRC
** Age
:PROPERTIES:
:header-args:elisp: :tangle target/desktop/emacs-age.el
:END:
#+BEGIN_SRC nix :tangle target/desktop/emacs-age.nix
#+BEGIN_SRC nix
{
programs.emacs = {
enable = true;
extraPackages = epkgs: with epkgs; [
age
];
extraConfig = builtins.readFile ./emacs-age.el;
};
}
#+END_SRC
@@ -2207,7 +2164,7 @@ for completion. That makes it really annoying to use; don't use yasnippet with e
#+BEGIN_SRC elisp
(use-package age
:custom
(setopt age-default-identity "~/source/dotfiles/keys/yubi1age.txt")
(age-default-identity "~/source/dotfiles/keys/yubi1age.txt")
(age-default-recipient "~/source/dotfiles/keys/myself.txt")
:config
(setenv "PINENTRY_PROGRAM" "pinentry-mac")
@@ -2215,15 +2172,13 @@ for completion. That makes it really annoying to use; don't use yasnippet with e
#+END_SRC
** Claude Code
:PROPERTIES:
:header-args:elisp: :tangle target/desktop/emacs-claude-code.el
:END:
#+BEGIN_SRC nix :tangle target/desktop/emacs-claude-code.nix
{pkgs, ...}:
#+BEGIN_SRC nix
{
programs.emacs = {
programs.claude-code = {
enable = true;
};
programs.emacs = {
extraPackages = epkgs: with epkgs; [
(epkgs.trivialBuild {
pname = "claude-code";
@@ -2237,7 +2192,6 @@ for completion. That makes it really annoying to use; don't use yasnippet with e
packageRequires = [ epkgs.inheritenv ];
})
];
extraConfig = builtins.readFile ./emacs-claude-code.el;
};
}
#+END_SRC
@@ -2248,11 +2202,14 @@ for completion. That makes it really annoying to use; don't use yasnippet with e
:custom (claude-code-optimize-window-resize nil))
#+END_SRC
* Theme
:PROPERTIES:
:header-args:nix: :noweb-ref nix-configs
:END:
I like Catppuccin Frappe as my theme. Let's use it in as many places as we can.
** Bat
#+BEGIN_SRC nix :tangle target/base/bat-theme.nix
{pkgs, ...}:
#+BEGIN_SRC nix
{
programs.bat = {
config.theme = "catppuccin-frappe";
@@ -2272,15 +2229,14 @@ I like Catppuccin Frappe as my theme. Let's use it in as many places as we can.
#+END_SRC
** Helix
#+BEGIN_SRC nix :tangle target/base/helix-theme.nix
#+BEGIN_SRC nix
{
programs.helix.settings.theme = "catppuccin_frappe";
}
#+END_SRC
** Tmux
#+BEGIN_SRC nix :tangle target/base/tmux-theme.nix
{pkgs, ...}:
#+BEGIN_SRC nix
{
programs.tmux.plugins = [
{
@@ -2294,8 +2250,7 @@ I like Catppuccin Frappe as my theme. Let's use it in as many places as we can.
#+END_SRC
** Lazygit
#+BEGIN_SRC nix :tangle target/base/lazygit.nix
{pkgs, ...}:
#+BEGIN_SRC nix
{
xdg = {
enable = false
@@ -2315,8 +2270,7 @@ I like Catppuccin Frappe as my theme. Let's use it in as many places as we can.
#+END_SRC
** Starship
#+BEGIN_SRC nix :tangle target/base/starship_colors.nix
{pkgs, ...}:
#+BEGIN_SRC nix
{
programs.starship.settings = builtins.fromTOML (builtins.readFile
(pkgs.fetchFromGitHub
@@ -2330,14 +2284,16 @@ I like Catppuccin Frappe as my theme. Let's use it in as many places as we can.
#+END_SRC
** Wezterm
#+BEGIN_SRC lua :tangle target/desktop/wezterm.lua
config.color_scheme = 'Catppuccin Frappe'
:PROPERTIES:
:header-args:lua: :noweb-ref wezterm-config
:END:
return config
#+BEGIN_SRC lua
config.color_scheme = 'Catppuccin Frappe'
#+END_SRC
** Ghostty
#+BEGIN_SRC nix :tangle target/desktop/ghostty-theme.nix
#+BEGIN_SRC nix
{
programs.ghostty.settings.theme = "Catppuccin Frappe";
}
@@ -2345,23 +2301,16 @@ I like Catppuccin Frappe as my theme. Let's use it in as many places as we can.
** Emacs
:PROPERTIES:
:header-args:elisp: :tangle target/desktop/emacs-theme.el
:header-args:elisp: :tangle modules/home/emacs.el
:END:
#+BEGIN_SRC nix :tangle target/desktop/emacs-theme.nix
{pkgs, ...}: {
#+BEGIN_SRC nix
{
programs.emacs = {
enable = true;
extraPackages = epkgs: with epkgs; [
catppuccin-theme
];
extraConfig = "(defvar my-base-font-size ${if pkgs.stdenv.isDarwin then "130" else "100"})" +
builtins.readFile ./emacs-theme.el;
};
}
#+END_SRC
#+BEGIN_SRC elisp
extraConfig = ''(defvar my-base-font-size ${if pkgs.stdenv.isDarwin then "130" else "100"})
(require 'catppuccin-theme)
(setopt catppuccin-flavor 'frappe)
(load-theme 'catppuccin :no-confirm)
@@ -2371,4 +2320,7 @@ I like Catppuccin Frappe as my theme. Let's use it in as many places as we can.
(set-face-attribute 'default nil :font "Iosevka Term SS14" :height my-base-font-size)
(set-face-attribute 'fixed-pitch nil :font "Iosevka Term SS14" :height my-base-font-size)
(set-face-attribute 'variable-pitch nil :font "Iosevka Etoile" :height my-base-font-size)
'';
};
}
#+END_SRC
+46
View File
@@ -0,0 +1,46 @@
{ pkgs, ... }: {
home.stateVersion = "22.05";
home.username = "jfrikker";
home.homeDirectory = "/home/jfrikker";
# home.packages = [ pkgs.pinentry ];
jfrikker.enable = true;
jfrikker.desktop.enable = true;
programs.ghostty = {
enable = true;
settings = {
font-family = "Iosevka Term Extended";
font-size = 10;
};
};
programs.foot = {
enable = true;
settings = {
main = {
font = "Iosevka Term:size=10:width=expanded";
};
};
};
home.pointerCursor = {
enable = true;
package = pkgs.vanilla-dmz;
name = "Vanilla-DMZ";
sway.enable = true;
gtk.enable = true;
};
wayland.windowManager.sway = {
enable = true;
config.modifier = "Mod4";
# config.terminal = "${pkgs.ghostty}/bin/ghostty";
config.input = {
"1452:628:bcm5974" = {
scroll_factor = "0.4";
};
};
};
programs.emacs.package = pkgs.emacs-pgtk;
}
+6
View File
@@ -0,0 +1,6 @@
{
home.stateVersion = "22.05";
home.username = "jfrikker";
home.homeDirectory = "/home/jfrikker";
jfrikker.enable = true;
}
+9
View File
@@ -0,0 +1,9 @@
{ pkgs, ... }: {
home.stateVersion = "22.05";
home.username = "jfrikker";
home.homeDirectory = "/Users/jfrikker";
home.packages = [ pkgs.pinentry_mac ];
jfrikker.enable = true;
jfrikker.desktop.enable = true;
jfrikker.redbook.enable = true;
}
+646
View File
@@ -0,0 +1,646 @@
{lib, pkgs, config, ...}: let
inherit (lib)
mkIf
mkMerge
;
cfg = config.jfrikker;
in {
options.jfrikker = {
enable = lib.mkEnableOption "Joe Frikker's configuration";
desktop.enable = lib.mkEnableOption "Desktop (GUI) applications";
redbook.enable = lib.mkEnableOption "Redbook-specific configuration";
};
config = mkIf cfg.enable (mkMerge [
{
home.packages = with pkgs; [
rlwrap
(sbcl.withPackages (ps: with ps; [
alexandria
cl-markup
cl-mock
clack
clack-handler-woo
dbi
defstar
dexador
fare-csv
group-by
lack-request
lack-response
local-time
log4cl
mito
myway
prove
prove-asdf
replic
serapeum
shasht
slynk
smug
split-sequence
str
sxql-composer
trivia
trivial-mmap
trivial-ws
trivial-open-browser
trivial-timeout
uuid
]))
];
}
{
home.packages = with pkgs; [
rage
age-plugin-yubikey
yubikey-manager
];
}
{
home.packages = with pkgs; [
dust
fd
ripgrep
tokei
xh
];
programs.eza = {
enable = true;
enableBashIntegration = true;
enableZshIntegration = true;
icons = "auto";
};
}
{
home.packages = with pkgs; [
ledger
];
}
{
home.packages = with pkgs; [
nil
nixfmt
];
}
{
home.packages = with pkgs; [
magic-wormhole
];
}
(mkIf cfg.redbook.enable {
home.packages = with pkgs; [
openssh
];
})
(mkIf cfg.desktop.enable {
home.packages = with pkgs; [
google-chrome
nerd-fonts.jetbrains-mono
nerd-fonts.symbols-only
(iosevka-bin.override { variant = "Aile"; })
(iosevka-bin.override { variant = "Etoile"; })
(iosevka-bin.override { variant = "SGr-IosevkaTermSS14"; })
nerd-fonts.symbols-only
keymapp
proton-pass
wireshark
];
fonts.fontconfig.enable = true;
})
(mkIf (cfg.redbook.enable && cfg.desktop.enable) {
home.packages = with pkgs; [
linear
notion-app
(slack.overrideAttrs {
version = "4.50.143";
src = pkgs.fetchurl {
url = "https://downloads.slack-edge.com/desktop-releases/mac/arm64/4.50.143/Slack-4.50.143-macOS.dmg";
hash = "sha256-f5oYi8NPKXWpDcowFYMUjptbQs4V9hK2bm1TuaQeJn0=";
};
})
teams
];
})
{
programs = {
bash.enable = true;
gh.enable = true;
home-manager.enable = true;
jq.enable = true;
lazygit.enable = true;
zoxide.enable = true;
};
}
{
programs.bat = {
enable = true;
config.style = "numbers";
};
}
{
programs.nix-index.enable = true;
programs.nix-index-database.comma.enable = true;
}
{
programs.direnv = {
enable = true;
nix-direnv.enable = true;
};
}
{
programs.fzf = {
defaultCommand = "fd --type f";
fileWidgetCommand = "fd --type f";
fileWidgetOptions = ["--preview" "'bat --color=always --style=numbers --line-range=:500 {}'"];
changeDirWidgetCommand = "fd --type d";
tmux.enableShellIntegration = true;
};
}
{
programs.git = {
enable = true;
settings.user.name = "Joe Frikker";
settings.user.email = "joe@redbookcattle.com";
settings.github.user = "joe@redbookcattle.com";
settings.merge.conflictstyle = "zdiff3";
};
programs.delta = {
enable = true;
enableGitIntegration = true;
};
}
{
programs.helix = {
enable = true;
defaultEditor = true;
settings.editor = {
auto-format = false;
auto-pairs = false;
auto-save.after-delay.enable = true;
auto-save.after-delay.timeout = 1000;
cursorline = true;
idle-timeout = 0;
rulers = [120];
text-width = 100;
lsp.goto-reference-include-declaration = false;
cursor-shape.insert = "bar";
smart-tab.supersede-menu = true;
whitespace.render.newline = "all";
};
settings.keys.normal.space = {
space = "file_picker";
"," = "buffer_picker";
# b = "@:sh wezterm cli spawn --cwd . -- tig blame <C-r>%<ret>";
};
languages.language-server.eslint = {
args = ["--stdio"];
command = "vscode-eslint-language-server";
config.nodePath = "";
config.quiet = false;
config.rulesCustomizations = [];
config.run = "onType";
config.validate = "on";
config.codeAction.disableRuleComment.enable = true;
config.codeAction.disableRuleComment.location = "separateLine";
config.codeAction.showDocumentation.enable = true;
config.problems.shortenToSingleLine = false;
};
languages.language-server.jdtls.config.java = {
autobuild.enabled = true;
completion.maxResults = 1000;
format.settings.url = "https://raw.githubusercontent.com/google/styleguide/gh-pages/eclipse-java-google-style.xml";
};
languages.language-server.rust-analyzer.config.files.watcher = "client";
languages.language = [
{
name = "typescript";
language-servers = [ "typescript-language-server" "vscode-eslint-language-server" ];
indent.tab-width = 4;
indent.unit = " ";
}
{
name = "tsx";
language-servers = [ "typescript-language-server" "vscode-eslint-language-server" ];
indent.tab-width = 4;
indent.unit = " ";
}
{
name = "java";
indent.tab-width = 4;
indent.unit = " ";
}
];
};
}
{
programs.nh = {
enable = true;
};
}
{
programs.starship = {
enable = true;
settings = {
add_newline = false;
container.disabled = true;
git_branch.symbol = " ";
git_status.ahead = "⇡\${count}";
git_status.behind = "⇣\${count}";
git_status.diverged = "⇕⇡\${ahead_count}⇣\${behind_count}";
git_status.format = "([\\[\$conflicted\$staged\$ahead_behind\\]](\$style) )";
java.symbol = " ";
line_break.disabled = true;
nix_shell.symbol = " ";
nodejs.symbol = " ";
package.disabled = true;
palette = "catppuccin_frappe";
python.symbol = " ";
package.symbol = " ";
rust.symbol = " ";
docker_context.disabled = true;
shell.disabled = false;
};
};
}
{
programs.tmux = {
baseIndex = 1;
clock24 = true;
customPaneNavigationAndResize = true;
historyLimit = 50000;
enable = true;
escapeTime = 0;
keyMode = "vi";
mouse = true;
shell = pkgs.zsh + "/bin/zsh";
shortcut = "Space";
tmuxinator.enable = true;
terminal = "xterm-256color";
extraConfig = ''
bind-key -T copy-mode-vi 'v' send -X begin-selection
bind-key -T copy-mode-vi 'y' send -X copy-selection-and-cancel
bind-key -T launcher g popup -h 100% -w 100% -E lazygit
bind-key g switch-client -Tlauncher
set -g default-command ""
'';
};
}
(mkIf cfg.desktop.enable {
programs.wezterm = {
enable = true;
extraConfig = ''
local config = {}
config.default_prog = { '${pkgs.zsh}/bin/zsh', '-l'}
config.font_size = ${if pkgs.stdenv.isDarwin then "13.0" else "10.0"}
'' + builtins.readFile ./wezterm.lua;
};
})
(mkIf cfg.desktop.enable {
programs.kitty = {
enable = true;
font = {
name = "Iosevka Term SS14";
package = pkgs.iosevka-bin.override { variant = "SGr-IosevkaTermSS14"; };
size = 13;
};
themeFile = "Catppuccin-Frappe";
keybindings = {
"ctrl+1" = "goto_tab 1";
"ctrl+2" = "goto_tab 2";
"ctrl+3" = "goto_tab 3";
"ctrl+4" = "goto_tab 4";
"ctrl+5" = "goto_tab 5";
"ctrl+6" = "goto_tab 6";
"ctrl+7" = "goto_tab 7";
"ctrl+8" = "goto_tab 8";
"ctrl+9" = "goto_tab 9";
};
};
})
{
programs.ghostty = {
enable = false;
package = pkgs.ghostty-bin;
settings = {
adjust-cell-height = "15%";
font-family = "Iosevka Term SS14";
font-size = 13;
};
};
}
{
programs.zsh = {
enable = true;
oh-my-zsh.enable = true;
syntaxHighlighting.enable = true;
autosuggestion.enable = true;
historySubstringSearch.enable = true;
history.share = false;
cdpath = ["~/source"];
};
}
{
programs.zsh.plugins = [
{
name = "zsh-nix-shell";
file = "nix-shell.plugin.zsh";
src = pkgs.fetchFromGitHub {
owner = "chisui";
repo = "zsh-nix-shell";
rev = "v0.7.0";
sha256 = "149zh2rm59blr2q458a5irkfh82y3dwdich60s9670kl3cl5h2m1";
};
}
];
}
(mkIf cfg.desktop.enable {
programs.emacs = {
enable = true;
extraConfig = builtins.readFile ./emacs.el;
};
})
{
programs.emacs = {
extraPackages = epkgs: with epkgs; [
ace-window
doom-modeline
free-keys
ligature
mixed-pitch
popper
];
};
}
{
programs.emacs = {
extraPackages = epkgs: with epkgs; [
apheleia
avy
edit-indirect
embark
god-mode
# evil
# evil-collection
# evil-org
string-inflection
];
};
}
{
programs.emacs = {
extraPackages = epkgs: with epkgs; [
buffer-terminator
];
};
}
{
programs.emacs = {
extraPackages = epkgs: with epkgs; [
consult-eglot
graphql-ts-mode
haskell-ts-mode
jenkinsfile-mode
jq-mode
(lispy.overrideAttrs {
packageRequires = [
ace-window iedit swiper zoutline hydra
];
ignoreCompilationError = true;
})
# lispyville
lua-mode
nix-mode
pnpm-mode
prisma-ts-mode
rust-mode
sly
sly-macrostep
sql-indent
tree-sitter
(treesit-grammars.with-grammars (g: [
g.tree-sitter-bash
g.tree-sitter-commonlisp
g.tree-sitter-css
g.tree-sitter-dockerfile
g.tree-sitter-dot
g.tree-sitter-elisp
g.tree-sitter-graphql
g.tree-sitter-gitcommit
g.tree-sitter-gitignore
g.tree-sitter-haskell
g.tree-sitter-html
g.tree-sitter-java
g.tree-sitter-javascript
g.tree-sitter-jq
g.tree-sitter-json
g.tree-sitter-json5
g.tree-sitter-just
g.tree-sitter-ledger
g.tree-sitter-llvm
g.tree-sitter-make
g.tree-sitter-nginx
g.tree-sitter-nix
g.tree-sitter-org
g.tree-sitter-php
g.tree-sitter-prisma
g.tree-sitter-python
g.tree-sitter-rust
g.tree-sitter-rust-format-args
g.tree-sitter-scss
g.tree-sitter-sql
g.tree-sitter-toml
g.tree-sitter-tsx
g.tree-sitter-typescript
g.tree-sitter-xml
g.tree-sitter-yaml
]))
yaml-pro
];
};
}
{
programs.emacs = {
extraPackages = epkgs: with epkgs; [
envrc
];
};
}
{
programs.emacs = {
extraPackages = epkgs: with epkgs; [
consult-gh
diff-hl
forge
git-timemachine
magit
];
};
}
{
programs.emacs = {
extraPackages = epkgs: with epkgs; [
cape
consult
corfu
embark-consult
marginalia
orderless
vertico
];
};
}
{
programs.emacs = {
extraPackages = epkgs: with epkgs; [
org-modern
org-present
org-roam
verb
visual-fill-column
];
};
}
{
programs.emacs = {
extraPackages = epkgs: with epkgs; [
eat
];
};
}
(mkIf (cfg.redbook.enable && cfg.desktop.enable) {
programs.emacs = {
extraPackages = epkgs: with epkgs; [
slack
ox-slack
];
extraConfig = builtins.readFile ./slack.el;
};
})
{
programs.emacs = {
extraPackages = epkgs: with epkgs; [
ledger-mode
];
};
}
{
programs.emacs = {
extraPackages = epkgs: with epkgs; [
age
];
};
}
{
programs.claude-code = {
enable = true;
};
programs.emacs = {
extraPackages = epkgs: with epkgs; [
(epkgs.trivialBuild {
pname = "claude-code";
version = "0.4.5";
src = pkgs.fetchFromGitHub {
owner = "stevemolitor";
repo = "claude-code.el";
rev = "03199df8b3a1e9cd4857f0851f7a912ba524aff3";
sha256 = "sha256-5QJrWIu4EgnHcOqMwlrs2JBBx7aI9OaSJswesr6Apfk=";
};
packageRequires = [ epkgs.inheritenv ];
})
];
};
}
{
programs.bat = {
config.theme = "catppuccin-frappe";
themes = {
catppuccin-frappe = {
src = pkgs.fetchFromGitHub {
owner = "catppuccin";
repo = "sublime-text"; # Bat uses sublime syntax for its themes
rev = "3d8625d937d89869476e94bc100192aa220ce44a";
sha256 = "3ABUsfJpb6RO6AiuuSL5gwDofJIwC5tlEMzBrlY9/s0=";
};
file = "Frappe.tmTheme";
};
};
};
}
{
programs.helix.settings.theme = "catppuccin_frappe";
}
{
programs.tmux.plugins = [
{
plugin = pkgs.tmuxPlugins.catppuccin;
extraConfig = ''set -g @catppuccin_window_tabs_enabled on
set -g @catppuccin_window_default_text "#W"
set -g @catppuccin_window_current_text "#W"'';
}
];
}
{
xdg = {
enable = false
;
# configFile."lazygit/config.yml" = {
# enable = true;
# source = pkgs.fetchFromGitHub
# {
# owner = "catppuccin";
# repo = "lazygit";
# rev = "b2ecb6d41b6f54a82104879573c538e8bdaeb0bf"; # Replace with the latest commit hash
# sha256 = "9BBmWRcjNaJE9T0RKVEJaSnkrbMom0CLYE8PzAT6yFw=";
# } + /themes/frappe.yml;
# };
};
}
{
programs.starship.settings = builtins.fromTOML (builtins.readFile
(pkgs.fetchFromGitHub
{
owner = "catppuccin";
repo = "starship";
rev = "3e3e54410c3189053f4da7a7043261361a1ed1bc"; # Replace with the latest commit hash
sha256 = "soEBVlq3ULeiZFAdQYMRFuswIIhI9bclIU8WXjxd7oY=";
} + /palettes/frappe.toml));
}
{
programs.ghostty.settings.theme = "Catppuccin Frappe";
}
{
programs.emacs = {
extraPackages = epkgs: with epkgs; [
catppuccin-theme
];
extraConfig = ''(defvar my-base-font-size ${if pkgs.stdenv.isDarwin then "130" else "100"})
(require 'catppuccin-theme)
(setopt catppuccin-flavor 'frappe)
(load-theme 'catppuccin :no-confirm)
;; (set-face-attribute 'default nil :font "JetBrainsMono Nerd Font" :height 130)
;; (set-face-attribute 'fixed-pitch nil :font "JetBrainsMono Nerd Font" :height 130)
(set-face-attribute 'default nil :font "Iosevka Term SS14" :height my-base-font-size)
(set-face-attribute 'fixed-pitch nil :font "Iosevka Term SS14" :height my-base-font-size)
(set-face-attribute 'variable-pitch nil :font "Iosevka Etoile" :height my-base-font-size)
'';
};
}
]);
}
+881
View File
@@ -0,0 +1,881 @@
(setopt save-interprogram-paste-before-kill t)
(setopt enable-recursive-minibuffers t)
(setopt line-spacing 0.15)
(setopt mouse-wheel-tilt-scroll t)
(setq-default truncate-lines t)
(setopt tab-bar-show nil)
(tab-bar-mode)
(setopt inhibit-startup-screen t)
(setopt initial-scratch-message nil)
(menu-bar-mode -1)
(scroll-bar-mode -1)
(tool-bar-mode -1)
(setopt make-backup-files nil)
(setopt create-lockfiles nil)
(setopt auto-save-default nil)
(setopt view-read-only t)
(setopt sentence-end-double-space nil)
(setopt kill-whole-line t)
(column-number-mode t)
(which-key-mode)
(setopt dired-auto-revert-buffer t)
(global-hl-line-mode)
(setopt tab-always-indent 'complete)
(setq-default cursor-type 'bar)
(repeat-mode)
(savehist-mode)
(require 'bind-key)
(unbind-key "C-x RET")
(unbind-key "C-x #")
(unbind-key "C-x 5")
(unbind-key "C-x 6")
(unbind-key "C-x \\")
(unbind-key "C-x `")
(unbind-key "C-x m")
(unbind-key "C-x l")
(unbind-key "C-x i")
(unbind-key "C-x u")
(unbind-key "C-x @")
(unbind-key "C-x C-b")
(unbind-key "C-x C-d")
(unbind-key "C-x C-l")
(unbind-key "C-x C-p")
(unbind-key "C-x C-u")
(unbind-key "C-x C-z")
(setopt doom-modeline-irc nil)
(setopt doom-modeline-workspace-name nil)
(setopt doom-modeline-buffer-encoding nil)
(setopt doom-modeline-vcs-max-length 30)
(doom-modeline-mode)
(ligature-set-ligatures 'prog-mode
'("--" "---" "==" "===" "!=" "!==" "=!="
"=:=" "=/=" "<=" ">=" "&&" "&&&" "&=" "++" "+++" "***" ";;" "!!"
"??" "???" "?:" "?." "?=" "<:" ":<" ":>" ">:" "<:<" "<>" "<<<" ">>>"
"<<" ">>" "||" "-|" "_|_" "|-" "||-" "|=" "||=" "##" "###" "####"
"#{" "#[" "]#" "#(" "#?" "#_" "#_(" "#:" "#!" "#=" "^=" "<$>" "<$"
"$>" "<+>" "<+" "+>" "<*>" "<*" "*>" "</" "</>" "/>" "<!--" "<#--"
"-->" "->" "->>" "<<-" "<-" "<=<" "=<<" "<<=" "<==" "<=>" "<==>"
"==>" "=>" "=>>" ">=>" ">>=" ">>-" ">-" "-<" "-<<" ">->" "<-<" "<-|"
"<=|" "|=>" "|->" "<->" "<~~" "<~" "<~>" "~~" "~~>" "~>" "~-" "-~"
"~@" "[||]" "|]" "[|" "|}" "{|" "[<" ">]" "|>" "<|" "||>" "<||"
"|||>" "<|||" "<|>" "..." ".." ".=" "..<" ".?" "::" ":::" ":=" "::="
":?" ":?>" "//" "///" "/*" "*/" "/=" "//=" "/==" "@_" "__" "???"
"<:<" ";;;"))
(global-ligature-mode t)
(add-hook 'text-mode-hook 'mixed-pitch-mode)
(defun no-mixed-pitch ()
(mixed-pitch-mode -1))
(add-hook 'yaml-ts-mode-hook 'no-mixed-pitch)
(add-hook 'mhtml-mode 'no-mixed-pitch)
(add-hook 'nxml-mode 'no-mixed-pitch)
(bind-keys ("M-o" . ace-window)
("s-o" . ace-window)
("C-c o" . ace-window))
(setopt aw-keys '(?a ?s ?d ?f ?g ?h ?j ?k ?l))
(setopt aw-dispatch-always t)
(bind-keys ("s-f" . project-find-file)
("s-F" . project-switch-project)
;; ("s-s" . persp-switch)
)
(with-eval-after-load 'tab-bar
(bind-keys :map tab-bar-mode-map
("s-s" . tab-bar-switch-to-tab)))
(server-mode -1)
(setopt visible-bell t)
(transient-mark-mode -1)
(bind-keys :repeat-map tab-bar-repeat-map
("<left>" . tab-bar-history-back)
("<right>" . tab-bar-history-forward))
(tab-bar-history-mode)
(setopt compilation-scroll-output 'first-error)
(defun jf/window-children (window)
(let ((result nil)
(child (window-child window)))
(while child
(push child result)
(setq child (window-next-sibling child)))
(reverse result)))
(defun jf/window-main-root (&optional frame)
"Return FRAME's main (non-side) window or window subtree."
(let* ((root (frame-root-window (or frame (selected-frame))))
(children (jf/window-children root)))
(if (seq-some (lambda (w) (window-parameter w 'window-side)) children)
(seq-find (lambda (w) (not (window-parameter w 'window-side))) children)
root)))
(defun jf/window-leaves (window)
"Return the live leaf windows in WINDOW's subtree."
(if (window-live-p window)
(list window)
(mapcan #'jf/window-leaves (jf/window-children window))))
(defun jf/topright-window (windows)
"Return whichever of WINDOWS sits furthest up, then furthest right."
(car (sort (copy-sequence windows)
(lambda (a b)
(let ((top-a (nth 1 (window-edges a)))
(top-b (nth 1 (window-edges b))))
(if (= top-a top-b)
(> (nth 0 (window-edges a)) (nth 0 (window-edges b)))
(< top-a top-b)))))))
(defun jf/display-buffer-right (buffer alist)
"Display BUFFER on the right of the main editing area.
Applies three rules, based on the shape of the frame's non-side windows:
1. One window -> split it and show BUFFER in the new right window.
2. Two windows side-by-side -> show BUFFER in the right one. If the
right window is selected, swap the two windows first (keeping
focus on the buffer that was active) so BUFFER doesn't evict it.
3. Any other layout -> show BUFFER in the upper-rightmost window."
(let ((main (jf/window-main-root)))
(cond
((window-live-p main)
(let* ((new (split-window main nil 'right))
(width (max 1 (- (frame-width) 120)))
(delta (window-resizable new (- width (window-width new)) t)))
(window-resize new delta t)
(window--display-buffer buffer new 'window alist)))
((and (window-left-child main)
(= (length (jf/window-children main)) 2)
(seq-every-p #'window-live-p (jf/window-children main)))
(let* ((left (window-left-child main))
(right (window-next-sibling left)))
(when (eq (selected-window) right)
(window-swap-states left right)
(select-window left))
(window--display-buffer buffer right 'reuse alist)))
(t
(window--display-buffer buffer (jf/topright-window (jf/window-leaves main)) 'reuse alist)))))
(setopt popper-reference-buffers
'("\\*Flymake diagnostics .*"
"\\*Embark Export: .*"
"\\*Embark Collect .*"
"\\*xref\\*"
"\\*compilation\\*"
"\\*pnpm:.*"
"\\*sly-mrepl *"
"\\*lispy-message\\*"
"\\*occur\\*"
".*eshell\\*"
"\\*SQL: .*"
"magit-revision: .*"
"\\*Help\\*"
"\\*rustfmt\\*"
"\\*slack: .*"
"\\*forge: .*"
"new-pullreq"
"\\*claude:.*"
"\\*Man .*"
"\\*List .*"
"\\*eldoc\\*"))
(setopt popper-display-control nil)
(popper-mode)
(popper-echo-mode)
(bind-keys ("C-q" . popper-toggle)
("C-;" . popper-cycle))
(defvar jf/fullscreen-popup--param 'jf/fullscreen-saved-configuration
"Key used to stash the window configuration a fullscreen popup replaced.
Stored per-tab when `tab-bar-mode' is active, otherwise as a plain frame
parameter; see `jf/tab-or-frame-parameter'.")
(defvar-local jf/fullscreen-popup-p nil
"Non-nil in a buffer currently being displayed as a fullscreen popup.")
(defun jf/current-tab-cell (&optional frame)
"Return FRAME's current tab's raw data cell, or nil without `tab-bar-mode'."
(and (bound-and-true-p tab-bar-mode)
(assq 'current-tab (tab-bar-tabs frame))))
(defun jf/tab-or-frame-parameter (parameter &optional frame)
"Like `frame-parameter', but scoped to FRAME's selected tab when tabs are in use.
A plain frame parameter is shared by every tab on that frame, which is wrong
for state like `jf/fullscreen-popup--param': switching tabs swaps in an
entirely different window layout, so \"the layout to restore\" has to travel
with the tab, not the frame."
(if-let ((tab (jf/current-tab-cell frame)))
(alist-get parameter tab)
(frame-parameter frame parameter)))
(defun jf/set-tab-or-frame-parameter (parameter value &optional frame)
"Set PARAMETER to VALUE, scoped like `jf/tab-or-frame-parameter'."
(if-let ((tab (jf/current-tab-cell frame)))
(let ((cell (assq parameter tab)))
(if cell
(setcdr cell value)
(setcdr tab (cons (cons parameter value) (cdr tab)))))
(set-frame-parameter frame parameter value)))
(defun jf/display-buffer-fullscreen (buffer alist)
"Display BUFFER, deleting other windows, saving the prior layout.
Intended for use in `display-buffer-alist' for popups (e.g. Magit
status/log) that should take over the frame while displayed, but
restore the previous window configuration once closed via either
`q' or `popper-toggle' -- both end up calling `quit-window', which
is where the restore actually happens; see
`jf/quit-window-restore-fullscreen'."
(unless (jf/tab-or-frame-parameter jf/fullscreen-popup--param)
(jf/set-tab-or-frame-parameter jf/fullscreen-popup--param
(current-window-configuration)))
(when-let ((window (or (display-buffer-reuse-window buffer alist)
(display-buffer-same-window buffer alist)
(display-buffer-pop-up-window buffer alist)
(display-buffer-use-some-window buffer alist))))
(let ((ignore-window-parameters t))
(delete-other-windows window))
(with-current-buffer buffer
(setq jf/fullscreen-popup-p t))
window))
(defun jf/quit-window-restore-fullscreen (orig-fn &optional kill window)
"Restore the saved window configuration after quitting a fullscreen popup.
Advice around `quit-window' so both `q' (which Magit and other
special-mode buffers bind to buffer-quitting commands that call
`quit-window') and Popper's close/toggle commands (which also call
`quit-window' directly) trigger the restore. Only restores once the
last fullscreen popup on the tab (or frame, without `tab-bar-mode')
has closed, so opening one fullscreen popup from within another
falls back to the outer one first."
(let* ((window (or window (selected-window)))
(was-fullscreen (buffer-local-value 'jf/fullscreen-popup-p
(window-buffer window)))
(frame (window-frame window)))
(funcall orig-fn kill window)
(when (and was-fullscreen
(not (and (window-live-p window)
(buffer-local-value 'jf/fullscreen-popup-p
(window-buffer window))))
(jf/tab-or-frame-parameter jf/fullscreen-popup--param frame))
(let ((conf (jf/tab-or-frame-parameter jf/fullscreen-popup--param frame)))
(jf/set-tab-or-frame-parameter jf/fullscreen-popup--param nil frame)
(set-window-configuration conf)))))
(advice-add 'quit-window :around #'jf/quit-window-restore-fullscreen)
(setopt split-width-threshold 200)
(setopt split-height-threshold nil)
(setopt display-buffer-base-action
'((display-buffer-reuse-window
display-buffer-reuse-mode-window
display-buffer-use-some-window)))
(setq display-buffer-alist
'(((or "\\*Flymake diagnostics .*"
"\\*Embark Export: .*"
"\\*Embark Collect .*"
"\\*xref\\*"
"\\*compilation\\*"
"\\*pnpm:.*"
"\\*sly-mrepl *"
"\\*lispy-message\\*"
"\\*occur\\*"
".*eshell\\*"
"\\*SQL: .*")
(display-buffer-in-side-window)
(side . bottom)
(slot . 0)
(window-height . 0.33))
((or "magit: *"
"magit-log*"
"\\*Messages\\*"
"\\*trace-output\\*"
"\\*EGLOT connections\\*"
"magit-revision: .*"
"\\*Help\\*"
"\\*rustfmt\\*"
"\\*slack: .*"
"\\*forge: .*"
"new-pullreq"
"\\*claude:.*"
"\\*Man .*"
"\\*List .*"
"\\*Embark Actions\\*"
"\\*eldoc\\*")
(display-buffer-reuse-window
display-buffer-reuse-mode-window
jf/display-buffer-right))))
(setopt window-persistent-parameters
(cl-list* '(no-delete-other-windows . writable)
'(no-other-window . writable)
window-persistent-parameters))
;; (setopt evil-want-keybinding nil)
;; (require 'evil)
;; (evil-mode 1)
;; (require 'evil-collection)
;; (evil-collection-init)
;; (require 'evil-org)
;; (add-hook 'org-mode-hook 'evil-org-mode)
;; (evil-org-set-key-theme '(navigation insert textobjects additional calendar))
;; (require 'evil-org-agenda)
;; (evil-org-agenda-set-keys)
(require 'god-mode)
(require 'which-key)
(bind-keys :map god-local-mode-map
("i" . (lambda () (interactive) (god-mode-all -1)))
("z" . repeat))
(bind-keys ("<escape>" . (lambda () (interactive) (god-mode-all 1))))
(defun my-god-mode-update-cursor-type ()
(setq cursor-type (cond
((and (featurep 'org-present) org-present-mode) nil)
((or (and (featurep 'god-mode) god-local-mode) buffer-read-only) 'box)
(t 'bar))))
(add-hook 'post-command-hook 'my-god-mode-update-cursor-type)
(which-key-enable-god-mode-support)
(defun avy-goto-char-timer-embark ()
(interactive)
(require 'avy)
(let ((avy-action-oneshot
(lambda (pt)
(unwind-protect
(save-excursion
(goto-char pt)
(embark-act))
(select-window
(cdr (ring-ref avy-ring 0)))))))
(avy-goto-char-timer)))
(bind-keys
("C-j" . avy-goto-char-timer)
("M-j" . avy-goto-char-timer-embark)
("C-." . embark-act))
(with-eval-after-load 'lispy
(bind-keys :map lispy-mode-map
("C-j" . avy-goto-char-timer)))
(with-eval-after-load 'org
(bind-keys :map org-mode-map
("C-j" . avy-goto-char-timer)))
(setopt isearch-wrap-pause 'no-ding)
(defun string-inflection-rust-style-cycle-function (str)
(cond
((string-inflection-snake-case-p str)
(string-inflection-upcase-function str))
((string-inflection-upcase-p str)
(string-inflection-pascal-case-function str))
(t
(string-inflection-snake-case-function str))))
(defun string-inflection-rust-style-cycle ()
(interactive)
(require 'string-inflection)
(string-inflection--symbol-or-region #'string-inflection-rust-style-cycle-function))
(bind-keys :repeat-map string-inflection-java-map
("u" . string-inflection-java-style-cycle))
(bind-keys :repeat-map string-inflection-rust-map
("u" . string-inflection-rust-style-cycle))
(bind-keys ("C-x 4 n" . edit-indirect-region))
(with-eval-after-load 'apheleia
(push '(prisma-format "prisma" "format" "--schema" filepath) apheleia-formatters))
(buffer-terminator-mode 1)
(bind-keys
("s-b" . consult-project-buffer))
(electric-pair-mode 1)
(setq-default indent-tabs-mode nil)
(setq-default tab-width 4)
(global-tree-sitter-mode 1)
(setopt ediff-split-window-function 'split-window-horizontally)
(defun project-nix-flake ()
(interactive)
(nix-flake (project-root (project-current t))))
(bind-keys ("C-x p n" . project-nix-flake))
(setq-default fill-column 120)
(defun jf-init-fill-column ()
(display-fill-column-indicator-mode 1))
(add-hook 'prog-mode-hook 'jf-init-fill-column)
(with-eval-after-load 'prog-mode
(defun my-prog-fill-reindent-defun (&optional argument)
"Refill or reindent the paragraph or defun that contains point.
If the point is in a string or a comment, fill the paragraph that
contains point or follows point.
Otherwise, reindent the function definition that contains point
or follows point."
(interactive "P")
(save-excursion
(let ((treesit-text-node
(and (treesit-available-p)
(treesit-parser-list)
(treesit-node-match-p
(treesit-node-at (point)) 'text t))))
(if (or treesit-text-node
(and (not (and (treesit-available-p) (treesit-parser-list))) (nth 8 (syntax-ppss)))
(re-search-forward "\\s-*\\s<" (line-end-position) t))
(fill-paragraph argument (region-active-p))
(beginning-of-defun)
(let ((start (point)))
(end-of-defun)
(indent-region start (point) nil))))))
(advice-add 'prog-fill-reindent-defun :override #'my-prog-fill-reindent-defun))
(add-hook 'compilation-filter-hook 'ansi-color-compilation-filter)
(autoload 'flymake-show-project-diagnostics "flymake")
(autoload 'flymake-goto-next-error "flymake")
(autoload 'flymake-goto-prev-error "flymake")
(with-eval-after-load 'prog-mode
(bind-keys :map prog-mode-map
("C-c D" . flymake-show-project-diagnostics)
("M-n" . flymake-goto-next-error)
("M-p" . flymake-goto-prev-error)))
(with-eval-after-load 'flymake
(bind-keys :map flymake-project-diagnostics-mode-map
("q" . quit-window)))
(setopt eglot-ignored-server-capabilities '(:inlayHintProvider :semanticTokensProvider))
(add-hook 'eglot-managed-mode-hook (lambda () (eglot-inlay-hints-mode -1)) nil t)
(setopt eglot-code-action-indications nil)
(setopt eglot-events-buffer-config '(:size 300000 :format full))
(with-eval-after-load 'eglot
(bind-keys :map eglot-mode-map
("C-c a" . eglot-code-actions)
("C-c r" . eglot-rename)
("C-c i" . eglot-find-implementation)))
(with-eval-after-load 'eglot
(add-to-list 'eglot-stay-out-of 'yasnippet))
(setq major-mode-remap-alist '((rust-mode . rust-mode)))
(setopt rust-mode-treesitter-derive t)
(with-eval-after-load 'rust-prog-mode
(bind-keys :map rust-mode-map
("C-c u" . string-inflection-rust-style-cycle)))
(defun yaml-validate ()
(interactive)
(compile (concat "yamllint -d '{extends: default, rules: {indentation: {indent-sequences: false}, braces: {max-spaces-inside: 1}}}' " (buffer-file-name)) t))
(add-hook 'yaml-ts-mode-hook 'yaml-pro-ts-mode)
(setopt inferior-lisp-program "sbcl")
(setopt lispy-compat '(god-mode edebug))
(add-hook 'emacs-lisp-mode-hook (lambda () (lispy-mode 1)))
(add-hook 'lisp-mode-hook (lambda () (lispy-mode 1)))
(add-hook 'lisp-data-mode-hook (lambda () (lispy-mode 1)))
(with-eval-after-load 'lispy
;; (require 'lispyville)
;; (add-hook 'lispy-mode-hook #'lispyville-mode)
(bind-keys :map lispy-mode-map
("i" . (lambda ()
(interactive)
(if (and (featurep 'god-mode) god-global-mode)
(god-mode-all -1)
(special-lispy-tab))))))
(add-to-list 'auto-mode-alist '("\\.ts\\'" . typescript-mode))
(add-to-list 'major-mode-remap-alist '(typescript-mode . typescript-ts-mode))
(add-to-list 'auto-mode-alist '("\\.tsx\\'" . tsx-mode))
(add-to-list 'major-mode-remap-alist '(tsx-mode . tsx-ts-mode))
(setopt typescript-ts-mode-indent-offset 2)
(with-eval-after-load 'typescript-ts-mode
(defun my-tsx-ts-mode--indent-compatibility-b893426 ()
"Indent rules helper, to handle different releases of tree-sitter-tsx.
Check if a node type is available, then return the right indent rules."
;; handle https://github.com/tree-sitter/tree-sitter-typescript/commit/b893426b82492e59388a326b824a346d829487e8
(condition-case nil
(progn (treesit-query-capture 'tsx '((jsx_fragment) @capture))
`(((match "<" "jsx_fragment") parent 0)
((parent-is "jsx_fragment") parent typescript-ts-mode-indent-offset)))
(treesit-query-error
`(((match "<" "jsx_text") parent 0)
((parent-is "jsx_text") grand-parent typescript-ts-mode-indent-offset)))))
(advice-add 'tsx-ts-mode--indent-compatibility-b893426 :override #'my-tsx-ts-mode--indent-compatibility-b893426))
(defvar my/edit-indirect-tag-modes
'(("graphql" . graphql-ts-mode)
("gql" . graphql-ts-mode)
("sql" . sql-mode)
("css" . css-mode))
"Map of tagged-template tag names to major modes.")
(defun my/edit-indirect--node-bounds (node)
"Return (BEG . END) for NODE's contents, excluding delimiters."
(cons (1+ (treesit-node-start node))
(1- (treesit-node-end node))))
(defun my/edit-indirect-tagged-template-at-point ()
(interactive)
(let* ((node (treesit-node-at (point)))
(tmpl-node (treesit-parent-until
node
(lambda (n) (equal (treesit-node-type n) "template_string"))))
(str-node (unless tmpl-node
(treesit-parent-until
node
(lambda (n) (equal (treesit-node-type n) "string")))))
(target-node (or tmpl-node str-node)))
(unless target-node
(user-error "Point is not inside a string or template literal"))
(let* ((tagged-node (and tmpl-node (treesit-node-parent tmpl-node)))
(tag-node (and tagged-node
(equal (treesit-node-type tagged-node) "call_expression")
(treesit-node-child-by-field-name tagged-node "function")))
(tag-name (and tag-node (treesit-node-text tag-node t)))
(mode (cond
(tag-name (or (cdr (assoc tag-name my/edit-indirect-tag-modes))
major-mode))
(t 'text-mode)))
(bounds (my/edit-indirect--node-bounds target-node))
(buf (edit-indirect-region (car bounds) (cdr bounds) t)))
(with-current-buffer buf
(funcall mode)))))
(with-eval-after-load 'typescript-ts-mode
(define-key typescript-ts-mode-map (kbd "C-c '") #'my/edit-indirect-tagged-template-at-point)
(define-key tsx-ts-mode-map (kbd "C-c '") #'my/edit-indirect-tagged-template-at-point))
(with-eval-after-load 'eglot
(add-to-list 'eglot-server-programs '((prisma-ts-mode) "prisma-language-server" "--stdio")))
(push '(java-mode . java-ts-mode) major-mode-remap-alist)
(with-eval-after-load 'java-ts-mode
(bind-keys :map java-ts-mode-map
("C-c u" . string-inflection-java-style-cycle))
(push `((n-p-gp nil "block" "lambda_expression") parent-bol java-ts-mode-indent-offset)
(cdar java-ts-mode--indent-rules))
(push `((n-p-gp "}" "block" "lambda_expression") parent-bol 0)
(cdar java-ts-mode--indent-rules))
(add-hook 'java-mode-hook (lambda () (c-set-offset 'arglist-intro '+)))
(defvar jf/class-name-to-file-search-path (list "src/main/java" "src/test/java"))
(defun jf/class-name-to-file (class-name)
(let ((root (project-root (project-current t)))
(fragment (format "%s.java" (replace-regexp-in-string "\\." "/" class-name)))
(result))
(dolist (p jf/class-name-to-file-search-path result)
(unless result
(let ((path (format "%s/%s" p fragment)))
(when (file-exists-p (concat root path))
(setq result path)))))))
(defun jf/compile-class-to-file ()
(jf/class-name-to-file (concat (match-string 1) (match-string 2)))))
;(add-to-list 'compilation-error-regexp-alist-alist
; '(java-stack-trace .
; ("^[[:space:]]*at \\(\\(?:[[:lower:]]+\\.\\)+\\)[^(]+(\\([[:alnum:]]+\\)\\.java:\\([[:digit:]]+\\))"
; jf/compile-class-to-file 3)))
;(add-to-list 'compilation-error-regexp-alist 'java-stack-trace)
(add-hook 'sql-mode-hook 'sqlind-minor-mode)
(setopt haskell-ts-use-indent t)
(add-hook 'after-init-hook 'envrc-global-mode)
(setopt envrc-show-summary-in-minibuffer nil)
(setopt magit-define-global-key-bindings 'recommended)
(bind-keys ("s-g" . magit))
(setopt magit-save-repository-buffers 'dontask)
(setopt magit-commit-show-diff nil)
(with-eval-after-load 'magit
(set-face-attribute 'git-commit-summary nil :inherit nil)
(defun magit-fetch-all-on-load ()
(magit-run-git-async "fetch" "--all"))
(add-hook 'magit-status-mode-hook 'magit-fetch-all-on-load)
(remove-hook 'magit-status-headers-hook 'magit-insert-tags-header)
(require 'forge)
(add-hook 'magit-post-refresh-hook 'diff-hl-magit-post-refresh))
(with-eval-after-load 'forge
(add-hook 'forge-edit-post-hook 'forge-create-pullreq-insert-single-commit-message)
(setopt forge-status-buffer-default-topic-filters
(forge--topics-spec :type 'topic :active nil :state 'open :order 'newest)))
(global-diff-hl-mode)
(bind-keys
;; ("C-c M-x" . consult-mode-command)
("C-c h" . consult-history)
;; ("C-c k" . consult-kmacro)
;; ("C-c m" . consult-man)
;; ([remap Info-search] . consult-info)
;; ("C-x M-:" . consult-complex-command)
("C-x b" . consult-buffer)
("s-B" . consult-buffer)
("C-x 4 b" . consult-buffer-other-window)
("C-x 5 b" . consult-buffer-other-frame)
;; ("C-x t b" . consult-buffer-other-tab)
("C-x r b" . consult-bookmark)
("C-x p b" . consult-project-buffer)
("M-#" . consult-register-load)
("M-'" . consult-register-store)
("C-M-#" . consult-register)
("M-y" . consult-yank-pop)
("M-g e" . consult-compile-error)
("M-g f" . consult-flymake)
("M-g g" . consult-goto-line)
("M-g M-g" . consult-goto-line)
("M-g o" . consult-org-heading)
("M-g m" . consult-mark)
("M-g k" . consult-global-mark)
("M-g i" . consult-imenu)
("M-g I" . consult-imenu-multi)
("M-s r" . consult-ripgrep)
("M-s l" . consult-line)
("M-s L" . consult-line-multi)
("M-s e" . consult-isearch-history)
:map isearch-mode-map
("M-e" . consult-isearch-history)
("M-s e" . consult-isearch-history)
("M-s l" . consult-line)
("M-s L" . consult-line-multi)
:map minibuffer-local-map
("M-s" . consult-history)
("M-r" . consult-history))
(advice-add 'register-preview :override #'consult-register-window)
(setopt register-preview-delay 0.5)
(setopt xref-show-xrefs-function 'consult-xref)
(setopt xref-show-definitions-function 'consult-xref)
(eval-when-compile
(require 'consult))
(with-eval-after-load 'consult
(consult-customize
consult-theme :preview-key '(:debounce 0.2 any)
consult-ripgrep consult-git-grep consult-grep consult-man
consult-bookmark consult-recent-file consult-xref
consult-source-bookmark consult-source-file-register
consult-source-recent-file
consult-source-buffer
;; :preview-key "M-."
consult-source-project-recent-file
:preview-key '(:debounce 0.4 any)))
(setopt consult-narrow-key "<") ;; "C-+"
(use-package vertico
:custom
(vertico-count 25)
:config
(vertico-mode))
(setopt completion-styles '(orderless basic))
(use-package marginalia
:config
(marginalia-mode))
(use-package corfu
:custom
(corfu-cycle t)
(corfu-popupinfo-mode nil)
(corfu-quit-at-boundary nil)
(corfu-on-exact-match 'show)
:config
(global-corfu-mode))
;; (setq completion-in-region-function #'consult-completion-in-region)
(use-package cape
:custom
(add-hook 'completion-at-point-functions 'cape-file))
(use-package org
:bind (("C-c A" . org-agenda)
("C-c C" . org-capture)
("C-c l" . org-id-store-link))
:custom
(org-babel-load-languages '((emacs-lisp . t) (sql . t)))
(org-confirm-babel-evaluate nil)
(org-link-keep-stored-after-insertion t)
(org-capture-templates
'(("t" "Todo" entry
(here)
"** TODO %?\n:LOGBOOK:\n- State \"TODO\" %U\n:END:\n")
("w" "Work stuff")
("wp" "Work Project" entry
(file+headline "~/org/todo/work.org.age" "Next Actions")
"*** PROJ %?\n- State \"PROJ\" %U\n")
("wa" "Work Next Action" entry
(file+headline "~/org/todo/work.org.age" "Next Actions")
"*** TODO %?\n- State \"TODO\" %U\n")
("p" "Personal stuff")
("pp" "Personal Project" entry
(file+headline "~/org/todo/personal.org.age" "Next Actions")
"*** PROJ %?\n- State \"PROJ\" %U\n")
("pa" "Personal Next Action" entry
(file+headline "~/org/todo/personal.org.age" "Next Actions")
"*** TODO %?\n- State \"TODO\" %U\n")))
(org-agenda-files '("~/org/todo/work.org" "~/org/todo/personal.org.age"))
(org-agenda-todo-ignore-scheduled 'future)
(org-agenda-tags-todo-honor-ignore-options t)
(org-enforce-todo-dependencies t)
(org-agenda-dim-blocked-tasks 'invisible)
:config
(add-hook 'org-mode-hook 'visual-line-mode)
(set-face-attribute 'org-level-1 nil :font "Iosevka Aile")
(set-face-attribute 'org-level-2 nil :font "Iosevka Aile")
(set-face-attribute 'org-level-3 nil :font "Iosevka Aile")
(set-face-attribute 'org-level-4 nil :font "Iosevka Aile")
(set-face-attribute 'org-level-5 nil :font "Iosevka Aile")
(set-face-attribute 'org-level-6 nil :font "Iosevka Aile")
(set-face-attribute 'org-level-7 nil :font "Iosevka Aile")
(set-face-attribute 'org-level-8 nil :font "Iosevka Aile"))
(defvar-local my/org-present-face-remapping-cookies nil)
(use-package org-present
:config
(require 'face-remap)
(require 'visual-fill-column)
(defun my/org-present-start ()
(setq-local my/org-present-face-remapping-cookies nil)
;; Tweak font sizes
(dolist (face '((default :height 2.0)
(header-line :height 4.0 :background "#303446")
(org-document-title :height 1.75)
(org-code :height 2.0)
(org-verbatim :height 2.0)
(org-block :height 1.25)
(org-block-begin-line :height 0.7)
(org-level-1 :height 3.0)
(org-level-2 :height 3.0)
(org-level-3 :height 3.0)
(org-level-4 :height 3.0)
(org-level-5 :height 3.0)
(org-level-6 :height 3.0)
(org-level-7 :height 3.0)
(org-level-8 :height 3.0)))
(push (apply #'face-remap-add-relative face) my/org-present-face-remapping-cookies))
;; Set a blank header line string to create blank space at the top
(setq header-line-format " ")
;; Display inline images automatically
(org-display-inline-images)
(org-present-hide-cursor)
;; Center the presentation and wrap lines
(visual-fill-column-mode 1)
(setq visual-fill-column-center-text t)
;; (visual-line-mode 1)
)
(defun my/org-present-end ()
;; Reset font customizations
(dolist (cookie my/org-present-face-remapping-cookies)
(face-remap-remove-relative cookie))
;; Clear the header line string so that it isn't displayed
(setq header-line-format nil)
;; Stop displaying inline images
(org-remove-inline-images)
(org-present-show-cursor)
;; Stop centering the document
(visual-fill-column-mode 0)
;; (visual-line-mode 0)
)
(add-hook 'org-present-mode-hook 'my/org-present-start)
(add-hook 'org-present-mode-quit-hook 'my/org-present-end))
;; (require 'org-roam)
;; (bind-keys ("C-c n l" . org-roam-buffer-toggle)
;; ("C-c n f" . org-roam-node-find)
;; ("C-c n g" . org-roam-graph)
;; ("C-c n i" . org-roam-node-insert)
;; ("C-c n c" . org-roam-capture))
;; (setq org-roam-node-display-template (concat "${title:*} " (propertize "${tags:10}" 'face 'org-tag)))
;; (org-roam-db-autosync-mode)
(use-package org-modern
:hook org-mode)
;; (define-key org-mode-map (kbd "C-c C-r") verb-command-map)
(use-package eat
:commands (eat)
:hook (eshell-load-hook . eat-eshell-mode))
(use-package age
:custom
(age-default-identity "~/source/dotfiles/keys/yubi1age.txt")
(age-default-recipient "~/source/dotfiles/keys/myself.txt")
:config
(setenv "PINENTRY_PROGRAM" "pinentry-mac")
(age-file-enable))
(use-package claude-code
:bind-keymap ("C-c c" . claude-code-command-map)
:custom (claude-code-optimize-window-resize nil))
+10
View File
@@ -0,0 +1,10 @@
(use-package lui
:defer t
:custom
(lui-time-stamp-format "[%Y-%m-%d %H:%M]"))
(use-package slack
:commands slack-start
:custom
(slack-render-profile-images-p nil)
(slack-buffer-function #'switch-to-buffer))
+10
View File
@@ -0,0 +1,10 @@
(use-package lui
:defer t
:custom
(lui-time-stamp-format "[%Y-%m-%d %H:%M]"))
(use-package slack
:commands slack-start
:custom
(slack-render-profile-images-p nil)
(slack-buffer-function #'switch-to-buffer))
+154
View File
@@ -0,0 +1,154 @@
local config = {}
config.font = wezterm.font 'Iosevka Term SS14'
config.font_size = 13.0
-- config.font = wezterm.font("JetBrains Mono")
config.inactive_pane_hsb = {
saturation = 0.5,
brightness = 0.5,
}
config.pane_focus_follows_mouse = true
config.switch_to_last_active_tab_when_closing_tab = true
config.tab_bar_at_bottom = true
config.use_fancy_tab_bar = false
config.window_decorations = "RESIZE"
local workspace_switcher = wezterm.plugin.require("https://github.com/MLFlexer/smart_workspace_switcher.wezterm")
workspace_switcher.zoxide_path='~/.nix-profile/bin/zoxide'
wezterm.on('smart_workspace_switcher.workspace_switcher.created', function(window, path, workspace)
local editor = window:active_tab()
editor:set_title("edit")
editor:panes()[1]:send_text("hx\n")
local run = window:spawn_tab {}
run:set_title "run"
local term = window:spawn_tab {}
term:set_title "term"
editor:activate()
end)
local function segments_for_right_status(window)
return {
window:active_workspace(),
}
end
wezterm.on('update-status',
function(window, _)
local SOLID_LEFT_ARROW = utf8.char(0xe0b2)
local segments = segments_for_right_status(window)
local color_scheme = window:effective_config().resolved_palette
-- Note the use of wezterm.color.parse here, this returns
-- a Color object, which comes with functionality for lightening
-- or darkening the colour (amongst other things).
local bg = wezterm.color.parse(color_scheme.background)
local fg = color_scheme.foreground
-- Each powerline segment is going to be coloured progressively
-- darker/lighter depending on whether we're on a dark/light colour
-- scheme. Let's establish the "from" and "to" bounds of our gradient.
local gradient_to, gradient_from = bg
gradient_from = gradient_to:lighten(0.2)
-- Yes, WezTerm supports creating gradients, because why not?! Although
-- they'd usually be used for setting high fidelity gradients on your terminal's
-- background, we'll use them here to give us a sample of the powerline segment
-- colours we need.
local gradient = wezterm.color.gradient(
{
orientation = 'Horizontal',
colors = { gradient_from, gradient_to },
},
#segments -- only gives us as many colours as we have segments.
)
-- We'll build up the elements to send to wezterm.format in this table.
local elements = {}
for i, seg in ipairs(segments) do
local is_first = i == 1
if is_first then
table.insert(elements, { Background = { Color = 'none' } })
end
table.insert(elements, { Foreground = { Color = gradient[i] } })
table.insert(elements, { Text = SOLID_LEFT_ARROW })
table.insert(elements, { Foreground = { Color = fg } })
table.insert(elements, { Background = { Color = gradient[i] } })
table.insert(elements, { Text = ' ' .. seg .. ' ' })
end
window:set_right_status(wezterm.format(elements))
end)
config.leader = { key = ' ', mods = 'CTRL', timeout_milliseconds = 10000 }
config.keys = {
{
key = "s",
mods = "CMD",
action = workspace_switcher.switch_workspace(),
},
{
key = "-",
mods = "CMD",
action = wezterm.action.SplitVertical {},
},
{
key = "\\",
mods = "CMD",
action = wezterm.action.SplitHorizontal {},
},
{
key = "h",
mods = "CMD",
action = wezterm.action.ActivatePaneDirection "Left",
},
{
key = "j",
mods = "CMD",
action = wezterm.action.ActivatePaneDirection "Down",
},
{
key = "k",
mods = "CMD",
action = wezterm.action.ActivatePaneDirection "Up",
},
{
key = "l",
mods = "CMD",
action = wezterm.action.ActivatePaneDirection "Right",
},
{
key = "g",
mods = "CMD",
action = wezterm.action.SpawnCommandInNewTab {
args = { wezterm.home_dir .. "/.nix-profile/bin/zsh", "-l", "-i", "-c", "lazygit" }
}
},
{
key = "t",
mods = "CMD",
action = wezterm.action.SpawnCommandInNewTab {}
},
{
key = 'z',
mods = 'CMD',
action = wezterm.action.TogglePaneZoomState,
},
{
key = 'd',
mods = 'CMD',
action = wezterm.action.CloseCurrentTab { confirm = true },
},
}
for i = 1, 9 do
-- CTRL+ALT + number to activate that tab
table.insert(config.keys, {
key = tostring(i),
mods = 'LEADER',
action = wezterm.action.ActivateTab(i - 1),
})
end
config.color_scheme = 'Catppuccin Frappe'
return config