Compare commits
2 commits
e2085e0e86
...
5a25314924
| Author | SHA1 | Date | |
|---|---|---|---|
| 5a25314924 | |||
| 6f0b34ed75 |
4 changed files with 53 additions and 430 deletions
|
|
@ -1,5 +1,3 @@
|
|||
# -- Monitors & input defaults --
|
||||
# Monitor layout is host-specific; written by the flake per host.
|
||||
source = ~/.config/hypr/monitors.conf
|
||||
|
||||
device {
|
||||
|
|
@ -7,14 +5,6 @@ device {
|
|||
kb_options = caps:ctrl_modifier,grp:win_space_toggle
|
||||
}
|
||||
|
||||
# TrackPoint (Corne nipple): hold middle button + move to scroll, joystick-style
|
||||
device {
|
||||
name = corne-tp
|
||||
scroll_method = on_button_down
|
||||
scroll_button = 274 # BTN_MIDDLE
|
||||
scroll_button_lock = false # set true to toggle scroll on/off with a tap instead of holding
|
||||
}
|
||||
|
||||
input {
|
||||
kb_layout = us,dk
|
||||
kb_options = grp:win_space_toggle
|
||||
|
|
@ -27,7 +17,7 @@ input {
|
|||
natural_scroll = true
|
||||
scroll_factor = 0.9
|
||||
tap-to-click = false
|
||||
clickfinger_behavior = true # 2-finger click = right-click, 3-finger = middle (Mac-like)
|
||||
clickfinger_behavior = true
|
||||
disable_while_typing = true
|
||||
}
|
||||
}
|
||||
|
|
@ -48,8 +38,6 @@ dwindle {
|
|||
force_split = 2
|
||||
}
|
||||
|
||||
# Apps don't get to maximize themselves: kitty (0.49) asks ~250ms after it
|
||||
# maps, so every new terminal opened maximized. SUPER+F still works.
|
||||
windowrule = match:class .*, suppress_event maximize
|
||||
|
||||
misc {
|
||||
|
|
@ -63,25 +51,19 @@ ecosystem {
|
|||
no_donation_nag = true
|
||||
}
|
||||
|
||||
# -- Environment --
|
||||
env = QT_QPA_PLATFORMTHEME,qt6ct
|
||||
env = QT_STYLE_OVERRIDE,Adwaita-Dark
|
||||
env = XDG_SCREENSHOTS_DIR,$HOME/Pictures/Screenshots
|
||||
# hyprshot ignores XDG_SCREENSHOTS_DIR: it reads HYPRSHOT_DIR, else XDG_PICTURES_DIR,
|
||||
# else $HOME. Without this, screenshots land loose in ~/Pictures.
|
||||
env = HYPRSHOT_DIR,$HOME/Pictures/Screenshots
|
||||
|
||||
# -- Autostart --
|
||||
exec-once = uwsm finalize
|
||||
# Boot lands on the lock screen rather than an unlocked desktop. Unlocking it
|
||||
# also unlocks the keyring (see security.pam.services.hyprlock in flake.nix).
|
||||
exec-once = hyprlock
|
||||
exec-once = swaybg -c '#16181a'
|
||||
exec-once = GDK_BACKEND=wayland eww daemon
|
||||
exec-once = systemctl --user start hyprpolkitagent
|
||||
|
||||
# -- Core --
|
||||
bind = SUPER, Return, exec, kitty
|
||||
bind = SUPER, A, exec, caffeine
|
||||
bind = SUPER, D, exec, fuzzel
|
||||
bind = SUPER, R, exec, eww open battery-popup
|
||||
bindr = SUPER, R, exec, eww close battery-popup
|
||||
|
|
@ -89,88 +71,45 @@ bind = SUPER, Q, killactive
|
|||
bind = SUPER, F, fullscreen, 1
|
||||
bind = SUPER SHIFT, Space, togglefloating
|
||||
bind = SUPER, Escape, exec, hyprlock
|
||||
|
||||
# Amphetamine-style stay-awake toggle: idle + sleep + lid. See flake.nix.
|
||||
bind = SUPER, A, exec, caffeine
|
||||
|
||||
# -- Floating panels --
|
||||
# Each gets its own app_id so the rule below floats only these and not every
|
||||
# terminal. Quit with the TUI's own `q`; no toggle wrapper.
|
||||
#
|
||||
# The float/size rule is in monitors.conf, generated per host: Hyprland 0.56
|
||||
# `size` takes ONLY absolute pixels -- percentages are silently ignored (they
|
||||
# parse fine and then do nothing), so the value depends on the resolution.
|
||||
bind = SUPER, W, exec, kitty --class panel-wifi impala
|
||||
bind = SUPER, E, exec, kitty --class panel-bt bluetui
|
||||
|
||||
|
||||
# -- Focus --
|
||||
bind = SUPER, h, movefocus, l
|
||||
bind = SUPER, j, movefocus, d
|
||||
bind = SUPER, k, movefocus, u
|
||||
bind = SUPER, l, movefocus, r
|
||||
|
||||
# -- Move windows --
|
||||
bind = SUPER SHIFT, h, movewindow, l
|
||||
bind = SUPER SHIFT, j, movewindow, d
|
||||
bind = SUPER SHIFT, k, movewindow, u
|
||||
bind = SUPER SHIFT, l, movewindow, r
|
||||
|
||||
# -- Workspaces (AeroSpace-style) --
|
||||
# Each workspace lives on one monitor. SUPER+N shows N on its monitor and
|
||||
# focuses it, leaving the other screens alone; a new workspace opens on the
|
||||
# focused monitor. SUPER+ALT+h/l carries a workspace to another monitor.
|
||||
bind = SUPER, 1, workspace, 1
|
||||
bind = SUPER, 2, workspace, 2
|
||||
bind = SUPER, 3, workspace, 3
|
||||
bind = SUPER, 4, workspace, 4
|
||||
bind = SUPER, 5, workspace, 5
|
||||
|
||||
# Send the window without following it, like AeroSpace's move-node-to-workspace.
|
||||
bind = SUPER SHIFT, 1, movetoworkspacesilent, 1
|
||||
bind = SUPER SHIFT, 2, movetoworkspacesilent, 2
|
||||
bind = SUPER SHIFT, 3, movetoworkspacesilent, 3
|
||||
bind = SUPER SHIFT, 4, movetoworkspacesilent, 4
|
||||
bind = SUPER SHIFT, 5, movetoworkspacesilent, 5
|
||||
|
||||
# AeroSpace's alt-tab / alt-shift-tab: previous workspace, and send the
|
||||
# current workspace to the next monitor (+1 wraps past the last one).
|
||||
bind = SUPER, Tab, workspace, previous
|
||||
bind = SUPER SHIFT, Tab, movecurrentworkspacetomonitor, +1
|
||||
bind = SUPER ALT, Tab, movecurrentworkspacetomonitor, +1
|
||||
|
||||
# -- Move current workspace to another monitor --
|
||||
bind = SUPER ALT, h, movecurrentworkspacetomonitor, l
|
||||
bind = SUPER ALT, l, movecurrentworkspacetomonitor, r
|
||||
|
||||
# -- Resize (hold for repeat) --
|
||||
binde = SUPER CTRL, h, resizeactive, -40 0
|
||||
binde = SUPER CTRL, j, resizeactive, 0 40
|
||||
binde = SUPER CTRL, k, resizeactive, 0 -40
|
||||
binde = SUPER CTRL, l, resizeactive, 40 0
|
||||
|
||||
# -- Mouse --
|
||||
bindm = SUPER, mouse:272, movewindow
|
||||
bindm = SUPER, mouse:273, resizewindow
|
||||
|
||||
# -- Audio (bindel: locked + repeat; bindl: locked, no repeat) --
|
||||
bindel = , XF86AudioRaiseVolume, exec, wpctl set-volume -l 1.0 @DEFAULT_AUDIO_SINK@ 5%+
|
||||
bindel = , XF86AudioLowerVolume, exec, wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%-
|
||||
bindl = , XF86AudioMute, exec, wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle
|
||||
bindl = , XF86AudioMicMute, exec, wpctl set-mute @DEFAULT_AUDIO_SOURCE@ toggle
|
||||
|
||||
# -- Brightness --
|
||||
bindel = , XF86MonBrightnessUp, exec, brightnessctl set 5%+
|
||||
bindel = , XF86MonBrightnessDown, exec, brightnessctl set 5%-
|
||||
|
||||
# -- Media --
|
||||
bindl = , XF86AudioPlay, exec, playerctl play-pause
|
||||
bindl = , XF86AudioNext, exec, playerctl next
|
||||
bindl = , XF86AudioPrev, exec, playerctl previous
|
||||
|
||||
# -- Screenshots --
|
||||
# Super+Ctrl+S: focused monitor -> file + clipboard
|
||||
bind = SUPER CTRL, S, exec, hyprshot -m output
|
||||
# Super+Shift+S: region (screen frozen while selecting) -> file + clipboard
|
||||
bind = SUPER SHIFT, S, exec, hyprshot -m region -z
|
||||
|
||||
|
|
|
|||
|
|
@ -1,141 +1,87 @@
|
|||
vim.o.winborder = "rounded" -- floating windows (hover docs, pickers) get rounded borders
|
||||
vim.o.tabstop = 2 -- a tab character is rendered 2 columns wide
|
||||
vim.o.ignorecase = true -- searching is case insensitive
|
||||
vim.o.shiftwidth = 2 -- >> and << indent by 2
|
||||
vim.o.smartindent = true -- indent new lines based on the line above
|
||||
vim.opt.wrap = false -- long lines run off the screen instead of wrapping
|
||||
vim.opt.number = true -- show line numbers
|
||||
vim.o.relativenumber = true -- ...but relative to the cursor, so 5j / 5k are easy to aim
|
||||
vim.o.termguicolors = true -- 24 bit color, the colorscheme needs this
|
||||
vim.o.undofile = true -- keep undo history on disk, so you can undo after reopening a file
|
||||
vim.o.incsearch = true -- jump to the match while you are still typing the search
|
||||
vim.o.signcolumn = "yes" -- always show the left gutter (diagnostics live there) so text never jumps
|
||||
vim.opt.clipboard = "unnamedplus" -- yank and paste use the system clipboard
|
||||
vim.opt.expandtab = true -- pressing tab inserts spaces, not a tab character
|
||||
vim.o.winborder = "rounded"
|
||||
vim.o.tabstop = 2
|
||||
vim.o.ignorecase = true
|
||||
vim.o.shiftwidth = 2
|
||||
vim.o.smartindent = true
|
||||
vim.opt.wrap = false
|
||||
vim.opt.number = true
|
||||
vim.o.relativenumber = true
|
||||
vim.o.termguicolors = true
|
||||
vim.o.undofile = true
|
||||
vim.o.incsearch = true
|
||||
vim.o.signcolumn = "yes"
|
||||
vim.opt.clipboard = "unnamedplus"
|
||||
vim.opt.expandtab = true
|
||||
vim.g.nix_managed = true
|
||||
|
||||
-- vim.pack is neovim's built in plugin manager. it clones these repos into
|
||||
-- stdpath("data")/site/pack the first time you start. `vim.pack.update()`
|
||||
-- updates them.
|
||||
vim.pack.add({
|
||||
{ src = "https://github.com/nvim-tree/nvim-web-devicons" }, -- filetype icons (needs a nerd font in your terminal)
|
||||
{ src = "https://github.com/scottmckendry/cyberdream.nvim" }, -- the colorscheme
|
||||
{ src = "https://github.com/stevearc/oil.nvim" }, -- file manager that is just an editable buffer
|
||||
{ src = "https://github.com/neovim/nvim-lspconfig" }, -- ready made configs for language servers
|
||||
{ src = "https://github.com/saghen/blink.cmp" }, -- the autocomplete popup
|
||||
{ src = "https://github.com/folke/snacks.nvim" }, -- grab bag of small tools. we use the picker, terminal and lazygit
|
||||
{ src = "https://github.com/folke/todo-comments.nvim" }, -- highlights TODO/FIXME/HACK and can list them
|
||||
{ src = "https://github.com/folke/trouble.nvim" }, -- a readable list of errors and warnings
|
||||
{ src = "https://github.com/nvim-treesitter/nvim-treesitter" },-- real syntax parsing, better highlighting
|
||||
{ src = "https://github.com/j-hui/fidget.nvim" }, -- little lsp progress spinner in the corner
|
||||
{ src = "https://github.com/nvim-lualine/lualine.nvim" }, -- the statusline at the bottom
|
||||
})
|
||||
|
||||
-- most plugins only need setup() called with no arguments to turn them on.
|
||||
require("blink.cmp").setup()
|
||||
require("todo-comments").setup()
|
||||
require("trouble").setup()
|
||||
require("fidget").setup()
|
||||
require("lualine").setup({
|
||||
options = {
|
||||
-- plain | instead of the default powerline arrows, so it looks right in any font
|
||||
component_separators = { left = "|", right = "|" },
|
||||
section_separators = { left = "|", right = "|" },
|
||||
},
|
||||
})
|
||||
require("oil").setup({
|
||||
default_file_explorer = true, -- opening a directory opens oil instead of netrw
|
||||
delete_to_trash = true, -- deleting a file in oil sends it to the trash, not the void
|
||||
skip_confirm_for_simple_edits = true, -- don't ask "are you sure" for renames and single deletes
|
||||
view_options = { show_hidden = true }, -- show dotfiles
|
||||
-- oil's own keymaps, inside an oil buffer only.
|
||||
default_file_explorer = true,
|
||||
delete_to_trash = true,
|
||||
skip_confirm_for_simple_edits = true,
|
||||
view_options = { show_hidden = true },
|
||||
keymaps = {
|
||||
["g?"] = { "actions.show_help", mode = "n" }, -- everything oil can do
|
||||
["<CR>"] = "actions.select", -- open the file/directory under the cursor
|
||||
["-"] = { "actions.parent", mode = "n" }, -- go up one directory
|
||||
["_"] = { "actions.open_cwd", mode = "n" }, -- jump to the directory nvim was started in
|
||||
["`"] = { "actions.cd", mode = "n" }, -- make this directory nvim's working directory
|
||||
["g?"] = { "actions.show_help", mode = "n" },
|
||||
["<CR>"] = "actions.select",
|
||||
["-"] = { "actions.parent", mode = "n" },
|
||||
["_"] = { "actions.open_cwd", mode = "n" },
|
||||
["`"] = { "actions.cd", mode = "n" },
|
||||
},
|
||||
use_default_keymaps = false, -- only the five above, nothing else
|
||||
use_default_keymaps = false,
|
||||
})
|
||||
require("snacks").setup({ picker = { ui_select = true } }) -- any "pick one" prompt uses the snacks picker
|
||||
require("snacks").setup({ picker = { ui_select = true } })
|
||||
|
||||
vim.cmd("colorscheme cyberdream")
|
||||
|
||||
-- briefly flash whatever you just yanked, so you can see what got copied
|
||||
vim.api.nvim_create_autocmd("TextYankPost", {
|
||||
callback = function()
|
||||
vim.highlight.on_yank()
|
||||
end,
|
||||
})
|
||||
|
||||
|
||||
-- These are the language servers we turn on. the server programs themselves are
|
||||
-- installed by nix (see programs.neovim.extraPackages in flake.nix), this line
|
||||
-- only tells neovim to start them for the right filetypes.
|
||||
vim.lsp.enable({ "lua_ls", "ts_ls", "rust_analyzer", "html", "cssls", "jsonls", "nixd" })
|
||||
|
||||
-- This means that we should run the callback when the event LspAttach happens
|
||||
-- aka. when a language server attaches to the buffer. that is when these
|
||||
-- keymaps start doing something useful, so we only set them then.
|
||||
vim.api.nvim_create_autocmd("LspAttach", {
|
||||
callback = function(ev)
|
||||
vim.keymap.set('n', 'gd', vim.lsp.buf.definition) -- go to where the thing under the cursor is defined
|
||||
vim.keymap.set('n', 'gD', vim.lsp.buf.declaration) -- go to its declaration (mostly a C/C++ thing)
|
||||
vim.keymap.set('n', 'gr', Snacks.picker.lsp_references) -- list every place it is used
|
||||
vim.keymap.set('n', 'gt', Snacks.picker.lsp_type_definitions) -- go to the definition of its type
|
||||
vim.keymap.set('n', '<leader>ss', Snacks.picker.lsp_symbols) -- search symbols in this file
|
||||
vim.keymap.set('n', '<leader>sS', Snacks.picker.lsp_workspace_symbols) -- search symbols in the whole project
|
||||
vim.keymap.set('n', '<leader>ca', vim.lsp.buf.code_action) -- offer the fixes/refactors the server suggests
|
||||
vim.keymap.set('n', '<leader>cr', vim.lsp.buf.rename) -- rename it everywhere at once
|
||||
vim.keymap.set('n', 'gd', vim.lsp.buf.definition)
|
||||
vim.keymap.set('n', 'gD', vim.lsp.buf.declaration)
|
||||
vim.keymap.set('n', 'gr', Snacks.picker.lsp_references)
|
||||
vim.keymap.set('n', 'gt', Snacks.picker.lsp_type_definitions)
|
||||
vim.keymap.set('n', '<leader>ss', Snacks.picker.lsp_symbols)
|
||||
vim.keymap.set('n', '<leader>sS', Snacks.picker.lsp_workspace_symbols)
|
||||
vim.keymap.set('n', '<leader>ca', vim.lsp.buf.code_action)
|
||||
vim.keymap.set('n', '<leader>cr', vim.lsp.buf.rename)
|
||||
end
|
||||
})
|
||||
|
||||
-- This is your leader key. set it to whatever you like. but space is nice i think
|
||||
vim.g.mapleader = " "
|
||||
-- space+o in normal mode saves this file and re-runs it, so config changes apply
|
||||
-- without restarting neovim. (to update the plugins themselves: :lua vim.pack.update())
|
||||
vim.keymap.set('n', '<leader>o', ':update<CR>:source<CR>')
|
||||
-- space+w in normal mode writes (saves) the current buffer
|
||||
vim.keymap.set('n', '<leader>w', ':write<CR>')
|
||||
-- space+q in normal mode quits
|
||||
vim.keymap.set('n', '<leader>q', ':quit<CR>')
|
||||
-- space+f in normal mode opens a file picker where you can fuzzy search for files by their name
|
||||
vim.keymap.set('n', '<leader>f', function() Snacks.picker.files() end)
|
||||
-- space+sg in normal mode opens a fuzzy searcher that searches through the contents of all files
|
||||
vim.keymap.set('n', '<leader>sg', function() Snacks.picker.grep() end)
|
||||
-- space+e in normal mode opens a new buffer with Oil. this is the file manager or what you would call it
|
||||
-- The cool thing about oil is that you can edit all of your files like neovim buffers
|
||||
vim.keymap.set('n', '<leader>e', ':Oil<CR>')
|
||||
|
||||
-- ctrl+h/j/k/l move to the split left/down/up/right. <C-w>h is neovim's own
|
||||
-- "go to the window on the left", these just put it on an easier key.
|
||||
-- normal mode only: inside the terminal these keys belong to the shell
|
||||
-- (ctrl+l clears it), and you leave that terminal with ctrl+t anyway.
|
||||
vim.keymap.set('n', '<C-h>', '<C-w>h')
|
||||
vim.keymap.set('n', '<C-l>', '<C-w>l')
|
||||
vim.keymap.set('n', '<C-k>', '<C-w>k')
|
||||
vim.keymap.set('n', '<C-j>', '<C-w>j')
|
||||
|
||||
-- ctrl+t toggles a floating zsh terminal. it works both in normal mode and from
|
||||
-- inside the terminal itself, so the same key opens and closes it
|
||||
vim.keymap.set({ "n", "t" }, "<C-t>", function() Snacks.terminal.toggle("zsh") end)
|
||||
-- space+g in normal mode opens lazygit in floating window (tui for git)
|
||||
vim.keymap.set('n', '<leader>g', function() Snacks.lazygit() end)
|
||||
-- space+t in normal mode opens a picker of todo comments where you can search through them
|
||||
vim.keymap.set('n', '<leader>t', function() Snacks.picker.todo_comments() end)
|
||||
-- space+x in normal mode opens a bottom bar that shows warning and errors from your LSP in the current buffer
|
||||
vim.keymap.set('n', '<leader>x', ":Trouble diagnostics toggle filter.buf=0<CR>")
|
||||
-- space+shift+X does the same but for every file in the project
|
||||
vim.keymap.set('n', '<leader>X', ":Trouble diagnostics<CR>")
|
||||
-- space+| in normal mode vertically splits the current buffer
|
||||
vim.keymap.set('n', '<leader>|', ":vsplit<CR>")
|
||||
-- space+_ in normal mode horizontally splits the current buffer
|
||||
vim.keymap.set('n', '<leader>_', ":split<CR>")
|
||||
-- ESC in normal mode clears the highlighting left over from your last search
|
||||
vim.keymap.set('n', '<ESC>', ":noh<CR>")
|
||||
-- > in visual mode indents the selected lines (gv reselects them so you can keep pressing >)
|
||||
vim.keymap.set("v", ">", ">gv", { silent = true, desc = "Indent and reselect" })
|
||||
-- < in visual mode unindents the selected lines
|
||||
vim.keymap.set("v", "<", "<gv", { silent = true, desc = "Unindent and reselect" })
|
||||
-- space+lf in normal mode calls the lsp's formatter on the current buffer
|
||||
vim.keymap.set('n', '<leader>lf', vim.lsp.buf.format)
|
||||
|
|
|
|||
|
|
@ -1,68 +0,0 @@
|
|||
{
|
||||
"plugins": {
|
||||
"Navigator.nvim": {
|
||||
"rev": "d43816089689ccffd23543bc02331e9a68f3ec2f",
|
||||
"src": "https://github.com/dynamotn/Navigator.nvim"
|
||||
},
|
||||
"blink.cmp": {
|
||||
"rev": "c573a15a62bd0bfd4006ee0849b24f5404395500",
|
||||
"src": "https://github.com/saghen/blink.cmp"
|
||||
},
|
||||
"catppuccin": {
|
||||
"rev": "e068ab5f8261f23f6f71ffd8791ae40315b77b9c",
|
||||
"src": "https://github.com/catppuccin/nvim"
|
||||
},
|
||||
"copilot.lua": {
|
||||
"rev": "ad7e729e9a6348f7da482be0271d452dbc4c8e2c",
|
||||
"src": "https://github.com/zbirenbaum/copilot.lua"
|
||||
},
|
||||
"cyberdream.nvim": {
|
||||
"rev": "39f69ebcd8de69c741bb7a65353aa37dd0680ad1",
|
||||
"src": "https://github.com/scottmckendry/cyberdream.nvim"
|
||||
},
|
||||
"fidget.nvim": {
|
||||
"rev": "889e2e96edef4e144965571d46f7a77bcc4d0ddf",
|
||||
"src": "https://github.com/j-hui/fidget.nvim"
|
||||
},
|
||||
"lualine.nvim": {
|
||||
"rev": "a905eeebc4e63fdc48b5135d3bf8aea5618fb21c",
|
||||
"src": "https://github.com/nvim-lualine/lualine.nvim"
|
||||
},
|
||||
"nvim-lspconfig": {
|
||||
"rev": "4b7fbaa239c5db6b36f424a4521ca9f1a401be33",
|
||||
"src": "https://github.com/neovim/nvim-lspconfig"
|
||||
},
|
||||
"nvim-treesitter": {
|
||||
"rev": "4916d6592ede8c07973490d9322f187e07dfefac",
|
||||
"src": "https://github.com/nvim-treesitter/nvim-treesitter"
|
||||
},
|
||||
"nvim-web-devicons": {
|
||||
"rev": "c72328a5494b4502947a022fe69c0c47e53b6aa6",
|
||||
"src": "https://github.com/nvim-tree/nvim-web-devicons"
|
||||
},
|
||||
"oil.nvim": {
|
||||
"rev": "0fcc83805ad11cf714a949c98c605ed717e0b83e",
|
||||
"src": "https://github.com/stevearc/oil.nvim"
|
||||
},
|
||||
"snacks.nvim": {
|
||||
"rev": "ad9ede6a9cddf16cedbd31b8932d6dcdee9b716e",
|
||||
"src": "https://github.com/folke/snacks.nvim"
|
||||
},
|
||||
"todo-comments.nvim": {
|
||||
"rev": "31e3c38ce9b29781e4422fc0322eb0a21f4e8668",
|
||||
"src": "https://github.com/folke/todo-comments.nvim"
|
||||
},
|
||||
"tree-sitter-surrealdb.nvim": {
|
||||
"rev": "a875cb4be3035a0cb525c35c4c6f1512fb9fa27d",
|
||||
"src": "https://github.com/dariuscorvus/tree-sitter-surrealdb.nvim"
|
||||
},
|
||||
"trouble.nvim": {
|
||||
"rev": "bd67efe408d4816e25e8491cc5ad4088e708a69a",
|
||||
"src": "https://github.com/folke/trouble.nvim"
|
||||
},
|
||||
"typst-preview.nvim": {
|
||||
"rev": "87db18b8d19c8b0eed399f52e4c527ce5afe4817",
|
||||
"src": "https://github.com/chomosuke/typst-preview.nvim"
|
||||
}
|
||||
}
|
||||
}
|
||||
226
flake.nix
226
flake.nix
|
|
@ -24,38 +24,10 @@
|
|||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
inputs.home-manager.follows = "home-manager";
|
||||
};
|
||||
|
||||
# linear-tui has no flake of its own, so take the source and build it below.
|
||||
# Pinned to a tag; `nix flake update` moves it and records the hash in
|
||||
# flake.lock, so there is no sha256 to maintain by hand.
|
||||
linear-tui-src = {
|
||||
url = "github:k1-c/linear-tui/v0.13.0";
|
||||
flake = false;
|
||||
};
|
||||
};
|
||||
|
||||
outputs = { self, nixpkgs, apple-silicon, home-manager, firefox-addons, zen-browser, linear-tui-src, ... }:
|
||||
outputs = { self, nixpkgs, apple-silicon, home-manager, firefox-addons, zen-browser, ... }:
|
||||
let
|
||||
# linear-tui, built from the pinned source input above. Upstream ships no
|
||||
# flake and it is not in nixpkgs, but it has a committed Cargo.lock, so
|
||||
# cargoLock.lockFile covers the dependency hashes with nothing to vendor.
|
||||
#
|
||||
# No OpenSSL/pkg-config needed: the crate selects reqwest's rustls
|
||||
# backend on purpose, and takes its trust roots from the OS store.
|
||||
linearTui = pkgs: pkgs.rustPlatform.buildRustPackage {
|
||||
pname = "linear-tui";
|
||||
version = "0.13.0";
|
||||
src = linear-tui-src;
|
||||
cargoLock.lockFile = "${linear-tui-src}/Cargo.lock";
|
||||
# One test (a_worktree_belongs_to_its_repository) shells out to `git`,
|
||||
# which the build sandbox lacks -- it panics on NotFound unwrapping
|
||||
# Command::new("git"). Supplying git lets all 512 tests run.
|
||||
nativeCheckInputs = [ pkgs.git ];
|
||||
|
||||
meta.mainProgram = "linear-tui";
|
||||
};
|
||||
|
||||
# ───────────────────── shared home-manager user ─────────────────────
|
||||
home = { pkgs, osConfig, ... }: {
|
||||
imports = [ zen-browser.homeModules.beta ];
|
||||
home.stateVersion = "25.11";
|
||||
|
|
@ -65,9 +37,6 @@
|
|||
package = pkgs.eww;
|
||||
};
|
||||
|
||||
# Raw configs that stay files (no good native module).
|
||||
# `hypr` is recursive so we can drop a host-specific monitors.conf in
|
||||
# alongside the shared files (hyprland.conf `source`s it).
|
||||
xdg.configFile = {
|
||||
"hypr" = { source = ./config/hypr; recursive = true; };
|
||||
"hypr/monitors.conf".text =
|
||||
|
|
@ -96,17 +65,6 @@
|
|||
"fuzzel".source = ./config/fuzzel;
|
||||
};
|
||||
|
||||
|
||||
# Launcher hygiene. These .desktop entries ship with packages we do want,
|
||||
# but they are noise in fuzzel. A NoDisplay entry in XDG_DATA_HOME
|
||||
# shadows the package's own copy, which is the only way to hide one
|
||||
# without patching the package.
|
||||
#
|
||||
# Deliberately home.file and NOT xdg.desktopEntries: that option only
|
||||
# emits anything when xdg.enable = true, which we don't set, so it
|
||||
# silently produces no files at all.
|
||||
# nvim - neovim's "Neovim wrapper" entry; we only launch it from a terminal
|
||||
# uuctl - uwsm's systemd-user-unit picker, pulled in by withUWSM
|
||||
home.file = {
|
||||
".local/share/applications/nvim.desktop".text = ''
|
||||
[Desktop Entry]
|
||||
|
|
@ -122,10 +80,6 @@
|
|||
'';
|
||||
};
|
||||
|
||||
# Notification daemon. Nothing owned org.freedesktop.Notifications before
|
||||
# this, so notify-send failed outright: hyprshot's "Screenshot saved"
|
||||
# toasts went nowhere, and kitty logged a DBus ServiceUnknown error on
|
||||
# every launch. Colours match the cyberdream kitty theme above.
|
||||
services.mako = {
|
||||
enable = true;
|
||||
settings = {
|
||||
|
|
@ -147,8 +101,6 @@
|
|||
enable = true;
|
||||
settings = {
|
||||
font_size = "11.5";
|
||||
|
||||
# cyberdream theme
|
||||
background = "#16181a";
|
||||
foreground = "#ffffff";
|
||||
cursor = "#ffffff";
|
||||
|
|
@ -188,26 +140,20 @@
|
|||
hyprcursor.enable = true;
|
||||
};
|
||||
|
||||
# Dark GTK apps (file dialogs, etc).
|
||||
gtk = {
|
||||
enable = true;
|
||||
theme = { name = "Adwaita-dark"; package = pkgs.gnome-themes-extra; };
|
||||
gtk3.extraConfig.gtk-application-prefer-dark-theme = 1;
|
||||
gtk4.extraConfig.gtk-application-prefer-dark-theme = 1;
|
||||
# Adopt the new default: don't force a theme on GTK4/libadwaita apps
|
||||
# (dark still applies via prefer-dark-theme above). Silences the
|
||||
# stateVersion < 26.05 legacy-default warning.
|
||||
gtk4.theme = null;
|
||||
};
|
||||
|
||||
# Neovim: init.lua verbatim; plugins + LSP pinned by Nix.
|
||||
programs.neovim = {
|
||||
enable = true;
|
||||
withPython3 = false;
|
||||
withRuby = false;
|
||||
withNodeJs = false;
|
||||
initLua = "vim.g.nix_managed = true\n"
|
||||
+ builtins.readFile ./config/nvim/init.lua;
|
||||
initLua = builtins.readFile ./config/nvim/init.lua;
|
||||
plugins = with pkgs.vimPlugins; [
|
||||
nvim-web-devicons cyberdream-nvim oil-nvim nvim-lspconfig
|
||||
typst-preview-nvim blink-cmp Navigator-nvim
|
||||
|
|
@ -222,7 +168,6 @@
|
|||
];
|
||||
};
|
||||
|
||||
# Zen browser + Tridactyl, extensions pinned (works on aarch64 + x86).
|
||||
programs.zen-browser = {
|
||||
enable = true;
|
||||
setAsDefaultBrowser = true;
|
||||
|
|
@ -230,16 +175,11 @@
|
|||
settings = {
|
||||
"browser.newtabpage.enabled" = false;
|
||||
"privacy.donottrackheader.enabled" = true;
|
||||
"signon.rememberSignons" = false;
|
||||
|
||||
# Dark mode
|
||||
"browser.theme.toolbar-theme" = 0;
|
||||
"browser.theme.content-theme" = 0;
|
||||
"layout.css.prefers-color-scheme.content-override" = 0;
|
||||
"ui.systemUsesDarkTheme" = 1;
|
||||
};
|
||||
# Re-instantiate pkgs with the firefox-addons overlay + allowUnfree so
|
||||
# the (unfree) 1Password addon evaluates under *our* config.
|
||||
extensions.packages = let
|
||||
addonsPkgs = import pkgs.path {
|
||||
inherit (pkgs.stdenv.hostPlatform) system;
|
||||
|
|
@ -254,7 +194,6 @@
|
|||
};
|
||||
};
|
||||
|
||||
# zsh + starship, no framework.
|
||||
programs.zsh = {
|
||||
enable = true;
|
||||
autosuggestion.enable = true;
|
||||
|
|
@ -263,17 +202,12 @@
|
|||
};
|
||||
programs.starship.enable = true;
|
||||
|
||||
|
||||
|
||||
# SSH auth via the 1Password agent — private keys stay in the vault,
|
||||
# never on disk or in the Nix store.
|
||||
programs.ssh = {
|
||||
enable = true;
|
||||
enableDefaultConfig = false;
|
||||
settings."*".IdentityAgent = "~/.1password/agent.sock";
|
||||
};
|
||||
|
||||
# git identity + SSH commit signing through 1Password's op-ssh-sign.
|
||||
programs.git = {
|
||||
enable = true;
|
||||
settings = {
|
||||
|
|
@ -281,12 +215,9 @@
|
|||
user.email = "mads@deepvis.ai";
|
||||
user.signingkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAPlpVGZLhfrJqh2j5q3reyGOPQQ9BgW8syQ28tYjlg2";
|
||||
gpg.format = "ssh";
|
||||
# NixOS store path — NOT 1Password's suggested /opt/1Password/... which doesn't exist here.
|
||||
"gpg \"ssh\"".program =
|
||||
"${pkgs._1password-gui}/share/1password/op-ssh-sign";
|
||||
commit.gpgsign = true;
|
||||
# Transparently use SSH (1Password agent) for the deepvis server,
|
||||
# so existing HTTPS remotes need no manual `git remote set-url`.
|
||||
url."git@git.deepvis.ai:".insteadOf = "https://git.deepvis.ai/";
|
||||
};
|
||||
};
|
||||
|
|
@ -294,34 +225,14 @@
|
|||
home.packages = with pkgs; [ ripgrep fd tridactyl-native lazygit rustc cargo clippy rustfmt rust-analyzer claude-code gcc bluetui impala postgresql fastfetch (linearTui pkgs) ];
|
||||
};
|
||||
|
||||
# ───────────────────── shared system (both hosts) ─────────────────────
|
||||
common = { pkgs, ... }: {
|
||||
nix.settings.experimental-features = [ "nix-command" "flakes" ];
|
||||
# Trusted so client-side nix config takes effect — substituters and
|
||||
# remote builders are trusted settings, silently ignored for anyone
|
||||
# else. A cache that appears to do nothing is the usual symptom.
|
||||
nix.settings.trusted-users = [ "mads" ];
|
||||
|
||||
# The deepvis binary cache: the embedded flakes in models/ort-nix
|
||||
# (onnxruntime built from source, a CUDA training env) are hours of
|
||||
# work to build and seconds to substitute.
|
||||
nix.settings.extra-substituters = [ "https://deepvis.cachix.org" ];
|
||||
nix.settings.extra-trusted-public-keys = [
|
||||
"deepvis.cachix.org-1:UE/H6ERLwqhSqubzh8+pzl9eTm0kpMExGe0ym6fENp8="
|
||||
];
|
||||
# Private cache, so reads need a token. nix refuses `netrc-file` on
|
||||
# the command line under the daemon, and a token in the substituter
|
||||
# URL would land in the process table — a root-owned 0600 netrc is
|
||||
# the only form the calling process cannot read.
|
||||
nix.settings.netrc-file = "/etc/nix/netrc";
|
||||
|
||||
# x86_64 derivations build off this machine rather than under local
|
||||
# qemu emulation, and aarch64 ones go out too when the local
|
||||
# machine is busy.
|
||||
#
|
||||
# The host keys are pinned system-wide because the ssh'ing party is
|
||||
# the root daemon, which has no known_hosts and never gets a tty to
|
||||
# answer a trust prompt.
|
||||
programs.ssh.knownHosts."builder" = {
|
||||
extraHostNames = [ "5.9.71.104" "builder.tailf5eaab.ts.net" ];
|
||||
publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHnKIrxYtlovvYGgkpEZXY8wG/CuSLMGOM/84eIlyeVW";
|
||||
|
|
@ -334,51 +245,18 @@
|
|||
{
|
||||
hostName = "builder";
|
||||
sshUser = "builder";
|
||||
# The daemon (root) does the ssh'ing, so it needs an explicit
|
||||
# on-disk key — it has no access to a user's agent.
|
||||
sshKey = "/home/mads/.ssh/id_ed25519";
|
||||
protocol = "ssh-ng";
|
||||
system = "x86_64-linux";
|
||||
maxJobs = 16;
|
||||
supportedFeatures = [ "big-parallel" "kvm" "nixos-test" ];
|
||||
}
|
||||
# nixbuild.net, for both architectures. Listed after `builder` so
|
||||
# the machine we already pay for is preferred.
|
||||
#
|
||||
# Every feature it supports is advertised, not just the two in the
|
||||
# quickstart: nix only sends a derivation to a builder claiming
|
||||
# *every* feature that derivation requires, so omitting `kvm` or
|
||||
# `nixos-test` would silently route those back to local builds.
|
||||
{
|
||||
hostName = "eu.nixbuild.net";
|
||||
sshUser = "root";
|
||||
sshKey = "/home/mads/.ssh/id_ed25519";
|
||||
protocol = "ssh-ng";
|
||||
system = "x86_64-linux";
|
||||
maxJobs = 100;
|
||||
supportedFeatures = [ "benchmark" "big-parallel" "ca-derivations" "kvm" "nixos-test" ];
|
||||
}
|
||||
{
|
||||
hostName = "eu.nixbuild.net";
|
||||
sshUser = "root";
|
||||
sshKey = "/home/mads/.ssh/id_ed25519";
|
||||
protocol = "ssh-ng";
|
||||
system = "aarch64-linux";
|
||||
maxJobs = 100;
|
||||
supportedFeatures = [ "benchmark" "big-parallel" "ca-derivations" "kvm" "nixos-test" ];
|
||||
}
|
||||
];
|
||||
|
||||
# iwd owns Wi-Fi (driven from impala, which is iwd-only); networkd does
|
||||
# DHCP and resolved does DNS. No NetworkManager: running it on top of
|
||||
# iwd meant two managers with separate saved networks, which ended in
|
||||
# "Secrets were required, but not provided".
|
||||
networking.wireless.iwd.enable = true;
|
||||
networking.useNetworkd = true; # DHCP on any ethernet/wifi by default
|
||||
systemd.network.wait-online.anyInterface = true; # one link up is enough
|
||||
networking.useNetworkd = true;
|
||||
systemd.network.wait-online.anyInterface = true;
|
||||
|
||||
# iwd only reads /var/lib/iwd. C = copy once, so a password added to
|
||||
# the file later (or via impala) is never overwritten.
|
||||
systemd.tmpfiles.rules = [
|
||||
"C /var/lib/iwd/eduroam.8021x 0600 root root - ${pkgs.writeText "eduroam.8021x" ''
|
||||
[Security]
|
||||
|
|
@ -389,26 +267,17 @@
|
|||
''}"
|
||||
];
|
||||
|
||||
# Secret Service (org.freedesktop.secrets) provider, D-Bus-activated on
|
||||
# demand. Without it 1Password can't persist the 2FA device token
|
||||
# ("unable to save your two-factor token") and re-prompts every unlock.
|
||||
services.gnome.gnome-keyring.enable = true;
|
||||
|
||||
programs._1password.enable = true;
|
||||
programs._1password-gui = {
|
||||
enable = true;
|
||||
polkitPolicyOwners = [ "mads" ];
|
||||
};
|
||||
# Zen (a Firefox fork) runs as "zen-beta"; 1Password only trusts an
|
||||
# allowlist of browser process names, so add it or the extension can't
|
||||
# unlock via the desktop app. Manifest already lives in ~/.mozilla.
|
||||
environment.etc."1password/custom_allowed_browsers".text = ''
|
||||
zen-beta
|
||||
'';
|
||||
|
||||
services.tailscale.enable = true;
|
||||
# Tailscale SSH: keyless, portless SSH gated by tailnet ACLs.
|
||||
# Needs a matching "ssh" rule in the admin console to actually permit access.
|
||||
services.tailscale.extraUpFlags = [ "--ssh" ];
|
||||
|
||||
time.timeZone = "Europe/Copenhagen"; # set yours
|
||||
|
|
@ -417,35 +286,11 @@
|
|||
programs.hyprland = { enable = true; withUWSM = true; };
|
||||
programs.hyprlock.enable = true;
|
||||
|
||||
# Every GUI app lives in the one wayland-wm@hyprland.service cgroup, so
|
||||
# with systemd's default OOMPolicy=stop a kernel OOM-kill of ANY process
|
||||
# in it stops the whole unit -- compositor included. 1Password was always
|
||||
# the victim (highest oom_score_adj), but losing it killed the entire
|
||||
# desktop, and uwsm sets Restart=no, so nothing came back. It read as
|
||||
# "Hyprland crashed" when the compositor was never at fault.
|
||||
#
|
||||
# continue: log the kill, lose that one app, keep the session. Merges
|
||||
# into the drop-in the uwsm module already generates for this unit.
|
||||
systemd.user.services."wayland-wm@".serviceConfig.OOMPolicy = "continue";
|
||||
|
||||
# Autologin means no password reaches PAM at login, so the gnome-keyring
|
||||
# login keyring is never created or unlocked -- which is why 1Password
|
||||
# could not persist its 2FA device token and re-prompted the YubiKey
|
||||
# every unlock. Putting pam_gnome_keyring in hyprlock's stack instead
|
||||
# makes the lock screen we already have do that job, so there is still
|
||||
# exactly one password prompt and no second login screen.
|
||||
security.pam.services.hyprlock.enableGnomeKeyring = true;
|
||||
services.hypridle.enable = true;
|
||||
|
||||
# ── Amphetamine-style "stay awake" ──
|
||||
# caffeine.service holds ONE logind block-inhibitor covering all three
|
||||
# ways this machine can go dark:
|
||||
# idle -> hypridle stops counting (no blank, no hyprlock)
|
||||
# sleep -> suspend requests are refused
|
||||
# handle-lid-switch -> closing the lid does nothing
|
||||
# systemd owns the process, so "is it on?" is just "is the unit
|
||||
# active?" -- no pidfile, and it can't be orphaned. Deliberately no
|
||||
# wantedBy: it only ever starts via SUPER+A or the `caffeine` command.
|
||||
systemd.user.services.caffeine = {
|
||||
description = "Caffeine - inhibit idle, sleep and lid-switch";
|
||||
serviceConfig = {
|
||||
|
|
@ -459,8 +304,6 @@
|
|||
extraPortals = [ pkgs.xdg-desktop-portal-hyprland ];
|
||||
};
|
||||
|
||||
|
||||
# greetd autologins mads straight into Hyprland (via uwsm).
|
||||
services.greetd = {
|
||||
enable = true;
|
||||
settings = {
|
||||
|
|
@ -473,8 +316,6 @@
|
|||
|
||||
hardware.bluetooth.enable = true;
|
||||
programs.zsh.enable = true;
|
||||
# No NixOS manual: it puts a "NixOS Manual" entry in the launcher and we
|
||||
# read the docs on the web. man pages are unaffected.
|
||||
documentation.nixos.enable = false;
|
||||
|
||||
fonts.packages = [ pkgs.nerd-fonts.jetbrains-mono ];
|
||||
|
|
@ -484,7 +325,6 @@
|
|||
wl-clipboard grim slurp swaybg brightnessctl playerctl hyprshot
|
||||
hyprpolkitagent xdg-utils
|
||||
|
||||
# Front-end for caffeine.service (above). Bound to SUPER+A.
|
||||
(writeShellApplication {
|
||||
name = "caffeine";
|
||||
runtimeInputs = [ systemd ];
|
||||
|
|
@ -524,14 +364,12 @@
|
|||
isNormalUser = true;
|
||||
extraGroups = [ "wheel" "video" "docker" ];
|
||||
shell = pkgs.zsh;
|
||||
initialPassword = "changeme"; # CHANGE after first boot (`passwd`)
|
||||
initialPassword = "changeme";
|
||||
};
|
||||
|
||||
system.stateVersion = "25.11";
|
||||
|
||||
home-manager.useGlobalPkgs = true;
|
||||
home-manager.useUserPackages = true;
|
||||
# Back up (don't clobber) any pre-existing files HM wants to manage.
|
||||
home-manager.backupFileExtension = "hm-bak";
|
||||
home-manager.users.mads = home;
|
||||
};
|
||||
|
|
@ -550,69 +388,45 @@
|
|||
in
|
||||
{
|
||||
nixosConfigurations = {
|
||||
# ── Apple Silicon MacBook (Asahi) ──
|
||||
mbp = mkHost {
|
||||
system = "aarch64-linux";
|
||||
modules = [
|
||||
apple-silicon.nixosModules.apple-silicon-support
|
||||
./hosts/mbp/hardware-configuration.nix # generated on the Mac
|
||||
./hosts/mbp/hardware-configuration.nix
|
||||
({ ... }: {
|
||||
networking.hostName = "mbp";
|
||||
|
||||
# Wi-Fi/BT firmware, vendored (a pure flake can't read /boot/asahi).
|
||||
hardware.asahi.peripheralFirmwareDirectory = ./firmware;
|
||||
hardware.asahi.enable = true;
|
||||
|
||||
boot.loader.systemd-boot.enable = true;
|
||||
boot.loader.systemd-boot.configurationLimit = 3; # 500M ESP is small
|
||||
boot.loader.systemd-boot.configurationLimit = 3;
|
||||
boot.extraModprobeConfig = "options hid_apple fnmode=1";
|
||||
boot.blacklistedKernelModules = [ "pcspkr" ];
|
||||
|
||||
# Root is btrfs (p8). A scrub re-reads every block and verifies its
|
||||
# checksum, which is the only way bit rot on this SSD surfaces before
|
||||
# something tries to read the damaged file. Metadata is DUP, so a bad
|
||||
# metadata block gets repaired from its copy automatically.
|
||||
services.btrfs.autoScrub = {
|
||||
enable = true;
|
||||
interval = "monthly";
|
||||
fileSystems = [ "/" ];
|
||||
};
|
||||
|
||||
# 15G of RAM and no swap at all: a `nixos-rebuild` forks ~60 nix
|
||||
# evaluators, and stacked on a browser and a few editor sessions
|
||||
# that was enough to exhaust it. The kernel then OOM-killed a
|
||||
# process inside wayland-wm@hyprland.service, and systemd's default
|
||||
# OOMPolicy=stop tore the whole graphical session down with it.
|
||||
#
|
||||
# zram rather than a swapfile, because root is compress=zstd and a
|
||||
# btrfs swapfile needs its own nodatacow, uncompressed subvolume.
|
||||
zramSwap = {
|
||||
enable = true;
|
||||
memoryPercent = 50; # 7.6G of backing store, ~a third of that in real RAM
|
||||
memoryPercent = 50;
|
||||
};
|
||||
|
||||
# Swapping to RAM is cheap, so let the kernel compress anon pages
|
||||
# rather than evict page cache. At the OOM above, cache had already
|
||||
# been squeezed to 40M while 13G sat in anon and nothing was
|
||||
# reclaimable — the default swappiness of 60 gets that backwards here.
|
||||
boot.kernel.sysctl = {
|
||||
"vm.swappiness" = 180;
|
||||
"vm.page-cluster" = 0; # zram has no seek penalty, so no readahead
|
||||
"vm.page-cluster" = 0;
|
||||
};
|
||||
|
||||
# Build x86_64 derivations (packing-station iso/deploys) via qemu.
|
||||
boot.binfmt.emulatedSystems = [ "x86_64-linux" ];
|
||||
|
||||
# Resolve .local names, so the packing stations can be reached and
|
||||
# deployed to by hostname instead of by address.
|
||||
services.avahi = {
|
||||
enable = true;
|
||||
nssmdns4 = true;
|
||||
};
|
||||
services.resolved.settings.Resolve.MulticastDNS = false; # avahi owns mDNS
|
||||
services.resolved.settings.Resolve.MulticastDNS = false;
|
||||
|
||||
# Asahi kernel + Mesa cache, and the Raspberry Pi vendor
|
||||
# kernel/firmware cache (else both compile from source).
|
||||
nix.settings = {
|
||||
extra-substituters = [
|
||||
"https://nixos-apple-silicon.cachix.org"
|
||||
|
|
@ -627,47 +441,40 @@
|
|||
];
|
||||
};
|
||||
|
||||
# ── Arbitrary x86_64 PC ──
|
||||
pc = mkHost {
|
||||
system = "x86_64-linux";
|
||||
modules = [
|
||||
./hosts/pc/hardware-configuration.nix # generated on the PC
|
||||
./hosts/pc/hardware-configuration.nix
|
||||
({ config, ... }: {
|
||||
networking.hostName = "pc";
|
||||
|
||||
# GigE camera link: static, never a route out. The segment also
|
||||
# carries AAU's IPv6 RAs, and taking them made v6 traffic default
|
||||
# out this port into a dead end.
|
||||
networking.interfaces.enp7s0 = {
|
||||
useDHCP = false;
|
||||
ipv4.addresses = [ { address = "192.168.12.1"; prefixLength = 24; } ];
|
||||
};
|
||||
systemd.network.networks."40-enp7s0" = {
|
||||
networkConfig.IPv6AcceptRA = false;
|
||||
networkConfig.ConfigureWithoutCarrier = true; # camera may be off
|
||||
networkConfig.ConfigureWithoutCarrier = true;
|
||||
linkConfig.RequiredForOnline = "no";
|
||||
};
|
||||
boot.loader.systemd-boot.enable = true;
|
||||
boot.loader.efi.canTouchEfiVariables = true; # normal x86 UEFI
|
||||
boot.loader.efi.canTouchEfiVariables = true;
|
||||
|
||||
# Desktop: never suspend or hibernate, even if something asks.
|
||||
systemd.sleep.settings.Sleep = {
|
||||
AllowSuspend = "no";
|
||||
AllowHibernation = "no";
|
||||
AllowHybridSleep = "no";
|
||||
AllowSuspendThenHibernate = "no";
|
||||
};
|
||||
# Ignore the keys that would normally trigger sleep.
|
||||
services.logind.suspendKey = "ignore";
|
||||
services.logind.hibernateKey = "ignore";
|
||||
services.logind.lidSwitch = "ignore";
|
||||
|
||||
# NVIDIA (RTX 20-series or newer → open kernel module).
|
||||
services.xserver.videoDrivers = [ "nvidia" ];
|
||||
hardware.graphics.enable = true; # OpenGL/Vulkan userspace (was hardware.opengl)
|
||||
hardware.graphics.enable = true;
|
||||
hardware.nvidia = {
|
||||
modesetting.enable = true; # required for Wayland/Hyprland
|
||||
open = true; # open kernel module (Turing+)
|
||||
modesetting.enable = true;
|
||||
open = true;
|
||||
nvidiaSettings = true;
|
||||
package = config.boot.kernelPackages.nvidiaPackages.stable;
|
||||
};
|
||||
|
|
@ -676,7 +483,6 @@
|
|||
};
|
||||
};
|
||||
|
||||
# `nix develop` on either arch.
|
||||
devShells = nixpkgs.lib.genAttrs [ "aarch64-linux" "x86_64-linux" ] (system: {
|
||||
default = nixpkgs.legacyPackages.${system}.mkShell {
|
||||
packages = [ nixpkgs.legacyPackages.${system}.nodejs ];
|
||||
|
|
|
|||
Loading…
Reference in a new issue