first commit
This commit is contained in:
commit
2a3ea31491
52 changed files with 2991 additions and 0 deletions
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
*.txt
|
||||||
|
*.key
|
||||||
|
*.age
|
||||||
10
.sops.yaml
Normal file
10
.sops.yaml
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
keys:
|
||||||
|
- &local_T14p "age1y38cnfvt42ar4seqx8n2cw0ynwls2rdl6jyzhv9wuv6jcfqrwckqwlh9p0"
|
||||||
|
- &server_hetzner "age1sjq27nh4znq75fzzx6epwd6700wgg23v9xenzvmam4kmncvjdcesakv9e2"
|
||||||
|
|
||||||
|
creation_rules:
|
||||||
|
- path_regex: secrets.yaml$
|
||||||
|
key_groups:
|
||||||
|
- age:
|
||||||
|
- *local_T14p
|
||||||
|
- *server_hetzner
|
||||||
29
apps/fuzzel/default.nix
Normal file
29
apps/fuzzel/default.nix
Normal file
|
|
@ -0,0 +1,29 @@
|
||||||
|
{ config, pkgs, lib, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.my.apps.fuzzel;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options.my.apps.fuzzel = {
|
||||||
|
enable = lib.mkEnableOption "Fuzzel launcher";
|
||||||
|
|
||||||
|
package = lib.mkOption {
|
||||||
|
type = lib.types.package;
|
||||||
|
default = pkgs.fuzzel;
|
||||||
|
defaultText = "pkgs.fuzzel";
|
||||||
|
description = "Fuzzel package to install.";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = lib.mkIf cfg.enable {
|
||||||
|
home.packages = [
|
||||||
|
cfg.package
|
||||||
|
pkgs.jetbrains-mono
|
||||||
|
];
|
||||||
|
|
||||||
|
xdg.enable = true;
|
||||||
|
|
||||||
|
# fuzzel uses ~/.config/fuzzel/fuzzel.ini
|
||||||
|
xdg.configFile."fuzzel/fuzzel.ini".source = ./fuzzel.ini;
|
||||||
|
};
|
||||||
|
}
|
||||||
41
apps/fuzzel/fuzzel.ini
Normal file
41
apps/fuzzel/fuzzel.ini
Normal file
|
|
@ -0,0 +1,41 @@
|
||||||
|
# Fuzzel config
|
||||||
|
# Catppuccin Mocha-ish palette + Emacs navigation keys
|
||||||
|
|
||||||
|
[main]
|
||||||
|
font=JetBrains Mono:size=14
|
||||||
|
dpi-aware=yes
|
||||||
|
prompt=Search:
|
||||||
|
terminal=foot
|
||||||
|
layer=overlay
|
||||||
|
|
||||||
|
# Window sizing
|
||||||
|
width=45
|
||||||
|
lines=8
|
||||||
|
horizontal-pad=20
|
||||||
|
vertical-pad=16
|
||||||
|
inner-pad=10
|
||||||
|
|
||||||
|
[colors]
|
||||||
|
# Catppuccin Mocha palette
|
||||||
|
background=1e1e2eff
|
||||||
|
text=cdd6f4ff
|
||||||
|
match=cba6f7ff
|
||||||
|
selection=585b70ff
|
||||||
|
selection-text=f5e0dcff
|
||||||
|
border=cba6f7ff
|
||||||
|
|
||||||
|
[border]
|
||||||
|
width=2
|
||||||
|
radius=12
|
||||||
|
|
||||||
|
[key-bindings]
|
||||||
|
# List navigation
|
||||||
|
next=Control+n
|
||||||
|
prev=Control+p
|
||||||
|
|
||||||
|
# Optional extras
|
||||||
|
next-page=Page_Down
|
||||||
|
prev-page=Page_Up
|
||||||
|
accept=Return
|
||||||
|
cancel=Escape
|
||||||
|
|
||||||
1
apps/neovim/autopairs.lua
Normal file
1
apps/neovim/autopairs.lua
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
require("nvim-autopairs").setup {}
|
||||||
76
apps/neovim/catppuccin.lua
Normal file
76
apps/neovim/catppuccin.lua
Normal file
|
|
@ -0,0 +1,76 @@
|
||||||
|
require("catppuccin").setup({
|
||||||
|
flavour = "auto", -- latte, frappe, macchiato, mocha
|
||||||
|
background = { -- :h background
|
||||||
|
light = "latte",
|
||||||
|
dark = "mocha",
|
||||||
|
},
|
||||||
|
transparent_background = false, -- disables setting the background color.
|
||||||
|
float = {
|
||||||
|
transparent = false, -- enable transparent floating windows
|
||||||
|
solid = false, -- use solid styling for floating windows, see |winborder|
|
||||||
|
},
|
||||||
|
show_end_of_buffer = false, -- shows the '~' characters after the end of buffers
|
||||||
|
term_colors = false, -- sets terminal colors (e.g. `g:terminal_color_0`)
|
||||||
|
dim_inactive = {
|
||||||
|
enabled = false, -- dims the background color of inactive window
|
||||||
|
shade = "dark",
|
||||||
|
percentage = 0.15, -- percentage of the shade to apply to the inactive window
|
||||||
|
},
|
||||||
|
no_italic = false, -- Force no italic
|
||||||
|
no_bold = false, -- Force no bold
|
||||||
|
no_underline = false, -- Force no underline
|
||||||
|
styles = { -- Handles the styles of general hi groups (see `:h highlight-args`):
|
||||||
|
comments = { "italic" }, -- Change the style of comments
|
||||||
|
conditionals = { "italic" },
|
||||||
|
loops = {},
|
||||||
|
functions = {},
|
||||||
|
keywords = {},
|
||||||
|
strings = {},
|
||||||
|
variables = {},
|
||||||
|
numbers = {},
|
||||||
|
booleans = {},
|
||||||
|
properties = {},
|
||||||
|
types = {},
|
||||||
|
operators = {},
|
||||||
|
-- miscs = {}, -- Uncomment to turn off hard-coded styles
|
||||||
|
},
|
||||||
|
lsp_styles = { -- Handles the style of specific lsp hl groups (see `:h lsp-highlight`).
|
||||||
|
virtual_text = {
|
||||||
|
errors = { "italic" },
|
||||||
|
hints = { "italic" },
|
||||||
|
warnings = { "italic" },
|
||||||
|
information = { "italic" },
|
||||||
|
ok = { "italic" },
|
||||||
|
},
|
||||||
|
underlines = {
|
||||||
|
errors = { "underline" },
|
||||||
|
hints = { "underline" },
|
||||||
|
warnings = { "underline" },
|
||||||
|
information = { "underline" },
|
||||||
|
ok = { "underline" },
|
||||||
|
},
|
||||||
|
inlay_hints = {
|
||||||
|
background = true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
color_overrides = {},
|
||||||
|
custom_highlights = {},
|
||||||
|
default_integrations = true,
|
||||||
|
auto_integrations = false,
|
||||||
|
integrations = {
|
||||||
|
cmp = true,
|
||||||
|
gitsigns = true,
|
||||||
|
nvimtree = true,
|
||||||
|
notify = false,
|
||||||
|
mini = {
|
||||||
|
enabled = true,
|
||||||
|
indentscope_color = "",
|
||||||
|
},
|
||||||
|
telescope = {
|
||||||
|
enabled = true,
|
||||||
|
},
|
||||||
|
lsp_trouble = true,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
vim.cmd.colorscheme "catppuccin"
|
||||||
86
apps/neovim/cmp.lua
Normal file
86
apps/neovim/cmp.lua
Normal file
|
|
@ -0,0 +1,86 @@
|
||||||
|
-- https://github.com/hrsh7th/nvim-cmp
|
||||||
|
local cmp = require'cmp'
|
||||||
|
|
||||||
|
cmp.setup({
|
||||||
|
snippet = {
|
||||||
|
-- REQUIRED - you must specify a snippet engine
|
||||||
|
expand = function(args)
|
||||||
|
vim.fn["vsnip#anonymous"](args.body) -- For `vsnip` users.
|
||||||
|
-- require('luasnip').lsp_expand(args.body) -- For `luasnip` users.
|
||||||
|
-- require('snippy').expand_snippet(args.body) -- For `snippy` users.
|
||||||
|
-- vim.fn["UltiSnips#Anon"](args.body) -- For `ultisnips` users.
|
||||||
|
-- vim.snippet.expand(args.body) -- For native neovim snippets (Neovim v0.10+)
|
||||||
|
|
||||||
|
-- For `mini.snippets` users:
|
||||||
|
-- local insert = MiniSnippets.config.expand.insert or MiniSnippets.default_insert
|
||||||
|
-- insert({ body = args.body }) -- Insert at cursor
|
||||||
|
-- cmp.resubscribe({ "TextChangedI", "TextChangedP" })
|
||||||
|
-- require("cmp.config").set_onetime({ sources = {} })
|
||||||
|
end,
|
||||||
|
},
|
||||||
|
window = {
|
||||||
|
completion = cmp.config.window.bordered(),
|
||||||
|
documentation = cmp.config.window.bordered(),
|
||||||
|
},
|
||||||
|
mapping = cmp.mapping.preset.insert({
|
||||||
|
['<C-b>'] = cmp.mapping.scroll_docs(-4),
|
||||||
|
['<C-f>'] = cmp.mapping.scroll_docs(4),
|
||||||
|
['<C-j>'] = cmp.mapping.complete(),
|
||||||
|
['<C-e>'] = cmp.mapping.abort(),
|
||||||
|
['<CR>'] = cmp.mapping.confirm({ select = true }), -- Accept currently selected item. Set `select` to `false` to only confirm explicitly selected items.
|
||||||
|
}),
|
||||||
|
sources = cmp.config.sources({
|
||||||
|
{ name = 'nvim_lsp' },
|
||||||
|
{ name = 'vsnip' }, -- For vsnip users.
|
||||||
|
-- { name = 'luasnip' }, -- For luasnip users.
|
||||||
|
-- { name = 'ultisnips' }, -- For ultisnips users.
|
||||||
|
-- { name = 'snippy' }, -- For snippy users.
|
||||||
|
}, {
|
||||||
|
{ name = 'buffer' },
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
-- To use git you need to install the plugin petertriho/cmp-git and uncomment lines below
|
||||||
|
-- Set configuration for specific filetype.
|
||||||
|
--[[ cmp.setup.filetype('gitcommit', {
|
||||||
|
sources = cmp.config.sources({
|
||||||
|
{ name = 'git' },
|
||||||
|
}, {
|
||||||
|
{ name = 'buffer' },
|
||||||
|
})
|
||||||
|
)
|
||||||
|
require("cmp_git").setup() ]]--
|
||||||
|
|
||||||
|
-- Use buffer source for `/` and `?` (if you enabled `native_menu`, this won't work anymore).
|
||||||
|
cmp.setup.cmdline({ '/', '?' }, {
|
||||||
|
mapping = cmp.mapping.preset.cmdline(),
|
||||||
|
sources = {
|
||||||
|
{ name = 'buffer' }
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
-- Use cmdline & path source for ':' (if you enabled `native_menu`, this won't work anymore).
|
||||||
|
cmp.setup.cmdline(':', {
|
||||||
|
mapping = cmp.mapping.preset.cmdline(),
|
||||||
|
sources = cmp.config.sources({
|
||||||
|
{ name = 'path' }
|
||||||
|
}, {
|
||||||
|
{ name = 'cmdline' }
|
||||||
|
}),
|
||||||
|
matching = { disallow_symbol_nonprefix_matching = false }
|
||||||
|
})
|
||||||
|
|
||||||
|
-- Set up lspconfig.
|
||||||
|
local capabilities = require('cmp_nvim_lsp').default_capabilities()
|
||||||
|
|
||||||
|
function config_and_enable_lsp(language, extra_config)
|
||||||
|
--lsp_config = { capabilities = capabilities }
|
||||||
|
--vim.lsp.config(language, lsp_config)
|
||||||
|
vim.lsp.enable(language)
|
||||||
|
end
|
||||||
|
|
||||||
|
vim.lsp.config('*', {
|
||||||
|
capabilities = capabilities
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
113
apps/neovim/default.nix
Normal file
113
apps/neovim/default.nix
Normal file
|
|
@ -0,0 +1,113 @@
|
||||||
|
{ config, pkgs, inputs, my-r,... }:
|
||||||
|
let
|
||||||
|
nvim-config-store = builtins.filterSource (path: type: baseNameOf path != "default.nix") ./.;
|
||||||
|
nvim-config-files = builtins.attrNames (builtins.readDir nvim-config-store);
|
||||||
|
nvim-config-lis = map (path: builtins.readFile "${nvim-config-store}/${path}") (nvim-config-files);
|
||||||
|
nvim-config = builtins.concatStringsSep "\n" nvim-config-lis;
|
||||||
|
|
||||||
|
in
|
||||||
|
{
|
||||||
|
programs.neovim = {
|
||||||
|
enable = true;
|
||||||
|
defaultEditor = true;
|
||||||
|
|
||||||
|
plugins = with pkgs.vimPlugins; [
|
||||||
|
nvim-treesitter.withAllGrammars
|
||||||
|
nvim-lspconfig
|
||||||
|
telescope-nvim
|
||||||
|
nvim-cmp
|
||||||
|
cmp-nvim-lsp
|
||||||
|
nvim-tree-lua
|
||||||
|
which-key-nvim
|
||||||
|
trouble-nvim
|
||||||
|
kanagawa-nvim
|
||||||
|
lazygit-nvim
|
||||||
|
quarto-nvim
|
||||||
|
otter-nvim
|
||||||
|
otter-nvim
|
||||||
|
image-nvim
|
||||||
|
molten-nvim
|
||||||
|
toggleterm-nvim
|
||||||
|
markdown-preview-nvim
|
||||||
|
lualine-nvim
|
||||||
|
gitsigns-nvim
|
||||||
|
indent-blankline-nvim
|
||||||
|
guess-indent-nvim
|
||||||
|
nvim-autopairs
|
||||||
|
catppuccin-nvim
|
||||||
|
];
|
||||||
|
|
||||||
|
extraLuaConfig = nvim-config;
|
||||||
|
|
||||||
|
|
||||||
|
extraPackages = with pkgs; [
|
||||||
|
#quarto
|
||||||
|
pyright
|
||||||
|
ripgrep
|
||||||
|
lua-language-server
|
||||||
|
rust-analyzer
|
||||||
|
lazygit
|
||||||
|
tectonic
|
||||||
|
imagemagick
|
||||||
|
jupyter
|
||||||
|
pnglatex
|
||||||
|
nil
|
||||||
|
nixfmt
|
||||||
|
|
||||||
|
rustc
|
||||||
|
cargo
|
||||||
|
rustfmt
|
||||||
|
clippy
|
||||||
|
rust-analyzer
|
||||||
|
];
|
||||||
|
|
||||||
|
extraLuaPackages = p: with p; [
|
||||||
|
magick
|
||||||
|
];
|
||||||
|
|
||||||
|
|
||||||
|
extraPython3Packages = ps: with ps; [
|
||||||
|
pynvim
|
||||||
|
jupyter-client
|
||||||
|
cairosvg
|
||||||
|
pnglatex
|
||||||
|
plotly
|
||||||
|
pyperclip
|
||||||
|
ipython
|
||||||
|
nbformat
|
||||||
|
];
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
xdg.dataFile."jupyter/kernels/ir-nix/kernel.json".text = ''
|
||||||
|
{
|
||||||
|
"argv": [
|
||||||
|
"${my-r.env}/bin/R",
|
||||||
|
"--slave",
|
||||||
|
"-e",
|
||||||
|
"IRkernel::main()",
|
||||||
|
"--args",
|
||||||
|
"{connection_file}"
|
||||||
|
],
|
||||||
|
"display_name": "R (nix)",
|
||||||
|
"language": "R"
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
|
||||||
|
home.file.".Rprofile".text = ''
|
||||||
|
graphics::par(bg = "white")
|
||||||
|
options(
|
||||||
|
jupyter.rich_display = TRUE,
|
||||||
|
#jupyter.display_mimetypes = c("text/plain", "image/png", "text/latex"),
|
||||||
|
jupyter.display_mimetypes = c("text/plain", "image/png"),
|
||||||
|
jupyter.plot_mimetypes = "image/png"
|
||||||
|
)
|
||||||
|
'';
|
||||||
|
|
||||||
|
#sessionVariables = {
|
||||||
|
# EDITOR = "nvim";
|
||||||
|
# VISUAL = "nvim";
|
||||||
|
#};
|
||||||
|
}
|
||||||
21
apps/neovim/diagnostic.lua
Normal file
21
apps/neovim/diagnostic.lua
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
local sign = function(opts)
|
||||||
|
vim.fn.sign_define(opts.name, {
|
||||||
|
texthl = opts.name,
|
||||||
|
text = opts.text,
|
||||||
|
numhl = ''
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
|
sign({name = 'DiagnosticSignError', text = '✘'})
|
||||||
|
sign({name = 'DiagnosticSignWarn', text = '▲'})
|
||||||
|
sign({name = 'DiagnosticSignHint', text = '⚑'})
|
||||||
|
sign({name = 'DiagnosticSignInfo', text = '»'})
|
||||||
|
|
||||||
|
vim.diagnostic.config({
|
||||||
|
virtual_text = false,
|
||||||
|
severity_sort = true,
|
||||||
|
float = {
|
||||||
|
border = 'rounded',
|
||||||
|
source = 'always',
|
||||||
|
},
|
||||||
|
})
|
||||||
66
apps/neovim/gitsigns.lua
Normal file
66
apps/neovim/gitsigns.lua
Normal file
|
|
@ -0,0 +1,66 @@
|
||||||
|
require('gitsigns').setup{
|
||||||
|
on_attach = function(bufnr)
|
||||||
|
local gitsigns = require('gitsigns')
|
||||||
|
|
||||||
|
local function map(mode, l, r, opts)
|
||||||
|
opts = opts or {}
|
||||||
|
opts.buffer = bufnr
|
||||||
|
vim.keymap.set(mode, l, r, opts)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Navigation
|
||||||
|
map('n', ']c', function()
|
||||||
|
if vim.wo.diff then
|
||||||
|
vim.cmd.normal({']c', bang = true})
|
||||||
|
else
|
||||||
|
gitsigns.nav_hunk('next')
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
map('n', '[c', function()
|
||||||
|
if vim.wo.diff then
|
||||||
|
vim.cmd.normal({'[c', bang = true})
|
||||||
|
else
|
||||||
|
gitsigns.nav_hunk('prev')
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
-- Actions
|
||||||
|
map('n', '<leader>hs', gitsigns.stage_hunk)
|
||||||
|
map('n', '<leader>hr', gitsigns.reset_hunk)
|
||||||
|
|
||||||
|
map('v', '<leader>hs', function()
|
||||||
|
gitsigns.stage_hunk({ vim.fn.line('.'), vim.fn.line('v') })
|
||||||
|
end)
|
||||||
|
|
||||||
|
map('v', '<leader>hr', function()
|
||||||
|
gitsigns.reset_hunk({ vim.fn.line('.'), vim.fn.line('v') })
|
||||||
|
end)
|
||||||
|
|
||||||
|
map('n', '<leader>hS', gitsigns.stage_buffer)
|
||||||
|
map('n', '<leader>hR', gitsigns.reset_buffer)
|
||||||
|
map('n', '<leader>hp', gitsigns.preview_hunk)
|
||||||
|
map('n', '<leader>hi', gitsigns.preview_hunk_inline)
|
||||||
|
|
||||||
|
map('n', '<leader>hb', function()
|
||||||
|
gitsigns.blame_line({ full = true })
|
||||||
|
end)
|
||||||
|
|
||||||
|
map('n', '<leader>hd', gitsigns.diffthis)
|
||||||
|
|
||||||
|
map('n', '<leader>hD', function()
|
||||||
|
gitsigns.diffthis('~')
|
||||||
|
end)
|
||||||
|
|
||||||
|
map('n', '<leader>hQ', function() gitsigns.setqflist('all') end)
|
||||||
|
map('n', '<leader>hq', gitsigns.setqflist)
|
||||||
|
|
||||||
|
-- Toggles
|
||||||
|
map('n', '<leader>tb', gitsigns.toggle_current_line_blame)
|
||||||
|
map('n', '<leader>tw', gitsigns.toggle_word_diff)
|
||||||
|
|
||||||
|
|
||||||
|
-- Text object
|
||||||
|
map({'o', 'x'}, 'ih', gitsigns.select_hunk)
|
||||||
|
end
|
||||||
|
}
|
||||||
1
apps/neovim/guess-indent.lua
Normal file
1
apps/neovim/guess-indent.lua
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
require("guess-indent").setup {}
|
||||||
10
apps/neovim/ibl.lua
Normal file
10
apps/neovim/ibl.lua
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
require("ibl").setup {
|
||||||
|
indent = {
|
||||||
|
char = "",
|
||||||
|
highlight = "IblIndent",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
--│, ┆, ⋅, ╎
|
||||||
|
|
||||||
|
-- Use very subtle color
|
||||||
|
vim.api.nvim_set_hl(0, "IblIndent", { fg = "#3a3a3a" })
|
||||||
61
apps/neovim/init.lua
Normal file
61
apps/neovim/init.lua
Normal file
|
|
@ -0,0 +1,61 @@
|
||||||
|
vim.g.mapleader = ' '
|
||||||
|
vim.g.maplocalleader = ' '
|
||||||
|
|
||||||
|
vim.g.have_nerd_font = true
|
||||||
|
|
||||||
|
vim.o.number = true
|
||||||
|
|
||||||
|
vim.o.mouse = 'a'
|
||||||
|
|
||||||
|
--vim.o.showmode = false
|
||||||
|
|
||||||
|
vim.schedule(function()
|
||||||
|
vim.o.clipboard = 'unnamedplus'
|
||||||
|
end)
|
||||||
|
|
||||||
|
|
||||||
|
vim.o.breakindent = true
|
||||||
|
vim.o.undofile = true
|
||||||
|
|
||||||
|
vim.o.ignorecase = true
|
||||||
|
vim.o.smartcase = true
|
||||||
|
|
||||||
|
vim.o.signcolumn = 'yes'
|
||||||
|
|
||||||
|
vim.o.colorcolumn = "80"
|
||||||
|
|
||||||
|
vim.o.updatetime = 250
|
||||||
|
|
||||||
|
vim.o.timeoutlen = 300
|
||||||
|
|
||||||
|
vim.o.splitright = true
|
||||||
|
vim.o.splitbelow = true
|
||||||
|
|
||||||
|
vim.o.list = true
|
||||||
|
vim.opt.listchars = { tab = '» ', trail = '·', nbsp = '␣' }
|
||||||
|
|
||||||
|
vim.o.inccommand = 'split'
|
||||||
|
|
||||||
|
vim.o.cursorline = true
|
||||||
|
|
||||||
|
vim.o.scrolloff = 15
|
||||||
|
|
||||||
|
vim.o.confirm = true
|
||||||
|
|
||||||
|
vim.keymap.set('i', 'jk', '<Escape>')
|
||||||
|
vim.keymap.set('i', 'kj', '<Escape>')
|
||||||
|
--vim.keymap.set('i', 'jf', '<Escape>')
|
||||||
|
|
||||||
|
|
||||||
|
-- See `:help wincmd` for a list of all window commands
|
||||||
|
vim.keymap.set('n', '<C-h>', '<C-w><C-h>', { desc = 'Move focus to the left window' })
|
||||||
|
vim.keymap.set('n', '<C-l>', '<C-w><C-l>', { desc = 'Move focus to the right window' })
|
||||||
|
vim.keymap.set('n', '<C-j>', '<C-w><C-j>', { desc = 'Move focus to the lower window' })
|
||||||
|
vim.keymap.set('n', '<C-k>', '<C-w><C-k>', { desc = 'Move focus to the upper window' })
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
vim.o.tabstop = 2
|
||||||
|
vim.o.smartindent = true
|
||||||
|
vim.o.shiftwidth = 2
|
||||||
|
vim.o.expandtab = true
|
||||||
14
apps/neovim/lazygit.lua
Normal file
14
apps/neovim/lazygit.lua
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
vim.g.lazygit_floating_window_winblend = 0 -- transparency of floating window
|
||||||
|
vim.g.lazygit_floating_window_scaling_factor = 0.9 -- scaling factor for floating window
|
||||||
|
vim.g.lazygit_floating_window_border_chars = {'╭','─', '╮', '│', '╯','─', '╰', '│'} -- customize lazygit popup window border characters
|
||||||
|
vim.g.lazygit_floating_window_use_plenary = 0 -- use plenary.nvim to manage floating window if available
|
||||||
|
vim.g.lazygit_use_neovim_remote = 1 -- fallback to 0 if neovim-remote is not installed
|
||||||
|
|
||||||
|
vim.g.lazygit_use_custom_config_file_path = 0 -- config file path is evaluated if this value is 1
|
||||||
|
vim.g.lazygit_config_file_path = '' -- custom config file path
|
||||||
|
-- OR
|
||||||
|
vim.g.lazygit_config_file_path = {} -- table of custom config file paths
|
||||||
|
|
||||||
|
vim.g.lazygit_on_exit_callback = nil -- optional function callback when exiting lazygit (useful for example to refresh some UI elements after lazy git has made some changes)
|
||||||
|
|
||||||
|
vim.keymap.set("n", "<Leader>gg", ":LazyGit<CR>", { desc = "LazyGit" })
|
||||||
101
apps/neovim/lsp.lua
Normal file
101
apps/neovim/lsp.lua
Normal file
|
|
@ -0,0 +1,101 @@
|
||||||
|
local lspconfig = require('lspconfig')
|
||||||
|
|
||||||
|
vim.lsp.config('lua_ls', { cmd = { 'lua-language-server' },
|
||||||
|
settings = {
|
||||||
|
Lua = {
|
||||||
|
runtime = {
|
||||||
|
version = 'LuaJIT',
|
||||||
|
path = vim.split(package.path, ';'),
|
||||||
|
},
|
||||||
|
diagnostics = {
|
||||||
|
globals = { 'vim' },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
vim.lsp.config('rust_analyzer', {
|
||||||
|
settings = {
|
||||||
|
['rust-analyzer'] = {
|
||||||
|
diagnostics = {
|
||||||
|
enable = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
local languages = {
|
||||||
|
'rust_analyzer',
|
||||||
|
'r_language_server',
|
||||||
|
'lua_ls',
|
||||||
|
'quarto',
|
||||||
|
'nil_ls',
|
||||||
|
'pyright'
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, language in ipairs(languages) do
|
||||||
|
vim.lsp.enable(language)
|
||||||
|
end
|
||||||
|
|
||||||
|
vim.diagnostic.config {
|
||||||
|
severity_sort = true,
|
||||||
|
float = { border = 'rounded', source = 'if_many' },
|
||||||
|
underline = { severity = vim.diagnostic.severity.ERROR },
|
||||||
|
signs = vim.g.have_nerd_font and {
|
||||||
|
text = {
|
||||||
|
[vim.diagnostic.severity.ERROR] = ' ',
|
||||||
|
[vim.diagnostic.severity.WARN] = ' ',
|
||||||
|
[vim.diagnostic.severity.INFO] = ' ',
|
||||||
|
[vim.diagnostic.severity.HINT] = ' ',
|
||||||
|
},
|
||||||
|
} or {},
|
||||||
|
virtual_text = {
|
||||||
|
source = 'if_many',
|
||||||
|
spacing = 2,
|
||||||
|
format = function(diagnostic)
|
||||||
|
local diagnostic_message = {
|
||||||
|
[vim.diagnostic.severity.ERROR] = diagnostic.message,
|
||||||
|
[vim.diagnostic.severity.WARN] = diagnostic.message,
|
||||||
|
[vim.diagnostic.severity.INFO] = diagnostic.message,
|
||||||
|
[vim.diagnostic.severity.HINT] = diagnostic.message,
|
||||||
|
}
|
||||||
|
return diagnostic_message[diagnostic.severity]
|
||||||
|
end,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
vim.api.nvim_create_autocmd("LspAttach", {
|
||||||
|
callback = function(event)
|
||||||
|
local buf = event.buf
|
||||||
|
local opts = function(desc)
|
||||||
|
return { buffer = buf, desc = desc }
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Jumping + finding
|
||||||
|
vim.keymap.set("n", "gd", vim.lsp.buf.definition, opts("[G]oto Definition"))
|
||||||
|
vim.keymap.set("n", "gD", vim.lsp.buf.declaration, opts("Goto [D]eclaration"))
|
||||||
|
vim.keymap.set("n", "gi", vim.lsp.buf.implementation, opts("[G]oto [I]mplementation"))
|
||||||
|
vim.keymap.set("n", "gr", vim.lsp.buf.references, opts("[G]oto [R]eferences"))
|
||||||
|
|
||||||
|
-- Info + documentation
|
||||||
|
vim.keymap.set("n", "K", vim.lsp.buf.hover, opts("Hover Documentation"))
|
||||||
|
vim.keymap.set("n", "<C-k>", vim.lsp.buf.signature_help, opts("Signature Help"))
|
||||||
|
|
||||||
|
-- Actions + rename
|
||||||
|
vim.keymap.set("n", "<leader>rn", vim.lsp.buf.rename, opts("[R]e[n]ame"))
|
||||||
|
vim.keymap.set({ "n", "v" }, "<leader>ca", vim.lsp.buf.code_action, opts("[C]ode [A]ction"))
|
||||||
|
|
||||||
|
-- Diagnostics navigation
|
||||||
|
vim.keymap.set("n", "[d", vim.diagnostic.goto_prev, opts("Prev Diagnostic"))
|
||||||
|
vim.keymap.set("n", "]d", vim.diagnostic.goto_next, opts("Next Diagnostic"))
|
||||||
|
vim.keymap.set("n", "<leader>e", vim.diagnostic.open_float, opts("Show Error"))
|
||||||
|
vim.keymap.set("n", "<leader>q", vim.diagnostic.setloclist, opts("Diagnostic Quickfix"))
|
||||||
|
|
||||||
|
-- Formatting
|
||||||
|
vim.keymap.set("n", "<leader>f", function()
|
||||||
|
vim.lsp.buf.format({ async = true })
|
||||||
|
end, opts("[F]ormat Buffer"))
|
||||||
|
end,
|
||||||
|
})
|
||||||
54
apps/neovim/lua-line.lua
Normal file
54
apps/neovim/lua-line.lua
Normal file
|
|
@ -0,0 +1,54 @@
|
||||||
|
require('lualine').setup {
|
||||||
|
options = {
|
||||||
|
icons_enabled = true,
|
||||||
|
theme = 'auto',
|
||||||
|
component_separators = { left = '', right = ''},
|
||||||
|
section_separators = { left = '', right = ''},
|
||||||
|
disabled_filetypes = {
|
||||||
|
statusline = {},
|
||||||
|
winbar = {},
|
||||||
|
},
|
||||||
|
ignore_focus = {},
|
||||||
|
always_divide_middle = true,
|
||||||
|
always_show_tabline = true,
|
||||||
|
globalstatus = false,
|
||||||
|
refresh = {
|
||||||
|
statusline = 1000,
|
||||||
|
tabline = 1000,
|
||||||
|
winbar = 1000,
|
||||||
|
refresh_time = 16, -- ~60fps
|
||||||
|
events = {
|
||||||
|
'WinEnter',
|
||||||
|
'BufEnter',
|
||||||
|
'BufWritePost',
|
||||||
|
'SessionLoadPost',
|
||||||
|
'FileChangedShellPost',
|
||||||
|
'VimResized',
|
||||||
|
'Filetype',
|
||||||
|
'CursorMoved',
|
||||||
|
'CursorMovedI',
|
||||||
|
'ModeChanged',
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
sections = {
|
||||||
|
lualine_a = {'mode'},
|
||||||
|
lualine_b = {'branch', 'diff', 'diagnostics'},
|
||||||
|
lualine_c = {'filename'},
|
||||||
|
lualine_x = {'encoding', 'fileformat', 'filetype'},
|
||||||
|
lualine_y = {'progress'},
|
||||||
|
lualine_z = {'location'}
|
||||||
|
},
|
||||||
|
inactive_sections = {
|
||||||
|
lualine_a = {},
|
||||||
|
lualine_b = {},
|
||||||
|
lualine_c = {'filename'},
|
||||||
|
lualine_x = {'location'},
|
||||||
|
lualine_y = {},
|
||||||
|
lualine_z = {}
|
||||||
|
},
|
||||||
|
tabline = {},
|
||||||
|
winbar = {},
|
||||||
|
inactive_winbar = {},
|
||||||
|
extensions = {}
|
||||||
|
}
|
||||||
48
apps/neovim/molten.lua
Normal file
48
apps/neovim/molten.lua
Normal file
|
|
@ -0,0 +1,48 @@
|
||||||
|
vim.g.molten_auto_open_output = true
|
||||||
|
vim.g.molten_wrap_output = true
|
||||||
|
vim.g.molten_output_show_exec_time = true
|
||||||
|
vim.g.molten_output_win_hide_on_leave = false
|
||||||
|
vim.g.molten_use_border_highlights = true
|
||||||
|
vim.g.molten_virt_text_output = true
|
||||||
|
vim.g.molten_image_provider = "image.nvim"
|
||||||
|
vim.g.molten_image_location = "both"
|
||||||
|
vim.g.molten_output_virt_lines = true
|
||||||
|
vim.g.molten_cover_empty_lines = true
|
||||||
|
vim.g.molten_output_truncate = "bottom"
|
||||||
|
vim.g.molten_virt_text_max_lines = 20
|
||||||
|
--vim.g.molten_output = "pane"
|
||||||
|
|
||||||
|
vim.api.nvim_set_hl(0, "NormalFloat", { bg = "#1e1e2e" })
|
||||||
|
vim.api.nvim_set_hl(0, "FloatBorder", { bg = "#1e1e2e" })
|
||||||
|
-- vim.api.nvim_set_hl(0, "MoltenVirtualText", {
|
||||||
|
-- bg = "#ae0606",
|
||||||
|
-- fg = "#ffd787",
|
||||||
|
-- italic = true,
|
||||||
|
-- })
|
||||||
|
|
||||||
|
require("image").setup({
|
||||||
|
editor = {
|
||||||
|
-- force a visible background for plots
|
||||||
|
background = "white", -- or "#ffffff" or "black"
|
||||||
|
inline = {
|
||||||
|
enable = true,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
vim.keymap.set("n", "<localleader>mi", ":MoltenInit<CR>",
|
||||||
|
{ silent = true, desc = "Initialize the plugin" })
|
||||||
|
vim.keymap.set("n", "<localleader>e", ":MoltenEvaluateOperator<CR>",
|
||||||
|
{ silent = true, desc = "run operator selection" })
|
||||||
|
vim.keymap.set("n", "<localleader>rl", ":MoltenEvaluateLine<CR>",
|
||||||
|
{ silent = true, desc = "evaluate line" })
|
||||||
|
vim.keymap.set("n", "<localleader>rr", ":MoltenReevaluateCell<CR>",
|
||||||
|
{ silent = true, desc = "re-evaluate cell" })
|
||||||
|
vim.keymap.set("v", "<localleader>r", ":<C-u>MoltenEvaluateVisual<CR>gv",
|
||||||
|
{ silent = true, desc = "evaluate visual selection" })
|
||||||
|
vim.keymap.set("n", "<localleader>rd", ":MoltenDelete<CR>",
|
||||||
|
{ silent = true, desc = "molten delete cell" })
|
||||||
|
vim.keymap.set("n", "<localleader>oh", ":MoltenHideOutput<CR>",
|
||||||
|
{ silent = true, desc = "hide output" })
|
||||||
|
vim.keymap.set("n", "<localleader>os", ":noautocmd MoltenEnterOutput<CR>",
|
||||||
|
{ silent = true, desc = "show/enter output" })
|
||||||
25
apps/neovim/nvim-tree.lua
Normal file
25
apps/neovim/nvim-tree.lua
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
-- disable netrw at the very start of your init.lua
|
||||||
|
vim.g.loaded_netrw = 1
|
||||||
|
vim.g.loaded_netrwPlugin = 1
|
||||||
|
|
||||||
|
-- optionally enable 24-bit colour
|
||||||
|
vim.opt.termguicolors = true
|
||||||
|
|
||||||
|
|
||||||
|
-- OR setup with some options
|
||||||
|
require("nvim-tree").setup({
|
||||||
|
sort = {
|
||||||
|
sorter = "case_sensitive",
|
||||||
|
},
|
||||||
|
view = {
|
||||||
|
width = 30,
|
||||||
|
},
|
||||||
|
renderer = {
|
||||||
|
group_empty = true,
|
||||||
|
},
|
||||||
|
filters = {
|
||||||
|
dotfiles = true,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
vim.keymap.set('n', '<Leader>d', ':NvimTreeToggle<CR>', { desc = 'Open or close the tree' })
|
||||||
5
apps/neovim/otter.lua
Normal file
5
apps/neovim/otter.lua
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
require("otter").setup({
|
||||||
|
buffers = {
|
||||||
|
write_to_disk = true,
|
||||||
|
},
|
||||||
|
})
|
||||||
37
apps/neovim/quarto.lua
Normal file
37
apps/neovim/quarto.lua
Normal file
|
|
@ -0,0 +1,37 @@
|
||||||
|
local quarto = require('quarto')
|
||||||
|
require('quarto').setup{
|
||||||
|
debug = true,
|
||||||
|
lspFeatures = {
|
||||||
|
enabled = true,
|
||||||
|
hover = true,
|
||||||
|
chunks = "curly",
|
||||||
|
languages = { "r", "python", "julia", "bash", "html" },
|
||||||
|
diagnostics = {
|
||||||
|
enabled = false,
|
||||||
|
lint_cache = false,
|
||||||
|
triggers = { "BufWritePost" },
|
||||||
|
},
|
||||||
|
completion = {
|
||||||
|
enabled = true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
codeRunner = {
|
||||||
|
enabled = true,
|
||||||
|
default_method = "molten", -- "molten", "slime", "iron" or <function>
|
||||||
|
ft_runners = { r = "molten", python = "molten" }, -- filetype to runner, ie. `{ python = "molten" }`.
|
||||||
|
-- Takes precedence over `default_method`
|
||||||
|
never_run = { 'yaml' }, -- filetypes which are never sent to a code runner
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
vim.keymap.set('n', '<leader>qp', quarto.quartoPreview, { silent = true, noremap = true })
|
||||||
|
|
||||||
|
local runner = require("quarto.runner")
|
||||||
|
vim.keymap.set("n", "<localleader>rr", runner.run_cell, { desc = "run cell", silent = true })
|
||||||
|
vim.keymap.set("n", "<localleader>ra", runner.run_above, { desc = "run cell and above", silent = true })
|
||||||
|
vim.keymap.set("n", "<localleader>rR", runner.run_all, { desc = "run all cells", silent = true })
|
||||||
|
vim.keymap.set("n", "<localleader>rl", runner.run_line, { desc = "run line", silent = true })
|
||||||
|
vim.keymap.set("v", "<localleader>r", runner.run_range, { desc = "run visual range", silent = true })
|
||||||
|
vim.keymap.set("n", "<localleader>RA", function()
|
||||||
|
runner.run_all(true)
|
||||||
|
end, { desc = "run all cells of all languages", silent = true })
|
||||||
36
apps/neovim/telescope.lua
Normal file
36
apps/neovim/telescope.lua
Normal file
|
|
@ -0,0 +1,36 @@
|
||||||
|
local builtin = require('telescope.builtin')
|
||||||
|
vim.keymap.set('n', '<leader>ff', builtin.find_files, { desc = 'Telescope find files' })
|
||||||
|
vim.keymap.set('n', '<leader>fg', builtin.live_grep, { desc = 'Telescope live grep' })
|
||||||
|
vim.keymap.set('n', '<leader>fb', builtin.buffers, { desc = 'Telescope buffers' })
|
||||||
|
vim.keymap.set('n', '<leader>fh', builtin.help_tags, { desc = 'Telescope help tags' })
|
||||||
|
|
||||||
|
require('telescope').setup{
|
||||||
|
defaults = {
|
||||||
|
-- Default configuration for telescope goes here:
|
||||||
|
-- config_key = value,
|
||||||
|
mappings = {
|
||||||
|
i = {
|
||||||
|
-- map actions.which_key to <C-h> (default: <C-/>)
|
||||||
|
-- actions.which_key shows the mappings for your picker,
|
||||||
|
-- e.g. git_{create, delete, ...}_branch for the git_branches picker
|
||||||
|
["<C-h>"] = "which_key"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
pickers = {
|
||||||
|
-- Default configuration for builtin pickers goes here:
|
||||||
|
-- picker_name = {
|
||||||
|
-- picker_config_key = value,
|
||||||
|
-- ...
|
||||||
|
-- }
|
||||||
|
-- Now the picker_config_key will be applied every time you call this
|
||||||
|
-- builtin picker
|
||||||
|
},
|
||||||
|
extensions = {
|
||||||
|
-- Your extension configuration goes here:
|
||||||
|
-- extension_name = {
|
||||||
|
-- extension_config_key = value,
|
||||||
|
-- }
|
||||||
|
-- please take a look at the readme of the extension you want to configure
|
||||||
|
}
|
||||||
|
}
|
||||||
5
apps/neovim/toggleterm.lua
Normal file
5
apps/neovim/toggleterm.lua
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
require("toggleterm").setup()
|
||||||
|
|
||||||
|
vim.keymap.set("n", "<Leader>tt", '<cmd>ToggleTerm direction=float<CR>', { noremap = ture, silent = true })
|
||||||
|
vim.keymap.set("n", "<Leader>tv", '<cmd>ToggleTerm direction=vertical<CR>', { noremap = ture, silent = true })
|
||||||
|
vim.keymap.set("n", "<Leader>th", '<cmd>ToggleTerm direction=horizontal<CR>', { noremap = ture, silent = true })
|
||||||
23
apps/neovim/treesitter.lua
Normal file
23
apps/neovim/treesitter.lua
Normal file
|
|
@ -0,0 +1,23 @@
|
||||||
|
vim.api.nvim_create_autocmd("FileType", {
|
||||||
|
pattern = "*",
|
||||||
|
callback = function()
|
||||||
|
local ft = vim.bo.filetype
|
||||||
|
local lang = vim.treesitter.language.get_lang(ft)
|
||||||
|
|
||||||
|
if not lang or not vim.treesitter.language.add(lang) then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
vim.treesitter.start()
|
||||||
|
|
||||||
|
-- Set folding if available
|
||||||
|
if vim.treesitter.query.get(lang, "folds") then
|
||||||
|
vim.wo.foldexpr = "v:lua.vim.treesitter.foldexpr()"
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Set indentation if available (overrides traditional indent)
|
||||||
|
if vim.treesitter.query.get(lang, "indents") then
|
||||||
|
vim.bo.indentexpr = "nvim_treesitter#indent()"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
})
|
||||||
204
apps/neovim/trouble.lua
Normal file
204
apps/neovim/trouble.lua
Normal file
|
|
@ -0,0 +1,204 @@
|
||||||
|
---@class trouble.Mode: trouble.Config,trouble.Section.spec
|
||||||
|
---@field desc? string
|
||||||
|
---@field sections? string[]
|
||||||
|
|
||||||
|
---@class trouble.Config
|
||||||
|
---@field mode? string
|
||||||
|
---@field config? fun(opts:trouble.Config)
|
||||||
|
---@field formatters? table<string,trouble.Formatter> custom formatters
|
||||||
|
---@field filters? table<string, trouble.FilterFn> custom filters
|
||||||
|
---@field sorters? table<string, trouble.SorterFn> custom sorters
|
||||||
|
local defaults = {
|
||||||
|
auto_close = false, -- auto close when there are no items
|
||||||
|
auto_open = false, -- auto open when there are items
|
||||||
|
auto_preview = true, -- automatically open preview when on an item
|
||||||
|
auto_refresh = true, -- auto refresh when open
|
||||||
|
auto_jump = false, -- auto jump to the item when there's only one
|
||||||
|
focus = false, -- Focus the window when opened
|
||||||
|
restore = true, -- restores the last location in the list when opening
|
||||||
|
follow = true, -- Follow the current item
|
||||||
|
indent_guides = true, -- show indent guides
|
||||||
|
max_items = 200, -- limit number of items that can be displayed per section
|
||||||
|
multiline = true, -- render multi-line messages
|
||||||
|
pinned = false, -- When pinned, the opened trouble window will be bound to the current buffer
|
||||||
|
warn_no_results = true, -- show a warning when there are no results
|
||||||
|
open_no_results = false, -- open the trouble window when there are no results
|
||||||
|
---@type trouble.Window.opts
|
||||||
|
win = {}, -- window options for the results window. Can be a split or a floating window.
|
||||||
|
-- Window options for the preview window. Can be a split, floating window,
|
||||||
|
-- or `main` to show the preview in the main editor window.
|
||||||
|
---@type trouble.Window.opts
|
||||||
|
preview = {
|
||||||
|
type = "main",
|
||||||
|
-- when a buffer is not yet loaded, the preview window will be created
|
||||||
|
-- in a scratch buffer with only syntax highlighting enabled.
|
||||||
|
-- Set to false, if you want the preview to always be a real loaded buffer.
|
||||||
|
scratch = true,
|
||||||
|
},
|
||||||
|
-- Throttle/Debounce settings. Should usually not be changed.
|
||||||
|
---@type table<string, number|{ms:number, debounce?:boolean}>
|
||||||
|
throttle = {
|
||||||
|
refresh = 20, -- fetches new data when needed
|
||||||
|
update = 10, -- updates the window
|
||||||
|
render = 10, -- renders the window
|
||||||
|
follow = 100, -- follows the current item
|
||||||
|
preview = { ms = 100, debounce = true }, -- shows the preview for the current item
|
||||||
|
},
|
||||||
|
-- Key mappings can be set to the name of a builtin action,
|
||||||
|
-- or you can define your own custom action.
|
||||||
|
---@type table<string, trouble.Action.spec|false>
|
||||||
|
keys = {
|
||||||
|
["?"] = "help",
|
||||||
|
r = "refresh",
|
||||||
|
R = "toggle_refresh",
|
||||||
|
q = "close",
|
||||||
|
o = "jump_close",
|
||||||
|
["<esc>"] = "cancel",
|
||||||
|
["<cr>"] = "jump",
|
||||||
|
["<2-leftmouse>"] = "jump",
|
||||||
|
["<c-s>"] = "jump_split",
|
||||||
|
["<c-v>"] = "jump_vsplit",
|
||||||
|
-- go down to next item (accepts count)
|
||||||
|
-- j = "next",
|
||||||
|
["}"] = "next",
|
||||||
|
["]]"] = "next",
|
||||||
|
-- go up to prev item (accepts count)
|
||||||
|
-- k = "prev",
|
||||||
|
["{"] = "prev",
|
||||||
|
["[["] = "prev",
|
||||||
|
dd = "delete",
|
||||||
|
d = { action = "delete", mode = "v" },
|
||||||
|
i = "inspect",
|
||||||
|
p = "preview",
|
||||||
|
P = "toggle_preview",
|
||||||
|
zo = "fold_open",
|
||||||
|
zO = "fold_open_recursive",
|
||||||
|
zc = "fold_close",
|
||||||
|
zC = "fold_close_recursive",
|
||||||
|
za = "fold_toggle",
|
||||||
|
zA = "fold_toggle_recursive",
|
||||||
|
zm = "fold_more",
|
||||||
|
zM = "fold_close_all",
|
||||||
|
zr = "fold_reduce",
|
||||||
|
zR = "fold_open_all",
|
||||||
|
zx = "fold_update",
|
||||||
|
zX = "fold_update_all",
|
||||||
|
zn = "fold_disable",
|
||||||
|
zN = "fold_enable",
|
||||||
|
zi = "fold_toggle_enable",
|
||||||
|
gb = { -- example of a custom action that toggles the active view filter
|
||||||
|
action = function(view)
|
||||||
|
view:filter({ buf = 0 }, { toggle = true })
|
||||||
|
end,
|
||||||
|
desc = "Toggle Current Buffer Filter",
|
||||||
|
},
|
||||||
|
s = { -- example of a custom action that toggles the severity
|
||||||
|
action = function(view)
|
||||||
|
local f = view:get_filter("severity")
|
||||||
|
local severity = ((f and f.filter.severity or 0) + 1) % 5
|
||||||
|
view:filter({ severity = severity }, {
|
||||||
|
id = "severity",
|
||||||
|
template = "{hl:Title}Filter:{hl} {severity}",
|
||||||
|
del = severity == 0,
|
||||||
|
})
|
||||||
|
end,
|
||||||
|
desc = "Toggle Severity Filter",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
---@type table<string, trouble.Mode>
|
||||||
|
modes = {
|
||||||
|
-- sources define their own modes, which you can use directly,
|
||||||
|
-- or override like in the example below
|
||||||
|
lsp_references = {
|
||||||
|
-- some modes are configurable, see the source code for more details
|
||||||
|
params = {
|
||||||
|
include_declaration = true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
-- The LSP base mode for:
|
||||||
|
-- * lsp_definitions, lsp_references, lsp_implementations
|
||||||
|
-- * lsp_type_definitions, lsp_declarations, lsp_command
|
||||||
|
lsp_base = {
|
||||||
|
params = {
|
||||||
|
-- don't include the current location in the results
|
||||||
|
include_current = false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
-- more advanced example that extends the lsp_document_symbols
|
||||||
|
symbols = {
|
||||||
|
desc = "document symbols",
|
||||||
|
mode = "lsp_document_symbols",
|
||||||
|
focus = false,
|
||||||
|
win = { position = "right" },
|
||||||
|
filter = {
|
||||||
|
-- remove Package since luals uses it for control flow structures
|
||||||
|
["not"] = { ft = "lua", kind = "Package" },
|
||||||
|
any = {
|
||||||
|
-- all symbol kinds for help / markdown files
|
||||||
|
ft = { "help", "markdown" },
|
||||||
|
-- default set of symbol kinds
|
||||||
|
kind = {
|
||||||
|
"Class",
|
||||||
|
"Constructor",
|
||||||
|
"Enum",
|
||||||
|
"Field",
|
||||||
|
"Function",
|
||||||
|
"Interface",
|
||||||
|
"Method",
|
||||||
|
"Module",
|
||||||
|
"Namespace",
|
||||||
|
"Package",
|
||||||
|
"Property",
|
||||||
|
"Struct",
|
||||||
|
"Trait",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
-- stylua: ignore
|
||||||
|
icons = {
|
||||||
|
---@type trouble.Indent.symbols
|
||||||
|
indent = {
|
||||||
|
top = "│ ",
|
||||||
|
middle = "├╴",
|
||||||
|
last = "└╴",
|
||||||
|
-- last = "-╴",
|
||||||
|
-- last = "╰╴", -- rounded
|
||||||
|
fold_open = " ",
|
||||||
|
fold_closed = " ",
|
||||||
|
ws = " ",
|
||||||
|
},
|
||||||
|
folder_closed = " ",
|
||||||
|
folder_open = " ",
|
||||||
|
kinds = {
|
||||||
|
Array = " ",
|
||||||
|
Boolean = " ",
|
||||||
|
Class = " ",
|
||||||
|
Constant = " ",
|
||||||
|
Constructor = " ",
|
||||||
|
Enum = " ",
|
||||||
|
EnumMember = " ",
|
||||||
|
Event = " ",
|
||||||
|
Field = " ",
|
||||||
|
File = " ",
|
||||||
|
Function = " ",
|
||||||
|
Interface = " ",
|
||||||
|
Key = " ",
|
||||||
|
Method = " ",
|
||||||
|
Module = " ",
|
||||||
|
Namespace = " ",
|
||||||
|
Null = " ",
|
||||||
|
Number = " ",
|
||||||
|
Object = " ",
|
||||||
|
Operator = " ",
|
||||||
|
Package = " ",
|
||||||
|
Property = " ",
|
||||||
|
String = " ",
|
||||||
|
Struct = " ",
|
||||||
|
TypeParameter = " ",
|
||||||
|
Variable = " ",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
1
apps/neovim/which-key.lua
Normal file
1
apps/neovim/which-key.lua
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
local wk = require("which-key")
|
||||||
175
apps/sway/default.nix
Normal file
175
apps/sway/default.nix
Normal file
|
|
@ -0,0 +1,175 @@
|
||||||
|
{ config, pkgs, lib, ... }:
|
||||||
|
let
|
||||||
|
mod = "Mod4";
|
||||||
|
|
||||||
|
terminal = "ghostty";
|
||||||
|
menu = "fuzzel";
|
||||||
|
|
||||||
|
pactl = "${pkgs.pulseaudio}/bin/pactl";
|
||||||
|
light = "${pkgs.brightnessctl}/bin/brightnessctl";
|
||||||
|
grim = "${pkgs.grim}/bin/grim";
|
||||||
|
slurp = "${pkgs.slurp}/bin/slurp";
|
||||||
|
wlcopy = "${pkgs.wl-clipboard}/bin/wl-copy";
|
||||||
|
|
||||||
|
colors = {
|
||||||
|
base = "#1e1e2e";
|
||||||
|
surface0 = "#313244";
|
||||||
|
surface1 = "#45475a";
|
||||||
|
|
||||||
|
text = "#cdd6f4";
|
||||||
|
subtext = "#bac2de";
|
||||||
|
|
||||||
|
blue = "#89b4fa";
|
||||||
|
yellow = "#f9e2af";
|
||||||
|
peach = "#fab387";
|
||||||
|
red = "#f38ba8";
|
||||||
|
};
|
||||||
|
in
|
||||||
|
{
|
||||||
|
wayland.windowManager.sway = {
|
||||||
|
enable = true;
|
||||||
|
|
||||||
|
config = {
|
||||||
|
modifier = mod;
|
||||||
|
terminal = terminal;
|
||||||
|
menu = menu;
|
||||||
|
bars = [ ];
|
||||||
|
|
||||||
|
fonts = {
|
||||||
|
names = [ "sans-serif" ];
|
||||||
|
size = 10.0;
|
||||||
|
};
|
||||||
|
|
||||||
|
window = {
|
||||||
|
border = 3;
|
||||||
|
titlebar = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
gaps = {
|
||||||
|
inner = 0;
|
||||||
|
outer = 0;
|
||||||
|
smartGaps = false;
|
||||||
|
smartBorders = "on";
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
colors = {
|
||||||
|
focused = {
|
||||||
|
border = colors.yellow;
|
||||||
|
background = colors.yellow;
|
||||||
|
text = colors.base;
|
||||||
|
indicator = colors.yellow;
|
||||||
|
childBorder = colors.yellow;
|
||||||
|
};
|
||||||
|
|
||||||
|
focusedInactive = {
|
||||||
|
border = colors.surface1;
|
||||||
|
background = colors.surface1;
|
||||||
|
text = colors.text;
|
||||||
|
indicator = colors.surface1;
|
||||||
|
childBorder = colors.surface1;
|
||||||
|
};
|
||||||
|
|
||||||
|
unfocused = {
|
||||||
|
border = colors.surface1;
|
||||||
|
background = colors.surface1;
|
||||||
|
text = colors.text;
|
||||||
|
indicator = colors.surface1;
|
||||||
|
childBorder = colors.surface1;
|
||||||
|
};
|
||||||
|
|
||||||
|
urgent = {
|
||||||
|
border = colors.red;
|
||||||
|
background = colors.red;
|
||||||
|
text = colors.base;
|
||||||
|
indicator = colors.red;
|
||||||
|
childBorder = colors.red;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
keybindings = lib.mkOptionDefault {
|
||||||
|
# launcher
|
||||||
|
"${mod}+Return" = "exec ${terminal}";
|
||||||
|
"${mod}+d" = "exec ${menu}";
|
||||||
|
|
||||||
|
# basic
|
||||||
|
"${mod}+Shift+q" = "kill";
|
||||||
|
"${mod}+Shift+r" = "reload";
|
||||||
|
"${mod}+Shift+e" = "exec swaynag -t warning -m 'Exit sway?' -b 'Yes, exit' 'swaymsg exit'";
|
||||||
|
|
||||||
|
# focus movement
|
||||||
|
"${mod}+h" = "focus left";
|
||||||
|
"${mod}+j" = "focus down";
|
||||||
|
"${mod}+k" = "focus up";
|
||||||
|
"${mod}+l" = "focus right";
|
||||||
|
|
||||||
|
# move windows
|
||||||
|
"${mod}+Shift+h" = "move left";
|
||||||
|
"${mod}+Shift+j" = "move down";
|
||||||
|
"${mod}+Shift+k" = "move up";
|
||||||
|
"${mod}+Shift+l" = "move right";
|
||||||
|
|
||||||
|
# split/layout
|
||||||
|
"${mod}+b" = "splith";
|
||||||
|
"${mod}+v" = "splitv";
|
||||||
|
"${mod}+e" = "layout toggle split";
|
||||||
|
"${mod}+s" = "layout stacking";
|
||||||
|
"${mod}+w" = "layout tabbed";
|
||||||
|
"${mod}+f" = "fullscreen toggle";
|
||||||
|
"${mod}+space" = "floating toggle";
|
||||||
|
"${mod}+a" = "focus parent";
|
||||||
|
|
||||||
|
# workspaces 1..10
|
||||||
|
"${mod}+1" = "workspace number 1";
|
||||||
|
"${mod}+2" = "workspace number 2";
|
||||||
|
"${mod}+3" = "workspace number 3";
|
||||||
|
"${mod}+4" = "workspace number 4";
|
||||||
|
"${mod}+5" = "workspace number 5";
|
||||||
|
"${mod}+6" = "workspace number 6";
|
||||||
|
"${mod}+7" = "workspace number 7";
|
||||||
|
"${mod}+8" = "workspace number 8";
|
||||||
|
"${mod}+9" = "workspace number 9";
|
||||||
|
"${mod}+0" = "workspace number 10";
|
||||||
|
|
||||||
|
"${mod}+Shift+1" = "move container to workspace number 1";
|
||||||
|
"${mod}+Shift+2" = "move container to workspace number 2";
|
||||||
|
"${mod}+Shift+3" = "move container to workspace number 3";
|
||||||
|
"${mod}+Shift+4" = "move container to workspace number 4";
|
||||||
|
"${mod}+Shift+5" = "move container to workspace number 5";
|
||||||
|
"${mod}+Shift+6" = "move container to workspace number 6";
|
||||||
|
"${mod}+Shift+7" = "move container to workspace number 7";
|
||||||
|
"${mod}+Shift+8" = "move container to workspace number 8";
|
||||||
|
"${mod}+Shift+9" = "move container to workspace number 9";
|
||||||
|
"${mod}+Shift+0" = "move container to workspace number 10";
|
||||||
|
|
||||||
|
# screenshots
|
||||||
|
"Print" = "exec ${grim} - | ${wlcopy}";
|
||||||
|
"Shift+Print" = "exec ${grim} -g \"$(${slurp})\" - | ${wlcopy}";
|
||||||
|
|
||||||
|
# audio keys
|
||||||
|
"XF86AudioRaiseVolume" = "exec ${pactl} set-sink-volume @DEFAULT_SINK@ +5%";
|
||||||
|
"XF86AudioLowerVolume" = "exec ${pactl} set-sink-volume @DEFAULT_SINK@ -5%";
|
||||||
|
"XF86AudioMute" = "exec ${pactl} set-sink-mute @DEFAULT_SINK@ toggle";
|
||||||
|
"XF86AudioMicMute" = "exec ${pactl} set-source-mute @DEFAULT_SOURCE@ toggle";
|
||||||
|
|
||||||
|
# brightness keys
|
||||||
|
"XF86MonBrightnessUp" = "exec ${light} set +5%";
|
||||||
|
"XF86MonBrightnessDown" = "exec ${light} set 5%-";
|
||||||
|
};
|
||||||
|
|
||||||
|
startup = [
|
||||||
|
{
|
||||||
|
command = "mako";
|
||||||
|
always = true;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
command = "fcitx5";
|
||||||
|
always = true;
|
||||||
|
}
|
||||||
|
#{ command = "waybar"; always = true; }
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
#extraConfig = '''';
|
||||||
|
};
|
||||||
|
}
|
||||||
91
apps/waybar/config.jsonc
Normal file
91
apps/waybar/config.jsonc
Normal file
|
|
@ -0,0 +1,91 @@
|
||||||
|
{
|
||||||
|
"layer": "top",
|
||||||
|
"position": "top",
|
||||||
|
"height": 25,
|
||||||
|
"spacing": 1,
|
||||||
|
|
||||||
|
"modules-left": ["sway/workspaces", "sway/mode"],
|
||||||
|
"modules-right": ["cpu", "memory", "network", "pulseaudio","battery", "clock"],
|
||||||
|
|
||||||
|
"sway/workspaces": {
|
||||||
|
"disable-scroll": true,
|
||||||
|
},
|
||||||
|
|
||||||
|
"sway/window": {
|
||||||
|
"max-length": 60
|
||||||
|
},
|
||||||
|
|
||||||
|
"network": {
|
||||||
|
"interval": 5,
|
||||||
|
"format-alt": "{icon} ↓{bandwidthDownBits} ↑{bandwidthUpBits}",
|
||||||
|
"format-wifi": "{icon} {signalStrength}%",
|
||||||
|
"format-icons": [" ", " ", " ", " ", " "],
|
||||||
|
|
||||||
|
"format-ethernet": " ",
|
||||||
|
"format-disconnected": " ",
|
||||||
|
|
||||||
|
"tooltip": true,
|
||||||
|
"tooltip-format": "{essid} {ipaddr}"
|
||||||
|
},
|
||||||
|
|
||||||
|
"pulseaudio": {
|
||||||
|
"format": "{icon} {volume}%",
|
||||||
|
"format-muted": " 0%",
|
||||||
|
"format-icons": {
|
||||||
|
"default": [" "],
|
||||||
|
},
|
||||||
|
"on-click": "pactl set-sink-mute @DEFAULT_SINK@ toggle",
|
||||||
|
},
|
||||||
|
|
||||||
|
"battery": {
|
||||||
|
"format": "{icon} {capacity}%",
|
||||||
|
"format-alt": "{icon} {time} {power}W",
|
||||||
|
"format-charging": "{icon} {capacity}%",
|
||||||
|
|
||||||
|
"states": {
|
||||||
|
"warning": 25,
|
||||||
|
"critical": 10
|
||||||
|
},
|
||||||
|
"format-icons": {
|
||||||
|
"default": ["", "", "", "", "", "", "", "", "", ""],
|
||||||
|
"charging": [" ", " ", " ", " ", " ", " ", " ", " ", " ", " "],
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
"clock": {
|
||||||
|
"format": " {:%H:%M}",
|
||||||
|
"tooltip-format": "{:%a %d %b %Y}"
|
||||||
|
},
|
||||||
|
|
||||||
|
"cpu": {
|
||||||
|
"interval": 2,
|
||||||
|
"format": " {usage}%",
|
||||||
|
"format-alt":" {usage}% {icon0}{icon1}{icon2}{icon3}{icon4}{icon5}{icon6}{icon7}{icon8}{icon9}{icon10}{icon11}{icon12}{icon13}{icon14}{icon15} {avg_frequency} GHz",
|
||||||
|
"states": {
|
||||||
|
"warning": 60,
|
||||||
|
"critical": 85,
|
||||||
|
},
|
||||||
|
"format-icons": [
|
||||||
|
"<span color='#b4befe'>▁</span>", // lavender (cool)
|
||||||
|
"<span color='#89b4fa'>▂</span>", // blue
|
||||||
|
"<span color='#cdd6f4'>▃</span>", // text
|
||||||
|
"<span color='#cdd6f4'>▄</span>", // text
|
||||||
|
"<span color='#f9e2af'>▅</span>", // yellow (warm)
|
||||||
|
"<span color='#f9e2af'>▆</span>", // yellow
|
||||||
|
"<span color='#fab387'>▇</span>", // peach (hot)
|
||||||
|
"<span color='#f38ba8'>█</span>" // red (very hot)
|
||||||
|
],
|
||||||
|
"tooltip": true
|
||||||
|
},
|
||||||
|
|
||||||
|
"memory": {
|
||||||
|
"interval": 5,
|
||||||
|
"format": " {percentage}%",
|
||||||
|
"format-alt": " {used}GiB / {avail}GiB",
|
||||||
|
"states": {
|
||||||
|
"warning": 70,
|
||||||
|
"critical": 90,
|
||||||
|
},
|
||||||
|
"tooltip": true
|
||||||
|
}
|
||||||
|
}
|
||||||
12
apps/waybar/default.nix
Normal file
12
apps/waybar/default.nix
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
{ config, pkgs, ... }:
|
||||||
|
{
|
||||||
|
programs.waybar = {
|
||||||
|
enable = true;
|
||||||
|
systemd.enable = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
xdg.configFile = {
|
||||||
|
"waybar/config.jsonc".source = ./config.jsonc;
|
||||||
|
"waybar/style.css".source = ./style.css;
|
||||||
|
};
|
||||||
|
}
|
||||||
150
apps/waybar/style.css
Normal file
150
apps/waybar/style.css
Normal file
|
|
@ -0,0 +1,150 @@
|
||||||
|
/* =========================================================
|
||||||
|
Waybar style.css — Catppuccin Mocha (GTK-safe)
|
||||||
|
Unified palette + consistent workspaces + severity states
|
||||||
|
========================================================= */
|
||||||
|
|
||||||
|
/* ---------- Catppuccin Mocha palette ---------- */
|
||||||
|
@define-color base #1e1e2e;
|
||||||
|
@define-color mantle #181825;
|
||||||
|
@define-color crust #11111b;
|
||||||
|
|
||||||
|
@define-color text #cdd6f4;
|
||||||
|
@define-color subtext #bac2de;
|
||||||
|
@define-color muted #9399b2;
|
||||||
|
|
||||||
|
@define-color surface0 #313244;
|
||||||
|
@define-color surface1 #45475a;
|
||||||
|
|
||||||
|
/* Accents */
|
||||||
|
@define-color blue #89b4fa;
|
||||||
|
@define-color green #a6e3a1;
|
||||||
|
@define-color peach #fab387;
|
||||||
|
@define-color yellow #f9e2af;
|
||||||
|
@define-color red #f38ba8;
|
||||||
|
@define-color teal #94e2d5;
|
||||||
|
@define-color lavender #b4befe;
|
||||||
|
|
||||||
|
/* Bar + state backgrounds */
|
||||||
|
@define-color bar_bg rgba(30, 30, 46, 0.88);
|
||||||
|
@define-color warn_bg rgba(249, 226, 175, 0.28);
|
||||||
|
@define-color crit_bg rgba(243, 139, 168, 0.38);
|
||||||
|
|
||||||
|
/* Workspace backgrounds */
|
||||||
|
@define-color ws_hover rgba(137, 180, 250, 0.16);
|
||||||
|
@define-color ws_focus rgba(137, 180, 250, 0.26);
|
||||||
|
|
||||||
|
/* ---------- Global reset ---------- */
|
||||||
|
* {
|
||||||
|
border: none;
|
||||||
|
border-radius: 0;
|
||||||
|
min-height: 0;
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------- Bar ---------- */
|
||||||
|
window#waybar {
|
||||||
|
background: @bar_bg;
|
||||||
|
color: @text;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* =========================================================
|
||||||
|
Workspaces
|
||||||
|
========================================================= */
|
||||||
|
|
||||||
|
#workspaces {
|
||||||
|
padding: 0 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#workspaces button {
|
||||||
|
padding: 0 5px;
|
||||||
|
margin: 0px 0px;
|
||||||
|
color: @subtext;
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
#workspaces button.focused {
|
||||||
|
color: @text;
|
||||||
|
background: @ws_focus;
|
||||||
|
}
|
||||||
|
|
||||||
|
#workspaces button:hover {
|
||||||
|
background: @ws_hover;
|
||||||
|
}
|
||||||
|
|
||||||
|
#workspaces button.urgent {
|
||||||
|
color: @text;
|
||||||
|
background: @crit_bg;
|
||||||
|
}
|
||||||
|
|
||||||
|
#mode {
|
||||||
|
padding: 0 12px;
|
||||||
|
|
||||||
|
background: #f9e2af; /* fully opaque yellow */
|
||||||
|
color: #1e1e2e; /* dark text */
|
||||||
|
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* =========================================================
|
||||||
|
Modules (shared)
|
||||||
|
========================================================= */
|
||||||
|
|
||||||
|
#network,
|
||||||
|
#pulseaudio,
|
||||||
|
#battery,
|
||||||
|
#clock,
|
||||||
|
#cpu,
|
||||||
|
#memory {
|
||||||
|
padding: 0 5px; /* literal spacing — GTK-safe */
|
||||||
|
margin: 0px 0px;
|
||||||
|
background: transparent;
|
||||||
|
color: @text;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Identity colors */
|
||||||
|
#network { color: @blue; }
|
||||||
|
#pulseaudio { color: @peach; }
|
||||||
|
#battery { color: @green; }
|
||||||
|
#clock { color: @text; font-weight: 500; }
|
||||||
|
#cpu { color: @lavender; }
|
||||||
|
#memory { color: @teal; }
|
||||||
|
|
||||||
|
/* =========================================================
|
||||||
|
Severity states (single, consistent approach)
|
||||||
|
========================================================= */
|
||||||
|
|
||||||
|
#battery.warning {
|
||||||
|
background: @warn_bg;
|
||||||
|
color: @text;
|
||||||
|
}
|
||||||
|
|
||||||
|
#battery.critical {
|
||||||
|
background: @crit_bg;
|
||||||
|
color: @text;
|
||||||
|
}
|
||||||
|
|
||||||
|
#network.disconnected {
|
||||||
|
background: @crit_bg;
|
||||||
|
color: @text;
|
||||||
|
}
|
||||||
|
|
||||||
|
#cpu.warning {
|
||||||
|
background: @warn_bg;
|
||||||
|
color: @text;
|
||||||
|
}
|
||||||
|
|
||||||
|
#cpu.critical {
|
||||||
|
background: @crit_bg;
|
||||||
|
color: @text;
|
||||||
|
}
|
||||||
|
|
||||||
|
#memory.warning {
|
||||||
|
background: @warn_bg;
|
||||||
|
color: @text;
|
||||||
|
}
|
||||||
|
|
||||||
|
#memory.critical {
|
||||||
|
background: @crit_bg;
|
||||||
|
color: @text;
|
||||||
|
}
|
||||||
92
flake.lock
generated
Normal file
92
flake.lock
generated
Normal file
|
|
@ -0,0 +1,92 @@
|
||||||
|
{
|
||||||
|
"nodes": {
|
||||||
|
"disko": {
|
||||||
|
"inputs": {
|
||||||
|
"nixpkgs": [
|
||||||
|
"nixpkgs"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1746728054,
|
||||||
|
"narHash": "sha256-eDoSOhxGEm2PykZFa/x9QG5eTH0MJdiJ9aR00VAofXE=",
|
||||||
|
"owner": "nix-community",
|
||||||
|
"repo": "disko",
|
||||||
|
"rev": "ff442f5d1425feb86344c028298548024f21256d",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "nix-community",
|
||||||
|
"ref": "latest",
|
||||||
|
"repo": "disko",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"home-manager": {
|
||||||
|
"inputs": {
|
||||||
|
"nixpkgs": [
|
||||||
|
"nixpkgs"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1758463745,
|
||||||
|
"narHash": "sha256-uhzsV0Q0I9j2y/rfweWeGif5AWe0MGrgZ/3TjpDYdGA=",
|
||||||
|
"owner": "nix-community",
|
||||||
|
"repo": "home-manager",
|
||||||
|
"rev": "3b955f5f0a942f9f60cdc9cacb7844335d0f21c3",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "nix-community",
|
||||||
|
"ref": "release-25.05",
|
||||||
|
"repo": "home-manager",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nixpkgs": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1765762245,
|
||||||
|
"narHash": "sha256-3iXM/zTqEskWtmZs3gqNiVtRTsEjYAedIaLL0mSBsrk=",
|
||||||
|
"owner": "NixOS",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"rev": "c8cfcd6ccd422e41cc631a0b73ed4d5a925c393d",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "NixOS",
|
||||||
|
"ref": "nixos-25.11",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root": {
|
||||||
|
"inputs": {
|
||||||
|
"disko": "disko",
|
||||||
|
"home-manager": "home-manager",
|
||||||
|
"nixpkgs": "nixpkgs",
|
||||||
|
"sops-nix": "sops-nix"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"sops-nix": {
|
||||||
|
"inputs": {
|
||||||
|
"nixpkgs": [
|
||||||
|
"nixpkgs"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1768863606,
|
||||||
|
"narHash": "sha256-1IHAeS8WtBiEo5XiyJBHOXMzECD6aaIOJmpQKzRRl64=",
|
||||||
|
"owner": "Mic92",
|
||||||
|
"repo": "sops-nix",
|
||||||
|
"rev": "c7067be8db2c09ab1884de67ef6c4f693973f4a2",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "Mic92",
|
||||||
|
"repo": "sops-nix",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root": "root",
|
||||||
|
"version": 7
|
||||||
|
}
|
||||||
124
flake.nix
Normal file
124
flake.nix
Normal file
|
|
@ -0,0 +1,124 @@
|
||||||
|
{
|
||||||
|
description = "My NixOS flake";
|
||||||
|
|
||||||
|
inputs = {
|
||||||
|
nixpkgs.url = "github:NixOS/nixpkgs/nixos-25.11";
|
||||||
|
|
||||||
|
disko = {
|
||||||
|
url = "github:nix-community/disko/latest";
|
||||||
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
|
};
|
||||||
|
|
||||||
|
home-manager = {
|
||||||
|
url = "github:nix-community/home-manager/release-25.05";
|
||||||
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
|
};
|
||||||
|
|
||||||
|
sops-nix = {
|
||||||
|
url = "github:Mic92/sops-nix";
|
||||||
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
outputs =
|
||||||
|
{
|
||||||
|
self,
|
||||||
|
nixpkgs,
|
||||||
|
disko,
|
||||||
|
home-manager,
|
||||||
|
sops-nix,
|
||||||
|
...
|
||||||
|
}@inputs:
|
||||||
|
let
|
||||||
|
system = "x86_64-linux";
|
||||||
|
pkgs = nixpkgs.legacyPackages.${system};
|
||||||
|
in
|
||||||
|
{
|
||||||
|
nixosConfigurations =
|
||||||
|
let
|
||||||
|
my-r = import ./languages/r.nix { inherit pkgs; };
|
||||||
|
my-python = import ./languages/python.nix { inherit pkgs; };
|
||||||
|
|
||||||
|
T14pModules = [
|
||||||
|
disko.nixosModules.disko
|
||||||
|
sops-nix.nixosModules.sops
|
||||||
|
home-manager.nixosModules.home-manager
|
||||||
|
|
||||||
|
./hosts/T14p/configuration.nix
|
||||||
|
|
||||||
|
{
|
||||||
|
home-manager.extraSpecialArgs = {
|
||||||
|
inherit inputs my-r my-python;
|
||||||
|
};
|
||||||
|
|
||||||
|
home-manager.useGlobalPkgs = true;
|
||||||
|
home-manager.useUserPackages = true;
|
||||||
|
|
||||||
|
home-manager.users.louis = import ./home/full.nix;
|
||||||
|
home-manager.users.root = import ./home/root.nix;
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
mkT14p = nixpkgs.lib.nixosSystem {
|
||||||
|
inherit system;
|
||||||
|
specialArgs = { inherit inputs; };
|
||||||
|
modules = T14pModules;
|
||||||
|
};
|
||||||
|
|
||||||
|
mkServer =
|
||||||
|
domain: isProd:
|
||||||
|
nixpkgs.lib.nixosSystem {
|
||||||
|
system = "x86_64-linux";
|
||||||
|
specialArgs = { inherit inputs domain isProd; };
|
||||||
|
modules = [
|
||||||
|
inputs.disko.nixosModules.disko
|
||||||
|
sops-nix.nixosModules.sops
|
||||||
|
|
||||||
|
./hosts/hetzner/configuration.nix
|
||||||
|
];
|
||||||
|
};
|
||||||
|
in
|
||||||
|
{
|
||||||
|
T14p = mkT14p;
|
||||||
|
|
||||||
|
hetzner-prod = mkServer "louisclee.com" true;
|
||||||
|
hetzner-test = mkServer "localhost" false;
|
||||||
|
};
|
||||||
|
|
||||||
|
apps.${system} =
|
||||||
|
let
|
||||||
|
target = "root@louisclee.com";
|
||||||
|
|
||||||
|
deployScript = pkgs.writeShellScriptBin "deploy" ''
|
||||||
|
${pkgs.nixos-rebuild}/bin/nixos-rebuild switch \
|
||||||
|
--flake .#hetzner-prod \
|
||||||
|
--target-host ${target} \
|
||||||
|
--use-remote-sudo
|
||||||
|
'';
|
||||||
|
|
||||||
|
initScript = pkgs.writeShellScriptBin "init" ''
|
||||||
|
nix run github:nix-community/nixos-anywhere -- \
|
||||||
|
--flake .#hetzner-prod \
|
||||||
|
--extra-files ./hosts/hetzner/extra-files \
|
||||||
|
${target}
|
||||||
|
'';
|
||||||
|
in
|
||||||
|
{
|
||||||
|
deploy = {
|
||||||
|
type = "app";
|
||||||
|
program = "${deployScript}/bin/deploy";
|
||||||
|
};
|
||||||
|
|
||||||
|
init = {
|
||||||
|
type = "app";
|
||||||
|
program = "${initScript}/bin/init";
|
||||||
|
};
|
||||||
|
|
||||||
|
vm = {
|
||||||
|
type = "app";
|
||||||
|
program = "${self.nixosConfigurations.hetzner-test.config.system.build.vm}/bin/run-webserver-vm";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
86
home/full.nix
Normal file
86
home/full.nix
Normal file
|
|
@ -0,0 +1,86 @@
|
||||||
|
{ config, pkgs, inputs, my-r, my-python,... }: {
|
||||||
|
home.username = "louis";
|
||||||
|
home.homeDirectory = "/home/louis";
|
||||||
|
|
||||||
|
home.enableNixpkgsReleaseCheck = false;
|
||||||
|
|
||||||
|
imports = [
|
||||||
|
../apps/neovim
|
||||||
|
../apps/sway
|
||||||
|
../apps/waybar
|
||||||
|
../apps/fuzzel
|
||||||
|
#../modules/model-downloads.nix
|
||||||
|
];
|
||||||
|
|
||||||
|
home.packages = with pkgs; [
|
||||||
|
fzf
|
||||||
|
chromium
|
||||||
|
poppler-utils
|
||||||
|
my-r.env
|
||||||
|
my-r.rstudio
|
||||||
|
my-python
|
||||||
|
which
|
||||||
|
ripgrep
|
||||||
|
kitty
|
||||||
|
gcc
|
||||||
|
gnumake
|
||||||
|
kdePackages.okular
|
||||||
|
quarto
|
||||||
|
julia
|
||||||
|
wechat
|
||||||
|
wemeet
|
||||||
|
zotero
|
||||||
|
sqlite
|
||||||
|
anki-bin
|
||||||
|
sqlitebrowser
|
||||||
|
dig
|
||||||
|
ghostty
|
||||||
|
inkscape
|
||||||
|
tig
|
||||||
|
wofi
|
||||||
|
grim
|
||||||
|
slurp
|
||||||
|
wl-clipboard
|
||||||
|
brightnessctl
|
||||||
|
pulseaudio
|
||||||
|
neofetch
|
||||||
|
llama-cpp
|
||||||
|
];
|
||||||
|
|
||||||
|
my.apps.fuzzel.enable = true;
|
||||||
|
|
||||||
|
programs.fish = {
|
||||||
|
enable = true;
|
||||||
|
interactiveShellInit = ''
|
||||||
|
export QUARTO_R="/home/louis/.nix-profile/bin/R";
|
||||||
|
export EDITOR="nvim";
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
#programs.zsh = {
|
||||||
|
# enable = true;
|
||||||
|
# enableCompletion = true;
|
||||||
|
# autosuggestion.enable = true;
|
||||||
|
# syntaxHighlighting.enable = true;
|
||||||
|
# sessionVariables = {
|
||||||
|
# QUARTO_R = "/home/louis/.nix-profile/bin/R";
|
||||||
|
# EDITOR = "nvim";
|
||||||
|
# };
|
||||||
|
#};
|
||||||
|
|
||||||
|
programs.git = {
|
||||||
|
enable = true;
|
||||||
|
userName = "Louis Chih-Ming Lee";
|
||||||
|
userEmail = "louis@louisclee.com";
|
||||||
|
};
|
||||||
|
|
||||||
|
#modelDownloads = {
|
||||||
|
# enable = true;
|
||||||
|
# dir = "${config.home.homeDirectory}/data/ai/models";
|
||||||
|
# urls = [
|
||||||
|
# "https://huggingface.co/bartowski/Meta-Llama-3.1-8B-Instruct-GGUF/resolve/main/Meta-Llama-3.1-8B-Instruct-Q4_K_M.gguf"
|
||||||
|
# ];
|
||||||
|
#};
|
||||||
|
|
||||||
|
home.stateVersion = "25.05";
|
||||||
|
}
|
||||||
12
home/root.nix
Normal file
12
home/root.nix
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
{ config, pkgs, inputs, ... }:
|
||||||
|
{
|
||||||
|
home.username = "root";
|
||||||
|
|
||||||
|
home.enableNixpkgsReleaseCheck = false;
|
||||||
|
|
||||||
|
imports = [
|
||||||
|
./../apps/neovim
|
||||||
|
];
|
||||||
|
|
||||||
|
home.stateVersion = "25.05";
|
||||||
|
}
|
||||||
275
hosts/T14p/configuration.nix
Normal file
275
hosts/T14p/configuration.nix
Normal file
|
|
@ -0,0 +1,275 @@
|
||||||
|
# Edit this configuration file to define what should be installed on
|
||||||
|
# your system. Help is available in the configuration.nix(5) man page, on
|
||||||
|
# https://search.nixos.org/options and in the NixOS manual (`nixos-help`).
|
||||||
|
|
||||||
|
{
|
||||||
|
inputs,
|
||||||
|
config,
|
||||||
|
lib,
|
||||||
|
pkgs,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
{
|
||||||
|
imports = [
|
||||||
|
# Include the results of the hardware scan.
|
||||||
|
./hardware-configuration.nix
|
||||||
|
#./impermanence.nix { inherit lib; }
|
||||||
|
./disko.nix
|
||||||
|
./network.nix
|
||||||
|
];
|
||||||
|
|
||||||
|
nix.settings.experimental-features = [
|
||||||
|
"nix-command"
|
||||||
|
"flakes"
|
||||||
|
];
|
||||||
|
|
||||||
|
# Use the systemd-boot EFI boot loader.
|
||||||
|
boot.loader.systemd-boot.enable = true;
|
||||||
|
boot.loader.efi.canTouchEfiVariables = true;
|
||||||
|
|
||||||
|
boot.kernelPackages = pkgs.linuxPackages_latest;
|
||||||
|
|
||||||
|
networking.hostName = "T14p"; # Define your hostname.
|
||||||
|
# Pick only one of the below networking options.
|
||||||
|
# networking.wireless.enable = true; # Enables wireless support via wpa_supplicant.
|
||||||
|
networking.networkmanager.enable = true; # Easiest to use and most distros use this by default.
|
||||||
|
|
||||||
|
services.mullvad-vpn.enable = true;
|
||||||
|
|
||||||
|
sops = {
|
||||||
|
defaultSopsFile = ./../../secrets.yaml;
|
||||||
|
defaultSopsFormat = "yaml";
|
||||||
|
age.keyFile = "/home/louis/.config/sops/age/keys.txt";
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
hardware.enableAllFirmware = true;
|
||||||
|
|
||||||
|
hardware.graphics = {
|
||||||
|
enable = true;
|
||||||
|
extraPackages = with pkgs; [
|
||||||
|
mesa
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
hardware.bluetooth = {
|
||||||
|
enable = true;
|
||||||
|
powerOnBoot = true;
|
||||||
|
#settings = {
|
||||||
|
# General = {
|
||||||
|
# Experimental = true;
|
||||||
|
# FastConnectable = true;
|
||||||
|
# };
|
||||||
|
# Policy = {
|
||||||
|
# AutoEnable = true;
|
||||||
|
# };
|
||||||
|
#};
|
||||||
|
};
|
||||||
|
|
||||||
|
# Set your time zone.
|
||||||
|
time.timeZone = "Europe/Amsterdam";
|
||||||
|
|
||||||
|
# Configure network proxy if necessary
|
||||||
|
# networking.proxy.default = "http://user:password@proxy:port/";
|
||||||
|
# networking.proxy.noProxy = "127.0.0.1,localhost,internal.domain";
|
||||||
|
|
||||||
|
# Select internationalisation properties.
|
||||||
|
i18n = {
|
||||||
|
defaultLocale = "en_US.UTF-8";
|
||||||
|
extraLocales = [
|
||||||
|
"zh_TW.UTF-8/UTF-8"
|
||||||
|
"zh_CN.UTF-8/UTF-8"
|
||||||
|
"nl_NL.UTF-8/UTF-8"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
i18n.inputMethod = {
|
||||||
|
type = "fcitx5";
|
||||||
|
enable = true;
|
||||||
|
fcitx5.addons = with pkgs; [
|
||||||
|
fcitx5-gtk
|
||||||
|
fcitx5-rime
|
||||||
|
fcitx5-chewing
|
||||||
|
qt6Packages.fcitx5-chinese-addons
|
||||||
|
rime-data
|
||||||
|
librime
|
||||||
|
];
|
||||||
|
fcitx5.waylandFrontend = true;
|
||||||
|
};
|
||||||
|
environment.variables = {
|
||||||
|
GTK_IM_MODULE = "fcitx";
|
||||||
|
QT_IM_MODULE = "fcitx";
|
||||||
|
XMODIFIERS = "@im=fcitx";
|
||||||
|
GLFW_IM_MODULE = "fcitx";
|
||||||
|
SDL_IM_MODULE = "fcitx";
|
||||||
|
MOZ_ENABLE_WAYLAND = 1;
|
||||||
|
QT_QPA_PLATFORM = "wayland";
|
||||||
|
};
|
||||||
|
|
||||||
|
# electron blurring in wayland
|
||||||
|
environment.sessionVariables = {
|
||||||
|
NIXOS_OZONE_WL = "1";
|
||||||
|
};
|
||||||
|
|
||||||
|
console = {
|
||||||
|
font = "Lat2-Terminus16";
|
||||||
|
#keyMap = "us";
|
||||||
|
useXkbConfig = true; # use xkb.options in tty.
|
||||||
|
};
|
||||||
|
|
||||||
|
# Enable the X11 windowing system.
|
||||||
|
services.xserver.enable = true;
|
||||||
|
|
||||||
|
#services.displayManager.cosmic-greeter.enable = true;
|
||||||
|
services.displayManager.gdm.enable = true;
|
||||||
|
services.desktopManager.cosmic.enable = true;
|
||||||
|
|
||||||
|
programs.sway = {
|
||||||
|
enable = true;
|
||||||
|
wrapperFeatures.gtk = true;
|
||||||
|
extraPackages = with pkgs; [
|
||||||
|
adwaita-icon-theme
|
||||||
|
gnome-themes-extra
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
fonts.packages = with pkgs; [
|
||||||
|
lxgw-fusionkai
|
||||||
|
noto-fonts
|
||||||
|
noto-fonts-cjk-sans
|
||||||
|
noto-fonts-cjk-serif
|
||||||
|
winePackages.fonts
|
||||||
|
noto-fonts-color-emoji
|
||||||
|
nerd-fonts.fira-code
|
||||||
|
];
|
||||||
|
|
||||||
|
services.keyd = {
|
||||||
|
enable = true;
|
||||||
|
keyboards = {
|
||||||
|
default = {
|
||||||
|
ids = [ "*" ];
|
||||||
|
settings = {
|
||||||
|
main = {
|
||||||
|
capslock = "layer(control)";
|
||||||
|
control = "capslock";
|
||||||
|
leftmeta = "layer(alt)";
|
||||||
|
leftalt = "layer(meta)";
|
||||||
|
rightalt = "esc";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
hhkb = {
|
||||||
|
ids = [ "04fe:0021:f2a164d2" ];
|
||||||
|
settings = { };
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
# Configure keymap in X11
|
||||||
|
# services.xserver.xkb.layout = "us";
|
||||||
|
# services.xserver.xkb.options = "eurosign:e,caps:escape";
|
||||||
|
|
||||||
|
# Enable CUPS to print documents.
|
||||||
|
services.printing.enable = true;
|
||||||
|
|
||||||
|
# Enable sound.
|
||||||
|
# services.pulseaudio.enable = true;
|
||||||
|
# OR
|
||||||
|
services.pipewire = {
|
||||||
|
enable = true;
|
||||||
|
pulse.enable = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
# Enable touchpad support (enabled default in most desktopManager).
|
||||||
|
services.libinput.enable = true;
|
||||||
|
|
||||||
|
# Define a user account. Don't forget to set a password with ‘passwd’.
|
||||||
|
users.users.louis = {
|
||||||
|
isNormalUser = true;
|
||||||
|
extraGroups = [
|
||||||
|
"wheel"
|
||||||
|
"networkmanager"
|
||||||
|
"video"
|
||||||
|
];
|
||||||
|
shell = pkgs.fish;
|
||||||
|
ignoreShellProgramCheck = true;
|
||||||
|
packages = with pkgs; [
|
||||||
|
keyd
|
||||||
|
tree
|
||||||
|
wl-clipboard
|
||||||
|
mako
|
||||||
|
killall
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
programs.firefox.enable = true;
|
||||||
|
|
||||||
|
# List packages installed in system profile.
|
||||||
|
# You can use https://search.nixos.org/ to find more packages (and options).
|
||||||
|
environment.systemPackages = with pkgs; [
|
||||||
|
vim # Do not forget to add an editor to edit configuration.nix! The Nano editor is also installed by default.
|
||||||
|
kdePackages.kdeconnect-kde
|
||||||
|
usbutils
|
||||||
|
wget
|
||||||
|
neovim
|
||||||
|
acpi
|
||||||
|
texliveFull
|
||||||
|
zathura
|
||||||
|
libreoffice
|
||||||
|
htop
|
||||||
|
ranger
|
||||||
|
teams-for-linux
|
||||||
|
gcc
|
||||||
|
gnumake
|
||||||
|
mullvad-vpn
|
||||||
|
mullvad
|
||||||
|
sops
|
||||||
|
age
|
||||||
|
ssh-to-age
|
||||||
|
];
|
||||||
|
|
||||||
|
# Some programs need SUID wrappers, can be configured further or are
|
||||||
|
# started in user sessions.
|
||||||
|
programs.mtr.enable = true;
|
||||||
|
programs.gnupg.agent = {
|
||||||
|
enable = true;
|
||||||
|
enableSSHSupport = true;
|
||||||
|
};
|
||||||
|
nixpkgs.config.allowUnfree = true;
|
||||||
|
|
||||||
|
# List services that you want to enable:
|
||||||
|
|
||||||
|
# Enable the OpenSSH daemon.
|
||||||
|
services.openssh.enable = true;
|
||||||
|
|
||||||
|
# Open ports in the firewall.
|
||||||
|
# networking.firewall.allowedTCPPorts = [ ... ];
|
||||||
|
# networking.firewall.allowedUDPPorts = [ ... ];
|
||||||
|
# Or disable the firewall altogether.
|
||||||
|
networking.firewall.enable = false;
|
||||||
|
|
||||||
|
# Copy the NixOS configuration file and link it from the resulting system
|
||||||
|
# (/run/current-system/configuration.nix). This is useful in case you
|
||||||
|
# accidentally delete configuration.nix.
|
||||||
|
#system.copySystemConfiguration = true;
|
||||||
|
|
||||||
|
# This option defines the first version of NixOS you have installed on this particular machine,
|
||||||
|
# and is used to maintain compatibility with application data (e.g. databases) created on older NixOS versions.
|
||||||
|
#
|
||||||
|
# Most users should NEVER change this value after the initial install, for any reason,
|
||||||
|
# even if you've upgraded your system to a new NixOS release.
|
||||||
|
#
|
||||||
|
# This value does NOT affect the Nixpkgs version your packages and OS are pulled from,
|
||||||
|
# so changing it will NOT upgrade your system - see https://nixos.org/manual/nixos/stable/#sec-upgrading for how
|
||||||
|
# to actually do that.
|
||||||
|
#
|
||||||
|
# This value being lower than the current NixOS release does NOT mean your system is
|
||||||
|
# out of date, out of support, or vulnerable.
|
||||||
|
#
|
||||||
|
# Do NOT change this value unless you have manually inspected all the changes it would make to your configuration,
|
||||||
|
# and migrated your data accordingly.
|
||||||
|
#
|
||||||
|
# For more information, see `man configuration.nix` or https://nixos.org/manual/nixos/stable/options#opt-system.stateVersion .
|
||||||
|
system.stateVersion = "25.05"; # Did you read the comment?
|
||||||
|
|
||||||
|
}
|
||||||
70
hosts/T14p/disko.nix
Normal file
70
hosts/T14p/disko.nix
Normal file
|
|
@ -0,0 +1,70 @@
|
||||||
|
{
|
||||||
|
disko.devices = {
|
||||||
|
disk = {
|
||||||
|
main = {
|
||||||
|
type = "disk";
|
||||||
|
device = "/dev/nvme1n1";
|
||||||
|
content = {
|
||||||
|
type = "gpt";
|
||||||
|
partitions = {
|
||||||
|
ESP = {
|
||||||
|
size = "512M";
|
||||||
|
type = "EF00";
|
||||||
|
content = {
|
||||||
|
type = "filesystem";
|
||||||
|
format = "vfat";
|
||||||
|
mountpoint = "/boot";
|
||||||
|
mountOptions = [ "umask=0077" ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
luks = {
|
||||||
|
size = "100%";
|
||||||
|
content = {
|
||||||
|
type = "luks";
|
||||||
|
name = "crypted";
|
||||||
|
# disable settings.keyFile if you want to use interactive password entry
|
||||||
|
#passwordFile = "/tmp/secret.key"; # Interactive
|
||||||
|
settings = {
|
||||||
|
allowDiscards = true;
|
||||||
|
#keyFile = "/tmp/secret.key";
|
||||||
|
};
|
||||||
|
#additionalKeyFiles = [ "/tmp/additionalSecret.key" ];
|
||||||
|
content = {
|
||||||
|
type = "btrfs";
|
||||||
|
extraArgs = [ "-f" ];
|
||||||
|
subvolumes = {
|
||||||
|
"@root" = {
|
||||||
|
mountpoint = "/";
|
||||||
|
mountOptions = [
|
||||||
|
"compress=zstd"
|
||||||
|
"noatime"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
"@persist" = {
|
||||||
|
mountpoint = "/persist";
|
||||||
|
mountOptions = [
|
||||||
|
"compress=zstd"
|
||||||
|
"noatime"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
"@nix" = {
|
||||||
|
mountpoint = "/nix";
|
||||||
|
mountOptions = [
|
||||||
|
"compress=zstd"
|
||||||
|
"noatime"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
"@swap" = {
|
||||||
|
mountpoint = "/.swapvol";
|
||||||
|
swap.swapfile.size = "20G";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
26
hosts/T14p/hardware-configuration.nix
Normal file
26
hosts/T14p/hardware-configuration.nix
Normal file
|
|
@ -0,0 +1,26 @@
|
||||||
|
# Do not modify this file! It was generated by ‘nixos-generate-config’
|
||||||
|
# and may be overwritten by future invocations. Please make changes
|
||||||
|
# to /etc/nixos/configuration.nix instead.
|
||||||
|
{ config, lib, pkgs, modulesPath, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
imports =
|
||||||
|
[ (modulesPath + "/installer/scan/not-detected.nix")
|
||||||
|
];
|
||||||
|
|
||||||
|
boot.initrd.availableKernelModules = [ "xhci_pci" "thunderbolt" "nvme" "usb_storage" "sd_mod" ];
|
||||||
|
boot.initrd.kernelModules = [ ];
|
||||||
|
boot.kernelModules = [ "kvm-intel" ];
|
||||||
|
boot.extraModulePackages = [ ];
|
||||||
|
|
||||||
|
# Enables DHCP on each ethernet and wireless interface. In case of scripted networking
|
||||||
|
# (the default) this is the recommended approach. When using systemd-networkd it's
|
||||||
|
# still possible to use this option, but it's recommended to use it in conjunction
|
||||||
|
# with explicit per-interface declarations with `networking.interfaces.<interface>.useDHCP`.
|
||||||
|
networking.useDHCP = lib.mkDefault true;
|
||||||
|
# networking.interfaces.enp0s31f6.useDHCP = lib.mkDefault true;
|
||||||
|
# networking.interfaces.wlp0s20f3.useDHCP = lib.mkDefault true;
|
||||||
|
|
||||||
|
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
|
||||||
|
hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
|
||||||
|
}
|
||||||
56
hosts/T14p/impermanence.nix
Normal file
56
hosts/T14p/impermanence.nix
Normal file
|
|
@ -0,0 +1,56 @@
|
||||||
|
{ lib, ... }:
|
||||||
|
let
|
||||||
|
impermanence = builtins.fetchTarball "https://github.com/nix-community/impermanence/archive/master.tar.gz";
|
||||||
|
in
|
||||||
|
{
|
||||||
|
boot.initrd.postResumeCommands = lib.mkAfter ''
|
||||||
|
mkdir /btrfs_tmp
|
||||||
|
mount /dev/mapper/crypted /btrfs_tmp
|
||||||
|
if [[ -e /btrfs_tmp/@root ]]; then
|
||||||
|
mkdir -p /btrfs_tmp/@old_roots
|
||||||
|
timestamp=$(date --date="@$(stat -c %Y /btrfs_tmp/root)" "+%Y-%m-%-d_%H:%M:%S")
|
||||||
|
mv /btrfs_tmp/@root "/btrfs_tmp/@old_roots/$timestamp"
|
||||||
|
fi
|
||||||
|
|
||||||
|
delete_subvolume_recursively() {
|
||||||
|
IFS=$'\n'
|
||||||
|
for i in $(btrfs subvolume list -o "$1" | cut -f 9- -d ' '); do
|
||||||
|
delete_subvolume_recursively "/btrfs_tmp/$i"
|
||||||
|
done
|
||||||
|
btrfs subvolume delete "$1"
|
||||||
|
}
|
||||||
|
|
||||||
|
for i in $(find /btrfs_tmp/@old_roots/ -maxdepth 1 -mtime +10); do
|
||||||
|
delete_subvolume_recursively "$i"
|
||||||
|
done
|
||||||
|
|
||||||
|
btrfs subvolume create /btrfs_tmp/@root
|
||||||
|
umount /btrfs_tmp
|
||||||
|
'';
|
||||||
|
|
||||||
|
imports = [ "${impermanence}/nixos.nix" ];
|
||||||
|
|
||||||
|
environment.persistence."/persist" = {
|
||||||
|
enable = true;
|
||||||
|
hideMounts = true;
|
||||||
|
directories = [
|
||||||
|
"/var/log"
|
||||||
|
"/var/lib/bluetooth"
|
||||||
|
"/var/lib/nixox"
|
||||||
|
"/var/lib/systemd/coredump"
|
||||||
|
"/etc/NetworkManager/system-connections"
|
||||||
|
];
|
||||||
|
files = [
|
||||||
|
"/etc/machine-id"
|
||||||
|
];
|
||||||
|
users.louis = {
|
||||||
|
directories = [
|
||||||
|
"Documents"
|
||||||
|
"Downloads"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
fileSystems."/persist".neededForBoot = true;
|
||||||
|
|
||||||
|
}
|
||||||
34
hosts/T14p/leiden.crt
Normal file
34
hosts/T14p/leiden.crt
Normal file
|
|
@ -0,0 +1,34 @@
|
||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIF3jCCA8agAwIBAgIQAf1tMPyjylGoG7xkDjUDLTANBgkqhkiG9w0BAQwFADCB
|
||||||
|
iDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0pl
|
||||||
|
cnNleSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNV
|
||||||
|
BAMTJVVTRVJUcnVzdCBSU0EgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAw
|
||||||
|
MjAxMDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBiDELMAkGA1UEBhMCVVMxEzARBgNV
|
||||||
|
BAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVU
|
||||||
|
aGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBSU0EgQ2Vy
|
||||||
|
dGlmaWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK
|
||||||
|
AoICAQCAEmUXNg7D2wiz0KxXDXbtzSfTTK1Qg2HiqiBNCS1kCdzOiZ/MPans9s/B
|
||||||
|
3PHTsdZ7NygRK0faOca8Ohm0X6a9fZ2jY0K2dvKpOyuR+OJv0OwWIJAJPuLodMkY
|
||||||
|
tJHUYmTbf6MG8YgYapAiPLz+E/CHFHv25B+O1ORRxhFnRghRy4YUVD+8M/5+bJz/
|
||||||
|
Fp0YvVGONaanZshyZ9shZrHUm3gDwFA66Mzw3LyeTP6vBZY1H1dat//O+T23LLb2
|
||||||
|
VN3I5xI6Ta5MirdcmrS3ID3KfyI0rn47aGYBROcBTkZTmzNg95S+UzeQc0PzMsNT
|
||||||
|
79uq/nROacdrjGCT3sTHDN/hMq7MkztReJVni+49Vv4M0GkPGw/zJSZrM233bkf6
|
||||||
|
c0Plfg6lZrEpfDKEY1WJxA3Bk1QwGROs0303p+tdOmw1XNtB1xLaqUkL39iAigmT
|
||||||
|
Yo61Zs8liM2EuLE/pDkP2QKe6xJMlXzzawWpXhaDzLhn4ugTncxbgtNMs+1b/97l
|
||||||
|
c6wjOy0AvzVVdAlJ2ElYGn+SNuZRkg7zJn0cTRe8yexDJtC/QV9AqURE9JnnV4ee
|
||||||
|
UB9XVKg+/XRjL7FQZQnmWEIuQxpMtPAlR1n6BB6T1CZGSlCBst6+eLf8ZxXhyVeE
|
||||||
|
Hg9j1uliutZfVS7qXMYoCAQlObgOK6nyTJccBz8NUvXt7y+CDwIDAQABo0IwQDAd
|
||||||
|
BgNVHQ4EFgQUU3m/WqorSs9UgOHYm8Cd8rIDZsswDgYDVR0PAQH/BAQDAgEGMA8G
|
||||||
|
A1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAFzUfA3P9wF9QZllDHPF
|
||||||
|
Up/L+M+ZBn8b2kMVn54CVVeWFPFSPCeHlCjtHzoBN6J2/FNQwISbxmtOuowhT6KO
|
||||||
|
VWKR82kV2LyI48SqC/3vqOlLVSoGIG1VeCkZ7l8wXEskEVX/JJpuXior7gtNn3/3
|
||||||
|
ATiUFJVDBwn7YKnuHKsSjKCaXqeYalltiz8I+8jRRa8YFWSQEg9zKC7F4iRO/Fjs
|
||||||
|
8PRF/iKz6y+O0tlFYQXBl2+odnKPi4w2r78NBc5xjeambx9spnFixdjQg3IM8WcR
|
||||||
|
iQycE0xyNN+81XHfqnHd4blsjDwSXWXavVcStkNr/+XeTWYRUc+ZruwXtuhxkYze
|
||||||
|
Sf7dNXGiFSeUHM9h4ya7b6NnJSFd5t0dCy5oGzuCr+yDZ4XUmFF0sbmZgIn/f3gZ
|
||||||
|
XHlKYC6SQK5MNyosycdiyA5d9zZbyuAlJQG03RoHnHcAP9Dc1ew91Pq7P8yF1m9/
|
||||||
|
qS3fuQL39ZeatTXaw2ewh0qpKJ4jjv9cJ2vhsE/zB+4ALtRZh8tSQZXq9EfX7mRB
|
||||||
|
VXyNWQKV3WKdwrnuWih0hKWbt5DHDAff9Yk2dDLWKMGwsAvgnEzDHNb842m1R0aB
|
||||||
|
L6KCq9NjRHDEjf8tM7qtj3u1cIiuPhnPQCjY/MiQu12ZIvVS5ljFH4gxQ+6IHdfG
|
||||||
|
jjxDah2nGN59PRbxYvnKkKj9
|
||||||
|
-----END CERTIFICATE-----
|
||||||
83
hosts/T14p/network.nix
Normal file
83
hosts/T14p/network.nix
Normal file
|
|
@ -0,0 +1,83 @@
|
||||||
|
{
|
||||||
|
pkgs,
|
||||||
|
lib,
|
||||||
|
config,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
let
|
||||||
|
wifi = ssid: alias: priority: {
|
||||||
|
sops.secrets."wifi_${alias}" = { };
|
||||||
|
sops.templates."wifi_${alias}.nmconnection" = {
|
||||||
|
path = "/etc/NetworkManager/system-connections/wifi_${ssid}.nmconnection";
|
||||||
|
owner = "root";
|
||||||
|
group = "root";
|
||||||
|
mode = "0600";
|
||||||
|
content = ''
|
||||||
|
[connection]
|
||||||
|
id=${ssid}
|
||||||
|
type=wifi
|
||||||
|
autoconnect=true
|
||||||
|
autoconnect-priority=${toString priority}
|
||||||
|
|
||||||
|
[wifi]
|
||||||
|
ssid=${ssid}
|
||||||
|
mode=infrastructure
|
||||||
|
|
||||||
|
[wifi-security]
|
||||||
|
key-mgmt=wpa-psk
|
||||||
|
psk=${config.sops.placeholder."wifi_${alias}"}
|
||||||
|
|
||||||
|
[ipv4]
|
||||||
|
method=auto
|
||||||
|
|
||||||
|
[ipv6]
|
||||||
|
addr-gen-mode=default
|
||||||
|
method=auto
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
in
|
||||||
|
lib.mkMerge [
|
||||||
|
(wifi "Ziggo966936B" "home" 100)
|
||||||
|
{
|
||||||
|
sops.secrets.wifi_leiden_identity = { };
|
||||||
|
sops.secrets.wifi_leiden_password = { };
|
||||||
|
sops.templates."wifi_eduroam.nmconnection" = {
|
||||||
|
path = "/etc/NetworkManager/system-connections/eduroam.nmconnection";
|
||||||
|
|
||||||
|
owner = "root";
|
||||||
|
group = "root";
|
||||||
|
mode = "0600";
|
||||||
|
|
||||||
|
content = ''
|
||||||
|
[connection]
|
||||||
|
id=eduroam
|
||||||
|
type=wifi
|
||||||
|
|
||||||
|
[wifi]
|
||||||
|
ssid=eduroam
|
||||||
|
mode=infrastructure
|
||||||
|
|
||||||
|
[wifi-security]
|
||||||
|
key-mgmt=wpa-eap
|
||||||
|
|
||||||
|
[802-1x]
|
||||||
|
eap=peap
|
||||||
|
identity=${config.sops.placeholder.wifi_leiden_identity}
|
||||||
|
password=${config.sops.placeholder.wifi_leiden_password}
|
||||||
|
anonymous-identity=anonymous@leidenuniv.nl
|
||||||
|
phase2-auth=mschapv2
|
||||||
|
ca-cert=${./leiden.crt}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
}
|
||||||
|
{
|
||||||
|
# Run nmcli reload after every switch
|
||||||
|
system.activationScripts.nm-reload = {
|
||||||
|
text = ''
|
||||||
|
${pkgs.networkmanager}/bin/nmcli connection reload || true
|
||||||
|
'';
|
||||||
|
deps = [ ];
|
||||||
|
};
|
||||||
|
}
|
||||||
|
]
|
||||||
64
hosts/hetzner/configuration.nix
Normal file
64
hosts/hetzner/configuration.nix
Normal file
|
|
@ -0,0 +1,64 @@
|
||||||
|
{
|
||||||
|
pkgs,
|
||||||
|
lib,
|
||||||
|
domain,
|
||||||
|
isProd,
|
||||||
|
inputs,
|
||||||
|
config,
|
||||||
|
modulesPath,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
{
|
||||||
|
|
||||||
|
imports = [
|
||||||
|
(modulesPath + "/installer/scan/not-detected.nix")
|
||||||
|
(modulesPath + "/profiles/qemu-guest.nix")
|
||||||
|
|
||||||
|
./disko-config.nix
|
||||||
|
./secret.nix
|
||||||
|
./media.nix
|
||||||
|
./nginx.nix
|
||||||
|
./immich.nix
|
||||||
|
./forego.nix
|
||||||
|
|
||||||
|
# ./vm.nix
|
||||||
|
];
|
||||||
|
|
||||||
|
system.stateVersion = "25.11";
|
||||||
|
|
||||||
|
environment.systemPackages = with pkgs; [
|
||||||
|
vim
|
||||||
|
cifs-utils
|
||||||
|
btrfs-progs
|
||||||
|
forgejo
|
||||||
|
];
|
||||||
|
|
||||||
|
nix.settings.experimental-features = [
|
||||||
|
"nix-command"
|
||||||
|
"flakes"
|
||||||
|
];
|
||||||
|
|
||||||
|
boot.loader.grub = {
|
||||||
|
# enable = true;
|
||||||
|
efiSupport = true;
|
||||||
|
efiInstallAsRemovable = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
services.openssh.enable = true;
|
||||||
|
users.users.root.openssh.authorizedKeys.keys = [
|
||||||
|
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDBUxBUar3CyZCZTet3s8s28Pu1d0viuDe6YoMQBVdFB louis@T14p"
|
||||||
|
];
|
||||||
|
|
||||||
|
networking.hostName = "webserver";
|
||||||
|
networking.firewall.allowedTCPPorts = [
|
||||||
|
80
|
||||||
|
443
|
||||||
|
22
|
||||||
|
];
|
||||||
|
|
||||||
|
|
||||||
|
security.acme = lib.mkIf isProd {
|
||||||
|
acceptTerms = true;
|
||||||
|
defaults.email = "admin@${domain}";
|
||||||
|
};
|
||||||
|
}
|
||||||
86
hosts/hetzner/disko-config.nix
Normal file
86
hosts/hetzner/disko-config.nix
Normal file
|
|
@ -0,0 +1,86 @@
|
||||||
|
{ lib, ... }:
|
||||||
|
let
|
||||||
|
disk-id = "scsi-0QEMU_QEMU_HARDDISK_110162268";
|
||||||
|
data-id = "scsi-0HC_Volume_104473479";
|
||||||
|
in
|
||||||
|
{
|
||||||
|
disko.devices = {
|
||||||
|
|
||||||
|
# --- DISK 1: MAIN OS (38GB) ---
|
||||||
|
disk.main = {
|
||||||
|
# You were right! This IS the correct ID for the 38GB drive.
|
||||||
|
device = "/dev/disk/by-id/${disk-id}";
|
||||||
|
type = "disk";
|
||||||
|
content = {
|
||||||
|
type = "gpt";
|
||||||
|
partitions = {
|
||||||
|
boot = {
|
||||||
|
size = "1M";
|
||||||
|
type = "EF02";
|
||||||
|
priority = 1;
|
||||||
|
};
|
||||||
|
ESP = {
|
||||||
|
size = "512M";
|
||||||
|
type = "EF00";
|
||||||
|
content = {
|
||||||
|
type = "filesystem";
|
||||||
|
format = "vfat";
|
||||||
|
mountpoint = "/boot";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
root = {
|
||||||
|
size = "100%";
|
||||||
|
content = {
|
||||||
|
type = "filesystem";
|
||||||
|
format = "ext4";
|
||||||
|
mountpoint = "/";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
disk.volume = {
|
||||||
|
# This is the ID for your volume (from your ls output)
|
||||||
|
device = "/dev/disk/by-id/${disk-id}";
|
||||||
|
type = "disk";
|
||||||
|
content = {
|
||||||
|
type = "gpt";
|
||||||
|
partitions = {
|
||||||
|
data = {
|
||||||
|
size = "100%";
|
||||||
|
content = {
|
||||||
|
type = "btrfs";
|
||||||
|
extraArgs = [ "-f" ];
|
||||||
|
mountpoint = "/mnt/data";
|
||||||
|
subvolumes = {
|
||||||
|
"@postgresql" = {
|
||||||
|
mountpoint = "/mnt/data/postgresql";
|
||||||
|
mountOptions = [
|
||||||
|
"nodatacow"
|
||||||
|
"noatime"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
"@forgejo" = {
|
||||||
|
mountpoint = "/mnt/data/forgejo";
|
||||||
|
mountOptions = [
|
||||||
|
"compress=zstd"
|
||||||
|
"noatime"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
"@immich" = {
|
||||||
|
mountpoint = "/mnt/data/immich";
|
||||||
|
mountOptions = [
|
||||||
|
"compress=zstd"
|
||||||
|
"noatime"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
71
hosts/hetzner/filesystem.nix
Normal file
71
hosts/hetzner/filesystem.nix
Normal file
|
|
@ -0,0 +1,71 @@
|
||||||
|
{ lib, config, ... }:
|
||||||
|
let
|
||||||
|
volume-id = "scsi-0HC_Volume_104473479";
|
||||||
|
in
|
||||||
|
{
|
||||||
|
systemd.tmpfiles.rules = [
|
||||||
|
"d /mnt/ 0755 root root -"
|
||||||
|
|
||||||
|
"d /mnt/box 0770 root root -"
|
||||||
|
|
||||||
|
"d /mnt/box/immich 0770 immich immich -"
|
||||||
|
"d /mnt/box/immich 0770 immich immich -"
|
||||||
|
"d /mnt/box/immich/library 0770 immich immich -"
|
||||||
|
"d /mnt/box/immich/upload 0770 immich immich -"
|
||||||
|
"d /mnt/box/immich/thumbs 0770 immich immich -"
|
||||||
|
"d /mnt/box/immich/encoded-video 0770 immich immich -"
|
||||||
|
"d /mnt/box/immich/profile 0770 immich immich -"
|
||||||
|
"d /mnt/box/immich/backups 0770 immich immich -"
|
||||||
|
|
||||||
|
"d /mnt/volume 0777 root root -"
|
||||||
|
"d /mnt/volume/postgresql 0700 postgres postgres -"
|
||||||
|
"d /mnt/volume/forgejo 0750 forgejo forgejo -"
|
||||||
|
|
||||||
|
"d /mnt/volume/immich 0750 immich immich -"
|
||||||
|
];
|
||||||
|
|
||||||
|
fileSystems."/mnt/data/postgres" = {
|
||||||
|
device = "/dev/disk/by-id/${volume-id}";
|
||||||
|
fsType = "btrfs";
|
||||||
|
options = [
|
||||||
|
"subvol=@postgres"
|
||||||
|
"nodatacow" # <--- Disables Copy-on-Write for performance
|
||||||
|
"noatime"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
fileSystems."/mnt/data/immich" = {
|
||||||
|
device = "/dev/disk/by-id/${volume-id}";
|
||||||
|
fsType = "btrfs";
|
||||||
|
options = [
|
||||||
|
"subvol=@immich"
|
||||||
|
"compress=zstd"
|
||||||
|
"noatime"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
fileSystems."/mnt/data/forgejo" = {
|
||||||
|
device = "/dev/disk/by-id/${volume-id}";
|
||||||
|
fsType = "btrfs";
|
||||||
|
options = [
|
||||||
|
"subvol=@forgejo"
|
||||||
|
"compress=zstd"
|
||||||
|
"noatime"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
#fileSystems."/mnt/box" = {
|
||||||
|
# device = "//u536222.your-storagebox.de/backup";
|
||||||
|
# fsType = "cifs";
|
||||||
|
# options = [
|
||||||
|
# "x-systemd.automount"
|
||||||
|
# "noauto"
|
||||||
|
# "rw"
|
||||||
|
# "credentials=${config.sops.secrets.storage_box_credentials.path}"
|
||||||
|
# "uid=900"
|
||||||
|
# "gid=100"
|
||||||
|
# "file_mode=0660"
|
||||||
|
# "dir_mode=0770"
|
||||||
|
# ];
|
||||||
|
#};
|
||||||
|
}
|
||||||
74
hosts/hetzner/forego.nix
Normal file
74
hosts/hetzner/forego.nix
Normal file
|
|
@ -0,0 +1,74 @@
|
||||||
|
{
|
||||||
|
domain,
|
||||||
|
isProd,
|
||||||
|
config,
|
||||||
|
pkgs,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
{
|
||||||
|
# 1. Access the Secret
|
||||||
|
sops.secrets.forgejo_db_password = {
|
||||||
|
owner = "forgejo";
|
||||||
|
# Restart forgejo if the password changes
|
||||||
|
restartUnits = [ "forgejo.service" ];
|
||||||
|
};
|
||||||
|
|
||||||
|
services.forgejo = {
|
||||||
|
enable = true;
|
||||||
|
|
||||||
|
# 2. STORAGE (SSD)
|
||||||
|
stateDir = "/mnt/data/forgejo";
|
||||||
|
|
||||||
|
# 3. DATABASE (Shared Postgres)
|
||||||
|
database = {
|
||||||
|
type = "postgres";
|
||||||
|
name = "forgejo";
|
||||||
|
user = "forgejo";
|
||||||
|
createDatabase = false; # We let NixOS manage this below
|
||||||
|
socket = "/run/postgresql"; # Ultra-fast socket connection
|
||||||
|
passwordFile = config.sops.secrets.forgejo_db_password.path;
|
||||||
|
};
|
||||||
|
|
||||||
|
# 4. SETTINGS
|
||||||
|
settings = {
|
||||||
|
server = {
|
||||||
|
DOMAIN = "git.${domain}";
|
||||||
|
ROOT_URL = "https://git.${domain}/";
|
||||||
|
HTTP_PORT = 3000;
|
||||||
|
# Run internal SSH on 2222 so it doesn't block your Admin SSH (22)
|
||||||
|
SSH_PORT = 2222;
|
||||||
|
START_SSH_SERVER = true;
|
||||||
|
};
|
||||||
|
# Disable registration to prevent random internet people from joining
|
||||||
|
service.DISABLE_REGISTRATION = true;
|
||||||
|
|
||||||
|
# Optional: Metrics for Grafana later
|
||||||
|
metrics.ENABLED = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
# 5. POSTGRESQL PROVISIONING
|
||||||
|
# This automatically creates the DB and User when you deploy
|
||||||
|
services.postgresql = {
|
||||||
|
ensureDatabases = [ "forgejo" ];
|
||||||
|
ensureUsers = [
|
||||||
|
{
|
||||||
|
name = "forgejo";
|
||||||
|
ensureDBOwnership = true;
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
# 6. REVERSE PROXY
|
||||||
|
services.nginx.virtualHosts."git.${domain}" = {
|
||||||
|
forceSSL = isProd;
|
||||||
|
enableACME = isProd;
|
||||||
|
locations."/" = {
|
||||||
|
proxyPass = "http://127.0.0.1:3000";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
# 7. FIREWALL
|
||||||
|
# Allow Git-over-SSH on the custom port
|
||||||
|
networking.firewall.allowedTCPPorts = [ 2222 ];
|
||||||
|
}
|
||||||
79
hosts/hetzner/immich.nix
Normal file
79
hosts/hetzner/immich.nix
Normal file
|
|
@ -0,0 +1,79 @@
|
||||||
|
{
|
||||||
|
domain,
|
||||||
|
lib,
|
||||||
|
isProd,
|
||||||
|
config,
|
||||||
|
pkgs,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
{
|
||||||
|
sops.secrets.immich_db_password = { };
|
||||||
|
sops.secrets.immich_jwt_secret = { };
|
||||||
|
|
||||||
|
sops.templates."immich.env".content = ''
|
||||||
|
DB_PASSWORD=${config.sops.placeholder.immich_db_password}
|
||||||
|
JWT_SECRET=${config.sops.placeholder.immich_jwt_secret}
|
||||||
|
'';
|
||||||
|
|
||||||
|
#users.users.immich.extraGroups = [ "users" ];
|
||||||
|
users.users.immich.uid = 900;
|
||||||
|
users.groups.immich.gid = 900;
|
||||||
|
|
||||||
|
services.immich = {
|
||||||
|
enable = true;
|
||||||
|
host = "127.0.0.1";
|
||||||
|
port = 2283;
|
||||||
|
|
||||||
|
mediaLocation = "/mnt/media/immich";
|
||||||
|
|
||||||
|
secretsFile = config.sops.templates."immich.env".path;
|
||||||
|
|
||||||
|
redis.enable = true;
|
||||||
|
database = {
|
||||||
|
enable = true;
|
||||||
|
createDB = true;
|
||||||
|
user = "immich";
|
||||||
|
name = "immich";
|
||||||
|
host = "/run/postgresql";
|
||||||
|
};
|
||||||
|
|
||||||
|
machine-learning.enable = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.services.immich-server = {
|
||||||
|
requires = [ "mnt-media.mount" ];
|
||||||
|
after = [ "mnt-media.mount" ];
|
||||||
|
|
||||||
|
serviceConfig = {
|
||||||
|
DynamicUser = lib.mkForce false;
|
||||||
|
ReadWritePaths = [ "/mnt/media/immich" ];
|
||||||
|
BindPaths = [ "/mnt/media/immich" ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
services.postgresql = {
|
||||||
|
enable = true;
|
||||||
|
|
||||||
|
dataDir = "/mnt/data/postgresql";
|
||||||
|
|
||||||
|
ensureDatabases = [ "immich" ];
|
||||||
|
ensureUsers = [
|
||||||
|
{
|
||||||
|
name = "immich";
|
||||||
|
ensureDBOwnership = true;
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
services.nginx.virtualHosts."photo.${domain}" = {
|
||||||
|
forceSSL = isProd;
|
||||||
|
enableACME = isProd;
|
||||||
|
|
||||||
|
locations."/" = {
|
||||||
|
proxyPass = "http://127.0.0.1:2283";
|
||||||
|
proxyWebsockets = true;
|
||||||
|
extraConfig = "client_max_body_size 50G;";
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
34
hosts/hetzner/media.nix
Normal file
34
hosts/hetzner/media.nix
Normal file
|
|
@ -0,0 +1,34 @@
|
||||||
|
{ config, ... }:
|
||||||
|
{
|
||||||
|
systemd.tmpfiles.rules = [
|
||||||
|
# 1. THE PARENT DIRS
|
||||||
|
# Change 0770 -> 0755 so users like 'postgres' can walk through the door.
|
||||||
|
"d /mnt/data 0755 root root -"
|
||||||
|
"d /mnt/media 0755 root root -"
|
||||||
|
|
||||||
|
# 2. THE SERVICES (SSD / Data)
|
||||||
|
# IMPORTANT: These MUST match where your services.postgresql.dataDir points
|
||||||
|
"d /mnt/data/postgresql 0700 postgres postgres -"
|
||||||
|
"d /mnt/data/forgejo 0750 forgejo forgejo -"
|
||||||
|
|
||||||
|
# 3. THE STORAGE (HDD / Media)
|
||||||
|
"d /mnt/media/immich 0750 immich immich -"
|
||||||
|
];
|
||||||
|
|
||||||
|
fileSystems."/mnt/media" = {
|
||||||
|
device = "//u536222.your-storagebox.de/backup";
|
||||||
|
fsType = "cifs";
|
||||||
|
options = [
|
||||||
|
"nofail"
|
||||||
|
"noperm"
|
||||||
|
"rw"
|
||||||
|
"credentials=${config.sops.secrets.storage_box_credentials.path}"
|
||||||
|
"uid=900"
|
||||||
|
"gid=900"
|
||||||
|
"forceuid"
|
||||||
|
"forcegid"
|
||||||
|
"file_mode=0660"
|
||||||
|
"dir_mode=0770"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
}
|
||||||
18
hosts/hetzner/nginx.nix
Normal file
18
hosts/hetzner/nginx.nix
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
{ domain, isProd, ... }:
|
||||||
|
{
|
||||||
|
services.nginx = {
|
||||||
|
enable = true;
|
||||||
|
recommendedProxySettings = true;
|
||||||
|
recommendedTlsSettings = isProd;
|
||||||
|
|
||||||
|
virtualHosts."${domain}" = {
|
||||||
|
forceSSL = isProd;
|
||||||
|
enableACME = isProd;
|
||||||
|
|
||||||
|
locations."/test" = {
|
||||||
|
return = "200 'Hello! You are accessing: ${domain}/test'";
|
||||||
|
extraConfig = "default_type text/plain;";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
10
hosts/hetzner/secret.nix
Normal file
10
hosts/hetzner/secret.nix
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
{ ... }:
|
||||||
|
{
|
||||||
|
sops = {
|
||||||
|
defaultSopsFile = ./../../secrets.yaml;
|
||||||
|
defaultSopsFormat = "yaml";
|
||||||
|
age.keyFile = "/var/lib/sops-nix/key.txt";
|
||||||
|
};
|
||||||
|
|
||||||
|
sops.secrets.storage_box_credentials = { };
|
||||||
|
}
|
||||||
55
hosts/hetzner/vm.nix
Normal file
55
hosts/hetzner/vm.nix
Normal file
|
|
@ -0,0 +1,55 @@
|
||||||
|
{ lib, ... }:
|
||||||
|
{
|
||||||
|
virtualisation.vmVariant = {
|
||||||
|
virtualisation = {
|
||||||
|
memorySize = 4096;
|
||||||
|
cores = 2;
|
||||||
|
graphics = false;
|
||||||
|
sharedDirectories = {
|
||||||
|
sops-keys = {
|
||||||
|
source = "/home/louis/.config/sops/age";
|
||||||
|
target = "/var/lib/sops-nix";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
forwardPorts = [
|
||||||
|
{
|
||||||
|
from = "host";
|
||||||
|
host.port = 8080;
|
||||||
|
guest.port = 80;
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
fileSystems."/mnt/volume" = lib.mkForce {
|
||||||
|
device = "none";
|
||||||
|
fsType = "tmpfs";
|
||||||
|
options = [
|
||||||
|
"size=2G"
|
||||||
|
"mode=777"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
fileSystems."/mnt/box" = lib.mkForce {
|
||||||
|
device = "none";
|
||||||
|
fsType = "tmpfs";
|
||||||
|
options = [
|
||||||
|
"size=2G"
|
||||||
|
"mode=777"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
sops.age.keyFile = lib.mkForce "/var/lib/sops-nix/keys.txt";
|
||||||
|
|
||||||
|
users.users.root.password = "root";
|
||||||
|
services.openssh.settings.PermitRootLogin = "yes";
|
||||||
|
services.openssh.settings.PasswordAuthentication = true;
|
||||||
|
|
||||||
|
documentation.enable = false;
|
||||||
|
systemd.services.NetworkManager-wait-online.enable = false;
|
||||||
|
|
||||||
|
networking.useDHCP = lib.mkDefault true;
|
||||||
|
|
||||||
|
services.qemuGuest.enable = true;
|
||||||
|
networking.enableIPv6 = false;
|
||||||
|
};
|
||||||
|
}
|
||||||
9
languages/python.nix
Normal file
9
languages/python.nix
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
{ pkgs, ... }:
|
||||||
|
pkgs.python3.withPackages (ps: with ps; [
|
||||||
|
pynvim
|
||||||
|
cairosvg
|
||||||
|
pnglatex
|
||||||
|
plotly
|
||||||
|
pyperclip
|
||||||
|
ipython
|
||||||
|
])
|
||||||
52
languages/r.nix
Normal file
52
languages/r.nix
Normal file
|
|
@ -0,0 +1,52 @@
|
||||||
|
{ pkgs, ... }:
|
||||||
|
let
|
||||||
|
r-packages = with pkgs.rPackages; [
|
||||||
|
ggplot2
|
||||||
|
BiocManager
|
||||||
|
ptmixed
|
||||||
|
reshape2
|
||||||
|
opencv
|
||||||
|
dplyr
|
||||||
|
stringi
|
||||||
|
stringr
|
||||||
|
tidyverse
|
||||||
|
waffle
|
||||||
|
languageserver
|
||||||
|
knitr
|
||||||
|
rmarkdown
|
||||||
|
IRkernel
|
||||||
|
matlib
|
||||||
|
lme4
|
||||||
|
emmeans
|
||||||
|
multcomp
|
||||||
|
lobstr
|
||||||
|
sloop
|
||||||
|
vioplot
|
||||||
|
corrplot
|
||||||
|
brolgar
|
||||||
|
mvtnorm
|
||||||
|
doBy
|
||||||
|
car
|
||||||
|
rbenchmark
|
||||||
|
testthat
|
||||||
|
MASS
|
||||||
|
faraway
|
||||||
|
EnvStats
|
||||||
|
leaps
|
||||||
|
ISLR
|
||||||
|
MuMIn
|
||||||
|
corrplot
|
||||||
|
caret
|
||||||
|
skimr
|
||||||
|
];
|
||||||
|
in
|
||||||
|
{
|
||||||
|
packages = r-packages;
|
||||||
|
env = pkgs.rWrapper.override {
|
||||||
|
packages = r-packages;
|
||||||
|
};
|
||||||
|
rstudio = pkgs.rstudioWrapper.override {
|
||||||
|
packages = r-packages;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
49
modules/model-downloads.nix
Normal file
49
modules/model-downloads.nix
Normal file
|
|
@ -0,0 +1,49 @@
|
||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.modelDownloads;
|
||||||
|
|
||||||
|
script = pkgs.writeShellScript "download-models" ''
|
||||||
|
set -eu
|
||||||
|
mkdir -p "${cfg.dir}"
|
||||||
|
|
||||||
|
for url in ${lib.concatStringsSep " " (map lib.escapeShellArg cfg.urls)}; do
|
||||||
|
name="$(basename "$url")"
|
||||||
|
out="${cfg.dir}/$name"
|
||||||
|
|
||||||
|
if [ -f "$out" ]; then
|
||||||
|
echo "OK: $name already exists"
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Downloading $name"
|
||||||
|
tmp="$out.part"
|
||||||
|
${pkgs.curl}/bin/curl -L --fail --retry 3 --retry-delay 2 -o "$tmp" "$url"
|
||||||
|
mv -f "$tmp" "$out"
|
||||||
|
done
|
||||||
|
'';
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options.modelDownloads = {
|
||||||
|
enable = lib.mkEnableOption "Download model files into a persistent directory";
|
||||||
|
|
||||||
|
dir = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
default = "/data/ai/models";
|
||||||
|
};
|
||||||
|
|
||||||
|
urls = lib.mkOption {
|
||||||
|
type = lib.types.listOf lib.types.str;
|
||||||
|
default = [ ];
|
||||||
|
description = "List of direct download URLs (filenames are taken from the URL).";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = lib.mkIf cfg.enable {
|
||||||
|
home.packages = [ pkgs.curl ];
|
||||||
|
|
||||||
|
home.activation.modelDownloads = lib.hm.dag.entryAfter [ "writeBoundary" ] ''
|
||||||
|
${script}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
}
|
||||||
33
secrets.yaml
Normal file
33
secrets.yaml
Normal file
|
|
@ -0,0 +1,33 @@
|
||||||
|
storage_box_credentials: ENC[AES256_GCM,data:REgBpguvSUAQOrobf0ywPPKcegsclEvqMcplNPh8NrRUVXhviJa6aVeUpzw2L+jelcGM8A==,iv:8nHaRMKCE6YxX0wV85roucRZKjzX7ims1fyLUObNui4=,tag:Xq9hqI6l6v5e58urdTf4rA==,type:str]
|
||||||
|
immich_db_password: ENC[AES256_GCM,data:+5py95Kqa3RU+jitZbbe82xndsRJ5cZPHravO8xxwzFf,iv:4PJP8itiBFWJ9OsrIHFs3qBK/69LENEtjm73KsqECC8=,tag:W0BD/d3Ebls0LJ5dpYrKVA==,type:str]
|
||||||
|
immich_jwt_secret: ENC[AES256_GCM,data:ir2gXv515OSGaMmtDGwAbJ+SPVoKf07rBbGhBkmd2zI=,iv:YbFpuFBb2RQDUx0FUXUF+rjfLo0lA1eQAUGnMi0u784=,tag:tAyFUz0hPLf5UmkFkJSmZQ==,type:str]
|
||||||
|
forgejo_db_password: ENC[AES256_GCM,data:HeOaEGGxIx8ZabhzgzMttxt72gJ3fLaPU+zdXI77t5W81b7Tsbsm/SpelZnnyWTiyQU=,iv:mxg4m9am5c6J5hTcCe7LxLWFLHWJZBpsoN++0eudgXY=,tag:/cFNWRm0xNB/+0pE7Ga39A==,type:str]
|
||||||
|
wifi_leiden_identity: ENC[AES256_GCM,data:nj9LEiHNwubm2iCc4PnBk/Q79KXEsg==,iv:PLq235mWh0vKUutvZN4+vQu+7dUfrqq76LzuHvaWLg4=,tag:K9pMdUnqMR62QeFRHmNoog==,type:str]
|
||||||
|
wifi_leiden_password: ENC[AES256_GCM,data:p2eAI6Fe66fhqCS4iz17xkBIpc1i,iv:Yf4ZbmxGAw70aiG06sr3o7m0EtJyDfwKspIiyux9hrA=,tag:3VlUcreKWpTnbmzPJhdxOw==,type:str]
|
||||||
|
wifi_home: ENC[AES256_GCM,data:yXcc8VGG+WFFEByr,iv:yTAAYCJueAUajrLd9AThypIhTggtEIFJYl9uCpPpXQs=,tag:vJ6T5N0MB8sFrESJ/0Pwtw==,type:str]
|
||||||
|
git_name: ENC[AES256_GCM,data:iIlG0/JuyJgh8Z4zE8K9X1PGPQ==,iv:po4WCA3p5xEwQdNh5cYycCh1D6mWIxUmIDIUg13aQs0=,tag:SCED1jmBTaH/WRll0anpYg==,type:str]
|
||||||
|
git_email: ENC[AES256_GCM,data:pCrxo99MHEue1kat6tVFGsaXrA==,iv:itQgTc9HW/tweKylcMHzqwm2yNiNtxYjc0BmGM+b1mY=,tag:Ri+euCueyv+xwEOeswidpg==,type:str]
|
||||||
|
sops:
|
||||||
|
age:
|
||||||
|
- recipient: age1y38cnfvt42ar4seqx8n2cw0ynwls2rdl6jyzhv9wuv6jcfqrwckqwlh9p0
|
||||||
|
enc: |
|
||||||
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBsRTBPRjJIaHZtOGpDaWJY
|
||||||
|
SnhOSE5BeGkrOUQwQ3dQRG5SSDRVdXk2ZGdnCjg1Yk5NT01sOElyNyswR0ZzK0JG
|
||||||
|
cXhHVHhLR2cwRjRJb1A4OWQ4N3VTekkKLS0tIHcwWG9ORlR3TjVpbTZhcm5yYXpj
|
||||||
|
OG5xRVIvWFJFRjlTR2hRVFpVbFI2em8KdwnBU+SgjLoujtFT7m58JwWJBuRcL+cr
|
||||||
|
QLtDXAWRjrop1l+cjE1le5nwwGFUYVgUzHWRi5V6tMYrkUyazj76gg==
|
||||||
|
-----END AGE ENCRYPTED FILE-----
|
||||||
|
- recipient: age1sjq27nh4znq75fzzx6epwd6700wgg23v9xenzvmam4kmncvjdcesakv9e2
|
||||||
|
enc: |
|
||||||
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA2YmdRYVFOeGdWR01DbGxk
|
||||||
|
YUg3UXZXcVpPcXUzL0hQaUd4bW9BOXg2U3pjClB2R1M2UEpiSWVyR0ZTZk5yQXor
|
||||||
|
eXBKYWVIbzdEQ1dUZFlyWk5tZjZFa1UKLS0tIDkvN0FsaGZLMkNPa1ZxWkk0SlNM
|
||||||
|
emZCZDM4djFEdDIya3NISElqRU9QUFkKJG1REQS0/HmY1jbOUlt/ynhlLwmrVbkK
|
||||||
|
mNdhF8BdfP0rCwjWLvWnmikxdLIBHeeeodipZFr5QDpBZqzFHUxBaA==
|
||||||
|
-----END AGE ENCRYPTED FILE-----
|
||||||
|
lastmodified: "2026-01-26T00:05:27Z"
|
||||||
|
mac: ENC[AES256_GCM,data:A0M7dnSZlO3A+vahwjtbSSLwjzTMF/GZjnw385siHeTrT3ICX9nfnh9MzgmT3k7AOsaJkbUuq5dl67pfNEaDxbLdYc6k2rFfyniVFq3t5JVPUr7+F1poijdKMSGrFMv/8uLDc0NlKDDa6VOEX4le7akqBRhAKMCqTZ5atmskwhg=,iv:sPJT9watBgpusk3lGPXLxNWNrMTLITxv1vo11a92uIc=,tag:YPhTUghRjYDZZo3VsYwAFQ==,type:str]
|
||||||
|
unencrypted_suffix: _unencrypted
|
||||||
|
version: 3.11.0
|
||||||
Loading…
Add table
Add a link
Reference in a new issue