WSL + more modularity

This commit is contained in:
System administrator 2024-01-30 04:25:25 +00:00 committed by Bryan Ramos
parent 7b63b3b04f
commit e513913099
Signed by: bryan
GPG key ID: 6ABDCD144D6643C8
57 changed files with 356 additions and 92 deletions

View file

@ -0,0 +1,3 @@
{
cd = "cd -L";
}

View file

@ -0,0 +1,2 @@
''
''

View file

@ -0,0 +1,63 @@
''
export DIRENV_LOG_FORMAT=
function cdg() {
if [[ $1 == "--help" ]]; then
echo "A simple utility for navigating to the root of a git repo"
return 0
fi
# Check for invalid command
if [[ -n "$1" ]]; then
echo "Invalid command: $1. Try 'cdg --help'."
return 1
fi
local root_dir
root_dir=$(git rev-parse --show-toplevel 2>/dev/null)
local git_status=$?
if [ $git_status -ne 0 ]; then
echo "Error: Not a git repo."
return 1
fi
cd "$root_dir"
}
function penpot() {
case "$1" in
run)
sudo docker compose -p penpot -f ~/Documents/tools/penpot/docker-compose.yaml up -d >/dev/null 2>&1
nohup bash -c '(sleep 10 && if [[ "$OSTYPE" == "linux-gnu"* ]]; then
xdg-open "http://localhost:9001"
elif [[ "$OSTYPE" == "darwin"* ]]; then
open "http://localhost:9001"
fi)' >/dev/null 2>&1 &
echo "Started penpot on http://localhost:9001"
;;
stop)
echo "Stopping penpot"
sudo docker compose -p penpot -f ~/Documents/tools/penpot/docker-compose.yaml down >/dev/null 2>&1
;;
update)
sudo docker compose -f ~/Documents/tools/penpot/docker-compose.yaml pull
echo "Updated penpot!"
;;
help)
xdg-open "https://help.penpot.app/"
echo "Opened penpot help page in your browser."
;;
*)
echo "Usage: penpot {run|stop|update|help}"
;;
esac
}
source ~/Documents/projects/ldv/ldv.sh
set -o vi
bind 'set completion-ignore-case on'
bind 'set completion-map-case on'
''

View file

@ -0,0 +1,93 @@
''
check_ssh() {
if [ -n "$SSH_CLIENT" ] || [ -n "$SSH_TTY" ]; then
ssh_PS1="\n\[\033[01;37m\]\u@\h:\[\033[00m\]"
return 0
fi
}
add_icon() {
local icon=$1
if [[ ! $venv_icons =~ $icon ]]; then
venv_icons+="$icon"
fi
}
remove_icon() {
local icon=$1
venv_icons=''${venv_icons//$icon/}
}
python_icon="\[\033[01;33m\]\[\033[00m\]"
node_icon="\[\033[01;93m\]󰌞\[\033[00m\]"
nix_icon="\[\033[01;34m\]\[\033[00m\]"
check_venv() {
if [ -n "$IN_NIX_SHELL" ]; then
add_icon "$nix_icon"
if [ -n "$VIRTUAL_ENV" ]; then
add_icon "$python_icon"
else
remove_icon "$python_icon"
fi
if [ -d "''${git_root}/node_modules" ]; then
add_icon "$node_icon"
else
remove_icon "$node_icon"
fi
else
remove_icon "$nix_icon"
return 0
fi
}
set_git_dir() {
if [ "$git_curr_dir" == "." ]; then
working_dir="\[\033[01;34m\] $git_root_dir\[\033[00m\]"
return 0
else
working_dir="\[\033[01;34m\] $git_root_dir/$git_curr_dir\[\033[00m\]"
return 0
fi
}
check_project() {
local git_dir=$(git rev-parse --git-dir 2>/dev/null)
if [ -n "$git_dir" ]; then
local git_branch=$(git branch --show-current 2>/dev/null)
git_branch=''${git_branch:-$(git rev-parse --short HEAD)}
local git_dir=$(git rev-parse --git-dir)
local git_root=$(dirname "$(realpath "$git_dir")")
local git_curr_dir=$(realpath --relative-to="$git_root" .)
local git_root_dir=$(basename "$git_root")
git_branch_PS1="\[\033[01;31m\]$git_branch 󰘬:\[\033[00m\]"
set_git_dir
check_venv
fi
return 0
}
function set_prompt() {
local green_arrow="\[\033[01;32m\]>> "
local white_text="\[\033[00m\]"
local working_dir="\[\033[01;34m\]\w\[\033[00m\]"
local ssh_PS1
local venv_icons
local git_branch_PS1
check_ssh
check_project
PS1="$ssh_PS1\n$working_dir\n$venv_icons$green_arrow$git_branch_PS1$white_text"
return 0
}
PROMPT_COMMAND="set_prompt"
''

View file

@ -0,0 +1,33 @@
{ lib, config, ... }:
with lib;
let
cfg = config.modules.bash;
in
{ options.modules.bash = { enable = mkEnableOption "bash"; };
config = mkIf cfg.enable {
programs.bash = {
enable = true;
enableCompletion = true;
initExtra = import ./config/prompt.nix;
profileExtra = import ./config/bashprofile.nix;
bashrcExtra = import ./config/bashrc.nix;
shellAliases = import ./config/alias.nix;
};
programs = {
direnv = {
enable = true;
enableBashIntegration = true;
nix-direnv.enable = true;
};
ripgrep.enable = true;
lsd = {
enable = true;
enableAliases = true;
};
};
};
}

10
src/modules/default.nix Normal file
View file

@ -0,0 +1,10 @@
{
imports = [
./bash
./git
./gpg
./gui
./security
./utils
];
}

View file

@ -0,0 +1,23 @@
{ lib, pkgs, config, ... }:
with lib;
let cfg = config.modules.git;
in
{ options.modules.git = { enable = mkEnableOption "git"; };
config = mkIf cfg.enable {
programs = {
git = {
enable = true;
} // config.user.gitConfig;
gh = {
enable = true;
settings.git_protocol = "ssh";
};
};
home.packages = with pkgs; [
git-crypt
];
};
}

View file

@ -0,0 +1,22 @@
{ lib, config, ... }:
with lib;
let
cfg = config.modules.gpg;
in
{ options.modules.gpg = { enable = mkEnableOption "gpg"; };
config = mkIf cfg.enable {
programs.gpg = {
enable = true;
publicKeys = [ config.user.pgpKey ];
};
services.gpg-agent = {
enable = true;
enableSshSupport = true;
enableBashIntegration = true;
pinentryFlavor = "tty";
};
};
}

View file

@ -0,0 +1,15 @@
{ lib, config, ... }:
with lib;
let
cfg = config.modules.gui;
in
{ options.modules.gui = { enable = mkEnableOption "gui"; };
imports = [ ./desktopEnvironments ];
config = mkIf cfg.enable {
modules = {
sway.enable = true;
};
};
}

View file

@ -0,0 +1,5 @@
{
imports = [
./sway
];
}

View file

@ -0,0 +1,69 @@
{
scrolling = {
history = 10000;
multiplier = 3;
};
window = {
opacity = 0.90;
};
colors = {
primary = {
background = "#000000";
foreground = "#cdd6f4";
};
normal = {
black = "#1e2127";
red = "#e06c75";
green = "#98c379";
yellow = "#d19a66";
blue = "#61afef";
magenta = "#c678dd";
cyan = "#56b6c2";
white = "#abb2bf";
};
bright = {
black = "#5c6370";
red = "#e06c75";
green = "#98c379";
yellow = "#d19a66";
blue = "#61afef";
magenta = "#c678dd";
cyan = "#56b6c2";
white = "#ffffff";
};
};
font = {
size = 12;
normal = {
family = "Terminus";
style = "Regular";
};
bold = {
family = "Terminus";
style = "Bold";
};
italic = {
family = "Terminus";
style = "Italic";
};
bold_italic = {
family = "Terminus";
style = "Bold Italic";
};
};
#cursor = {
# shape = "Block";
# blinking = "Always";
# blink_interval = 750;
#};
}

View file

@ -0,0 +1,15 @@
{ lib, config, ... }:
with lib;
let
cfg = config.modules.gui.alacritty;
in
{ options.modules.gui.alacritty = { enable = mkEnableOption "gui.alacritty"; };
config = mkIf cfg.enable {
programs.alacritty = {
enable = true;
settings = import ./config/alacritty.nix;
};
};
}

View file

@ -0,0 +1,16 @@
{ pkgs, lib, config, ... }:
with lib;
let
cfg = config.modules.gui.browsers;
in
{ options.modules.gui.browsers = { enable = mkEnableOption "gui.browsers"; };
config = mkIf cfg.enable {
programs.firefox.enable = true;
home.packages = with pkgs; [
tor-browser
];
};
}

View file

@ -0,0 +1,37 @@
{ pkgs, lib, config, ... }:
with lib;
let
cfg = config.modules.gui.corn;
in
{ options.modules.gui.corn = { enable = mkEnableOption "gui.corn"; };
config = mkIf cfg.enable {
home.packages = with pkgs; [
trezor-suite
trezorctl
trezord
electrum
bisq-desktop
];
systemd.user.services = {
trezord = {
Unit = {
Description = "Trezor Bridge";
After = [ "network.target" ];
Wants = [ "network.target" ];
PartOf = [ "graphical-session.target" ];
};
Service = {
ExecStart = "${pkgs.trezord}/bin/trezord-go";
Restart = "always";
};
Install = {
WantedBy = [ "default.target" ];
};
};
};
};
}

View file

@ -0,0 +1,11 @@
{
imports = [
./alacritty
./browsers
./corn
./fun
./utils
./neovim
./writing
];
}

View file

@ -0,0 +1,25 @@
{ pkgs, lib, config, ... }:
with lib;
let
cfg = config.modules.gui.fun;
in
{ options.modules.gui.fun = { enable = mkEnableOption "gui.fun"; };
config = mkIf cfg.enable {
programs.obs-studio = {
enable = true;
plugins = with pkgs.obs-studio-plugins; [
wlrobs
obs-pipewire-audio-capture
input-overlay
];
};
home.packages = with pkgs; [
spotify
webcord
showmethekey
];
};
}

View file

@ -0,0 +1,2 @@
-- bootstrap lazy.nvim, LazyVim and your plugins
require("config.lazy")

View file

@ -0,0 +1,177 @@
-- Autocmds are automatically loaded on the VeryLazy event
-- Default autocmds that are always set: https://github.com/LazyVim/LazyVim/blob/main/lua/lazyvim/config/autocmds.lua
-- Add any additional autocmds here
vim.g.autoformat = false
vim.cmd([[
au BufRead,BufNewFile *.purs set filetype=purescript
]])
require("which-key").register({
t = {
"<cmd>:new | setlocal nonumber norelativenumber | resize 10 | terminal<CR>",
"Open terminal in new window",
},
}, {
prefix = "<leader>",
})
require("notify").setup({
background_colour = "#000000",
})
local lsp = require("lsp-zero").preset({})
--require("null-ls").setup({
-- -- you can reuse a shared lspconfig on_attach callback here
-- on_attach = function(client, bufnr)
-- if client.supports_method("textDocument/formatting") then
-- vim.api.nvim_clear_autocmds({ group = vim.api.nvim_create_augroup("LspFormatting", {}), buffer = bufnr })
-- vim.api.nvim_create_autocmd("BufWritePre", {
-- group = augroup,
-- buffer = bufnr,
-- callback = function()
-- vim.lsp.buf.format({
-- bufnr = bufnr,
-- filter = function(client)
-- return client.name == "null-ls"
-- end,
-- })
-- vim.lsp.buf.formatting_sync()
-- end,
-- })
-- end
-- end,
--})
-- https://github.com/neovim/nvim-lspconfig/blob/master/doc/server_configurations.md
lsp.setup_servers({
--"tsserver",
"hls",
"pyright",
"nil_ls",
"cssls",
"html",
"jsonls",
"diagnosticls",
"lua_ls",
"marksman",
"purescriptls",
"tailwindcss",
"bashls",
"dhall_lsp_server",
"volar",
"clangd",
})
require("lspconfig").lua_ls.setup(lsp.nvim_lua_ls())
lsp.setup()
local cmp_nvim_lsp = require "cmp_nvim_lsp"
require("lspconfig").clangd.setup {
on_attach = on_attach,
capabilities = cmp_nvim_lsp.default_capabilities(),
cmd = {
"clangd",
"--offset-encoding=utf-16",
},
}
require("lspconfig").volar.setup({
filetypes = { "typescript", "javascript", "javascriptreact", "typescriptreact", "vue", "json" },
})
require("lspconfig").nil_ls.setup {
settings = {
["nil"] = {
nix = {
flake = {
autoArchive = true,
}
}
}
}
}
local cmp = require("cmp")
cmp.setup({
snippet = {
expand = function(args)
require("luasnip").lsp_expand(args.body)
end,
},
sources = {
{ name = "nvim_lsp" },
{ name = "luasnip" },
-- other sources...
},
formatting = {
format = function(entry, vim_item)
vim_item.menu = ""
return vim_item
end,
},
-- other configurations...
})
cmp.setup({
enabled = function()
-- disable completion in comments
local context = require("cmp.config.context")
-- keep command mode completion enabled when cursor is in a comment
if vim.api.nvim_get_mode().mode == "c" then
return true
else
return not context.in_treesitter_capture("comment") and not context.in_syntax_group("comment")
end
end,
mapping = {
["<C-p>"] = cmp.mapping.select_prev_item(),
["<C-n>"] = cmp.mapping.select_next_item(),
-- ["<Down>"] = cmp.mapping.select_next_item(),
-- ["<Up>"] = cmp.mapping.select_prev_item(),
["<C-d>"] = cmp.mapping.scroll_docs(-4),
["<C-f>"] = cmp.mapping.scroll_docs(4),
["<Tab>"] = cmp.mapping(function(fallback)
if cmp.visible() then
cmp.select_next_item()
elseif cmp.completed then
cmp.confirm({ select = true })
else
fallback()
end
end, { "i", "s" }),
["<S-Tab>"] = cmp.mapping.select_prev_item(),
["<CR>"] = cmp.mapping(function(fallback)
fallback()
end, { "i", "s" }),
},
})
local dap = require("dap")
dap.adapters.haskell = {
type = "executable",
command = "haskell-debug-adapter",
args = { "--hackage-version=0.0.33.0" },
}
dap.configurations.haskell = {
{
type = "haskell",
request = "launch",
name = "Debug",
workspace = "${workspaceFolder}",
startup = "${file}",
stopOnEntry = true,
logFile = vim.fn.stdpath("data") .. "/haskell-dap.log",
logLevel = "WARNING",
ghciEnv = vim.empty_dict(),
ghciPrompt = "λ: ",
-- Adjust the prompt to the prompt you see when you invoke the ghci command below
ghciInitialPrompt = "λ: ",
ghciCmd = "stack ghci --test --no-load --no-build --main-is TARGET --ghci-options -fprint-evld-with-show",
},
}

View file

@ -0,0 +1,8 @@
-- Keymaps are automatically loaded on the VeryLazy event
-- Default keymaps that are always set: https://github.com/LazyVim/LazyVim/blob/main/lua/lazyvim/config/keymaps.lua
-- Add any additional keymaps here
vim.keymap.set("n", "<C-U>", "<C-U>zz", { silent = true })
vim.keymap.set("n", "<C-D>", "<C-D>zz", { silent = true })
vim.keymap.set("n", "H", ":bprev<CR>", { silent = true })
vim.keymap.set("n", "L", ":bnext<CR>", { silent = true })

View file

@ -0,0 +1,44 @@
local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim"
if not vim.loop.fs_stat(lazypath) then
-- bootstrap lazy.nvim
-- stylua: ignore
vim.fn.system({ "git", "clone", "--filter=blob:none", "https://github.com/folke/lazy.nvim.git", "--branch=stable", lazypath })
end
vim.opt.rtp:prepend(vim.env.LAZY or lazypath)
require("lazy").setup({
spec = {
-- add LazyVim and import its plugins
{ "LazyVim/LazyVim", import = "lazyvim.plugins" },
-- import any extras modules here
{ import = "lazyvim.plugins.extras.dap.core" },
-- import/override with your plugins
{ import = "plugins" },
},
defaults = {
-- By default, only LazyVim plugins will be lazy-loaded. Your custom plugins will load during startup.
-- If you know what you're doing, you can set this to `true` to have all your custom plugins lazy-loaded by default.
lazy = false,
-- It's recommended to leave version=false for now, since a lot the plugin that support versioning,
-- have outdated releases, which may break your Neovim install.
version = false, -- always use the latest git commit
-- version = "*", -- try installing the latest stable version for plugins that support semver
},
install = { colorscheme = { "github-theme" } },
checker = { enabled = true }, -- automatically check for plugin updates
performance = {
rtp = {
-- disable some rtp plugins
disabled_plugins = {
"gzip",
-- "matchit",
-- "matchparen",
-- "netrwPlugin",
"tarPlugin",
"tohtml",
"tutor",
"zipPlugin",
},
},
},
})

View file

@ -0,0 +1,29 @@
-- Options are automatically loaded before lazy.nvim startup
-- Default options that are always set: https://github.com/LazyVim/LazyVim/blob/main/lua/lazyvim/config/options.lua
-- Add any additional options here
vim.opt.tabstop = 2
vim.opt.shiftwidth = 2
vim.opt.softtabstop = 2
vim.opt.expandtab = true
vim.opt.smartindent = true
vim.cmd([[
autocmd FileType python setlocal tabstop=4 shiftwidth=4 softtabstop=4
]])
vim.cmd([[
autocmd FileType haskell setlocal tabstop=4 shiftwidth=4 softtabstop=4
]])
vim.opt.ignorecase = true
vim.opt.smartcase = true
vim.opt.swapfile = false
vim.opt.backup = false
vim.opt.undofile = true
vim.o.termguicolors = true
vim.opt.guicursor = "n-v-c:block,i:block,r:block"
vim.cmd [[highlight PmenuSel guifg=#53565d guibg=#f0c981]]

View file

@ -0,0 +1,102 @@
return {
{
"olimorris/onedarkpro.nvim",
lazy = false,
priority = 1000,
config = function()
require("onedarkpro").setup({
colors = {
bg = "#000000",
fg = "#abb2bf",
red = "#ef596f",
orange = "#d19a66",
yellow = "#e5c07b",
green = "#89ca78",
cyan = "#2bbac5",
blue = "#61afef",
purple = "#d55fde",
white = "#abb2bf",
black = "#000000",
gray = "#434852",
highlight = "#e2be7d",
comment = "#7f848e",
none = "NONE",
},
options = {
transparency = true,
},
})
vim.cmd("colorscheme onedark_dark")
end,
},
{
"VonHeikemen/lsp-zero.nvim",
branch = "v2.x",
dependencies = {
{ "neovim/nvim-lspconfig" },
{ "hrsh7th/nvim-cmp" },
{ "hrsh7th/cmp-buffer" },
{ "hrsh7th/cmp-path" },
{ "hrsh7th/cmp-nvim-lsp" },
{ "L3MON4D3/LuaSnip" },
},
},
--[[
{
"jackMort/ChatGPT.nvim",
event = "VeryLazy",
config = function()
require("chatgpt").setup({
api_key_cmd = "pass show api/chatgpt-apikey",
})
end,
dependencies = {
"MunifTanjim/nui.nvim",
"nvim-lua/plenary.nvim",
"nvim-telescope/telescope.nvim",
},
},
]]
{
"nvim-treesitter/nvim-treesitter-context",
config = function()
require("treesitter-context").setup({
enable = true, -- Enable this plugin (Can be enabled/disabled later via commands)
max_lines = 0, -- How many lines the window should span. Values <= 0 mean no limit.
min_window_height = 0, -- Minimum editor window height to enable context. Values <= 0 mean no limit.
line_numbers = false,
multiline_threshold = 20, -- Maximum number of lines to collapse for a single context line
trim_scope = "outer", -- Which context lines to discard if `max_lines` is exceeded. Choices: 'inner', 'outer'
mode = "cursor", -- Line used to calculate context. Choices: 'cursor', 'topline'
-- Separator between context and content. Should be a single character string, like '-'.
-- When separator is set, the context will only show up when there are at least 2 lines above cursorline.
separator = "-",
zindex = 20, -- The Z-index of the context window
on_attach = nil, -- (fun(buf: integer): boolean) return false to disable attaching
})
end,
},
{
"nvim-neo-tree/neo-tree.nvim",
config = function()
require("neo-tree").setup({
window = {
position = "left",
width = 20,
},
})
end,
},
{ "williamboman/mason.nvim", enabled = false },
{ "williamboman/mason-lspconfig.nvim", enabled = false },
{ "jay-babu/mason-nvim-dap.nvim", enabled = false },
{ "catppuccin/nvim", enabled = false },
{ "folke/flash.nvim", enabled = false }
}

View file

@ -0,0 +1,24 @@
{ pkgs, ... }:
let
lsp = with pkgs; [
nil nixfmt
marksman shfmt
sumneko-lua-language-server stylua
haskell-language-server hlint
nodePackages."@tailwindcss/language-server"
dhall-lsp-server
];
lsp' = with pkgs.nodePackages; [
vscode-langservers-extracted
typescript-language-server
bash-language-server
diagnostic-languageserver
pyright
purescript-language-server
volar
];
in
lsp ++ lsp'

View file

@ -0,0 +1,25 @@
{ pkgs, lib, config, ... }:
with lib;
let
cfg = config.modules.gui.neovim;
in
{ options.modules.gui.neovim = { enable = mkEnableOption "gui.neovim"; };
config = mkIf cfg.enable {
programs.neovim = {
enable = true;
defaultEditor = true;
vimAlias = true;
extraPackages = import ./config/servers.nix { inherit pkgs; };
};
home.file.".config/nvim" = {
source = ./config/lazyvim;
recursive = true;
};
home.packages = with pkgs; [
lazygit
];
};
}

View file

@ -0,0 +1,21 @@
{ pkgs, lib, config, ... }:
with lib;
let
cfg = config.modules.gui.utils;
in
{ options.modules.gui.utils = { enable = mkEnableOption "gui.utils"; };
config = mkIf cfg.enable {
programs.btop.enable = true;
home.packages = with pkgs; [
gimp
okular
pdftk
teams-for-linux
zoom-us
exercism
];
};
}

View file

@ -0,0 +1,17 @@
{ pkgs, lib, config, ... }:
with lib;
let
cfg = config.modules.gui.writing;
in
{ options.modules.gui.writing = { enable = mkEnableOption "gui.writing"; };
config = mkIf cfg.enable {
home.packages = with pkgs; [
mdbook
texlive.combined.scheme-tetex
pandoc
asciidoctor
];
};
}

View file

@ -0,0 +1,179 @@
{ pkgs, config, ... }:
let
inherit (config.lib.formats.rasi) mkLiteral;
in
{ enable = true;
package = pkgs.rofi-wayland;
location = "center";
terminal = "\${pkgs.alacritty}/bin/alacritty";
theme = {
"*" = {
nord0 = mkLiteral "#2e3440";
nord1 = mkLiteral "#3b4252";
nord2 = mkLiteral "#434c5e";
nord3 = mkLiteral "#4c566a";
nord4 = mkLiteral "#d8dee9";
nord5 = mkLiteral "#e5e9f0";
nord6 = mkLiteral "#eceff4";
nord7 = mkLiteral "#8fbcbb";
nord8 = mkLiteral "#88c0d0";
nord9 = mkLiteral "#81a1c1";
nord10 = mkLiteral "#5e81ac";
nord11 = mkLiteral "#bf616a";
nord12 = mkLiteral "#d08770";
nord13 = mkLiteral "#ebcb8b";
nord14 = mkLiteral "#a3be8c";
nord15 = mkLiteral "#b48ead";
spacing = 2;
background-color = mkLiteral "var(nord1)";
background = mkLiteral "var(nord1)";
foreground = mkLiteral "var(nord4)";
normal-background = mkLiteral "var(background)";
normal-foreground = mkLiteral "var(foreground)";
alternate-normal-background = mkLiteral "var(background)";
alternate-normal-foreground = mkLiteral "var(foreground)";
selected-normal-background = mkLiteral "var(nord8)";
selected-normal-foreground = mkLiteral "var(background)";
active-background = mkLiteral "var(background)";
active-foreground = mkLiteral "var(nord10)";
alternate-active-background = mkLiteral "var(background)";
alternate-active-foreground = mkLiteral "var(nord10)";
selected-active-background = mkLiteral "var(nord10)";
selected-active-foreground = mkLiteral "var(background)";
urgent-background = mkLiteral "var(background)";
urgent-foreground = mkLiteral "var(nord11)";
alternate-urgent-background = mkLiteral "var(background)";
alternate-urgent-foreground = mkLiteral "var(nord11)";
selected-urgent-background = mkLiteral "var(nord11)";
selected-urgent-foreground = mkLiteral "var(background)";
};
element = {
padding = mkLiteral "0px 0px 0px 7px";
spacing = mkLiteral "5px";
border = 0;
cursor = mkLiteral "pointer";
};
"element normal.normal" = {
background-color = mkLiteral "var(normal-background)";
text-color = mkLiteral "var(normal-foreground)";
};
"element normal.urgent" = {
background-color = mkLiteral "var(urgent-background)";
text-color = mkLiteral "var(urgent-foreground)";
};
"element normal.active" = {
background-color = mkLiteral "var(active-background)";
text-color = mkLiteral "var(active-foreground)";
};
"element selected.normal" = {
background-color = mkLiteral "var(selected-normal-background)";
text-color = mkLiteral "var(selected-normal-foreground)";
};
"element selected.urgent" = {
background-color = mkLiteral "var(selected-urgent-background)";
text-color = mkLiteral "var(selected-urgent-foreground)";
};
"element selected.active" = {
background-color = mkLiteral "var(selected-active-background)";
text-color = mkLiteral "var(selected-active-foreground)";
};
"element alternate.normal" = {
background-color = mkLiteral "var(alternate-normal-background)";
text-color = mkLiteral "var(alternate-normal-foreground)";
};
"element alternate.urgent" = {
background-color = mkLiteral "var(alternate-urgent-background)";
text-color = mkLiteral "var(alternate-urgent-foreground)";
};
"element alternate.active" = {
background-color = mkLiteral "var(alternate-active-background)";
text-color = mkLiteral "var(alternate-active-foreground)";
};
"element-text" = {
background-color = mkLiteral "rgba(0, 0, 0, 0%)";
text-color = mkLiteral "inherit";
highlight = mkLiteral "inherit";
cursor = mkLiteral "inherit";
};
"element-icon" = {
background-color = mkLiteral "rgba(0, 0, 0, 0%)";
size = mkLiteral "1.0000em";
text-color = mkLiteral "inherit";
cursor = mkLiteral "inherit";
};
window = {
padding = 0;
border = 0;
background-color = mkLiteral "var(background)";
};
mainbox = {
padding = 0;
border = 0;
};
message = {
margin = mkLiteral "0px 7px";
};
textbox = {
text-color = mkLiteral "var(foreground)";
};
listview = {
margin = mkLiteral "0px 0px 5px";
scrollbar = true;
spacing = mkLiteral "2px";
fixed-height = 0;
};
scrollbar = {
padding = 0;
handle-width = mkLiteral "14px";
border = 0;
handle-color = mkLiteral "var(nord3)";
};
button = {
spacing = 0;
text-color = mkLiteral "var(normal-foreground)";
cursor = mkLiteral "pointer";
};
"button selected" = {
background-color = mkLiteral "var(selected-normal-background)";
text-color = mkLiteral "var(selected-normal-foreground)";
};
inputbar = {
padding = mkLiteral "7px";
margin = mkLiteral "7px";
spacing = 0;
text-color = mkLiteral "var(normal-foreground)";
background-color = mkLiteral "var(nord3)";
children = [ "entry" ];
};
entry = {
spacing = 0;
cursor = mkLiteral "text";
text-color = mkLiteral "var(normal-foreground)";
background-color = mkLiteral "var(nord3)";
};
};
}

View file

@ -0,0 +1,5 @@
''
if [ -z "$DISPLAY" ] && [ "$(tty)" = "/dev/tty1" ]; then
exec sway
fi
''

View file

@ -0,0 +1,84 @@
{ config, lib, pkgs, ... }:
let
modifier = config.wayland.windowManager.sway.config.modifier;
in
{ enable = true;
xwayland = true;
wrapperFeatures.gtk = true;
extraSessionCommands = ''
export _JAVA_AWT_WM_NONREPARENTING=1
'';
config = {
output = {
HDMI-A-1 = {
resolution = "1920x1080";
position = "0,0";
bg = "~/Pictures/wallpapers/mountains.jpg fill";
};
DP-1 = {
resolution = "1080x1920";
position = "1920,0";
transform = "90";
bg = "~/Pictures/wallpapers/mountains.jpg fill";
};
};
modifier = "Mod1";
menu = "rofi -show drun -show-icons -drun-icon-theme Qogir -font 'Noto Sans 14'";
terminal = "alacritty";
input = {
keyboard = {
xkb_numlock = "enabled";
xkb_layout = "us";
};
pointer = {
accel_profile = "flat";
pointer_accel = "0.65";
};
};
bars = [
{
position = "top";
statusCommand = ''while :; do echo "$(free -h | awk '/^Mem/ {print $3}') '|' $(date +'%I:%M:%S %p') '|' $(date +'%m-%d-%Y')"; sleep 1; done'';
fonts = {
names = [ "Noto Sans" ];
size = 10.0;
};
colors = {
background = "#0A0E14";
statusline = "#FFFFFF";
};
}
];
gaps = {
smartGaps = false;
inner = 10;
};
floating.border = 0;
window.border= 0;
keybindings = lib.mkOptionDefault {
"${modifier}+q" = "kill";
"Print" = "exec grim ~/Pictures/screenshot-$(date +'%Y%m%d-%H%M%S').png";
"Shift+Print" = "exec grim -g \"$(slurp)\" ~/Pictures/screenshot-$(date +'%Y%m%d-%H%M%S').png";
"${modifier}+Print" = ''exec sh -c 'grim -g "$(swaymsg -t get_tree | jq -j '"'"'.. | select(.type?) | select(.focused).rect | "\(.x),\(.y) \(.width)x\(.height)"'"'"')" ~/Pictures/screenshot-$(date +'%Y%m%d-%H%M%S').png' '';
"${modifier}+Shift+f" = "exec alacritty -e sh -c 'EDITOR=nvim ranger'";
"${modifier}+Shift+d" = "exec emote";
};
};
extraConfig = ''
for_window [app_id="one.alynx.showmethekey" title="Floating Window - Show Me The Key"] {
floating enable
sticky enable
}
exec_always ${pkgs.autotiling}/bin/autotiling
'';
}

View file

@ -0,0 +1,59 @@
{ pkgs, lib, config, ... }:
with lib;
let
cfg = config.modules.sway;
in
{ options.modules.sway = { enable = mkEnableOption "sway"; };
imports = [ ../modules ];
config = mkIf cfg.enable {
wayland.windowManager.sway = import ./config/sway.nix { inherit pkgs config lib; };
programs.rofi = import ./config/rofi.nix { inherit pkgs config lib; };
programs.bash = {
profileExtra = import ./config/shellHook.nix;
shellAliases = {
open = "xdg-open";
};
};
gtk = {
enable = true;
theme.package = pkgs.juno-theme;
theme.name = "Juno-ocean";
iconTheme.package = pkgs.qogir-icon-theme;
iconTheme.name = "Qogir";
};
qt = {
enable = true;
style.package = pkgs.juno-theme;
platformTheme = "gtk";
};
home.packages = with pkgs; [
xdg-utils
grim
slurp
wl-clipboard
autotiling
ranger
highlight
terminus-nerdfont
noto-fonts
noto-fonts-cjk
noto-fonts-emoji
emote
];
programs = {
imv.enable = true;
};
fonts.fontconfig.enable = true;
};
}

View file

@ -0,0 +1,16 @@
{ pkgs, lib, config, ... }:
with lib;
let
cfg = config.modules.security;
in
{ options.modules.security = { enable = mkEnableOption "security"; };
config = mkIf cfg.enable {
home.packages = with pkgs; [
pass
wireguard-tools
ipscan
];
};
}

View file

@ -0,0 +1,18 @@
{ pkgs, lib, config, ... }:
with lib;
let
cfg = config.modules.utils;
in
{ options.modules.utils = { enable = mkEnableOption "utils"; };
imports = [ ./modules ];
config = mkIf cfg.enable {
home.packages = with pkgs; [
wget curl tree neofetch
unzip fping calc qrencode
fd pkg-config pciutils
rsync zip
];
};
}

View file

@ -0,0 +1,8 @@
{
imports = [
./dev
./email
./irc
./vim
];
}

View file

@ -0,0 +1,20 @@
{ pkgs, lib, config, ... }:
with lib;
let
cfg = config.modules.utils.dev;
in
{ options.modules.utils.dev = { enable = mkEnableOption "utils.dev"; };
config = mkIf cfg.enable {
home.packages = with pkgs; [
nix-init
nix-prefetch-git
glibc
gcc
docker
];
};
}

View file

@ -0,0 +1,561 @@
#
# aerc main configuration
[general]
#
# Used as a default path for save operations if no other path is specified.
# ~ is expanded to the current user home dir.
#
#default-save-path=
# If set to "gpg", aerc will use system gpg binary and keystore for all crypto
# operations. If set to "internal", the internal openpgp keyring will be used.
# If set to "auto", the system gpg will be preferred unless the internal
# keyring already exists, in which case the latter will be used.
#
# Default: auto
#pgp-provider=auto
# By default, the file permissions of accounts.conf must be restrictive and
# only allow reading by the file owner (0600). Set this option to true to
# ignore this permission check. Use this with care as it may expose your
# credentials.
#
# Default: false
#unsafe-accounts-conf=false
# Output log messages to specified file. A path starting with ~/ is expanded to
# the user home dir. When redirecting aerc's output to a file using > shell
# redirection, this setting is ignored and log messages are printed to stdout.
#
#log-file=
# Only log messages above the specified level to log-file. Supported levels
# are: trace, debug, info, warn and error. When redirecting aerc's output to
# a file using > shell redirection, this setting is ignored and the log level
# is forced to trace.
#
# Default: info
#log-level=info
# Set the $TERM environment variable used for the embedded terminal.
#
# Default: xterm-256color
#term=xterm-256color
# Display OSC8 strings in the embedded terminal
#
# Default: false
#enable-osc8=false
[ui]
#
# Describes the format for each row in a mailbox view. This is a comma
# separated list of column names with an optional align and width suffix. After
# the column name, one of the '<' (left), ':' (center) or '>' (right) alignment
# characters can be added (by default, left) followed by an optional width
# specifier. The width is either an integer representing a fixed number of
# characters, or a percentage between 1% and 99% representing a fraction of the
# terminal width. It can also be one of the '*' (auto) or '=' (fit) special
# width specifiers. Auto width columns will be equally attributed the remaining
# terminal width. Fit width columns take the width of their contents. If no
# width specifier is set, '*' is used by default.
#
# Default: date<20,name<17,flags>4,subject<*
#index-columns=date<20,name<17,flags>4,subject<*
#
# Each name in index-columns must have a corresponding column-$name setting.
# All column-$name settings accept golang text/template syntax. See
# aerc-templates(7) for available template attributes and functions.
#
# Default settings
#column-date={{.DateAutoFormat .Date.Local}}
#column-name={{index (.From | names) 0}}
#column-flags={{.Flags | join ""}}
#column-subject={{.ThreadPrefix}}{{.Subject}}
#
# String separator inserted between columns. When the column width specifier is
# an exact number of characters, the separator is added to it (i.e. the exact
# width will be fully available for the column contents).
#
# Default: " "
#column-separator=" "
#
# See time.Time#Format at https://godoc.org/time#Time.Format
#
# Default: 2006-01-02 03:04 PM (ISO 8601 + 12 hour time)
#timestamp-format=2006-01-02 03:04 PM
#
# Index-only time format for messages that were received/sent today.
# If this is not specified, timestamp-format is used instead.
#
#this-day-time-format=
#
# Index-only time format for messages that were received/sent within the last
# 7 days. If this is not specified, timestamp-format is used instead.
#
#this-week-time-format=
#
# Index-only time format for messages that were received/sent this year.
# If this is not specified, timestamp-format is used instead.
#
#this-year-time-format=
#
# Width of the sidebar, including the border.
#
# Default: 20
#sidebar-width=20
#
# Message to display when viewing an empty folder.
#
# Default: (no messages)
#empty-message=(no messages)
# Message to display when no folders exists or are all filtered
#
# Default: (no folders)
#empty-dirlist=(no folders)
# Enable mouse events in the ui, e.g. clicking and scrolling with the mousewheel
#
# Default: false
#mouse-enabled=false
#
# Ring the bell when new messages are received
#
# Default: true
#new-message-bell=true
#
# Template to use for Account tab titles
#
# Default: {{.Account}}
#tab-title-account={{.Account}}
# Marker to show before a pinned tab's name.
#
# Default: `
#pinned-tab-marker='`'
# Template for the left side of the directory list.
# See aerc-templates(7) for all available fields and functions.
#
# Default: {{.Folder}}
#dirlist-left={{.Folder}}
# Template for the right side of the directory list.
# See aerc-templates(7) for all available fields and functions.
#
# Default: {{if .Unread}}{{humanReadable .Unread}}/{{end}}{{if .Exists}}{{humanReadable .Exists}}{{end}}
#dirlist-right={{if .Unread}}{{humanReadable .Unread}}/{{end}}{{if .Exists}}{{humanReadable .Exists}}{{end}}
# Delay after which the messages are actually listed when entering a directory.
# This avoids loading messages when skipping over folders and makes the UI more
# responsive. If you do not want that, set it to 0s.
#
# Default: 200ms
#dirlist-delay=200ms
# Display the directory list as a foldable tree that allows to collapse and
# expand the folders.
#
# Default: false
#dirlist-tree=false
# If dirlist-tree is enabled, set level at which folders are collapsed by
# default. Set to 0 to disable.
#
# Default: 0
#dirlist-collapse=0
# List of space-separated criteria to sort the messages by, see *sort*
# command in *aerc*(1) for reference. Prefixing a criterion with "-r "
# reverses that criterion.
#
# Example: "from -r date"
#
#sort=
# Moves to next message when the current message is deleted
#
# Default: true
#next-message-on-delete=true
# Automatically set the "seen" flag when a message is opened in the message
# viewer.
#
# Default: true
#auto-mark-read=true
# The directories where the stylesets are stored. It takes a colon-separated
# list of directories. If this is unset or if a styleset cannot be found, the
# following paths will be used as a fallback in that order:
#
# ${XDG_CONFIG_HOME:-~/.config}/aerc/stylesets
# ${XDG_DATA_HOME:-~/.local/share}/aerc/stylesets
# /nix/store/jzlsc52f1zsczi5rmjrbff45i7ng3cph-aerc-0.15.2/share/aerc/stylesets
#
#stylesets-dirs=
# Uncomment to use box-drawing characters for vertical and horizontal borders.
#
# Default: " "
#border-char-vertical=" "
#border-char-horizontal=" "
# Sets the styleset to use for the aerc ui elements.
#
# Default: default
#styleset-name=default
# Activates fuzzy search in commands and their arguments: the typed string is
# searched in the command or option in any position, and need not be
# consecutive characters in the command or option.
#
# Default: false
#fuzzy-complete=false
# How long to wait after the last input before auto-completion is triggered.
#
# Default: 250ms
#completion-delay=250ms
# The minimum required characters to allow auto-completion to be triggered after
# completion-delay.
#
# Default: 1
#completion-min-chars=1
#
# Global switch for completion popovers
#
# Default: true
#completion-popovers=true
# Uncomment to use UTF-8 symbols to indicate PGP status of messages
#
# Default: ASCII
#icon-unencrypted=
#icon-encrypted=✔
#icon-signed=✔
#icon-signed-encrypted=✔
#icon-unknown=✘
#icon-invalid=⚠
# Reverses the order of the message list. By default, the message list is
# ordered with the newest (highest UID) message on top. Reversing the order
# will put the oldest (lowest UID) message on top. This can be useful in cases
# where the backend does not support sorting.
#
# Default: false
#reverse-msglist-order = false
# Reverse display of the mesage threads. Default order is the the intial
# message is on the top with all the replies being displayed below. The
# reverse option will put the initial message at the bottom with the
# replies on top.
#
# Default: false
#reverse-thread-order=false
# Sort the thread siblings according to the sort criteria for the messages. If
# sort-thread-siblings is false, the thread siblings will be sorted based on
# the message UID in ascending order. This option is only applicable for
# client-side threading with a backend that enables sorting. Note that there's
# a performance impact when sorting is activated.
#
# Default: false
#sort-thread-siblings=false
#[ui:account=foo]
#
# Enable a threaded view of messages. If this is not supported by the backend
# (IMAP server or notmuch), threads will be built by the client.
#
# Default: false
#threading-enabled=false
# Force client-side thread building
#
# Default: false
#force-client-threads=false
# Debounce client-side thread building
#
# Default: 50ms
#client-threads-delay=50ms
[statusline]
#
# Describes the format for the status line. This is a comma separated list of
# column names with an optional align and width suffix. See [ui].index-columns
# for more details. To completely mute the status line except for push
# notifications, explicitly set status-columns to an empty string.
#
# Default: left<*,center:=,right>*
#status-columns=left<*,center:=,right>*
#
# Each name in status-columns must have a corresponding column-$name setting.
# All column-$name settings accept golang text/template syntax. See
# aerc-templates(7) for available template attributes and functions.
#
# Default settings
#column-left=[{{.Account}}] {{.StatusInfo}}
#column-center={{.PendingKeys}}
#column-right={{.TrayInfo}}
#
# String separator inserted between columns.
# See [ui].column-separator for more details.
#
#column-separator=" "
# Specifies the separator between grouped statusline elements.
#
# Default: " | "
#separator=" | "
# Defines the mode for displaying the status elements.
# Options: text, icon
#
# Default: text
#display-mode=text
[viewer]
#
# Specifies the pager to use when displaying emails. Note that some filters
# may add ANSI codes to add color to rendered emails, so you may want to use a
# pager which supports ANSI codes.
#
# Default: less -R
#pager=less -R
#
# If an email offers several versions (multipart), you can configure which
# mimetype to prefer. For example, this can be used to prefer plaintext over
# html emails.
#
# Default: text/plain,text/html
#alternatives=text/plain,text/html
#
# Default setting to determine whether to show full headers or only parsed
# ones in message viewer.
#
# Default: false
#show-headers=false
#
# Layout of headers when viewing a message. To display multiple headers in the
# same row, separate them with a pipe, e.g. "From|To". Rows will be hidden if
# none of their specified headers are present in the message.
#
# Default: From|To,Cc|Bcc,Date,Subject
#header-layout=From|To,Cc|Bcc,Date,Subject
# Whether to always show the mimetype of an email, even when it is just a single part
#
# Default: false
#always-show-mime=false
# Parses and extracts http links when viewing a message. Links can then be
# accessed with the open-link command.
#
# Default: true
#parse-http-links=true
[compose]
#
# Specifies the command to run the editor with. It will be shown in an embedded
# terminal, though it may also launch a graphical window if the environment
# supports it. Defaults to $EDITOR, or vi.
#editor=
#
# Default header fields to display when composing a message. To display
# multiple headers in the same row, separate them with a pipe, e.g. "To|From".
#
# Default: To|From,Subject
#header-layout=To|From,Subject
#
# Specifies the command to be used to tab-complete email addresses. Any
# occurrence of "%s" in the address-book-cmd will be replaced with what the
# user has typed so far.
#
# The command must output the completions to standard output, one completion
# per line. Each line must be tab-delimited, with an email address occurring as
# the first field. Only the email address field is required. The second field,
# if present, will be treated as the contact name. Additional fields are
# ignored.
#
# This parameter can also be set per account in accounts.conf.
#address-book-cmd=
# Specifies the command to be used to select attachments. Any occurence of '%s'
# in the file-picker-cmd will be replaced the argument <arg> to :attach -m
# <arg>.
#
# The command must output the selected files to standard output, one file per
# line.
#file-picker-cmd=
#
# Allow to address yourself when replying
#
# Default: true
#reply-to-self=true
#
# Warn before sending an email that matches the specified regexp but does not
# have any attachments. Leave empty to disable this feature.
#
# Uses Go's regexp syntax, documented at https://golang.org/s/re2syntax. The
# "(?im)" flags are set by default (case-insensitive and multi-line).
#
# Example:
# no-attachment-warning=^[^>]*attach(ed|ment)
#
#no-attachment-warning=
#
# When set, aerc will generate "format=flowed" bodies with a content type of
# "text/plain; format=flowed" as described in RFC3676. This format is easier to
# handle for some mailing software, and generally just looks like ordinary
# text. To actually make use of this format's features, you'll need support in
# your editor.
#
#format-flowed=false
[multipart-converters]
#
# Converters allow to generate multipart/alternative messages by converting the
# main text/plain part into any other MIME type. Only exact MIME types are
# accepted. The commands are invoked with sh -c and are expected to output
# valid UTF-8 text.
#
# Example (obviously, this requires that you write your main text/plain body
# using the markdown syntax):
#text/html=pandoc -f markdown -t html --standalone
[filters]
#
# Filters allow you to pipe an email body through a shell command to render
# certain emails differently, e.g. highlighting them with ANSI escape codes.
#
# The commands are invoked with sh -c. The following folders are appended to
# the system $PATH to allow referencing filters from their name only:
#
# ${XDG_CONFIG_HOME:-~/.config}/aerc/filters
# ${XDG_DATA_HOME:-~/.local/share}/aerc/filters
# $PREFIX/share/aerc/filters
# /usr/share/aerc/filters
#
# The following variables are defined in the filter command environment:
#
# AERC_MIME_TYPE the part MIME type/subtype
# AERC_FORMAT the part content type format= parameter
# AERC_FILENAME the attachment filename (if any)
# AERC_SUBJECT the message Subject header value
# AERC_FROM the message From header value
#
# The first filter which matches the email's mimetype will be used, so order
# them from most to least specific.
#
# You can also match on non-mimetypes, by prefixing with the header to match
# against (non-case-sensitive) and a comma, e.g. subject,text will match a
# subject which contains "text". Use header,~regex to match against a regex.
#
text/plain=colorize
text/calendar=calendar
message/delivery-status=colorize
message/rfc822=colorize
#text/html=pandoc -f html -t plain | colorize
#text/html=html | colorize
#text/*=bat -fP --file-name="$AERC_FILENAME"
#application/x-sh=bat -fP -l sh
#image/*=catimg -w $(tput cols) -
#subject,~Git(hub|lab)=lolcat -f
#from,thatguywhodoesnothardwraphismessages=wrap -w 100 | colorize
# This special filter is only used to post-process email headers when
# [viewer].show-headers=true
# By default, headers are piped directly into the pager.
#
.headers=colorize
[openers]
#
# Openers allow you to specify the command to use for the :open and :open-link
# actions on a per-MIME-type basis. The :open-link URL scheme is used to
# determine the MIME type as follows: x-scheme-handler/<scheme>.
#
# {} is expanded as the temporary filename to be opened. If it is not
# encountered in the command, the temporary filename will be appened to the end
# of the command.
#
# Like [filters], openers support basic shell globbing. The first opener which
# matches the part's MIME type (or URL scheme handler MIME type) will be used,
# so order them from most to least specific.
#
# Examples:
# x-scheme-handler/irc=hexchat
# x-scheme-handler/http*=firefox
# text/html=surf -dfgms
# text/plain=gvim {} +125
# message/rfc822=thunderbird
[hooks]
#
# Hooks are triggered whenever the associated event occurs.
#
# Executed when a new email arrives in the selected folder
#mail-received=notify-send "New mail from $AERC_FROM_NAME" "$AERC_SUBJECT"
#
# Executed when aerc starts
#aerc-startup=aerc :terminal calcurse && aerc :next-tab
#
# Executed when aerc shuts down.
#aerc-shutdown=
[templates]
# Templates are used to populate email bodies automatically.
#
# The directories where the templates are stored. It takes a colon-separated
# list of directories. If this is unset or if a template cannot be found, the
# following paths will be used as a fallback in that order:
#
# ${XDG_CONFIG_HOME:-~/.config}/aerc/templates
# ${XDG_DATA_HOME:-~/.local/share}/aerc/templates
# /nix/store/jzlsc52f1zsczi5rmjrbff45i7ng3cph-aerc-0.15.2/share/aerc/templates
#
#template-dirs=
# The default template to be used for new messages.
#
# default: new_message
#new-message=new_message
# The default template to be used for quoted replies.
#
# default: quoted_reply
#quoted-reply=quoted_reply
# The default template to be used for forward as body.
#
# default: forward_as_body
#forwards=forward_as_body

View file

@ -0,0 +1,129 @@
# Binds are of the form <key sequence> = <command to run>
# To use '=' in a key sequence, substitute it with "Eq": "<Ctrl+Eq>"
# If you wish to bind #, you can wrap the key sequence in quotes: "#" = quit
<C-p> = :prev-tab<Enter>
<C-n> = :next-tab<Enter>
<C-t> = :term<Enter>
? = :help keys<Enter>
[messages]
q = :quit<Enter>
j = :next<Enter>
<Down> = :next<Enter>
<C-d> = :next 50%<Enter>
<C-f> = :next 100%<Enter>
<PgDn> = :next 100%<Enter>
k = :prev<Enter>
<Up> = :prev<Enter>
<C-u> = :prev 50%<Enter>
<C-b> = :prev 100%<Enter>
<PgUp> = :prev 100%<Enter>
g = :select 0<Enter>
G = :select -1<Enter>
J = :next-folder<Enter>
K = :prev-folder<Enter>
H = :collapse-folder<Enter>
L = :expand-folder<Enter>
v = :mark -t<Enter>
V = :mark -v<Enter>
T = :toggle-threads<Enter>
<Enter> = :view<Enter>
d = :prompt 'Really delete this message?' 'delete-message'<Enter>
D = :delete<Enter>
A = :archive flat<Enter>
C = :compose<Enter>
rr = :reply -a<Enter>
rq = :reply -aq<Enter>
Rr = :reply<Enter>
Rq = :reply -q<Enter>
c = :cf<space>
$ = :term<space>
! = :term<space>
| = :pipe<space>
/ = :search<space>
\ = :filter<space>
n = :next-result<Enter>
N = :prev-result<Enter>
<Esc> = :clear<Enter>
[messages:folder=Drafts]
<Enter> = :recall<Enter>
[view]
/ = :toggle-key-passthrough<Enter>/
q = :close<Enter>
O = :open<Enter>
S = :save<space>
| = :pipe<space>
D = :delete<Enter>
A = :archive flat<Enter>
<C-l> = :open-link <space>
f = :forward<Enter>
rr = :reply -a<Enter>
rq = :reply -aq<Enter>
Rr = :reply<Enter>
Rq = :reply -q<Enter>
H = :toggle-headers<Enter>
<C-k> = :prev-part<Enter>
<C-j> = :next-part<Enter>
J = :next<Enter>
K = :prev<Enter>
[view::passthrough]
$noinherit = true
$ex = <C-x>
<Esc> = :toggle-key-passthrough<Enter>
[compose]
# Keybindings used when the embedded terminal is not selected in the compose
# view
$noinherit = true
$ex = <C-x>
<C-k> = :prev-field<Enter>
<C-j> = :next-field<Enter>
<A-p> = :switch-account -p<Enter>
<A-n> = :switch-account -n<Enter>
<tab> = :next-field<Enter>
<backtab> = :prev-field<Enter>
<C-p> = :prev-tab<Enter>
<C-n> = :next-tab<Enter>
[compose::editor]
# Keybindings used when the embedded terminal is selected in the compose view
$noinherit = true
$ex = <C-x>
<C-k> = :prev-field<Enter>
<C-j> = :next-field<Enter>
<C-p> = :prev-tab<Enter>
<C-n> = :next-tab<Enter>
[compose::review]
# Keybindings used when reviewing a message to be sent
y = :send<Enter>
n = :abort<Enter>
v = :preview<Enter>
p = :postpone<Enter>
q = :choose -o d discard abort -o p postpone postpone<Enter>
e = :edit<Enter>
a = :attach<space>
d = :detach<space>
[terminal]
$noinherit = true
$ex = <C-x>
<C-p> = :prev-tab<Enter>
<C-n> = :next-tab<Enter>

View file

@ -0,0 +1,19 @@
{ lib, config, ... }:
with lib;
let
cfg = config.modules.utils.email;
in
{ options.modules.utils.email = { enable = mkEnableOption "utils.email"; };
config = mkIf cfg.enable {
programs.aerc = {
enable = true;
};
home.file.".config/aerc" = {
source = ./config;
recursive = true;
};
};
}

View file

@ -0,0 +1,17 @@
{ pkgs, lib, config, ... }:
with lib;
let
cfg = config.modules.utils.irc;
in
{ options.modules.utils.irc = { enable = mkEnableOption "utils.irc"; };
config = mkIf cfg.enable {
home.packages = with pkgs; [
weechat
];
programs.bash.shellAliases = {
chat = "weechat";
};
};
}

View file

@ -0,0 +1,68 @@
let data_dir = has('nvim') ? stdpath('data') . '/site' : '~/.vim'
if empty(glob(data_dir . '/autoload/plug.vim'))
silent execute '!curl -fLo '.data_dir.'/autoload/plug.vim --create-dirs https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim'
autocmd VimEnter * PlugInstall --sync | source $MYVIMRC
endif
if empty(glob('~/.vim/plugged'))
silent! :PlugInstall | q
endif
autocmd VimEnter * if len(filter(values(g:plugs), '!isdirectory(v:val.dir)'))
\| PlugInstall --sync | source $MYVIMRC
\| endif
call plug#begin('~/.vim/plugged')
Plug 'joshdick/onedark.vim'
Plug 'tpope/vim-surround'
Plug 'jiangmiao/auto-pairs'
Plug 'junegunn/fzf', { 'do': { -> fzf#install() } }
Plug 'junegunn/fzf.vim'
Plug 'mtdl9/vim-log-highlighting'
Plug 'machakann/vim-highlightedyank'
Plug 'itchyny/lightline.vim'
call plug#end()
let mapleader = " "
colorscheme onedark
let $FZF_DEFAULT_OPTS = '--bind=tab:up,shift-tab:down'
let g:fzf_layout = { 'window': 'enew' }
let g:highlightedyank_highlight_duration = 80
let g:lightline = { 'colorscheme': 'one', }
set laststatus=2
set number
set relativenumber
set cursorline
set noincsearch
set ignorecase
set clipboard=unnamedplus
set noswapfile
set tabstop=2
set shiftwidth=2
set expandtab
highlight CursorLine ctermbg=NONE guibg=NONE
highlight CursorLineNr ctermfg=magenta guifg=magenta
highlight HighlightedyankRegion ctermfg=NONE guifg=NONE
highlight Normal ctermbg=NONE guibg=NONE
highlight NormalNC ctermbg=NONE guibg=NONE
highlight Search ctermfg=yellow guifg=yellow
highlight Search ctermbg=black guibg=black
vnoremap < <gv
vnoremap > >gv
nnoremap <C-U> <C-U>zz
nnoremap <C-D> <C-D>zz
nnoremap <leader>e :Explore<CR>
nnoremap <leader><ESC> :noh<CR>
nnoremap <leader>/ :Rg<Space>
nnoremap <Leader>ts :execute "normal! a" . strftime('[%b %d %H:%M:%S - BR]')<CR>

View file

@ -0,0 +1,22 @@
{ pkgs, lib, config, ... }:
with lib;
let
cfg = config.modules.utils.vim;
in
{ options.modules.utils.vim = { enable = mkEnableOption "utils.vim"; };
config = mkIf cfg.enable {
home = {
packages = with pkgs; [
vim
];
file.".config/.vimrc" = {
source = ./config/vimrc;
};
};
programs.bash.shellAliases = {
vi = "${pkgs.vim}/bin/vim";
};
};
}

View file

@ -0,0 +1,9 @@
{ lib, pkgs, ... }:
{
imports = [
../../user
./hardware.nix
./system.nix
];
}

View file

@ -0,0 +1,106 @@
{ disks ? [ "/dev/nvme0n1" "/dev/sda" ], ... }:
{
disko.devices = {
disk = {
one = {
type = "disk";
device = builtins.elemAt disks 0;
content = {
type = "table";
format = "gpt";
partitions = [
{
name = "boot";
start = "0";
end = "100M";
fs-type = "fat32";
bootable = true;
content = {
type = "filesystem";
format = "vfat";
mountpoint = "/boot";
};
}
{
start = "100M";
end = "100%FREE";
content = {
type = "lvm_pv";
vg = "stick";
};
}
];
};
};
};
disk = {
two = {
type = "disk";
device = builtins.elemAt disks 1;
content = {
type = "table";
format = "gpt";
partitions = [
{
start = "0";
end = "100%";
content = {
type = "lvm_pv";
vg = "ssd";
};
}
];
};
};
};
lvm_vg = {
stick = {
type = "lvm_vg";
lvs = {
aaa = {
size = "1M";
};
zzz = {
size = "1M";
};
root = {
size = "100%";
content = {
name = "NixOS";
type = "filesystem";
format = "ext4";
mountpoint = "/";
mountOptions = [
"defaults"
];
};
};
};
};
};
lvm_vg = {
ssd = {
type = "lvm_vg";
lvs = {
aaa = {
size = "1M";
};
zzz = {
size = "1M";
};
home = {
size = "100%";
content = {
name = "home";
type = "filesystem";
format = "ext4";
mountpoint = "/home";
};
};
};
};
};
};
}

View file

@ -0,0 +1,56 @@
{ config, lib, pkgs, modulesPath, ... }:
{
imports = [ (modulesPath + "/installer/scan/not-detected.nix") ];
# Kernel
boot.initrd.availableKernelModules = [ "vmd" "xhci_pci" "ahci" "nvme" "usbhid" "usb_storage" "sd_mod" ];
boot.initrd.kernelModules = [ "dm-snapshot" ];
boot.extraModulePackages = [ ];
boot.kernelPackages = pkgs.linuxPackages_latest;
boot.kernelParams = [ "intel_iommu=on" ];
boot.kernelModules = [ "kvm-intel" "virtio" "vfio-pci" "coretemp" ];
# FStab
fileSystems = {
"/" = {
device = "/dev/disk/by-uuid/af24c5b3-8a6e-4333-a61d-922a97928cae";
fsType = "ext4";
};
"/home" = {
device = "/dev/disk/by-uuid/1639ee20-28d6-4649-814d-ba981c138b35";
fsType = "ext4";
};
"/boot" = {
device = "/dev/disk/by-uuid/74B9-4AAF";
fsType = "vfat";
};
};
# GPU
hardware.nvidia.open = true;
# Virtualisation
nix.settings.system-features = [ "kvm" ];
environment.systemPackages = with pkgs; [
virt-manager
];
virtualisation.libvirtd = {
enable = true;
qemu = {
package = pkgs.qemu_kvm;
runAsRoot = true;
ovmf.enable = true;
};
};
# CPU
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
powerManagement.cpuFreqGovernor = lib.mkDefault "performance";
hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
}

View file

@ -0,0 +1,43 @@
{ config, ... }:
{
programs.home-manager.enable = true;
programs.bash.shellAliases = {
nixup = "sudo nixos-rebuild switch --flake /etc/nixos/.#desktop";
};
imports = [
../../modules
../../user
];
home.stateVersion = "22.11";
home.username = "${config.user.name}";
home.homeDirectory = "/home/${config.user.name}";
modules = {
bash.enable = true;
git.enable = true;
gpg.enable = true;
security.enable = true;
utils = {
enable = true;
dev.enable = true;
irc.enable = true;
vim.enable = false;
};
gui = {
enable = true;
alacritty.enable = true;
browsers.enable = true;
corn.enable = true;
fun.enable = true;
neovim.enable = true;
utils.enable = true;
writing.enable = true;
};
};
}

View file

@ -0,0 +1,130 @@
{ pkgs, lib, config, ... }:
{ system.stateVersion = "22.11";
# Users
users.users = {
${config.user.name} = {
isNormalUser = true;
extraGroups = config.user.groups;
openssh.authorizedKeys.keys = config.user.sshKeys;
};
};
# Nix
nix = {
channel.enable = false;
package = pkgs.nixFlakes;
extraOptions = "experimental-features = nix-command flakes";
settings = {
auto-optimise-store = true;
trusted-users = [ "${config.user.name}" ];
};
gc = {
automatic = true;
dates = "weekly";
options = "--delete-older-than 30d";
};
};
# Bootloader
boot.loader = {
timeout = null;
grub = {
enable = true;
useOSProber = true;
devices = [ "nodev" ];
efiSupport = true;
configurationLimit = 5;
};
efi = {
canTouchEfiVariables = true;
};
};
environment.systemPackages = with pkgs; [
pavucontrol
];
# DE
programs.sway = {
enable = true;
package = null;
};
# Fonts
fonts.packages = with pkgs; [
terminus_font
nerdfonts
];
# Audio
services.pipewire = {
enable = true;
audio.enable = true;
wireplumber.enable = true;
pulse.enable = true;
jack.enable = true;
alsa.enable = true;
alsa.support32Bit = true;
};
# Sudo Options
security.sudo = {
wheelNeedsPassword = false;
execWheelOnly = true;
};
# System Services
services = {
cron = {
enable = true;
systemCronJobs = [];
};
};
# Locale
time = {
timeZone = "America/New_York";
};
services.timesyncd = {
enable = true;
servers = [
"0.pool.ntp.org"
"1.pool.ntp.org"
"2.pool.ntp.org"
"3.pool.ntp.org"
];
};
i18n.defaultLocale = "en_US.UTF-8";
console = {
font = "Lat2-Terminus16";
useXkbConfig = true;
};
# Networking
networking = {
hostName = "socrates";
useDHCP = lib.mkDefault true;
networkmanager.enable = true;
firewall = {
enable = true;
allowedTCPPorts = [ 22 80 443 ];
};
};
services.openssh = {
enable = true;
startWhenNeeded = true;
settings = {
X11Forwarding = false;
PasswordAuthentication = false;
};
};
}

View file

@ -0,0 +1 @@
#TODO: nixify the shitty laptop

View file

@ -0,0 +1 @@
# TODO: nixify the server

View file

@ -0,0 +1,8 @@
{ lib, ... }:
{
imports = [
../../user
./system.nix
];
}

33
src/systems/wsl/home.nix Normal file
View file

@ -0,0 +1,33 @@
{ config, ... }:
{
programs.home-manager.enable = true;
programs.bash.shellAliases = {
nixup = "sudo nixos-rebuild switch --flake .#windows";
};
imports = [
../../modules
../../user
];
home.stateVersion = "23.11";
home.username = "${config.user.name}";
home.homeDirectory = "/home/${config.user.name}";
modules = {
bash.enable = true;
git.enable = true;
gpg.enable = true;
gui.enable = false;
security.enable = true;
utils = {
enable = true;
dev.enable = true;
email.enable = true;
irc.enable = true;
vim.enable = true;
};
};
}

View file

@ -0,0 +1,83 @@
{ pkgs, lib, config, ... }:
{ system.stateVersion = "23.11";
# Users
users.users = {
${config.user.name} = {
isNormalUser = true;
extraGroups = config.user.groups;
openssh.authorizedKeys.keys = config.user.sshKeys;
};
};
boot.isContainer = true;
# Nix
nix = {
channel.enable = false;
package = pkgs.nixFlakes;
extraOptions = "experimental-features = nix-command flakes";
settings = {
auto-optimise-store = true;
trusted-users = [ "${config.user.name}" ];
};
gc = {
automatic = true;
dates = "weekly";
options = "--delete-older-than 30d";
};
};
# Sudo Options
security.sudo = {
wheelNeedsPassword = false;
execWheelOnly = true;
};
# System Services
services = {
cron = {
enable = true;
systemCronJobs = [];
};
};
# Locale
time = {
timeZone = "America/New_York";
};
services.timesyncd = {
enable = true;
servers = [
"0.pool.ntp.org"
"1.pool.ntp.org"
"2.pool.ntp.org"
"3.pool.ntp.org"
];
};
i18n.defaultLocale = "en_US.UTF-8";
console = {
font = "Lat2-Terminus16";
useXkbConfig = true;
};
# Networking
networking = {
useDHCP = lib.mkDefault true;
firewall = {
enable = true;
allowedTCPPorts = [ 22 80 443 ];
};
};
services.openssh = {
enable = true;
startWhenNeeded = true;
settings = {
X11Forwarding = false;
PasswordAuthentication = false;
};
};
}

64
src/user/default.nix Normal file
View file

@ -0,0 +1,64 @@
{ lib, pkgs, ... }:
# Replace with your user configurations
{
options = {
user = lib.mkOption {
type = lib.types.attrs;
default = {
name = "bryan";
shell = pkgs.bash;
groups = [
"wheel" "networkmanager" "home-manager"
"input" "video" "audio"
"kvm" "libvirtd" "docker"
];
sshKeys = [
"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDl4895aB9P5p/lp8Hq5rHun4clvhyTSHFi3U2d6OOBoW5Fm+VcQnW/xbjmCBsXk5BdiowsBxQhwnzdfz/KJL7J5RobomUEaVRwb9UwT88eJveLp14BG8j2J3SjfyhrCX+4jkPx0bPQk1HGcuYY+tPEXf1q/ps88Dhu0CARBIzYQOTYY6b1qWzxpDoFZGHjKG8g5iY6FIu65yKKvvVy1f8IgZ3l3IpwBWVamxgkTcYY0QYSrmzo1n7TXxwrWbvenAqBsQ0cBPs+gVa3uIr+1TJl0Az5SElBVGu3LvUdlk58trtPUj6TQR3YUkg7Vjll7WHOdqhux5ZQNhjkOsHerf0Tw86e6cEzgeTuIbQHIb0LcsUunwKcuh2+au7RO599cvHn0+xZE5MZBxloDDaJ3JsiliM8kyPP/U3ERj03cWLW7BqbT+sfjAOl21RCzk0iQxk1wt/8VmtCr9Adv7IyrtaYvf/bwRP+g+9ldmzKGt8Mdb605uVzZ70H/LLm17f40Te+QHaex5by/6p6cuwEEZtgIg53Wpglu0rA6UxrBfQEHKl/Jt3FLeE0mnEyYkkR2MnHNtyWRIXtuqYZMAm2Ub1pFHH7jQV1gGiDVTw6a2eIwK21a/hXtRjFUpFd1nB1n+KNfJBE4zT3wm3Ud7mKw/6rWnoRyhYZvGXkFdp+iEs49Q=="
"ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBK2ROz7EVvE+nzF5k9EYZ2v3JhBzk058uh3QJTzcG4t70fkZgh9y56AOx26eXlKQWuuV05e8EkWRuVI8gfA2ROI="
];
gitConfig= {
userName = "Bryan Ramos";
userEmail = "bryan@ramos.codes";
signing = {
key = "F1F3466458452B2DF351F1E864D12BA95ACE1F2D";
signByDefault = true;
};
extraConfig = {
init = { defaultBranch = "master"; };
mergetool = {
lazygit = {
cmd = "lazygit";
trustExitCode = true;
};
};
merge = {
tool = "lazygit";
};
safe = {
directory = "/etc/nixos";
};
};
ignores = [
"node_modules"
".direnv"
"dist-newstyle"
".nuxt/"
".output/"
"dist"
];
};
pgpKey = {
text = import ./pgpKey.nix;
trust = 5;
};
};
};
};
}

111
src/user/pgpKey.nix Normal file
View file

@ -0,0 +1,111 @@
''
-----BEGIN PGP PUBLIC KEY BLOCK-----
mQINBGP0BgMBEAC2v+n9plI0p+TqIrmvz7JHoYbtUK3NDkyNeIsgS+sE5nfLB1Ef
vQCR0HdysgpmAUywqEx+YK7Nkr4szoK8nDLpgpSfaDZNss+ePu6eYVTVktelBn2Q
5f5MKDILY9mkmDPgzvpDDhkFXGK3cpeUX+X5vY1W76yuRgm6zBDIux+yf027nw3U
phesn/WlWXRsmAXG2helt1nB6Foj6LjgwRG/aKMI8cQq0JS13cfUZO1nq2ifM0pm
4HqWgbZOKYWHsoOw4qNiuxWwVoL5E7UQW2MEyxZmLZaNohEpReYpI0N9FGB/AZYt
iKn9SO9SmG+afE+gxrExJYZSGVHHKlPc79dcIBVvYEA8dV/OJBjHc83EhUQVU4vQ
x1y386HYctlHVWZ64tc1XROlQe++NxfgQZz4jnvGzHMakr8/IZAV3LP3PGVAa7kx
iVrTE+WodK/kELm1PMLWlWmXT3GiumOngm4y1dWtUirqxni/Nl7BA4eHM3Q3OZiR
eEb80FkbXCoaP5REU1EdVlAW/ZGP+mTwiqekT5ThocaD/BgYSy9UlGf5YyOEnqOt
G+0JfS3mG0PysFjF0B5dMyBquikD4zVBo3+a7ppbrAage3EFhHiX0Les0q566I8p
0hlXS7nz0I4xAxxRLfydwJptndjZgeiq9o1XMRA0JUZQhzuk2VYQ6MSVhwARAQAB
tB9CcnlhbiBSYW1vcyA8YnJ5YW5AcmFtb3MuY29kZXM+iQJOBBMBCgA4FiEE8fNG
ZFhFKy3zUfHoZNErqVrOHy0FAmP0BgMCGwEFCwkIBwIGFQoJCAsCBBYCAwECHgEC
F4AACgkQZNErqVrOHy25SBAArl6JHrDm3fLXPhwtHf9WzxQvW6BmMgLQQ+bGGGba
A3e+eKb0ibSmXH9M22GOSxKqk2BePtoLFdyDKDFNwYDwzj0ioQ80Q9YR6aoSuwOf
HwXeiYsgK76IbsRciXSv6JgAsXO9UOGTlHlTgFsE3AMjnCgPrHbV3SZdkFt71XMo
fbRmYwC33HK6QNUXeq4O+gGO5vJI8Wx1mtmy6kq/3srzMpCGybg9M8C5AQoazo/u
WOjO57QkUdbAXO8HbHInexsstJJn+0o/FLfMoOy7v/cpzTLbbpONRzQbEq1/Utt1
TaIc1FTWT1b4oWnIGv2stlCGzx9IgsseJocSBG+kGgkKwVBWIcCwq+cCdfkOReCk
VHTg1oRH8t078346KuxEaA7ofKaByirQosZUeF5WTyMuJUDf1mNxxZngRKjIHD3c
lmK8REnYjQ4b+RfznfV8qc8tH624EUTNlT123ufUIvba0fR8OryhdxPOOgdLjlNL
XdkfG5oENnBy3EzGn7xgR6sCRtlFSEcfKQFcec1fjqYMHxPAExajmSHLwr5107LT
4B+F5eOt9CBFKW/cxnVwG/3oW0mzLa231V0eYquiYkbYHVswLdhr02vyHpLXXVZk
JgiLSXIJ6yKwLA9W8HgHgDYCp899Jl+wqhFLxr7oUjXcLhuZO9Q3P3req0SJRfUu
GTO5Ag0EY/QGQAEQANsJBUpkk0ZW5swgzC/c7pxv4VGS8VZcr3Isol8NHAUUwHyo
jqAYNtqW8PQLgQ34uuuC5GCS2hxN57WdgmSkv/to8THl6IbE1V/YVaaGXX9yiJmH
72//kc9g2prXyrtObwVhgKiYQxPPegm9ubLkb1khCTLhozCJDM1wbQxmE5I2cICC
5lwCi1NDsAyvUtWANzb0EXPZh2iPv8sWMh3RStAGSsboHzHYdR9RZGRjKG/ET5zv
OBbFpRLFjvMJUL22M0V5FFPbuz+4Aut21wkYdueHtREpUgAcba68Doz75jQb0PEZ
52hjLKuXVf0/1sEPXUs/sL8kyl6QzIqFIXsrjbw6BrGSdhn6YoY95koCb6AXUrFC
oOXQC5BecTcP7V3GOWDEaDUbjN8mc2t1ujs7KYIqi0UCiHa9m5L2Q/9TyOSLyjSf
0VKHzib7Ov76GvphbYoQSXWX8R6ogcexQH6aQlXI31ir/HsHkatImYomySZiwNVV
5PQD/7lbWGjLB6LB9PsyVIVl3uq+sSX7xKeogZkEuTcerKVJjpknisKh6aR/uJRV
KJs2U3MolyVanDb/y6VBJrCOu8ZiCZuDtCntUg8MxeLNFO0MVdgAPiHMtJd8YrzK
bhbkHBufAgOLMbGTYq47bQNuRz/CjIz0xll0tLeS9LD1hcSWX/nMhFgfxDjxABEB
AAGJBGwEGAEKACAWIQTx80ZkWEUrLfNR8ehk0SupWs4fLQUCY/QGQAIbAgJACRBk
0SupWs4fLcF0IAQZAQoAHRYhBDgB5+1vnI0s1XHgHmq9zRRNZkPIBQJj9AZAAAoJ
EGq9zRRNZkPIMbUQAJaDnJHMMXTNmANva65XjY2eJpoYBCIvd8FodRfFCbAPkNad
MtsCgd2dXZPizTOUNqcOujACd7u3P/VazYT0cUgjx6mpWdvxYuGMCM71WLHKeCaq
bXzzKrNaREMDTsMBn0wrIr5ZEuRsLOi4ZVZ5vFvtMQYnzjNT6gON+fHpaD6sShnR
VWXWaYtQ2ttN2+6gwmKCaqiH2suA+QkI/gPjqdMOeXvu6sMUd5IjaCBJy3Ddyjif
/ZYkJUjDkxG7aC4B2XtGUf0lPG+kiCHGjgTsvIeYYSpi/TyevTF8QNfZWcp/NBcf
ZXhCoUoA62zzQ2SXpydZpryKn8klAYQLLA8mq6v/ljqcwFyLYtx0Cw49Thspo/4r
ba1jzsv5QdBveIKdGjzcuexTaIEFB6rQXIFuVVfn074tpZIO+KmHO/z62i73bbko
67tm+VDvbgsGUd4536lSKMekbdn0+5ODl76AJCD0M+Vzxkl9X/fg4zgz0vG2Ppiq
08LqBPidA9EQ+tEHm7OIXk9Z+wApDCb27zwsiygkV9uWXuEaNYjCjUZTEw9CYTuH
CdCPOdeJYBzKpfGXldJo6F6NbLLXywL4ej2Lt99tqFF2tQ3I6SKyYx+I2veYsjKs
7g29bF4WuU1IVi4Kn144NUzEHOJZKeyYOwEz5+chq9KuYBY8b1OHe1Q5pEFIbVIP
/1pdwhs6zV8tJZOgzLb9q+yLuXH1Fk4YE9wZDh/rK3hpD+KGyNRa+0J70wdYDOqk
4C9ybAaljvJPXO622Ai/RlFLQVK4KdJ2Ig9mwtIhwBvjnKkCmG502HGRUa3HVpDK
pb9WDrH9eJPxkRew1y7Kl6ua10mNh7vMIbEDzZY36Eovzc127ANy/EQR8OwnI8Vg
39rCq1wDVeULHmF4j63cm3pHo6LK1OGZjAkg9XjT/aDpuqigcdEmFjmx7RSBPZFC
RZTJ6kcafbnxQfKx7soI7+1AWVSrTt+/XePZPubnFeMlfXtGVXejTG2rCWJqRpGZ
sjwgGiOtcnzvF37TQ4XrWV5T45XeSmG4hsF+zShXqevGulOwGNPtJbmiINTaeKun
1KxjSVpwkniOQgrWNSFCD2RzSEuQRKSg0XMbgPLbmplVO4WAzhQ/Ry4DpNqjJwkp
2z5WQ8XhfsxecNBc10pbPGyDUbXk96bZSXc31s5tKIyUaCxMmUu87Z0q9KEaVrGc
Tp69o4LIX8dhEqAx8Mk1AKpk8TsT0Ebc75X+xbzVoiimblUuB/+OrDsK7R0hihIe
TU+1xOJ1gyppkuacOuHioV4k9k4NUwgk+YrSKTrhFEzbM6gcOngTB0VTFzQlEjxB
wxl2qN7f0lFD6F0rLJ0Rm06xIwTNIe/0MfMXAJBB45DFuQINBGP0BlIBEADAkdgW
M8SyGyde5Op/B9yMHNPfuSNRjK4/HHmLez1GTriNwuqor5FRrDCO8VPUbQX/x06O
2HZj8fJWa+6hc9+giUTXNbYtlMVpZOUVhGxzuy2Y6YE82maBaJ3EB/KBP7zdgvKT
bxmjv5hre9u/LaY6tloCzeaBUWPV9+e5Bxq72qC507V/z6lc+PgxWWfGkmWBuT+v
laHWFb6ZM5ldtcMSdscrLBcxLMnjNIRlIaWpj+tvuInMdV3HrTn/bdHCP/Ybrf95
DYY+7p+KPGrdXJH121f8qZXRihTJerJOGvGbue6FIJ+wYSEr3nb9bNyym/w+Mk9Z
0wJZZVfjbqFNcGhTttZWlzdTJwerwj7cGsTtMcuIphhUdLhQns+dBTVKVrqvvHSu
p/w9IpnyDhcgqv8v23xfSCuKooWPn2E1/Pd4enLCHVzmFW1xQDtDunRuxBbHYpM4
5gknVdIp8bY23y1fj0mottIfgZZEfiMR6FJxseFcWuG7VdC7VITdgbNl5YDXw4ts
xmg2qrRSNUTkFAKNwIekqwziay4DcnWkoikH+n3bHre5wQqFzHIV03Zo8YcgKvyT
0hwAvn2wGRoIynInFMi2/314xbAUBq10QhREGOPS3oUvBUZxhTkiBMKVYyKA97JQ
c2Xhrkx9cuZxh3y7j3DflRBW9XLJvbcLGDziTwARAQABiQI2BBgBCgAgFiEE8fNG
ZFhFKy3zUfHoZNErqVrOHy0FAmP0BlICGwwACgkQZNErqVrOHy0dOxAAlNRb0yBq
SLLU/pQHjnqRQsLpXFmokcAVfZcEoODTMmzPf3uKDExkHBsyRjbRrEazMLQZIwIb
78AXvPx6W+lwkmrZ1IXfTkURMi2RmSSOcjTJzipM4WKkOy6zSg29chnBz8edq8AF
rErYdY5IgGCn3RHtkGjtKRSV0m4cdoO/wqGHtZdxEhmfmAzs+Wwevqb1nzptG3my
ZdEJ5rkgGcnvUjkJo815FjR1fuo0KSuVZVelvWMp6JFYMWc4FUh2bYWymIQ6u8/f
2v8EnacG/oNHDkZG0edTPU4dClHCtXqejAxazHYUojJkFdWUMoEIJ7VYg23N4WAW
0qf78uBOuGBjl8g5sOmu/IQpMsO51NiDSw/lGLfPsKJKTIe7N6Jxs8PT66Jqvw2U
4moKEAcoLGxXkIfY7UMFGflaADzBQEebNiekRMw/SAxB3mRptuQ96QuCrpLE7kmI
KPs0vk3om0Lz59q3JoYmMEoEIMM3Z1j94mp07nyJzKvOREtQYY7WIKG/sgUHekjm
lrUfez8xHCG4G0r4KTiu3rGT/rvCehTxvkl4Gmimeo+XNb7vwcr1O0/DTH3ZCG8o
+mwGnah7T6ch60YFSWm0RkxNozNHWJf5Ee6gVv7nEyB1pbuqhXHliv3hhK+/4SWW
RMwhK4b5axJn9aHTu3rwDdaDpUkkApY4rhq5Ag0EY/QGZAEQAOXjz3loH0/mn+Wn
wermse6fhyW+HJNIcWLdTZ3o44GhbkWb5VxCdb/FuOYIGxeTkF2KjCwHFCHCfN1/
P8okvsnlGhuiZQRpVHBv1TBPzx4m94unXgEbyPYndKN/KGsJf7iOQ/HRs9CTUcZy
5hj608Rd/Wr+mzzwOG7QIBEEjNhA5NhjpvWpbPGkOgVkYeMobyDmJjoUi7rnIoq+
9XLV/wiBneXcinAFZVqbGCRNxhjRBhKubOjWftNfHCtZu96cCoGxDRwE+z6BVre4
iv7VMmXQDPlISUFUa7cu9R2WTny2u09SPpNBHdhSSDtWOWXtYc52qG7HllA2GOQ6
wd6t/RPDzp7pwTOB5O4htAchvQtyxS6fApy6Hb5q7tE7n31y8efT7FkTkxkHGWgM
NoncmyKWIzyTI8/9TcRGPTdxYtbsGptP6x+MA6XbVELOTSJDGTXC3/xWa0Kv0B2/
sjKu1pi9/9vBE/6D72V2bMoa3wx1vrTm5XNnvQf8subXt/jRN75Adp7HlvL/qnpy
7AQRm2AiDndamCW7SsDpTGsF9AQcqX8m3cUt4TSacTJiSRHYycc23JZEhe26phkw
CbZRvWkUcfuNBXWAaINVPDprZ4jArbVr+Fe1GMVSkV3WcHWf4o18kETjNPfCbdR3
uYrD/qtaehHKFhm8ZeQV2n6ISzj1ABEBAAGJAjYEGAEKACAWIQTx80ZkWEUrLfNR
8ehk0SupWs4fLQUCY/QGZAIbIAAKCRBk0SupWs4fLcubD/oDGub4+uep50VBUa0u
BZAUu/oS664+53sZyvogMzeIT32DT3vDaa3W2aqUNX/dZVzOcsV07HO4yk6+kiSk
1Db2FbRFODbFcs5mBYo/EFSxExhQMQFqgXaW3FrpvL5ljAwsjdoSN93DnMkLnC9K
XZUyUT+RDcJnk0xS+0ex77nc8vp13n2huHuXU6BbEGofrT9br7Kyezh84GV9nxls
C0PwTX0gBaesqeY/9rtAXq+p+kYBafbny/3zrL8CBwqHqRZWiNbkyGWx9WHvizZE
0VJJzGl0CTP7aE/N42t+LDGuaA76SJXkkqGs7GmJ3EHVA8N/2Lwhf0saaG3cBrKx
lXrJoSY7TxeoJ7rdt/KRJfKsU0bdXgVXDFrlf4ZvctCLZmQ0nno2cgYemTnELRYv
FzrS2itqqWP1ev2iPpCbKp099i/w6D13C3jBVAVYPBapD6aaD7YHWLhHIA5zH7bF
n8IgacgKBoJ8u3jo3eeT5CXfsrnwOYdrqposfMCUOriJHx41nGUqjNZDG2ByHxgS
mnUd3lrjRDWTUzXj8pRN2K7Uqbbs2Mz4Q64MgbCkkTichMlVux8kH+O/I/veAYto
OEpwdDwa67AtzYKG0ssOJI+po9TlbKYS4O4H8XnPhYSOEw8eObNPYCX7jyAjXloo
1hbflYLyMYo1BxGR6bPS9gJA2w==
=5uun
-----END PGP PUBLIC KEY BLOCK-----
''