feat(users/Profpatsch): init initial aerc config
aerc is a mail client. It needs some ini files to work. This is an initial attempt at generating them. Change-Id: I087955f19d2c4527275500a1e13eeb071c98a7b9 Reviewed-on: https://cl.tvl.fyi/c/depot/+/5526 Tested-by: BuildkiteCI Reviewed-by: Profpatsch <mail@profpatsch.de>
This commit is contained in:
parent
f0e52f31cd
commit
2a6928fb4c
3 changed files with 335 additions and 0 deletions
12
users/Profpatsch/aerc-no-config-perms.patch
Normal file
12
users/Profpatsch/aerc-no-config-perms.patch
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
diff --git a/config/config.go b/config/config.go
|
||||||
|
index 0472daf..5eed379 100644
|
||||||
|
--- a/config/config.go
|
||||||
|
+++ b/config/config.go
|
||||||
|
@@ -779,6 +779,7 @@ func (config *AercConfig) LoadBinds(binds *ini.File, baseName string, baseGroup
|
||||||
|
// checkConfigPerms checks for too open permissions
|
||||||
|
// printing the fix on stdout and returning an error
|
||||||
|
func checkConfigPerms(filename string) error {
|
||||||
|
+ return nil;
|
||||||
|
info, err := os.Stat(filename)
|
||||||
|
if err != nil {
|
||||||
|
return nil // disregard absent files
|
253
users/Profpatsch/aerc.dhall
Normal file
253
users/Profpatsch/aerc.dhall
Normal file
|
@ -0,0 +1,253 @@
|
||||||
|
let
|
||||||
|
-- DSL for building INI files
|
||||||
|
ToIniFns =
|
||||||
|
λ ( Ini
|
||||||
|
: { -- A Section in the ini
|
||||||
|
Section : Type
|
||||||
|
, -- A couple of sections
|
||||||
|
SectionList : Type
|
||||||
|
}
|
||||||
|
) →
|
||||||
|
{ -- Create a new section
|
||||||
|
newSection : Ini.Section
|
||||||
|
, -- Add a key/value pair to the section
|
||||||
|
add : Text → Text → Ini.Section → Ini.Section
|
||||||
|
, -- Add all these key/value pairs to the section
|
||||||
|
addAll :
|
||||||
|
List { name : Text, value : Text } → Ini.Section → Ini.Section
|
||||||
|
, -- Create a new SectionList
|
||||||
|
newSectionList : Ini.SectionList
|
||||||
|
, -- Add a section to the list of sections
|
||||||
|
addSection : Text → Ini.Section → Ini.SectionList → Ini.SectionList
|
||||||
|
}
|
||||||
|
|
||||||
|
in λ ( imports
|
||||||
|
: { -- concatenate a list with newlines
|
||||||
|
concatNewline : List Text → Text
|
||||||
|
, -- Take an aerc filter from the aerc distribution /share directory
|
||||||
|
aercFilter : Text → Text
|
||||||
|
, -- given a dsl of functions to create an Ini, render the ini file
|
||||||
|
toIni :
|
||||||
|
( ∀(Ini : { Section : Type, SectionList : Type }) →
|
||||||
|
ToIniFns Ini →
|
||||||
|
{ globalSection : Ini.Section, sections : Ini.SectionList }
|
||||||
|
) →
|
||||||
|
Text
|
||||||
|
}
|
||||||
|
) →
|
||||||
|
let List/foldLeft
|
||||||
|
: ∀(a : Type) →
|
||||||
|
List a →
|
||||||
|
∀(list : Type) →
|
||||||
|
∀(cons : list → a → list) →
|
||||||
|
∀(nil : list) →
|
||||||
|
list
|
||||||
|
= λ(a : Type) →
|
||||||
|
λ(xs : List a) →
|
||||||
|
λ(list : Type) →
|
||||||
|
λ(cons : list → a → list) →
|
||||||
|
λ(nil : list) →
|
||||||
|
List/fold
|
||||||
|
a
|
||||||
|
xs
|
||||||
|
(list → list)
|
||||||
|
(λ(x : a) → λ(f : list → list) → λ(l : list) → f (cons l x))
|
||||||
|
(λ(l : list) → l)
|
||||||
|
nil
|
||||||
|
|
||||||
|
let List/map
|
||||||
|
: ∀(a : Type) → ∀(b : Type) → (a → b) → List a → List b
|
||||||
|
= λ(a : Type) →
|
||||||
|
λ(b : Type) →
|
||||||
|
λ(f : a → b) →
|
||||||
|
λ(xs : List a) →
|
||||||
|
List/build
|
||||||
|
b
|
||||||
|
( λ(list : Type) →
|
||||||
|
λ(cons : b → list → list) →
|
||||||
|
List/fold a xs list (λ(x : a) → cons (f x))
|
||||||
|
)
|
||||||
|
|
||||||
|
let
|
||||||
|
-- A builder is a list of “build methods” that go from (a -> a) and change the a step by step.
|
||||||
|
Builder/build =
|
||||||
|
λ(a : Type) →
|
||||||
|
λ(init : a) →
|
||||||
|
λ(builders : List (a → a)) →
|
||||||
|
List/foldLeft
|
||||||
|
(a → a)
|
||||||
|
builders
|
||||||
|
a
|
||||||
|
(λ(acc : a) → λ(f : a → a) → f acc)
|
||||||
|
init
|
||||||
|
|
||||||
|
in { accounts =
|
||||||
|
imports.toIni
|
||||||
|
( λ(Ini : { Section : Type, SectionList : Type }) →
|
||||||
|
λ(ini : ToIniFns Ini) →
|
||||||
|
{ globalSection = ini.newSection
|
||||||
|
, sections =
|
||||||
|
ini.addSection
|
||||||
|
"mail"
|
||||||
|
( ini.addAll
|
||||||
|
[ { name = "archive", value = "Archive" }
|
||||||
|
, { name = "copy-to", value = "Sent" }
|
||||||
|
, { name = "default", value = "INBOX" }
|
||||||
|
, { name = "from"
|
||||||
|
, value = "Profpatsch <mail@profpatsch.de>"
|
||||||
|
}
|
||||||
|
, { name = "source"
|
||||||
|
, value = "maildir://~/.Mail/mail"
|
||||||
|
}
|
||||||
|
, { name = "postpone", value = "Drafts" }
|
||||||
|
]
|
||||||
|
ini.newSection
|
||||||
|
)
|
||||||
|
ini.newSectionList
|
||||||
|
}
|
||||||
|
)
|
||||||
|
, aerc =
|
||||||
|
imports.toIni
|
||||||
|
( λ(Ini : { Section : Type, SectionList : Type }) →
|
||||||
|
λ(ini : ToIniFns Ini) →
|
||||||
|
{ globalSection = ini.newSection
|
||||||
|
, sections =
|
||||||
|
ini.addSection
|
||||||
|
"filters"
|
||||||
|
( Builder/build
|
||||||
|
Ini.Section
|
||||||
|
ini.newSection
|
||||||
|
[ ini.add "text/html" (imports.aercFilter "html")
|
||||||
|
, let _ =
|
||||||
|
"-- TODO: this awk should be taken from nix!"
|
||||||
|
|
||||||
|
in ini.add
|
||||||
|
"text/*"
|
||||||
|
"awk -f ${imports.aercFilter "plaintext"}"
|
||||||
|
]
|
||||||
|
)
|
||||||
|
ini.newSectionList
|
||||||
|
}
|
||||||
|
)
|
||||||
|
, binds =
|
||||||
|
let
|
||||||
|
-- keybinding and command to run
|
||||||
|
Key =
|
||||||
|
{ ctrl : Bool, key : Text, cmd : Text }
|
||||||
|
|
||||||
|
in let
|
||||||
|
-- render a key to config format
|
||||||
|
renderKey =
|
||||||
|
λ(k : Key) →
|
||||||
|
if k.ctrl
|
||||||
|
then "<C-${k.key}> = ${k.cmd}"
|
||||||
|
else "${k.key} = ${k.cmd}"
|
||||||
|
|
||||||
|
let
|
||||||
|
|
||||||
|
-- render a list of keys to config format
|
||||||
|
renderKeys =
|
||||||
|
λ(keys : List Key) → List/map Key Text renderKey keys
|
||||||
|
|
||||||
|
let
|
||||||
|
-- create a section whith a name and a list of keys
|
||||||
|
sect =
|
||||||
|
λ(section : Text) →
|
||||||
|
λ(keys : List Key) →
|
||||||
|
{ section, keys = renderKeys keys }
|
||||||
|
|
||||||
|
let
|
||||||
|
|
||||||
|
-- set key without modifiers
|
||||||
|
key =
|
||||||
|
λ(key : Text) → { key }
|
||||||
|
|
||||||
|
let
|
||||||
|
-- set special key without modifiers
|
||||||
|
special =
|
||||||
|
λ(key : Text) → { key = "<${key}>" }
|
||||||
|
|
||||||
|
let
|
||||||
|
-- no modifier
|
||||||
|
none =
|
||||||
|
{ ctrl = False }
|
||||||
|
|
||||||
|
let
|
||||||
|
-- set control key
|
||||||
|
ctrl =
|
||||||
|
{ ctrl = True }
|
||||||
|
|
||||||
|
let
|
||||||
|
-- set a command to execute
|
||||||
|
cmd =
|
||||||
|
λ(cmd : Text) → { cmd = ":${cmd}<Enter>" }
|
||||||
|
|
||||||
|
let
|
||||||
|
-- set a command, but stay on the prompt
|
||||||
|
prompt =
|
||||||
|
λ(cmd : Text) → { cmd = ":${cmd}<Space>" }
|
||||||
|
|
||||||
|
let config =
|
||||||
|
{ globalSection =
|
||||||
|
renderKeys
|
||||||
|
[ ctrl ∧ key "p" ∧ cmd "prev-tab"
|
||||||
|
, ctrl ∧ key "n" ∧ cmd "next-tab"
|
||||||
|
, ctrl ∧ key "t" ∧ cmd "term"
|
||||||
|
]
|
||||||
|
, sections =
|
||||||
|
[ sect
|
||||||
|
"messages"
|
||||||
|
[ ctrl ∧ key "q" ∧ cmd "quit"
|
||||||
|
, none ∧ special "Up" ∧ cmd "prev"
|
||||||
|
, none ∧ special "Down" ∧ cmd "next"
|
||||||
|
, none ∧ special "PgUp" ∧ cmd "prev 100%"
|
||||||
|
, none ∧ special "PgDn" ∧ cmd "next 100%"
|
||||||
|
, none ∧ key "g" ∧ cmd "select 0"
|
||||||
|
, none ∧ key "G" ∧ cmd "select -1"
|
||||||
|
, ctrl ∧ key "Up" ∧ cmd "prev-folder"
|
||||||
|
, ctrl ∧ key "Down" ∧ cmd "next-folder"
|
||||||
|
, none ∧ key "v" ∧ cmd "mark -t"
|
||||||
|
, none ∧ key "V" ∧ cmd "mark -v"
|
||||||
|
, none ∧ special "Enter" ∧ cmd "view"
|
||||||
|
, none ∧ key "c" ∧ cmd "compose"
|
||||||
|
, none ∧ key "|" ∧ prompt "pipe"
|
||||||
|
, none ∧ key "t" ∧ prompt "term"
|
||||||
|
, none ∧ key "/" ∧ prompt "search"
|
||||||
|
, none ∧ key "n" ∧ cmd "next-result"
|
||||||
|
, none ∧ key "N" ∧ cmd "prev-result"
|
||||||
|
, none ∧ special "Esc" ∧ cmd "clear"
|
||||||
|
]
|
||||||
|
, sect "view" [ none ∧ key "q" ∧ cmd "close" ]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
let Section = { section : Text, keys : List Text }
|
||||||
|
|
||||||
|
let iniToJson =
|
||||||
|
λ ( ini
|
||||||
|
: { globalSection : List Text
|
||||||
|
, sections : List Section
|
||||||
|
}
|
||||||
|
) →
|
||||||
|
let mkKeys = imports.concatNewline
|
||||||
|
|
||||||
|
let
|
||||||
|
-- TODO: escaping section header?
|
||||||
|
mkSection =
|
||||||
|
λ(section : Section) →
|
||||||
|
''
|
||||||
|
[${section.section}]
|
||||||
|
''
|
||||||
|
++ mkKeys section.keys
|
||||||
|
|
||||||
|
in mkKeys ini.globalSection
|
||||||
|
++ mkKeys
|
||||||
|
( List/map
|
||||||
|
Section
|
||||||
|
Text
|
||||||
|
mkSection
|
||||||
|
ini.sections
|
||||||
|
)
|
||||||
|
|
||||||
|
in iniToJson config
|
||||||
|
}
|
70
users/Profpatsch/aerc.nix
Normal file
70
users/Profpatsch/aerc.nix
Normal file
|
@ -0,0 +1,70 @@
|
||||||
|
{ depot, pkgs, lib, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
aerc-patched = pkgs.aerc.overrideAttrs (old: {
|
||||||
|
patches = old.patches or [ ] ++ [
|
||||||
|
./aerc-no-config-perms.patch
|
||||||
|
];
|
||||||
|
});
|
||||||
|
|
||||||
|
bins = depot.nix.getBins aerc-patched [ "aerc" ];
|
||||||
|
|
||||||
|
config =
|
||||||
|
depot.users.Profpatsch.importDhall.importDhall
|
||||||
|
{
|
||||||
|
root = ./.;
|
||||||
|
files = [
|
||||||
|
"aerc.dhall"
|
||||||
|
];
|
||||||
|
main = "aerc.dhall";
|
||||||
|
deps = [ ];
|
||||||
|
}
|
||||||
|
{
|
||||||
|
concatNewline = lib.concatStringsSep "\n";
|
||||||
|
aercFilter = name: "${aerc-patched}/share/aerc/filters/${name}";
|
||||||
|
toIni = getSections:
|
||||||
|
lib.generators.toINIWithGlobalSection { }
|
||||||
|
(getSections { } toIniDhall);
|
||||||
|
};
|
||||||
|
|
||||||
|
toIniDhall = {
|
||||||
|
newSection = { };
|
||||||
|
add = key: val: sect: sect // { ${key} = val; };
|
||||||
|
addAll = keyVals: sect: sect // builtins.listToAttrs keyVals;
|
||||||
|
newSectionList = { };
|
||||||
|
addSection = key: val: sect: sect // { ${key} = val; };
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
ini-file = name: ini: lib.pipe ini [
|
||||||
|
(lib.generators.toINI { })
|
||||||
|
(pkgs.writeText name)
|
||||||
|
];
|
||||||
|
|
||||||
|
binds-file = name: binds: pkgs.writeText name binds;
|
||||||
|
|
||||||
|
aerc-config = pkgs.linkFarm "alacritty-config" [
|
||||||
|
{
|
||||||
|
name = "aerc/accounts.conf";
|
||||||
|
path = pkgs.writeText "accounts.conf" config.accounts;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
name = "aerc/aerc.conf";
|
||||||
|
path = pkgs.writeText "aerc.conf" config.aerc;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
name = "aerc/binds.conf";
|
||||||
|
path = binds-file "binds.conf" config.binds;
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
aerc = depot.nix.writeExecline "aerc" { } [
|
||||||
|
"export"
|
||||||
|
"XDG_CONFIG_HOME"
|
||||||
|
aerc-config
|
||||||
|
bins.aerc
|
||||||
|
"$@"
|
||||||
|
];
|
||||||
|
|
||||||
|
in
|
||||||
|
aerc
|
Loading…
Reference in a new issue