feat: mkDeprecate, tex math conceal, more zen, spellcheck, show pids
parent
eef0fdcd14
commit
e4ae633a1d
|
@ -0,0 +1,29 @@
|
|||
\documentclass{article}
|
||||
|
||||
\begin{document}
|
||||
|
||||
\section{Sample LaTeX Document with Math Symbols}
|
||||
|
||||
Here are some math symbols and commands:
|
||||
|
||||
1. Infinity: $\infty$
|
||||
2. Element of: $a \in A$
|
||||
3. Angle: $\angle ABC$
|
||||
4. Approximation: $a \approx b$
|
||||
5. Union: $A \cup B$
|
||||
6. Intersection: $A \cap B$
|
||||
7. Big union: $\bigcup_{i=1}^{n} A_i$
|
||||
8. Big intersection: $\bigcap_{i=1}^{n} A_i$
|
||||
9. Down arrow: $\downarrow$
|
||||
10. Double down arrow: $\Downarrow$
|
||||
11. Copyright symbol: $\copyright$
|
||||
12. Quadruple space: $a \qquad b$
|
||||
13. Empty set: $\emptyset$
|
||||
14. Aleph symbol: $\aleph$
|
||||
15. Product: $\prod_{i=1}^{n} a_i$
|
||||
16. Integration: $\int f(x) \, dx$
|
||||
17. Clubsuit: $\clubsuit$
|
||||
18. dot: $\dot{B}$
|
||||
|
||||
\end{document}
|
||||
|
|
@ -53,10 +53,9 @@ vim.call('plug#begin')
|
|||
|
||||
-- libs and dependencies
|
||||
WPlug('nvim-lua/plenary.nvim') -- The base of all plugins
|
||||
WPlug('MunifTanjim/nui.nvim') -- For some .so or .dylib neovim UI action
|
||||
|
||||
|
||||
-- plugins
|
||||
--
|
||||
--
|
||||
-- -- plugins
|
||||
WPlug('nvim-treesitter/nvim-treesitter') -- language parser engine for highlighting
|
||||
WPlug('nvim-treesitter/nvim-treesitter-textobjects') -- more text objects
|
||||
WPlug('nvim-telescope/telescope.nvim', { branch = '0.1.x' }) -- file browser
|
||||
|
@ -101,10 +100,10 @@ WPlug('ThePrimeagen/harpoon') -- 1-click through marked files per p
|
|||
WPlug('TimUntersberger/neogit') -- Easy-to-see git status
|
||||
WPlug('folke/trouble.nvim') -- File-grouped workspace diagnostics
|
||||
WPlug('tpope/vim-dispatch') -- Allows quick build/compile/test vim commands
|
||||
WPlug('clojure-vim/vim-jack-in') -- Clojure: ":Boot", ":Clj", ":Lein"
|
||||
-- WPlug('clojure-vim/vim-jack-in') -- Clojure: ":Boot", ":Clj", ":Lein"
|
||||
WPlug('radenling/vim-dispatch-neovim') -- Add support for neovim's terminal emulator
|
||||
-- WPlug('Olical/conjure') -- REPL on the source for Clojure (and other LISPs)
|
||||
WPlug('gennaro-tedesco/nvim-jqx') -- JSON formatter (use :Jqx*)
|
||||
WPlug('gennaro-tedesco/nvim-jqx') -- JSON formatter (use :Jqx*).# TODO: supply chain?
|
||||
WPlug('kylechui/nvim-surround') -- surrounds with tags/parenthesis
|
||||
WPlug('simrat39/rust-tools.nvim') -- config rust-analyzer and nvim integration
|
||||
-- WPlug('tjdevries/sg.nvim') -- Cody and other cool sourcegraph stuffs
|
||||
|
@ -171,6 +170,14 @@ vim.api.nvim_create_autocmd({ "VimEnter" }, {
|
|||
|
||||
vim.g.gruvbox_contrast_dark = "soft";
|
||||
vim.g.gruvbox_contrast_light = "soft";
|
||||
|
||||
-- no more partial keystrokes, it's distracting
|
||||
vim.opt.showcmd = false;
|
||||
-- rely on lualine
|
||||
vim.opt.showmode = false;
|
||||
-- Suppress buffer/file written message
|
||||
vim.opt.shortmess = "atToOCF"
|
||||
|
||||
vim.opt.ignorecase = true;
|
||||
vim.opt.smartcase = true;
|
||||
vim.opt.incsearch = true;
|
||||
|
@ -190,6 +197,72 @@ vim.opt.colorcolumn = "80";
|
|||
|
||||
vim.opt.background = "dark";
|
||||
|
||||
vim.opt.spelllang = "en_us";
|
||||
do -- selective spell-checking
|
||||
local spellcheck = vim.api.nvim_create_augroup("SpellChecking", { clear = true })
|
||||
vim.api.nvim_create_autocmd({ "FileType" }, {
|
||||
group = spellcheck,
|
||||
pattern = { "tex", "markdown", "md", },
|
||||
callback = function() vim.opt_local.spell = true end,
|
||||
})
|
||||
end
|
||||
|
||||
do -- selective concealing/ligature {{{
|
||||
g_docs = "docs"
|
||||
group_map = {
|
||||
plaintex = g_docs,
|
||||
tex = g_docs,
|
||||
markdown = g_docs,
|
||||
}
|
||||
conceal_by_mode = {
|
||||
n = 2,
|
||||
i = 0,
|
||||
c = 2,
|
||||
v = 0,
|
||||
}
|
||||
|
||||
local group_handler = {
|
||||
[g_docs] = function(_ft, _group)
|
||||
vim.notify("group_handler: " .. vim.inspect({ _ft, _group }))
|
||||
vim.opt_local.concealcursor = "n"
|
||||
-- HACK: seems to be some lifetime racing issues here
|
||||
-- Putting this inside `vim.schedule` puts this at the end of the
|
||||
-- queue, so under the assumption that aucommands are done in an
|
||||
-- event loop, we're sure that the current augroup invocation
|
||||
-- would be done before syn is set
|
||||
vim.schedule(function()
|
||||
vim.opt_local.syn = "tex"
|
||||
end)
|
||||
end
|
||||
}
|
||||
local conceal = vim.api.nvim_create_augroup("Conceal", { clear = true })
|
||||
vim.api.nvim_create_autocmd({ "FileType" }, {
|
||||
group = conceal,
|
||||
pattern = { "*" },
|
||||
callback = function(args)
|
||||
-- `:h FileType` and `:h nvim_create_augroup`.
|
||||
-- `amatch`: value of filetype; args.match <- amatch
|
||||
local ft = args.match
|
||||
local group = group_map[ft]
|
||||
if group == nil then
|
||||
return
|
||||
end
|
||||
group_handler[group](ft, group)
|
||||
end
|
||||
})
|
||||
vim.api.nvim_create_autocmd({ "ModeChanged" }, {
|
||||
group = conceal,
|
||||
pattern = "?:?",
|
||||
callback = function()
|
||||
local new_mode = vim.fn.mode("1")
|
||||
local level = conceal_by_mode[new_mode]
|
||||
if level then
|
||||
vim.opt_local.conceallevel = level
|
||||
end
|
||||
end
|
||||
})
|
||||
end -- }}}
|
||||
|
||||
vim.api.nvim_create_user_command('Dark', function(opts)
|
||||
-- opts: {name, args: str, fargs: Splited<str>, range, ...}
|
||||
---@type string
|
||||
|
@ -307,8 +380,9 @@ require('trouble').setup {
|
|||
}
|
||||
|
||||
|
||||
-- TODO: Any way to collect all the TODOs and its variants?
|
||||
require('todo-comments').setup()
|
||||
-- TODO + Trouble: `:TodoTrouble`
|
||||
require('todo-comments').setup {}
|
||||
|
||||
|
||||
-- plugin keymaps
|
||||
|
||||
|
@ -320,11 +394,12 @@ end
|
|||
-- Comment.nvim
|
||||
require('Comment').setup()
|
||||
-- -- lukas-reineke/indent-blankline.nvim
|
||||
-- vim.opt.list = true
|
||||
-- vim.opt.listchars:append "space:⋅"
|
||||
-- vim.opt.listchars:append "eol:↴"
|
||||
vim.opt.list = true
|
||||
vim.opt.listchars:append "space:⋅"
|
||||
vim.opt.listchars:append "eol:↴"
|
||||
|
||||
require("ibl").setup {
|
||||
-- indent = {char = {space='', eol=''}, },
|
||||
-- show_end_of_line = true,
|
||||
-- space_char_blankline = " ",
|
||||
|
||||
|
@ -439,7 +514,6 @@ stdout> (builtin.__file)
|
|||
|
||||
log.debug(vim.inspect(filenames))
|
||||
|
||||
|
||||
for _, filename in pairs(filenames) do
|
||||
require('harpoon.mark').add_file(filename)
|
||||
end
|
||||
|
@ -1437,15 +1511,17 @@ require('lualine').setup {
|
|||
newfile_status = false,
|
||||
path = 1,
|
||||
symbols = {
|
||||
modified = '[+]',
|
||||
modified = '[~]',
|
||||
readonly = '[-]',
|
||||
unnamed = '[Unnamed]',
|
||||
newfile = '[New]',
|
||||
unnamed = '<?>',
|
||||
},
|
||||
},
|
||||
},
|
||||
lualine_x = { 'encoding', 'fileformat', 'filetype', },
|
||||
lualine_y = { 'progress' },
|
||||
lualine_x = { 'encoding', 'fileformat', {
|
||||
'filetype',
|
||||
colored = true,
|
||||
}, },
|
||||
lualine_y = { function() return "pid#" .. vim.loop.os_getpid() end },
|
||||
lualine_z = { 'location' },
|
||||
},
|
||||
inactive_sections = {
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
in {
|
||||
default = std.lib.dev.mkShell {
|
||||
name = "default";
|
||||
imports = [inputs.std.std.devshellProfiles.default];
|
||||
imports = [
|
||||
inputs.std.std.devshellProfiles.default
|
||||
];
|
||||
};
|
||||
}
|
||||
|
|
|
@ -30,6 +30,11 @@
|
|||
{config.programs.home-manager.enable = true;}
|
||||
# home-profiles.nix-index
|
||||
home-profiles.neovim
|
||||
{
|
||||
config.repo.shells.shellAliases = {
|
||||
nixr = "if [ -f $(pwd)/.nix-replrc ]; then nix repl $(pwd)/.nix-replrc; elif [ -f ~/.config/.nix-replrc ]; then nix repl ~/.config/.nix-replrc; else nix repl; fi";
|
||||
};
|
||||
}
|
||||
];
|
||||
in {
|
||||
homeConfigurations.htran = home-config {
|
||||
|
|
|
@ -8,12 +8,7 @@ _imports @ {
|
|||
namespace = "repo";
|
||||
imports = _imports // {inherit namespace;};
|
||||
in {
|
||||
git = {
|
||||
config,
|
||||
lib,
|
||||
options,
|
||||
...
|
||||
}: let
|
||||
git = { config, lib, options, ... }: let
|
||||
cfg = config."${namespace}".git;
|
||||
baseAliases = {
|
||||
a = "add";
|
||||
|
|
|
@ -96,6 +96,7 @@ in {
|
|||
* }
|
||||
*/
|
||||
plugins = let
|
||||
inherit (cell.lib.deprecate) mkDeprecate deprecate-seq-handler;
|
||||
inherit
|
||||
(inputs.nixpkgs-vimplugins.legacyPackages.${system}.vimPlugins)
|
||||
plenary-nvim
|
||||
|
@ -144,63 +145,75 @@ in {
|
|||
nvim-colorizer-lua
|
||||
git-worktree-nvim
|
||||
;
|
||||
# inherit (inputs.cells.dotfiles.packages) sg-nvim;
|
||||
in [
|
||||
plenary-nvim
|
||||
nvim-treesitter.withAllGrammars
|
||||
nvim-treesitter-textobjects
|
||||
telescope-fzf-native-nvim
|
||||
telescope-file-browser-nvim
|
||||
telescope-nvim
|
||||
nvim-lspconfig
|
||||
gruvbox-community
|
||||
neodev-nvim
|
||||
cmp-nvim-lsp
|
||||
cmp-path
|
||||
cmp-buffer
|
||||
cmp-cmdline
|
||||
nvim-cmp
|
||||
lspkind-nvim
|
||||
nvim-autopairs
|
||||
nvim-ts-autotag
|
||||
guess-indent-nvim
|
||||
harpoon
|
||||
luasnip
|
||||
nvim-treesitter-context
|
||||
fidget-nvim
|
||||
rust-tools-nvim
|
||||
telescope-live-grep-args-nvim
|
||||
comment-nvim
|
||||
sg-nvim = let
|
||||
_sg = inputs.cells.dotfiles.packages.sg-nvim;
|
||||
in {
|
||||
plugin = _sg;
|
||||
# NOTE: Wait, this mean the plugin is exclusively lua only since package.cpath is Lua API
|
||||
config = ''
|
||||
package.cpath = package.cpath .. ";${_sg}/lib/*.so;${_sg}/lib/*.dylib"
|
||||
'';
|
||||
type = "lua";
|
||||
};
|
||||
in
|
||||
deprecate-seq-handler 1 [
|
||||
(mkDeprecate {inherit sg-nvim;} {
|
||||
stage = 2;
|
||||
meta.since = "2023-10-20";
|
||||
})
|
||||
(mkDeprecate {inherit vim-jack-in;} {
|
||||
stage = 2;
|
||||
meta.since = "2023-10-20";
|
||||
})
|
||||
plenary-nvim
|
||||
nvim-treesitter.withAllGrammars
|
||||
nvim-treesitter-textobjects
|
||||
telescope-fzf-native-nvim
|
||||
telescope-file-browser-nvim
|
||||
telescope-nvim
|
||||
nvim-lspconfig
|
||||
gruvbox-community
|
||||
neodev-nvim
|
||||
cmp-nvim-lsp
|
||||
cmp-path
|
||||
cmp-buffer
|
||||
cmp-cmdline
|
||||
nvim-cmp
|
||||
lspkind-nvim
|
||||
nvim-autopairs
|
||||
nvim-ts-autotag
|
||||
guess-indent-nvim
|
||||
harpoon
|
||||
luasnip
|
||||
nvim-treesitter-context
|
||||
fidget-nvim
|
||||
rust-tools-nvim
|
||||
telescope-live-grep-args-nvim
|
||||
comment-nvim
|
||||
|
||||
cmp_luasnip
|
||||
gitsigns-nvim
|
||||
indent-blankline-nvim
|
||||
lualine-nvim
|
||||
mason-lspconfig-nvim
|
||||
mason-nvim
|
||||
neogit
|
||||
nvim-jqx
|
||||
nvim-surround
|
||||
nvim-web-devicons
|
||||
playground
|
||||
todo-comments-nvim
|
||||
trouble-nvim
|
||||
vim-dispatch
|
||||
vim-dispatch-neovim
|
||||
vim-fugitive
|
||||
nvim-colorizer-lua
|
||||
vim-jack-in
|
||||
# {
|
||||
# plugin = sg-nvim;
|
||||
# # NOTE: Wait, this mean the plugin is exclusively lua only since package.cpath is Lua API
|
||||
# config = ''
|
||||
# package.cpath = package.cpath .. ";${sg-nvim}/lib/*.so;${sg-nvim}/lib/*.dylib"
|
||||
# '';
|
||||
# type = "lua";
|
||||
# }
|
||||
git-worktree-nvim
|
||||
nui-nvim
|
||||
];
|
||||
cmp_luasnip
|
||||
gitsigns-nvim
|
||||
indent-blankline-nvim
|
||||
lualine-nvim
|
||||
mason-lspconfig-nvim
|
||||
mason-nvim
|
||||
neogit
|
||||
nvim-jqx
|
||||
nvim-surround
|
||||
nvim-web-devicons
|
||||
playground
|
||||
todo-comments-nvim
|
||||
trouble-nvim
|
||||
vim-dispatch
|
||||
vim-dispatch-neovim
|
||||
vim-fugitive
|
||||
nvim-colorizer-lua
|
||||
git-worktree-nvim
|
||||
(mkDeprecate {inherit nui-nvim;} {
|
||||
stage = 2;
|
||||
meta.since = "2023-10-20";
|
||||
})
|
||||
];
|
||||
};
|
||||
# home.packages = nvim_pkgs;
|
||||
};
|
||||
|
|
|
@ -1,9 +1,7 @@
|
|||
{
|
||||
std-passthru @ {
|
||||
inputs,
|
||||
cell,
|
||||
}: let
|
||||
namespace = "repo"; # ignore: unused
|
||||
|
||||
yamlToJsonDrv = pkgs: yamlContent: outputPath: (pkgs.runCommand
|
||||
outputPath
|
||||
{
|
||||
|
@ -15,6 +13,18 @@
|
|||
''
|
||||
echo "$yamlContent" | yq >$out
|
||||
'');
|
||||
|
||||
exec_tests = testUnit: let
|
||||
testNames = builtins.attrNames testUnit;
|
||||
evaluateTest = testName: assert testUnit."${testName}" == true; testName;
|
||||
in
|
||||
builtins.concatStringsSep ", " (builtins.foldl' (acc: testName: acc ++ [(evaluateTest testName)]) [] testNames);
|
||||
tests = import ./tests.nix std-passthru;
|
||||
in {
|
||||
fromYAML = yamlContent: builtins.fromJSON (builtins.readFile (yamlToJsonDrv inputs.nixpkgs yamlContent "fromYaml.json"));
|
||||
ty = import ./ty.nix std-passthru;
|
||||
deprecate = import ./mk-deprecate.nix std-passthru;
|
||||
|
||||
inherit tests;
|
||||
exec-tests = exec_tests tests;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
{inputs, cell}: {
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
{
|
||||
inputs,
|
||||
cell,
|
||||
}: let
|
||||
inherit (cell.lib.ty) brand-ctor brand-coalesce-seq unbranded_name;
|
||||
|
||||
deprecate_t = a @ {
|
||||
id ? null,
|
||||
msg ? null,
|
||||
ctx_str ? null,
|
||||
meta ? null,
|
||||
/*
|
||||
the higher the more likely to be removed
|
||||
*/
|
||||
stage ? 0,
|
||||
}: let
|
||||
ctx =
|
||||
if ctx_str == null
|
||||
then ""
|
||||
else ": ${ctx_str}";
|
||||
_msg =
|
||||
if msg == null
|
||||
then
|
||||
if id == null
|
||||
then "deprecated${ctx}"
|
||||
else "${id} is deprecated${ctx}"
|
||||
else msg;
|
||||
in
|
||||
builtins.trace _msg (v: (brand-ctor "deprecate" v) // {inherit stage;} // a);
|
||||
in {
|
||||
inherit deprecate_t;
|
||||
mkDeprecate = inherit_v: a: deprecate_t ({id = builtins.head (builtins.attrNames inherit_v);} // a) (builtins.head (builtins.attrValues inherit_v));
|
||||
deprecate-seq-handler = trim_stage: s: let
|
||||
v = builtins.foldl' (lst: {
|
||||
__value,
|
||||
__brand,
|
||||
...
|
||||
} @ a:
|
||||
if __brand == "deprecate" && trim_stage < a.stage
|
||||
then lst
|
||||
else
|
||||
lst
|
||||
++ [
|
||||
(
|
||||
if __brand == "deprecate" || __brand == unbranded_name
|
||||
then __value
|
||||
else a
|
||||
)
|
||||
]) [] (brand-coalesce-seq s);
|
||||
in
|
||||
v;
|
||||
}
|
|
@ -0,0 +1,89 @@
|
|||
{
|
||||
inputs,
|
||||
cell,
|
||||
}: {
|
||||
ty-deprecate = let
|
||||
exampleBrand = cell.lib.ty.brand-ctor "example";
|
||||
brandedItem = exampleBrand "someValue";
|
||||
in
|
||||
assert (brandedItem.__brand == "example");
|
||||
assert (brandedItem.__value == "someValue"); let
|
||||
coalescedItem = cell.lib.ty.brand-coalesce brandedItem;
|
||||
coalescedSeq = cell.lib.ty.brand-coalesce-seq [brandedItem "hello"];
|
||||
promoted = cell.lib.ty.brand-coalesce "hello";
|
||||
in
|
||||
assert (coalescedItem.__brand != "__unbranded__");
|
||||
assert (promoted.__brand == "__unbranded__");
|
||||
assert ((builtins.elemAt coalescedSeq 0) == brandedItem);
|
||||
assert ((let v = builtins.elemAt coalescedSeq 1; in builtins.trace "${builtins.toJSON v}" v) == promoted); let
|
||||
items = [(exampleBrand "A") (exampleBrand "B") (cell.lib.ty.brand-ctor "second" "C")];
|
||||
grouped = cell.lib.ty.brand-group items;
|
||||
in
|
||||
assert (builtins.length (grouped.example) == 2);
|
||||
assert (builtins.length (grouped.second) == 1); let
|
||||
retainItem = cell.lib.deprecate.mkDeprecate {myItem = "value";} {ctx_str = "example context";};
|
||||
deprecate = cell.lib.deprecate.mkDeprecate {deprecate = 15;} {stage = 256;};
|
||||
processedSeq = cell.lib.deprecate.deprecate-seq-handler 0 [retainItem];
|
||||
partiallyRemoved = cell.lib.deprecate.deprecate-seq-handler 2 [retainItem brandedItem];
|
||||
removeDeprecated = cell.lib.deprecate.deprecate-seq-handler 2 [deprecate brandedItem];
|
||||
passthru = cell.lib.deprecate.deprecate-seq-handler 4 [retainItem brandedItem deprecate];
|
||||
in
|
||||
assert (retainItem.__brand == "deprecate");
|
||||
# Since the stage is 0, it filters the deprecated item out
|
||||
assert (builtins.length processedSeq == 1);
|
||||
assert (builtins.head partiallyRemoved == "value");
|
||||
assert (builtins.head removeDeprecated == brandedItem);
|
||||
assert (builtins.length passthru == 2); true;
|
||||
deprecate = let
|
||||
inherit (cell.lib.deprecate) mkDeprecate deprecate-seq-handler;
|
||||
inherit (inputs.nixpkgs) system;
|
||||
inherit
|
||||
(inputs.nixpkgs-vimplugins.legacyPackages.${system}.vimPlugins)
|
||||
plenary-nvim
|
||||
nvim-treesitter
|
||||
nvim-treesitter-textobjects
|
||||
nvim-treesitter-context
|
||||
telescope-fzf-native-nvim
|
||||
telescope-file-browser-nvim
|
||||
vim-jack-in
|
||||
nui-nvim
|
||||
telescope-live-grep-args-nvim
|
||||
nvim-colorizer-lua
|
||||
git-worktree-nvim
|
||||
;
|
||||
sg-nvim = let
|
||||
_sg = inputs.cells.dotfiles.packages.sg-nvim;
|
||||
in {
|
||||
plugin = _sg;
|
||||
# NOTE: Wait, this mean the plugin is exclusively lua only since package.cpath is Lua API
|
||||
config = ''
|
||||
package.cpath = package.cpath .. ";${_sg}/lib/*.so;${_sg}/lib/*.dylib"
|
||||
'';
|
||||
type = "lua";
|
||||
};
|
||||
plugins = [
|
||||
(mkDeprecate {inherit sg-nvim;} {
|
||||
stage = 2;
|
||||
meta.since = "2023-10-20";
|
||||
})
|
||||
(mkDeprecate {inherit vim-jack-in;} {
|
||||
stage = 2;
|
||||
meta.since = "2023-10-20";
|
||||
})
|
||||
plenary-nvim
|
||||
nvim-treesitter.withAllGrammars
|
||||
nvim-treesitter-textobjects
|
||||
telescope-fzf-native-nvim
|
||||
telescope-file-browser-nvim
|
||||
nvim-treesitter-context
|
||||
telescope-live-grep-args-nvim
|
||||
nvim-colorizer-lua
|
||||
git-worktree-nvim
|
||||
nui-nvim
|
||||
];
|
||||
pluglen = builtins.length plugins;
|
||||
rm = let v = deprecate-seq-handler 1 plugins; in assert (builtins.length v) < pluglen; v;
|
||||
retain = let v = deprecate-seq-handler 10 plugins; in assert (builtins.length v) == pluglen; v;
|
||||
in
|
||||
builtins.trace (builtins.toJSON {inherit rm retain;}) true;
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
inputs,
|
||||
cell,
|
||||
}: let
|
||||
brand-ctor = name:
|
||||
assert builtins.isString name;
|
||||
v: {
|
||||
__brand = name;
|
||||
__value = v;
|
||||
};
|
||||
unbranded_name = "__unbranded__";
|
||||
unbranded_t = brand-ctor unbranded_name;
|
||||
brand-of = {
|
||||
__brand ? unbranded_name,
|
||||
__value ? null,
|
||||
}:
|
||||
__brand;
|
||||
brand-coalesce = v: if v ? __brand then v else unbranded_t v;
|
||||
in {
|
||||
inherit brand-ctor brand-of brand-coalesce unbranded_name;
|
||||
brand-group = seq: builtins.mapAttrs (_: builtins.map (v: v.__value)) (builtins.groupBy (brnd: brnd.__brand) seq);
|
||||
brand-coalesce-seq = builtins.map brand-coalesce;
|
||||
}
|
Loading…
Reference in New Issue