Compare commits

..

1 commit

Author SHA1 Message Date
52d89f41eb feat: init wezterm config
All checks were successful
Discord / discord commits (push) Has been skipped
2024-04-09 14:50:51 -04:00
753 changed files with 17138 additions and 28081 deletions

5
.gitattributes vendored
View file

@ -1,5 +0,0 @@
flake.lock -diff
flake.nix -diff
**/non-declarative-conf -diff
**/package-lock.json -diff
**/HomeAssistantGenerated -diff

28
.gitignore vendored
View file

@ -1,23 +1,9 @@
# Python
*.egg-info
# NPM
*node_modules
*build/
# Direnv
*.direnv/
# Generated by nix
result*
!results/
.nixd.json
## AGS
**/vars.ts
**/config.js
*icons
**/types
# Other
*.temp
*node_modules/
*types
*build/
result*
*config.js
*icons
*.direnv/

View file

@ -1,15 +1,6 @@
# My NixOS configs
TODO: add directory structure info and enforce it
- every root folder in the repo represents a flake output except inputs
- every root folder only has a `default.nix` and subfolders for each
of its attrs
- in a subfolder, there should always be a `default.nix`
- if there is non nix code, it will be in a `config` folder
- redo docs
- every module should not do anything if imported
## AGS
## Ags
You might find it weird that most of my config is written in TypeScript.
That's because all my desktops run
@ -26,8 +17,10 @@ in TypeScript because it's the scripting language I am most comfortable with.
### General
This repo is the complete configuration of machines I own,
running NixOS or Nix. Its structure is based on a flake's
[outputs](https://wiki.nixos.org/wiki/Flakes#Output_schema).
running NixOS or Nix. I tend to mix Home-Manager and NixOS
a lot to make my custom modules by using my global vars system
explained
[here](https://git.nelim.org/matt1432/nixos-configs/src/branch/master/devices)
### Flake Location
@ -51,21 +44,12 @@ sudo ln -sf /home/matt/.nix /etc/nixos
| ---------------------------------- | ----------- |
| `nixosConfigurations` | [devices](https://git.nelim.org/matt1432/nixos-configs/src/branch/master/devices)' + ISO's configurations |
| `nixOnDroidConfigurations.default` | [Nix-On-Droid](https://git.nelim.org/matt1432/nixos-configs/src/branch/master/devices/android)'s configuration |
| `packages` | Some custom [packages](https://git.nelim.org/matt1432/nixos-configs/src/branch/master/packages) not available in nixpkgs or modified from it |
| `scopedPackages` | Some custom [package scopes](https://git.nelim.org/matt1432/nixos-configs/src/branch/master/scopedPackages) not available in nixpkgs or modified from it |
| `apps` | Scripts ran from the flake defined [here](https://git.nelim.org/matt1432/nixos-configs/src/branch/master/apps) |
| `homeManagerModules` | [Modules](https://git.nelim.org/matt1432/nixos-configs/src/branch/master/homeManagerModules) made for home-manager |
| `homeManagerModules` | [Modules](https://git.nelim.org/matt1432/nixos-configs/src/branch/master/modules) made for NixOS systems |
| `formatter` | I format nix code with [alejandra](https://github.com/kamadorueda/alejandra) |
| `formatter` | I have yet to know if this has any uses but I format with [alejandra](https://github.com/kamadorueda/alejandra) |
| `devShells.default` | A dev shell to build an ISO from the live-image nixosConfiguration |
| `devShells.ags` | A dev shell to have a NodeJS env when I enter my AGS's config directory |
### Flake Inputs
To allow use of the full nix language for my inputs, I use [genflake](https://github.com/jorsn/flakegen).
Therefore, the flake I edit is located at `./outputs.nix`.
I also prefer using a more descriptive format for my inputs like so:
I prefer using a more descriptive format for my inputs like so:
```nix
nixpkgs = {
@ -83,23 +67,29 @@ nixpkgs = {
to make it more clear what is what in the flake URI
I also have a long list of inputs with `flake = false;` because
it makes it easier to update non-flake custom packages or overlays
to have the latest git. I make sure to end the names of these inputs
with `src` to make it clear what they are.
### Secrets
All my secrets are in a private git repo that makes use of
[sops-nix](https://github.com/Mic92/sops-nix).
I generate `.sops.yaml` from `.sops.nix`:
I only use secrets stored in `JSON` and generate `.sops.yaml`
from `.sops.nix`:
```nix
let
wim = "somekey";
binto = "somekey2";
oksys = "somekey2";
in {
creation_rules = [
{
path_regex = "secrets/[^/]+\\.(yaml|json|env|ini)$";
key_groups = [
{
age = [wim binto];
age = [wim oksys];
}
];
}

View file

@ -1,2 +0,0 @@
use flake $FLAKE#node
npm ci

View file

@ -1,451 +0,0 @@
import eslint from '@eslint/js';
import jsdoc from 'eslint-plugin-jsdoc';
import stylistic from '@stylistic/eslint-plugin';
import tseslint from 'typescript-eslint';
export default tseslint.config({
files: ['**/*.js', '**/*.ts'],
ignores: ['node_modules/**', 'types/**'],
extends: [
eslint.configs.recommended,
jsdoc.configs['flat/recommended-typescript'],
stylistic.configs['recommended-flat'],
...tseslint.configs.recommended,
...tseslint.configs.stylistic,
],
rules: {
// JSDoc settings
'jsdoc/tag-lines': ['warn', 'any', { startLines: 1 }],
'jsdoc/check-line-alignment': ['warn', 'always', {
tags: ['param', 'arg', 'argument', 'property', 'prop'],
}],
'jsdoc/no-types': 'off',
// Newer settings
'@typescript-eslint/no-extraneous-class': ['off'],
'@typescript-eslint/no-implied-eval': ['off'],
'class-methods-use-this': 'off',
'@stylistic/no-multiple-empty-lines': 'off',
// Pre-flat config
'@typescript-eslint/no-unused-vars': [
'error',
{
args: 'all',
argsIgnorePattern: '^_',
caughtErrors: 'all',
caughtErrorsIgnorePattern: '^_',
destructuredArrayIgnorePattern: '^_',
varsIgnorePattern: '^_',
ignoreRestSiblings: true,
},
],
'array-callback-return': [
'error',
{
allowImplicit: true,
checkForEach: true,
},
],
'no-constructor-return': [
'error',
],
'no-unreachable-loop': [
'error',
{
ignore: [
'ForInStatement',
'ForOfStatement',
],
},
],
'no-use-before-define': [
'error',
{
functions: false,
},
],
'block-scoped-var': [
'error',
],
'curly': [
'warn',
],
'default-case-last': [
'warn',
],
'default-param-last': [
'error',
],
'eqeqeq': [
'error',
'smart',
],
'func-names': [
'warn',
'never',
],
'func-style': [
'warn',
'expression',
],
'logical-assignment-operators': [
'warn',
'always',
],
'no-array-constructor': [
'error',
],
'no-empty-function': [
'warn',
],
'no-empty-static-block': [
'warn',
],
'no-extend-native': [
'error',
],
'no-extra-bind': [
'warn',
],
'no-implicit-coercion': [
'warn',
],
'no-iterator': [
'error',
],
'no-labels': [
'error',
],
'no-lone-blocks': [
'error',
],
'no-lonely-if': [
'error',
],
'no-loop-func': [
'error',
],
'no-magic-numbers': [
'error',
{
ignore: [
-1,
0.1,
0,
1,
2,
3,
4,
5,
10,
12,
33,
66,
100,
255,
360,
450,
500,
1000,
],
ignoreDefaultValues: true,
ignoreClassFieldInitialValues: true,
},
],
'no-multi-assign': [
'error',
],
'no-new-wrappers': [
'error',
],
'no-object-constructor': [
'error',
],
'no-proto': [
'error',
],
'no-return-assign': [
'error',
],
'no-sequences': [
'error',
],
'no-shadow': [
'error',
{
builtinGlobals: true,
allow: [
'Window',
],
},
],
'no-undef-init': [
'warn',
],
'no-undefined': [
'error',
],
'no-useless-constructor': [
'warn',
],
'no-useless-escape': [
'off',
],
'no-useless-return': [
'error',
],
'no-var': [
'error',
],
'no-void': [
'off',
],
'no-with': [
'error',
],
'object-shorthand': [
'error',
'always',
],
'one-var': [
'error',
'never',
],
'operator-assignment': [
'warn',
'always',
],
'prefer-arrow-callback': [
'error',
],
'prefer-const': [
'error',
],
'prefer-object-has-own': [
'error',
],
'prefer-regex-literals': [
'error',
],
'prefer-template': [
'warn',
],
'no-prototype-builtins': 'off',
'@typescript-eslint/no-var-requires': [
'off',
],
'@stylistic/array-bracket-newline': [
'warn',
'consistent',
],
'@stylistic/array-bracket-spacing': [
'warn',
'never',
],
'@stylistic/arrow-parens': [
'warn',
'always',
],
'@stylistic/brace-style': [
'warn',
'stroustrup',
],
'@stylistic/comma-dangle': [
'warn',
'always-multiline',
],
'@stylistic/comma-spacing': [
'warn',
{
before: false,
after: true,
},
],
'@stylistic/comma-style': [
'error',
'last',
],
'@stylistic/dot-location': [
'error',
'property',
],
'@stylistic/function-call-argument-newline': [
'warn',
'consistent',
],
'@stylistic/function-paren-newline': [
'warn',
'consistent',
],
'@stylistic/indent': [
'warn',
4,
{
SwitchCase: 1,
ignoreComments: true,
ignoredNodes: ['TemplateLiteral > *'],
},
],
'@stylistic/key-spacing': [
'warn',
{
beforeColon: false,
afterColon: true,
},
],
'@stylistic/keyword-spacing': [
'warn',
{
before: true,
},
],
'@stylistic/linebreak-style': [
'error',
'unix',
],
'@stylistic/lines-between-class-members': [
'warn',
'always',
{
exceptAfterSingleLine: true,
},
],
'@stylistic/max-len': [
'warn',
{
code: 105,
ignoreComments: true,
ignoreTrailingComments: true,
ignoreUrls: true,
},
],
'@stylistic/multiline-ternary': [
'warn',
'always-multiline',
],
'@stylistic/new-parens': [
'error',
],
'@stylistic/no-mixed-operators': [
'warn',
],
'@stylistic/no-mixed-spaces-and-tabs': [
'error',
],
'@stylistic/no-multi-spaces': [
'error',
],
'@stylistic/no-tabs': [
'error',
],
'@stylistic/no-trailing-spaces': [
'error',
],
'@stylistic/no-whitespace-before-property': [
'warn',
],
'@stylistic/nonblock-statement-body-position': [
'error',
'below',
],
'@stylistic/object-curly-newline': [
'warn',
{
consistent: true,
},
],
'@stylistic/object-curly-spacing': [
'warn',
'always',
],
'@stylistic/operator-linebreak': [
'warn',
'after',
],
'@stylistic/padded-blocks': [
'error',
'never',
],
'@stylistic/padding-line-between-statements': [
'warn',
{
blankLine: 'always',
prev: '*',
next: 'return',
},
{
blankLine: 'always',
prev: [
'const',
'let',
'var',
],
next: '*',
},
{
blankLine: 'any',
prev: [
'const',
'let',
'var',
],
next: [
'const',
'let',
'var',
],
},
{
blankLine: 'always',
prev: [
'case',
'default',
],
next: '*',
},
],
'@stylistic/quote-props': [
'error',
'consistent-as-needed',
],
'@stylistic/quotes': [
'error',
'single',
{
avoidEscape: true,
},
],
'@stylistic/semi': [
'error',
'always',
],
'@stylistic/semi-spacing': [
'warn',
],
'@stylistic/space-before-blocks': [
'warn',
],
'@stylistic/space-before-function-paren': [
'warn',
'never',
],
'@stylistic/space-infix-ops': [
'warn',
],
'@stylistic/spaced-comment': [
'warn',
'always',
],
'@stylistic/switch-colon-spacing': [
'warn',
],
'@stylistic/wrap-regex': [
'warn',
],
},
});

View file

@ -1,3 +0,0 @@
import eslintConf from './eslint.config';
export default eslintConf;

Binary file not shown.

View file

@ -1,16 +0,0 @@
{
"name": "eslint-conf",
"version": "0.0.0",
"type": "module",
"exports": "./index.ts",
"devDependencies": {
"@eslint/js": "9.17.0",
"@stylistic/eslint-plugin": "2.12.1",
"eslint": "9.17.0",
"eslint-plugin-jsdoc": "50.6.1",
"jiti": "2.4.2",
"pkg-types": "1.2.1",
"typescript": "5.7.2",
"typescript-eslint": "8.18.1"
}
}

View file

@ -1,25 +0,0 @@
{
"$schema": "https://json.schemastore.org/tsconfig",
"compilerOptions": {
// Env
"target": "ESNext",
"lib": [
"ESNext"
],
// Module
"module": "nodenext",
"moduleResolution": "bundler",
"baseUrl": ".",
// Emit
"noEmit": true,
"newLine": "LF",
// Interop
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"forceConsistentCasingInFileNames": true,
"isolatedModules": true,
// Type Checking
"strict": true,
"noImplicitAny": false
}
}

View file

@ -1,10 +0,0 @@
{
"$schema": "https://json.schemastore.org/tsconfig",
"extends": "./tsconfig.base.json",
"includes": [
"*.ts",
"**/*.ts",
"*.js",
"**/*.js"
]
}

View file

@ -1,20 +0,0 @@
{
inputs,
pkgs,
...
}: let
inherit (pkgs.lib) getExe listToAttrs nameValuePair;
buildApp = attrs: (pkgs.callPackage ./nix/buildApp.nix ({} // inputs // attrs));
mkApp = file: {
program = getExe (pkgs.callPackage file ({inherit buildApp;} // inputs));
type = "app";
};
mkApps = apps: listToAttrs (map (x: nameValuePair x (mkApp ./${x})) apps);
in
mkApps [
"extract-subs"
"update-sources"
]

View file

@ -1,2 +0,0 @@
use flake $FLAKE#subtitles-dev
npm ci

View file

@ -1,13 +0,0 @@
{
buildApp,
ffmpeg-full,
...
}:
buildApp {
src = ./.;
npmDepsHash = "sha256-ytaO1mqoORNB5rP/8X/WpIoHkxmi1+Pc6Nep02+fTZ8=";
runtimeInputs = [
ffmpeg-full
];
}

View file

@ -1,3 +0,0 @@
import eslintConf from 'eslint-conf';
export default eslintConf;

Binary file not shown.

View file

@ -1,21 +0,0 @@
{
"name": "extract-subs",
"version": "0.0.0",
"bin": "out/bin/app.cjs",
"type": "module",
"scripts": {
"build": "node_ver=$(node -v); esbuild src/app.ts --bundle --platform=node --target=\"node${node_ver:1:2}\" --outfile=out/bin/app.cjs"
},
"dependencies": {
"@types/fluent-ffmpeg": "2.1.27",
"fluent-ffmpeg": "2.1.3"
},
"devDependencies": {
"eslint-conf": "file:../config",
"@types/node": "22.10.2",
"esbuild": "0.24.2",
"eslint": "9.17.0",
"jiti": "2.4.2",
"typescript": "5.7.2"
}
}

View file

@ -1,157 +0,0 @@
import { spawnSync as spawn } from 'child_process';
import ffprobe from './ffprobe';
import { ISO6393To1 } from './lang-codes';
/* Types */
import { FfprobeStream } from 'fluent-ffmpeg';
const SPAWN_OPTS = {
stdio: [process.stdin, process.stdout, process.stderr],
};
/**
* These are the cli arguments
*
* @param videoPath the directory in which we want to sync the subtitles
* @param languages a comma-separated list of languages (3 letters) to sync the subtitles
*/
const video = process.argv[2];
const languages = process.argv[3]?.split(',');
// Global Vars
const subIndexes: number[] = [];
let videoPath: string;
let baseName: string;
/**
* Gets the relative path to the subtitle file of a ffmpeg stream.
*
* @param sub the stream of the subtitles to extract
* @returns the path of the subtitle file
*/
const getSubPath = (sub: FfprobeStream): string => {
const language = ISO6393To1.get(sub.tags.language);
const forced = sub.disposition?.forced === 0 ?
'' :
'.forced';
const hearingImpaired = sub.disposition?.hearing_impaired === 0 ?
'' :
'.sdh';
return `${baseName}${forced}.${language}${hearingImpaired}.srt`;
};
/**
* Removes all subtitles streams from the video file.
*/
const removeContainerSubs = (): void => {
spawn('mv', [
videoPath,
`${videoPath}.bak`,
], SPAWN_OPTS);
spawn('ffmpeg', [
'-i', `${videoPath}.bak`,
'-map', '0',
...subIndexes.map((i) => ['-map', `-0:${i}`]).flat(),
'-c', 'copy', videoPath,
], SPAWN_OPTS);
spawn('rm', [
`${videoPath}.bak`,
], SPAWN_OPTS);
};
/**
* Extracts a sub of a video file to a subtitle file.
*
* @param sub the stream of the subtitles to extract
*/
const extractSub = (sub: FfprobeStream): void => {
const subFile = getSubPath(sub);
spawn('ffmpeg', [
'-i', videoPath,
'-map', `0:${sub.index}`, subFile,
], SPAWN_OPTS);
subIndexes.push(sub.index);
};
/**
* Sorts the list of streams to only keep subtitles
* that can be extracted.
*
* @param lang the language of the subtitles
* @param streams the streams
* @returns the streams that represent subtitles
*/
const findSubs = (
lang: string,
streams: FfprobeStream[],
): FfprobeStream[] => {
const subs = streams.filter((s) => s.tags?.language &&
s.tags.language === lang &&
s.codec_type === 'subtitle');
const pgs = subs.filter((s) => s.codec_name === 'hdmv_pgs_subtitle');
// If we only have PGS subs, warn user
if (pgs.length === subs.length) {
console.warn(`No SRT subtitle tracks were found for ${lang}`);
}
// Remove PGS streams from subs
return subs.filter((s) => s.codec_name !== 'hdmv_pgs_subtitle');
};
/**
* Where the magic happens.
*/
const main = async(): Promise<void> => {
// Get rid of video extension
baseName = videoPath.split('/').at(-1)!.replace(/\.[^.]*$/, '');
// ffprobe the video file to see available sub tracks
const data = await ffprobe(videoPath);
if (!data?.streams) {
console.error('Couldn\'t find streams in video file');
return;
}
// Check for languages wanted
languages.forEach((lang) => {
const subs = findSubs(lang, data.streams);
if (subs.length === 0) {
console.warn(`No subtitle tracks were found for ${lang}`);
return;
}
// Extract all subs
subs.forEach((sub) => { extractSub(sub); });
});
removeContainerSubs();
};
// Check if there are 2 params
if (video && languages) {
videoPath = video;
main();
}
else {
console.error('Error: no argument passed');
process.exit(1);
}

View file

@ -1,8 +0,0 @@
import Ffmpeg from 'fluent-ffmpeg';
export default (videoPath: string) => new Promise<Ffmpeg.FfprobeData>((resolve) => {
Ffmpeg.ffprobe(videoPath, (_e, data) => {
resolve(data);
});
});

View file

@ -1,10 +0,0 @@
{
"$schema": "https://json.schemastore.org/tsconfig",
"extends": "../config/tsconfig.base.json",
"includes": [
"*.ts",
"**/*.ts",
"*.js",
"**/*.js"
]
}

View file

@ -1,39 +0,0 @@
{
runtimeInputs,
npmDepsHash,
src,
lib,
buildNpmPackage,
makeWrapper,
nodejs_latest,
jq,
...
}: let
inherit (lib) concatMapStringsSep;
inherit (builtins) fromJSON readFile;
packageJSON = fromJSON (readFile "${src}/package.json");
in
buildNpmPackage rec {
pname = packageJSON.name;
inherit (packageJSON) version;
inherit src runtimeInputs npmDepsHash;
prePatch = ''
mv ./tsconfig.json ./project.json
sed 's/^ *\/\/.*//' ${../config/tsconfig.json} > ./base.json
${jq}/bin/jq -sr '.[0] * .[1] | del(.extends)' ./project.json ./base.json > ./tsconfig.json
rm base.json project.json
'';
nativeBuildInputs = [makeWrapper];
postInstall = ''
wrapProgram $out/bin/${pname} \
--prefix PATH : ${concatMapStringsSep ":" (p: p + "/bin") runtimeInputs}
'';
nodejs = nodejs_latest;
meta.mainProgram = pname;
}

View file

@ -1,14 +0,0 @@
{
pkgs,
self,
...
}: let
inherit (pkgs.lib) mapAttrs removeSuffix;
in
mapAttrs (
name: app: (pkgs.symlinkJoin {
name = "app-${name}";
paths = [(removeSuffix "/bin/${name}" (toString app.program))];
})
)
(removeAttrs self.apps.${pkgs.system} ["genflake"])

View file

@ -1,2 +0,0 @@
use flake $FLAKE#node
npm ci

View file

@ -1,19 +0,0 @@
{
buildApp,
callPackage,
nix-update,
nodejs_latest,
prefetch-npm-deps,
...
}:
buildApp {
src = ./.;
npmDepsHash = "sha256-vIhR/+Pgj35sv/ZX1iL+xWheu6w7vQeJy4OEfa8tXFw=";
runtimeInputs = [
nix-update
nodejs_latest
prefetch-npm-deps
(callPackage ../../modules/docker/updateImage.nix {})
];
}

View file

@ -1,3 +0,0 @@
import eslintConf from 'eslint-conf';
export default eslintConf;

Binary file not shown.

View file

@ -1,18 +0,0 @@
{
"name": "update-sources",
"version": "0.0.0",
"bin": "out/bin/app.cjs",
"type": "module",
"scripts": {
"build": "node_ver=$(node -v); esbuild src/app.ts --bundle --platform=node --target=\"node${node_ver:1:2}\" --outfile=out/bin/app.cjs"
},
"devDependencies": {
"eslint-conf": "file:../config",
"@types/node": "22.10.2",
"esbuild": "0.24.2",
"eslint": "9.17.0",
"jiti": "2.4.2",
"pkg-types": "1.2.1",
"typescript": "5.7.2"
}
}

View file

@ -1,153 +0,0 @@
import { spawnSync } from 'node:child_process';
import { writeFileSync } from 'node:fs';
import { parseArgs } from './lib';
import { updateDocker } from './docker';
import { updateFirefoxAddons } from '././firefox';
import { updateFlakeInputs } from './flake';
import updateNodeModules from './node-modules';
import {
runNixUpdate,
updateCustomPackage,
updateVuetorrent,
} from './misc';
/* Constants */
const FLAKE = process.env.FLAKE;
if (!FLAKE) {
console.error('Env var FLAKE not found');
process.exit(1);
}
const args = parseArgs();
const main = async() => {
if (args['d'] || args['docker']) {
console.log(updateDocker());
}
if (args['i'] || args['inputs']) {
console.log(updateFlakeInputs());
}
if (args['f'] || args['firefox']) {
console.log(updateFirefoxAddons());
}
if (args['v'] || args['vuetorrent']) {
console.log(updateVuetorrent());
}
if (args['c'] || args['custom-sidebar']) {
console.log(updateCustomPackage(
'scopedPackages.x86_64-linux.lovelace-components.custom-sidebar',
));
}
if (args['s'] || args['some-sass-language-server']) {
console.log(updateCustomPackage('some-sass-language-server'));
}
if (args['n'] || args['node_modules']) {
console.log(await updateNodeModules());
}
if (args['h'] || args['homepage']) {
console.log(runNixUpdate('homepage'));
}
if (args['a'] || args['all']) {
// Update this first because of nix run cmd
const firefoxOutput = updateFirefoxAddons();
console.log(firefoxOutput);
const flakeOutput = updateFlakeInputs();
console.log(flakeOutput);
const dockerOutput = updateDocker();
console.log(dockerOutput);
const nodeModulesOutput = await updateNodeModules();
console.log(nodeModulesOutput);
const vuetorrentOutput = updateVuetorrent();
console.log(vuetorrentOutput);
// This doesn't need to be added to commit msgs
console.log(updateCustomPackage(
'scopedPackages.x86_64-linux.lovelace-components.custom-sidebar',
));
console.log(updateCustomPackage('some-sass-language-server'));
// nix-update executions
let nixUpdateOutputs = '';
const updatePackage = (pkg: string): void => {
const execution = runNixUpdate(pkg);
nixUpdateOutputs += execution.stdout;
console.log(execution.stderr);
console.log(execution.stdout);
};
updatePackage('homepage');
spawnSync('nixFastBuild', [], {
shell: true,
stdio: [process.stdin, process.stdout, process.stderr],
});
const indentOutput = (output: string): string => {
return ` ${output.split('\n').join('\n ')}`;
};
const output = [
'chore: update sources\n\n',
];
if (flakeOutput.length > 5) {
output.push(`Flake Inputs:\n${indentOutput(flakeOutput)}\n\n`);
}
if (dockerOutput.length > 5) {
output.push(`Docker Images:\n${indentOutput(dockerOutput)}\n`);
}
if (firefoxOutput.length > 5) {
output.push(`Firefox Addons:\n${indentOutput(firefoxOutput)}\n\n`);
}
if (nodeModulesOutput.length > 5) {
output.push(`Node modules:\n${indentOutput(nodeModulesOutput)}\n`);
}
if (vuetorrentOutput.length > 5) {
output.push(`Misc Sources:\n${indentOutput(vuetorrentOutput)}\n\n`);
}
if (nixUpdateOutputs.length > 5) {
output.push(`nix-update executions:\n${indentOutput(nixUpdateOutputs)}\n`);
}
if (args['f']) {
writeFileSync(args['f'] as string, output.join(''));
}
else {
console.log(output.join(''));
}
}
spawnSync('alejandra', ['-q', FLAKE], { shell: true });
};
main();

View file

@ -1,33 +0,0 @@
import { readdirSync } from 'node:fs';
import { spawnSync } from 'node:child_process';
/* Constants */
const FLAKE = process.env.FLAKE;
const updateImages = (imagePath: string): string | undefined => {
console.log(`Updating ${imagePath.split('/').at(-1)} images`);
const out = spawnSync('updateImages', [imagePath], { shell: true }).stdout.toString();
if (!out.startsWith('# Locked')) {
return out;
}
};
export const updateDocker = () => {
let updates = '';
updates += updateImages(`${FLAKE}/configurations/nos/modules/jellyfin`) ?? '';
updates += updateImages(`${FLAKE}/configurations/homie/modules/home-assistant/netdaemon`) ?? '';
const DIR = `${FLAKE}/configurations/nos/modules/docker`;
readdirSync(DIR, { withFileTypes: true, recursive: true }).forEach((path) => {
if (path.name === 'compose.nix') {
updates += updateImages(path.parentPath) ?? '';
}
});
return updates;
};

View file

@ -1,61 +0,0 @@
import { spawnSync } from 'node:child_process';
import { readFileSync } from 'node:fs';
/* Constants */
const FLAKE = process.env.FLAKE;
export const updateFirefoxAddons = () => {
console.log('Updating firefox addons using mozilla-addons-to-nix');
const DIR = `${FLAKE}/scopedPackages/firefox-addons`;
const GENERATED_FILE = `${DIR}/generated-firefox-addons.nix`;
const SLUGS = `${DIR}/addons.json`;
const nameMap = Object.fromEntries([...JSON.parse(readFileSync(SLUGS, 'utf-8'))]
.map((addon) => [addon.slug, addon.pname || addon.slug]));
const nixExpr = `'
x: let
inherit (builtins) attrValues filter hasAttr isAttrs map;
in
map (d: d.name) (filter (y:
isAttrs y &&
hasAttr "type" y &&
y.type == "derivation") (attrValues x))
'`;
const OLD_VERS = Object.fromEntries([...JSON.parse(spawnSync('nix', [
'eval',
'.#scopedPackages.x86_64-linux.firefoxAddons',
'--apply',
nixExpr,
'--json',
], { shell: true }).stdout.toString())]
.map((p) => {
const pname = p.replace(/-[0-9].*$/, '');
return [pname, p.replace(`${pname}-`, '')];
})
.filter((pinfo) => pinfo[0] !== 'frankerfacez'));
const NEW_VERS = Object.fromEntries(spawnSync(
'nix',
['run', 'sourcehut:~rycee/mozilla-addons-to-nix',
SLUGS, GENERATED_FILE],
{ shell: true },
).stdout
.toString()
.split('\n')
.map((p) => {
const pinfo = p.replace('Fetched ', '').split(' ');
return [nameMap[pinfo[0]], pinfo[2]];
}));
return Object.keys(OLD_VERS)
.sort()
.filter((pname) => OLD_VERS[pname] !== NEW_VERS[pname])
.map((pname) => `${pname}: ${OLD_VERS[pname]} -> ${NEW_VERS[pname]}`)
.join('\n');
};

View file

@ -1,44 +0,0 @@
import { spawnSync } from 'node:child_process';
/* Constants */
const FLAKE = process.env.FLAKE;
export const updateFlakeInputs = () => {
const output = spawnSync(
`git restore flake.lock &> /dev/null; nix flake update --flake ${FLAKE}` +
' |& grep -v "warning: updating lock file" |& grep -v "unpacking"',
[],
{ shell: true },
).stdout
.toString()
// Add an extra blank line between inputs
.split('\n•')
// Filter out some inputs
.filter((input) => ![
'systems',
'flake-utils',
'flake-parts',
'treefmt-nix',
'lib-aggregate',
'lib-aggregate/nixpkgs-lib',
'sops-nix/nixpkgs-stable',
'discord-overlay/Vencord-src',
'nix-gaming/umu',
].some((inputName) => input.startsWith(` Updated input '${inputName}'`)))
.join('\n\n•')
// help readability of git revs
.split('\n')
.map((l) => l
.replace(
/\/(.{40})\?narHash=sha256[^']*(.*)/,
(_, backref1, backref2) => `${backref2} rev: ${backref1}`,
)
.replace(
/\?ref.*&rev=(.{40})[^'&]*(.*)/,
(_, backref1, backref2) => `${backref2} rev: ${backref1}`,
))
.join('\n');
return output;
};

View file

@ -1,43 +0,0 @@
import { spawnSync } from 'node:child_process';
import { readFileSync, writeFileSync } from 'node:fs';
export const parseArgs = () => {
const args = {} as Record<string, unknown>;
let lastFlag: string | null = null;
for (let i = 2; i < process.argv.length; ++i) {
const arg = process.argv[i];
if (arg.toString().startsWith('-')) {
lastFlag = arg.toString().replace(/^-{1,2}/, '');
args[lastFlag] = true;
}
else if (lastFlag) {
args[lastFlag] = arg;
lastFlag = null;
}
else {
console.error(`Could not parse args: ${arg.toString()}`);
}
}
return args;
};
export const parseFetchurl = (url: string) => JSON.parse(spawnSync(
'nix', ['store', 'prefetch-file', '--refresh', '--json',
'--hash-type', 'sha256', url, '--name', '"escaped"'], { shell: true },
).stdout.toString()).hash;
export const replaceInFile = (replace: RegExp, replacement: string, file: string) => {
const fileContents = readFileSync(file);
const replaced = fileContents.toString().replace(replace, replacement);
writeFileSync(file, replaced);
};
export const npmRun = (args: string[], workspaceDir: string) => spawnSync(
'npm', args, { cwd: workspaceDir },
).stdout.toString();

View file

@ -1,73 +0,0 @@
import { writeFileSync } from 'node:fs';
import { spawnSync } from 'node:child_process';
import { parseFetchurl } from './lib';
/* Constants */
const FLAKE = process.env.FLAKE;
const genVueText = (
version: string,
hash: string,
url: string,
) => `# This file was autogenerated. DO NOT EDIT!
{
version = "${version}";
url = "${url}";
hash = "${hash}";
}
`;
export const updateVuetorrent = () => {
const FILE = `${FLAKE}/configurations/nos/modules/qbittorrent/vuetorrent.nix`;
const OLD_VERSION = JSON.parse(spawnSync('nix',
['eval', '-f', FILE, '--json'],
{ shell: true }).stdout.toString()).version;
const VERSION = JSON.parse(spawnSync('curl',
['-s', 'https://api.github.com/repos/VueTorrent/VueTorrent/releases/latest'],
{ shell: true }).stdout.toString()).tag_name.replace('v', '');
const URL = `https://github.com/VueTorrent/VueTorrent/releases/download/v${VERSION}/vuetorrent.zip`;
const HASH = parseFetchurl(URL);
const fileText = genVueText(VERSION, HASH, URL);
writeFileSync(FILE, fileText);
return OLD_VERSION !== VERSION ? `Vuetorrent: ${OLD_VERSION} -> ${VERSION}` : '';
};
export const updateCustomPackage = (pkg: string) => spawnSync(
`nix run ${FLAKE}#${pkg}.update`,
[],
{ shell: true },
).stderr.toString();
const getAttrVersion = (attr: string): string => spawnSync('nix',
['eval', '--raw', `${FLAKE}#${attr}.version`],
{ shell: true }).stdout.toString();
export const runNixUpdate = (
attr: string,
options: string[] = [],
): { stdout: string, stderr: string } => {
const OLD_VERSION = getAttrVersion(attr);
const execution = spawnSync(
`nix-update --flake ${attr} --write-commit-message >(head -n 1 -) > /dev/null`,
options,
{ shell: true, cwd: FLAKE },
);
const NEW_VERSION = getAttrVersion(attr);
return {
stdout: OLD_VERSION !== NEW_VERSION ? execution.stdout.toString() : '',
stderr: execution.stderr.toString(),
};
};

View file

@ -1,82 +0,0 @@
import { readPackageJSON, writePackageJSON } from 'pkg-types';
import { readdirSync } from 'node:fs';
import { spawnSync } from 'node:child_process';
import { replaceInFile, npmRun } from './lib';
/* Constants */
const FLAKE = process.env.FLAKE as string;
const updatePackageJson = async(workspaceDir: string, updates: object) => {
const currentPackageJson = await readPackageJSON(`${workspaceDir}/package.json`);
const outdated = JSON.parse(npmRun(['outdated', '--json'], workspaceDir));
const updateDeps = (deps: string) => {
Object.keys(currentPackageJson[deps]).forEach((dep) => {
const versions = outdated[dep];
const current = versions?.wanted || versions?.current;
if (!current) {
return;
}
if (current !== versions.latest) {
updates[dep] = `${current} -> ${versions.latest}`;
}
currentPackageJson[deps][dep] = versions.latest;
});
};
if (currentPackageJson.dependencies) {
updateDeps('dependencies');
}
if (currentPackageJson.devDependencies) {
updateDeps('devDependencies');
}
await writePackageJSON(`${workspaceDir}/package.json`, currentPackageJson);
};
const prefetchNpmDeps = (workspaceDir: string): string => {
npmRun(['install', '--package-lock-only'], workspaceDir);
return spawnSync(
'prefetch-npm-deps',
[`${workspaceDir}/package-lock.json`],
).stdout.toString().replace('\n', '');
};
export default async() => {
const updates = {};
const packages = readdirSync(FLAKE, { withFileTypes: true, recursive: true });
for (const path of packages) {
if (
path.name === 'package.json' &&
!path.parentPath.includes('node_modules') &&
!path.parentPath.includes('apps/config')
) {
await updatePackageJson(path.parentPath, updates);
const hash = prefetchNpmDeps(path.parentPath);
replaceInFile(
/npmDepsHash = ".*";/,
`npmDepsHash = "${hash}";`,
`${path.parentPath}/default.nix`,
);
}
}
return Object.entries(updates)
.map(([key, dep]) => `${key}: ${dep}`)
.join('\n');
};

View file

@ -1,10 +0,0 @@
{
"$schema": "https://json.schemastore.org/tsconfig",
"extends": "../config/tsconfig.base.json",
"includes": [
"*.ts",
"**/*.ts",
"*.js",
"**/*.js"
]
}

126
common/default.nix Normal file
View file

@ -0,0 +1,126 @@
{
config,
home-manager,
lib,
nh,
nix-melt,
nur,
nurl,
pkgs,
...
} @ inputs: {
imports = [
./vars
./modules
./pkgs
nur.nixosModules.nur
nh.nixosModules.default
home-manager.nixosModules.home-manager
../modules/arion
../modules/borgbackup
../modules/nvidia.nix
];
nixpkgs = {
config.allowUnfree = true;
overlays = import ./overlays inputs;
};
boot.tmp.cleanOnBoot = true;
nix = {
# Allow deleting store files with '.' in the name
package = pkgs.nix.overrideAttrs (o: {
patches =
(o.patches or [])
++ [
./overlays/nix/patch
];
});
# Edit nix.conf
settings = {
# Store
keep-outputs = true;
keep-derivations = true;
auto-optimise-store = true;
# Commands
experimental-features = ["nix-command" "flakes"];
http-connections = 0; # unlimited for local cache
warn-dirty = false;
show-trace = true;
# remote building
trusted-users = ["matt" "nixremote"];
};
};
nh = {
enable = true;
# weekly cleanup
clean = {
enable = true;
extraArgs = "--keep-since 30d";
};
};
services = {
fwupd.enable = true;
xserver.xkb = {
layout = "ca";
variant = "multix";
};
};
home-manager = let
inherit (config.vars) mainUser;
mainUserConf = config.home-manager.users.${mainUser};
default = {
imports = [
# Make the vars be the same on Nix and HM
{
options.vars = lib.mkOption {
type = lib.types.attrs;
readOnly = true;
default = config.vars;
};
}
nur.hmModules.nur
./home
./home/trash-d
./pkgs
];
home.packages =
[
nix-melt.packages.${pkgs.system}.default
nurl.packages.${pkgs.system}.default
]
++ (with config.nur.repos.rycee; [
mozilla-addons-to-nix
]);
};
in {
users = {
root =
default
// {
home.stateVersion = mainUserConf.home.stateVersion;
};
greeter =
lib.mkIf (config.services.greetd.enable)
(default
// {
home.stateVersion = mainUserConf.home.stateVersion;
});
${mainUser} = default;
};
};
}

View file

@ -0,0 +1,145 @@
{
config,
lib,
...
}: let
inherit (lib) concatStrings fileContents;
inherit (config.vars) promptColors;
in {
imports = [./programs.nix];
programs = {
starship = {
enable = true;
enableBashIntegration = true;
settings = {
format = concatStrings [
""
"[](fg:${promptColors.firstColor})"
"[ ](bg:${promptColors.firstColor} fg:#090c0c)"
"[](bg:${promptColors.secondColor} fg:${promptColors.firstColor})"
"$username$hostname"
"[](fg:${promptColors.secondColor} bg:${promptColors.thirdColor})"
"$directory"
"[](fg:${promptColors.thirdColor} bg:${promptColors.fourthColor})"
"$git_branch"
"[](fg:${promptColors.fourthColor})$shlvl$nix_shell"
"\n$character"
];
username = {
show_always = true;
style_user = "fg:${promptColors.textColor} bg:${promptColors.secondColor}";
style_root = "fg:red bg:${promptColors.secondColor} blink";
format = "[ $user]($style)";
};
hostname = {
ssh_only = false;
style = "fg:${promptColors.textColor} bg:${promptColors.secondColor}";
format = "[@$hostname ]($style)";
};
directory = {
style = "fg:${promptColors.firstColor} bg:${promptColors.thirdColor}";
format = "[ $path ]($style)";
truncate_to_repo = false;
truncation_length = 0;
substitutions = {
"Documents" = "󰈙 ";
"Downloads" = " ";
"Music" = " ";
"Pictures" = " ";
};
};
git_branch = {
style = "fg:${promptColors.secondColor} bg:${promptColors.fourthColor}";
symbol = "";
format = "[ $symbol $branch ]($style)";
};
shlvl = {
disabled = false;
repeat = true;
symbol = "󰔳 ";
format = "[ $symbol]($style)";
threshold = 1;
};
nix_shell = {
symbol = " ";
format = "[ $symbol]($style)";
};
character = {
success_symbol = "[\\$](bold green)";
error_symbol = "[\\$](bold red)";
};
};
};
bash = {
enable = true;
enableCompletion = true;
historyFile = "\$HOME/.cache/.bash_history";
historyFileSize = 100000; # default
historySize = 10000; # default
historyControl = [
"erasedups"
"ignorespace"
];
historyIgnore = [
"ls"
"exit"
"logout"
];
shellOptions = [
"histappend"
"checkwinsize"
"extglob"
"globstar"
"checkjobs"
"autocd"
"cdspell"
"dirspell"
"dotglob"
];
shellAliases = {
# Add whitespace after, to allow
# sudo to inherit all other aliases
sudo = "sudo ";
ls = "ls -lah --color=auto";
tree = "tree -a -I node_modules";
cp = "cp -r";
};
#profileExtra = ''
#'';
bashrcExtra =
/*
bash
*/
''
# Check if shell is interactive
[[ $- == *i* ]] || return 0
${fileContents ./config/dracula/less.sh}
${fileContents ./config/dracula/fzf.sh}
${fileContents ./config/colorgrid.sh}
${fileContents ./config/bashrc}
'';
#initExtra = ''
#'';
#logoutExtra = ''
#'';
};
};
}

View file

@ -1,14 +1,9 @@
self: {
config,
lib,
{
pkgs,
config,
...
}: let
inherit (lib) mkIf;
cfg = config.programs.bash;
in {
config.programs = mkIf cfg.enable {
}: {
programs = {
fzf = {
enable = true;
enableBashIntegration = true;
@ -46,16 +41,18 @@ in {
bat = {
enable = true;
config.theme = "dracula-bat";
themes.dracula-bat.src = self.scopedPackages.${pkgs.system}.dracula.bat;
extraPackages = builtins.attrValues {
inherit (pkgs.bat-extras) batman;
config = {
theme = "dracula-bat";
};
themes = {
dracula-bat = {
src = pkgs.dracula-theme;
file = "bat";
};
};
extraPackages = with pkgs.bat-extras; [
batman
];
};
};
# For accurate stack trace
_file = ./default.nix;
}

11
common/home/default.nix Normal file
View file

@ -0,0 +1,11 @@
{...}: {
imports = [
./bash
./direnv
./git
./neovim
./nix-index
./tmux
./packages.nix
];
}

View file

@ -0,0 +1,10 @@
{pkgs, ...}: {
programs.direnv = {
enable = true;
enableBashIntegration = true;
nix-direnv = {
enable = true;
package = pkgs.nix-direnv-flakes;
};
};
}

View file

@ -0,0 +1,82 @@
{pkgs, ...}: {
programs = {
git = {
enable = true;
lfs.enable = true;
includes = [
{path = "${pkgs.dracula-theme}/git-colors";}
{
condition = "hasconfig:remote.*.url:git@github.com:*/**";
contents = {
user = {
email = "matt@nelim.org";
name = "matt1432";
};
};
}
{
condition = "hasconfig:remote.*.url:git@git.nelim.org:*/**";
contents = {
user = {
email = "matt@nelim.org";
name = "matt1432";
};
};
}
{
condition = "hasconfig:remote.*.url:git@gitlab.info.uqam.ca:*/**";
contents = {
user = {
email = "gj591944@ens.uqam.ca";
name = "Mathis Hurtubise";
};
};
}
];
delta = {
enable = true;
options = {
side-by-side = true;
line-numbers-zero-style = "#E6EDF3"; #BD93F9";
};
};
extraConfig = {
diff.sopsdiffer.textconv = "sops --config /dev/null -d";
# https://github.com/dandavison/delta/issues/630#issuecomment-860046929
pager = let
cmd = "LESS='LRc --mouse' ${pkgs.delta}/bin/delta";
in {
diff = cmd;
show = cmd;
stash = cmd;
log = cmd;
reflog = cmd;
};
};
};
};
home.packages = with pkgs; [
(writeShellApplication {
name = "chore";
runtimeInputs = [git];
text = ''
DIR=''${1:-"$FLAKE"}
cd "$DIR" || exit 1
git add flake.lock
git commit -m 'chore: update flake.lock'
git push
'';
})
];
}

View file

@ -0,0 +1,2 @@
-- Add `:Format` command to format current buffer
vim.api.nvim_create_user_command("Format", "call CocAction('format')", {})

View file

@ -0,0 +1,34 @@
" by default, the indent is 2 spaces.
set smartindent
set expandtab
set shiftwidth=2
set softtabstop=2
set tabstop=2
" for html/rb files, 2 spaces
autocmd Filetype html setlocal ts=2 sw=2 expandtab
autocmd Filetype ruby setlocal ts=2 sw=2 expandtab
" for js/coffee/jade files, 4 spaces
autocmd Filetype javascript setlocal ts=4 sw=4 sts=0 expandtab
autocmd Filetype typescript setlocal ts=4 sw=4 sts=0 expandtab
autocmd Filetype java setlocal ts=4 sw=4 sts=0 expandtab
autocmd Filetype sh setlocal ts=4 sw=4 sts=0 expandtab
autocmd Filetype hyprlang setlocal ts=4 sw=4 sts=0 expandtab
" support scss @
autocmd FileType scss setl iskeyword+=@-@
set number
set relativenumber
" TODO: make this work for nix-on-droid
set undofile
set undodir=/home/matt/.cache/nvim/
" remove highlight on words
nnoremap <silent> <esc> :noh<cr><esc>
" Always show the signcolumn, otherwise it would shift the text each time
" diagnostics appear/become resolved
set signcolumn=yes

View file

@ -0,0 +1,340 @@
{
config,
pkgs,
lib,
nvim-theme-src,
coc-stylelintplus,
vimplugin-riscv-src,
...
}: let
inherit (config.vars) neovimIde;
inherit (lib) fileContents hasAttr optionalAttrs optionals;
javaSdk = pkgs.temurin-bin-17;
coc-stylelintplus-flake = coc-stylelintplus.packages.${pkgs.system}.default;
in {
home = optionalAttrs neovimIde {
packages = with pkgs; [
gradle
maven
alejandra
];
};
xdg.dataFile = optionalAttrs neovimIde {
".gradle/gradle.properties".text = ''
org.gradle.java.home = ${javaSdk}
'';
};
programs = {
java = optionalAttrs neovimIde {
enable = true;
package = javaSdk;
};
# I love doing typos
bash.shellAliases = {
nivm = "nvim";
nivim = "nvim";
};
neovim = {
enable = true;
withNodeJs = true;
withPython3 = true;
withRuby = false;
defaultEditor = true;
viAlias = true;
vimAlias = true;
extraPackages = with pkgs; ([
bat
gcc
]
++ optionals neovimIde [
nodejs_latest
nodePackages.npm
nodePackages.neovim
gradle
nil
]);
extraPython3Packages = ps:
optionals neovimIde [
ps.pylint
];
coc = optionalAttrs neovimIde {
enable = true;
settings = {
# General
colors.enable = true;
coc.preferences.formatOnType = true;
diagnostic.checkCurrentLine = true;
inlayHint.enable = false;
# ESLint
eslint = {
format.enable = true;
autoFixOnSave = true;
};
# Stylelint
stylelintplus = {
enable = true;
cssInJs = true;
autoFixOnSave = true;
autoFixOnFormat = true;
};
css.validate = false;
less.validate = false;
scss.validate = false;
wxss.validate = false;
# Lua
Lua = {
misc.parameters = [
"--metapath"
"~/.cache/sumneko_lua/meta"
"--logpath"
"~/.cache/sumneko_lua/log"
];
workspace.library = [
"$\{3rd\}/luv/library"
];
};
sumneko-lua = {
serverDir = "${pkgs.lua-language-server}/share/lua-language-server";
enableNvimLuaDev = true;
};
languageserver = {
# Nix
nix = {
command = "nil";
filetypes = ["nix"];
rootPatterns = ["flake.nix"];
settings = {
nil = {
formatting.command = ["alejandra"];
nix = {
maxMemoryMB = 2560;
flake.autoArchive = hasAttr "sops" config;
};
};
};
};
};
# Java
java = {
maven.downloadSources = true;
eclipse.downloadSources = true;
format.settings.url = "eclipse-formatter.xml";
jdt.ls = {
java.home = "${javaSdk}";
statusIcons = {
"busy" = "Busy";
"ready" = "OK";
"warning" = "Warning";
"error" = "Error";
};
};
};
# Bash
bashIde.shellcheckPath = "${pkgs.shellcheck}/bin/shellcheck";
markdownlint.config = {
no-trailing-spaces = true;
no-multiple-blanks = false;
no-duplicate-heading = false;
};
};
};
extraConfig = fileContents ./base.vim;
extraLuaConfig = fileContents ./base.lua;
plugins = with pkgs.vimPlugins;
([
fzfWrapper
fzf-vim
fugitive
{
plugin = dracula-nvim.overrideAttrs {
src = nvim-theme-src;
};
type = "viml";
config = fileContents ./plugins/dracula.vim;
}
{
plugin = todo-comments-nvim;
type = "lua";
config =
/*
lua
*/
''require('todo-comments').setup()'';
}
{
plugin = gitsigns-nvim;
type = "lua";
config = fileContents ./plugins/gitsigns.lua;
}
{
plugin = indent-blankline-nvim;
type = "lua";
config = fileContents ./plugins/indent.lua;
}
{
plugin = mini-nvim;
type = "lua";
config = fileContents ./plugins/mini.lua;
}
]
++ optionals neovimIde [
markdown-preview-nvim
# Coc configured
coc-css
coc-eslint
coc-java
coc-sh
coc-stylelintplus-flake
{
plugin = coc-snippets;
type = "viml";
config = fileContents ./plugins/snippets.vim;
}
## Lua
coc-sumneko-lua
neodev-nvim
## Fzf
coc-fzf
coc-highlight
coc-json
coc-pyright
coc-vimlsp
coc-yaml
coc-toml
coc-markdownlint
coc-tsserver
{
plugin = nvim-autopairs;
type = "lua";
config = fileContents ./plugins/autopairs.lua;
}
{
plugin = lualine-nvim;
type = "lua";
config = fileContents ./plugins/lualine.lua;
}
{
plugin = neo-tree-nvim;
type = "viml";
config = ''
${fileContents ./plugins/neotree.vim}
lua << EOF
${fileContents ./plugins/neotree.lua}
EOF
'';
}
(pkgs.vimUtils.buildVimPlugin {
name = "riscv-asm";
src = vimplugin-riscv-src;
})
])
# Treesitter
++ (with pkgs.vimPlugins; [
nvim-treesitter-context
nvim-treesitter-textobjects
{
type = "viml";
config = fileContents ./plugins/treesitter.vim;
plugin = nvim-treesitter.withPlugins (p: [
p.awk
p.bash
p.c
p.c_sharp
p.cairo
p.cmake
p.comment
p.cpp
p.css
p.csv
p.cuda
p.diff
p.dockerfile
p.dot
p.git_config
p.git_rebase
p.gitattributes
p.gitcommit
p.gitignore
p.go
p.gomod
p.gosum
p.groovy
p.haskell
p.haskell_persistent
p.hyprlang
p.html
p.ini
p.java
p.javascript
p.jq
p.jsdoc
p.json
p.json5
p.jsonc
p.jsonnet
p.kotlin
p.latex
p.lua
p.luadoc
p.make
p.markdown
p.meson
p.ninja
p.nix
p.passwd
p.perl
p.php
p.phpdoc
p.properties
p.python
p.rasi
p.regex
p.requirements
p.ruby
p.rust
p.scss
p.sql
p.ssh_config
p.toml
p.todotxt
p.typescript
p.udev
p.vim
p.vimdoc
p.vue
p.xml
p.yaml
]);
}
]);
};
};
}

View file

@ -0,0 +1,16 @@
-- Auto indent when pressing Enter between brackets
local remap = vim.api.nvim_set_keymap
local npairs = require('nvim-autopairs')
npairs.setup({map_cr=false})
_G.MUtils= {}
MUtils.completion_confirm=function()
if vim.fn["coc#pum#visible"]() ~= 0 then
return vim.fn["coc#pum#confirm"]()
else
return npairs.autopairs_cr()
end
end
remap('i' , '<CR>','v:lua.MUtils.completion_confirm()', {expr = true , noremap = true})

View file

@ -0,0 +1,10 @@
" set dot icon in place of trailing whitespaces
set list listchars=tab:\ \ ,nbsp:␣,trail:•,extends:⟩,precedes:⟨
lua << EOF
-- Add visual indicator for trailing whitespaces
vim.opt.fillchars = {eob = " "}
vim.cmd[[colorscheme dracula]]
EOF

View file

@ -0,0 +1,13 @@
local gitsigns = require("gitsigns")
local function visual_stage()
local first_line = vim.fn.line('v')
local last_line = vim.fn.getpos('.')[2]
gitsigns.stage_hunk({ first_line, last_line })
end
vim.keymap.set("v", "gs", function()
visual_stage()
end)
gitsigns.setup();

View file

@ -0,0 +1,26 @@
local highlight = {
"RainbowRed",
"RainbowYellow",
"RainbowBlue",
"RainbowOrange",
"RainbowGreen",
"RainbowViolet",
"RainbowCyan",
}
local hooks = require('ibl.hooks')
hooks.register(hooks.type.HIGHLIGHT_SETUP, function()
vim.api.nvim_set_hl(0, "RainbowRed", { fg = "#E06C75" })
vim.api.nvim_set_hl(0, "RainbowYellow", { fg = "#E5C07B" })
vim.api.nvim_set_hl(0, "RainbowBlue", { fg = "#61AFEF" })
vim.api.nvim_set_hl(0, "RainbowOrange", { fg = "#D19A66" })
vim.api.nvim_set_hl(0, "RainbowGreen", { fg = "#98C379" })
vim.api.nvim_set_hl(0, "RainbowViolet", { fg = "#C678DD" })
vim.api.nvim_set_hl(0, "RainbowCyan", { fg = "#56B6C2" })
end)
require('ibl').setup({
indent = {
highlight = highlight,
char = "",
},
})

View file

@ -0,0 +1,9 @@
require('lualine').setup({
options = {
theme = 'dracula',
globalstatus = true,
},
sections = {
lualine_x = {'g:coc_status', 'bo:filetype'},
}
})

View file

@ -0,0 +1,23 @@
local map = require('mini.map')
map.setup({
integrations = {
map.gen_integration.builtin_search(),
map.gen_integration.gitsigns(),
map.gen_integration.diagnostic(),
},
window = {
focusable = false,
width = 7,
winblend = 75,
},
})
local ts_input = require('mini.surround').gen_spec.input.treesitter
require('mini.surround').setup({
custom_surroundings = {
-- Use tree-sitter to search for function call
f = {
input = ts_input({ outer = '@call.outer', inner = '@call.inner' })
},
}
})

View file

@ -0,0 +1,38 @@
-- Override netrw
vim.g.loaded_netrw = 0
vim.g.loaded_netrwPlugin = 0
require('neo-tree').setup({
close_if_last_window = true,
enable_refresh_on_write = true,
window = {
width = 22,
},
filesystem = {
use_libuv_file_watcher = true,
group_empty_dirs = true,
filtered_items = {
visible = false,
hide_dotfiles = false,
hide_gitignored = true,
hide_by_name = {},
hide_by_pattern = {},
always_show = {},
never_show = {},
never_show_by_pattern = {},
},
},
source_selector = {
winbar = true,
statusline = false
},
follow_current_file = {
enabled = true,
leave_dirs_open = true,
}
})

View file

@ -0,0 +1,11 @@
" Auto open Neo-Tree on big enough window
function! OpenTree() abort
if &columns > 100
Neotree show
Neotree close
Neotree show
endif
lua MiniMap.open()
endfunction
autocmd VimEnter * call OpenTree()

View file

@ -0,0 +1,13 @@
" use vscode keybinds for snippets completion
inoremap <silent><expr> <TAB>
\ coc#pum#visible() ? coc#_select_confirm() :
\ coc#expandableOrJumpable() ? "\<C-r>=coc#rpc#request('doKeymap', ['snippets-expand-jump',''])\<CR>" :
\ CheckBackspace() ? "\<TAB>" :
\ coc#refresh()
function! CheckBackspace() abort
let col = col('.') - 1
return !col || getline('.')[col - 1] =~# '\s'
endfunction
let g:coc_snippet_next = '<tab>'

View file

@ -0,0 +1,21 @@
lua << EOF
require('nvim-treesitter.configs').setup({
highlight = { enable = true },
indent = { enable = true },
})
require('treesitter-context').setup({
enable = true,
max_lines = 3,
min_window_height = 20,
})
vim.filetype.add({
pattern = { [".*/hypr/.*%.conf"] = "hyprlang" },
})
EOF
" Add line under context
hi TreesitterContextBottom gui=underline guisp=Grey

View file

@ -0,0 +1,11 @@
{nix-index-db, ...}: {
imports = [nix-index-db.hmModules.nix-index];
programs = {
nix-index-database.comma.enable = true;
nix-index = {
enable = true;
enableBashIntegration = true;
};
};
}

30
common/home/packages.nix Normal file
View file

@ -0,0 +1,30 @@
{
config,
pkgs,
...
}: {
home.packages =
(with config.customPkgs; [
pokemon-colorscripts
repl
])
++ (with pkgs.nodePackages; [
undollar
])
++ (with pkgs; [
dracula-theme
neofetch
progress
wget
tree
openssh
mosh
rsync
killall
imagemagick
usbutils
zip
unzip
dig.dnsutils
]);
}

View file

@ -0,0 +1,31 @@
{pkgs, ...}: {
programs = {
# Make sure we have color support
bash.shellAliases.tmux = "tmux -2";
tmux = {
enable = true;
mouse = true;
keyMode = "vi";
terminal = "tmux-256color";
newSession = true;
historyLimit = 30000;
plugins = with pkgs.tmuxPlugins; [dracula];
extraConfig =
/*
bash
*/
''
bind-key -n Home send Escape "OH"
bind-key -n End send Escape "OF"
bind -T root WheelUpPane if-shell -F -t = "#{alternate_on}" "send-keys -M" "select-pane -t =; copy-mode -e; send-keys -M"
bind -T root WheelDownPane if-shell -F -t = "#{alternate_on}" "send-keys -M" "select-pane -t =; send-keys -M"
set -ga terminal-overrides ',xterm*:smcup@:rmcup@'
set -ga terminal-overrides ",*256col*:Tc"
'';
};
};
}

View file

@ -0,0 +1,7 @@
{pkgs, ...} @ inputs: let
trash = pkgs.callPackage ./trash-d.nix inputs;
in {
home.packages = [trash];
programs.bash.shellAliases.rm = "trash";
}

View file

@ -0,0 +1,31 @@
{
trash-d-src,
stdenv,
dmd,
dub,
ronn,
...
}:
stdenv.mkDerivation {
name = "trash";
version = trash-d-src.shortRev;
src = trash-d-src;
buildInputs = [dub dmd ronn];
buildPhase = ''
# https://github.com/svanderburg/node2nix/issues/217#issuecomment-751311272
export HOME=$(mktemp -d)
dub build
'';
installPhase = ''
mkdir -p $out/bin $out/man/man1
cp -a ./build/trash $out/bin/
ronn --roff --pipe MANUAL.md > $out/man/man1/trash.1
'';
}

51
common/modules/cachix.nix Normal file
View file

@ -0,0 +1,51 @@
{
config,
pkgs,
...
}: {
environment.systemPackages = with pkgs; [
(writeShellApplication {
name = "rebuild-no-cache";
runtimeInputs = [config.nh.package];
text = ''
nh os switch -- --option binary-caches "https://cache.nixos.org" "$@"
'';
})
];
nix = {
settings = {
substituters = [
"https://hyprland.cachix.org"
"https://nix-gaming.cachix.org"
# Nixpkgs-Wayland
"https://cache.nixos.org"
"https://nixpkgs-wayland.cachix.org"
"https://nix-community.cachix.org"
# Nix-community
"https://nix-community.cachix.org"
# Nh
"https://viperml.cachix.org"
# Caddy
"https://caddycf.cachix.org"
# Personal config cache
"https://cache.nelim.org"
];
trusted-public-keys = [
"hyprland.cachix.org-1:a7pgxzMz7+chwVL3/pzj6jIBMioiJM7ypFP8PwtkuGc="
"nix-gaming.cachix.org-1:nbjlureqMbRAxR1gJ/f3hxemL9svXaZF/Ees8vCUUs4="
# Nixpkgs-Wayland
"cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY="
"nixpkgs-wayland.cachix.org-1:3lwxaILxMRkVhehr5StQprHdEo4IrE8sRho9R9HOLYA="
# Nix-community
"nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs="
# Nh
"viperml.cachix.org-1:qZhKBMTfmcLL+OG6fj/hzsMEedgKvZVFRRAhq7j8Vh8="
# Caddy
"caddycf.cachix.org-1:6vbQaeiec/zKv9XfEwi9yWVCe7opbeJMu6w81UEXugY="
# Personal config cache
"cache.nelim.org:JmFqkUdH11EA9EZOFAGVHuRYp7EbsdJDHvTQzG2pPyY="
];
};
};
}

View file

@ -0,0 +1,8 @@
{...}: {
imports = [
./cachix.nix
./locale.nix
./locate.nix
./global.nix
];
}

23
common/modules/global.nix Normal file
View file

@ -0,0 +1,23 @@
{
config,
lib,
nixpkgs,
...
}: let
inherit (config.sops.secrets) access-token;
inherit (lib) hasAttr optionalString;
in {
# Minimize dowloads of indirect nixpkgs flakes
nix = {
registry.nixpkgs.flake = nixpkgs;
nixPath = ["nixpkgs=${nixpkgs}"];
extraOptions =
optionalString (hasAttr "sops" config)
"!include ${access-token.path}";
};
# Global hm settings
home-manager.useGlobalPkgs = true;
home-manager.useUserPackages = true;
}

39
common/modules/locale.nix Normal file
View file

@ -0,0 +1,39 @@
{pkgs, ...}: {
fonts = {
fontconfig = {
enable = true;
defaultFonts = {
emoji = ["Noto Color Emoji"];
monospace = ["Noto Nerd Font"];
sansSerif = ["Noto Nerd Font"];
serif = ["Noto Nerd Font"];
};
};
packages = with pkgs; [
(nerdfonts.override {
fonts = [
"JetBrainsMono"
"Go-Mono"
"Iosevka"
"NerdFontsSymbolsOnly"
"SpaceMono"
"Ubuntu"
"Noto"
];
})
noto-fonts
noto-fonts-cjk
noto-fonts-emoji
liberation_ttf
font-awesome
meslo-lgs-nf
jetbrains-mono
ubuntu_font_family
];
};
# Select internationalisation properties.
i18n.defaultLocale = "en_CA.UTF-8";
console.useXkbConfig = true;
}

79
common/modules/locate.nix Normal file
View file

@ -0,0 +1,79 @@
{
config,
pkgs,
lib,
...
}: let
inherit (config.vars) mainUser;
cfg = config.services.locate;
locateGroup = lib.getName cfg.package.name;
locate = "${cfg.package}/bin/locate";
updatedb = "${cfg.package}/bin/updatedb";
database = "/var/lib/locate/locatedb";
pruneFS = builtins.concatStringsSep " " cfg.pruneFS;
pruneNames = builtins.concatStringsSep " " cfg.pruneNames;
prunePaths = builtins.concatStringsSep " " cfg.prunePaths;
updatedbBin = ''
${updatedb} -o ${database} --prunefs "${pruneFS}" \
--prunepaths "${prunePaths}" --prunenames "${pruneNames}"
'';
in {
users.users.${mainUser}.extraGroups = [
locateGroup
];
# TODO: add timer
systemd.services.locate = {
wantedBy = ["default.target"];
serviceConfig = {
User = mainUser;
Group = locateGroup;
StateDirectory = "locate";
StateDirectoryMode = "0770";
ExecStart = updatedbBin;
};
};
home-manager.users.${mainUser}.programs.bash.shellAliases = {
locate = "${pkgs.writeShellScriptBin "lct" ''
exec ${locate} -d ${database} "$@" 2> >(grep -v "/var/cache/locatedb")
''}/bin/lct";
updatedb = updatedbBin;
};
services.locate = {
enable = true;
package = pkgs.mlocate;
localuser = null;
interval = "never";
prunePaths = [
"/var/lib/flatpak"
# Defaults
"/tmp"
"/var/tmp"
"/var/cache"
"/var/lock"
"/var/run"
"/var/spool"
"/nix/var/log/nix"
];
pruneNames = [
"node_modules"
# Defaults
".bzr"
".cache"
".git"
".hg"
".svn"
];
};
}

View file

@ -1,19 +1,14 @@
{
config,
self,
lib,
nur,
...
}: {
imports = [
self.nixosModules.base-droid
{
roles.base = {
enable = true;
user = "nix-on-droid";
};
}
self.nixosModules.tmux
{programs.tmux.enableCustomConf = true;}
./vars
./pkgs
./modules/global.nix
nur.nixosModules.nur
];
nix = {
@ -28,26 +23,35 @@
substituters = [
# Nix-community
"https://nix-community.cachix.org"
# FIXME: cache doesn't work
# Personal config cache
# "https://cache.nelim.org"
];
trustedPublicKeys = [
# Nix-community
"nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs="
# Personal config cache
# "cache.nelim.org:JmFqkUdH11EA9EZOFAGVHuRYp7EbsdJDHvTQzG2pPyY="
];
};
# Global hm settings
home-manager.config = {
imports = [
self.homeManagerModules.neovim
# Make the vars be the same on Nix and HM
{
programs.neovim = {
enable = true;
user = "nix-on-droid";
options.vars = lib.mkOption {
type = lib.types.attrs;
readOnly = true;
default = config.vars;
};
}
self.homeManagerModules.shell
{programs.bash.enable = true;}
nur.hmModules.nur
./home
./pkgs
{
programs.bash.sessionVariables = {
@ -69,9 +73,6 @@
# Experimenting server
servivi = "ssh -t matt@100.64.0.7 'tmux -2u new -At phone'";
# Home-assistant
homie = "ssh -t matt@100.64.0.10 'tmux -2u new -At phone'";
# Cluster nodes
thingone = "ssh -t matt@100.64.0.8 'tmux -2u new -At phone'";
thingtwo = "ssh -t matt@100.64.0.9 'tmux -2u new -At phone'";

View file

@ -0,0 +1,5 @@
{nixpkgs-wayland, ...} @ inputs: [
(import ./dracula-theme inputs)
nixpkgs-wayland.overlay
]

View file

@ -0,0 +1,46 @@
{
bat-theme-src,
gtk-theme-src,
xresources-theme-src,
...
} @ inputs: (final: prev: {
dracula-theme = prev.dracula-theme.overrideAttrs (oldAttrs: let
git-colors = prev.callPackage ./git.nix inputs;
plymouth = prev.callPackage ./plymouth.nix inputs;
wallpaper = prev.fetchurl (import ./wallpaper.nix);
in {
version = gtk-theme-src.shortRev;
src = gtk-theme-src;
installPhase = ''
runHook preInstall
mkdir -p $out/share/plymouth/themes $out/wallpapers
cp -a ${wallpaper} $out/wallpapers/waves.png
cp -a ${bat-theme-src}/Dracula.tmTheme $out/bat
cp -a ${git-colors}/git-colors $out/git-colors
cp -a ${plymouth}/share/plymouth/themes/dracula $out/share/plymouth/themes/
cp -a ${xresources-theme-src}/Xresources $out/xres
# -------------------------------------------
mkdir -p $out/share/themes/Dracula
cp -a {assets,cinnamon,gnome-shell,gtk-2.0,gtk-3.0,gtk-3.20,gtk-4.0,index.theme,metacity-1,unity,xfwm4} $out/share/themes/Dracula
cp -a kde/{color-schemes,plasma} $out/share/
cp -a kde/kvantum $out/share/Kvantum
mkdir -p $out/share/aurorae/themes
cp -a kde/aurorae/* $out/share/aurorae/themes/
mkdir -p $out/share/sddm/themes
cp -a kde/sddm/* $out/share/sddm/themes/
mkdir -p $out/share/icons/Dracula-cursors
mv kde/cursors/Dracula-cursors/index.theme $out/share/icons/Dracula-cursors/cursor.theme
mv kde/cursors/Dracula-cursors/cursors $out/share/icons/Dracula-cursors/cursors
runHook postInstall
'';
});
})

View file

@ -0,0 +1,23 @@
{
stdenv,
git-theme-src,
...
}:
stdenv.mkDerivation {
name = "dracula-git";
version = git-theme-src.shortRev;
src = git-theme-src;
installPhase = ''
# Git colors
cp -a ./config/gitconfig ./git-colors
chmod 777 ./git-colors
line=$(grep -n 'Dracula Dark Theme' ./git-colors | cut -d: -f1)
sed -i "1,$((line-1))d" ./git-colors
mkdir $out
cp -a ./git-colors $out
'';
}

View file

@ -1,14 +1,13 @@
{
stdenv,
dracula-plymouth-src,
mkVersion,
plymouth-theme-src,
...
}:
stdenv.mkDerivation {
pname = "dracula-plymouth";
version = mkVersion dracula-plymouth-src;
name = "dracula-plymouth";
version = plymouth-theme-src.shortRev;
src = dracula-plymouth-src;
src = plymouth-theme-src;
installPhase = ''
chmod 777 ./dracula

View file

@ -0,0 +1,4 @@
{
url = "https://raw.githubusercontent.com/aynp/dracula-wallpapers/main/Art/4k/Waves%201.png";
hash = "sha256-f9FwSOSvqTeDj4bOjYUQ6TM+/carCD9o5dhg/MnP/lk=";
}

12
common/overlays/nix/patch Normal file
View file

@ -0,0 +1,12 @@
diff --git a/src/libstore/path.cc b/src/libstore/path.cc
index e642abcd5..0e584ef33 100644
--- a/src/libstore/path.cc
+++ b/src/libstore/path.cc
@@ -12,7 +12,7 @@ static void checkName(std::string_view path, std::string_view name)
if (!((c >= '0' && c <= '9')
|| (c >= 'a' && c <= 'z')
|| (c >= 'A' && c <= 'Z')
- || c == '+' || c == '-' || c == '.' || c == '_' || c == '?' || c == '='))
+ || c == '+' || c == '-' || c == '.' || c == '_' || c == '?' || c == '=' || c == '!'))
throw BadStorePath("store path '%s' contains illegal character '%s'", path, c);
}

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,45 @@
#!/usr/bin/env python
"""
The original script:
https://github.com/dharmx/vile/blob/7d486c128c7e553912673755f97b118aaab0193d/src/shell/playerctl.py#L2
"""
import argparse
import json
from material_color_utilities_python import themeFromImage, hexFromArgb, Image
def range_type(value_string):
value = int(value_string)
if value not in range(0, 101):
raise argparse.ArgumentTypeError("%s is out of range, choose in [0-100]" % value)
return value
parser = argparse.ArgumentParser(
prog='coloryou',
description='This program extract Material You colors from an image. It returns them as a JSON object for scripting.')
parser.add_argument("image_path", help="A full path to your image", type=str)
parser.add_argument('-i', '--image', dest='image', default=40, type=range_type, metavar='i', choices=range(0,101), help="Value should be within [0, 100] (default: %(default)s). Set the tone for the main image accent.")
parser.add_argument('-b', '--button', dest='button', default=90, type=range_type, metavar='i', choices=range(0,101), help="Value should be within [0, 100] (default: %(default)s). Set the tone for the button accent.")
parser.add_argument('-t', '--text', dest='text', default=10, type=range_type, metavar='i', choices=range(0,101), help="Value should be within [0, 100] (default: %(default)s). Set the tone for the button text accent.")
parser.add_argument('-o', '--hover', dest='hover', default=80, type=range_type, metavar='i', choices=range(0,101), help="Value should be within [0, 100] (default: %(default)s). Set the tone for the hovering effect accent.")
args = parser.parse_args()
img = Image.open(args.image_path)
basewidth = 64
wpercent = (basewidth/float(img.size[0]))
hsize = int((float(img.size[1])*float(wpercent)))
img = img.resize((basewidth,hsize),Image.Resampling.LANCZOS)
theme = themeFromImage(img).get("palettes").get("primary")
parsed_colors = {"imageAccent": hexFromArgb(theme.tone(args.image)),
"buttonAccent": hexFromArgb(theme.tone(args.button)),
"buttonText": hexFromArgb(theme.tone(args.text)),
"hoverAccent": hexFromArgb(theme.tone(args.hover))}
print(json.dumps(parsed_colors))

View file

@ -0,0 +1,19 @@
{python3Packages, ...}:
python3Packages.buildPythonPackage {
pname = "coloryou";
version = "0.0.1";
src = ./.;
propagatedBuildInputs = with python3Packages; [utils material-color-utilities];
postInstall = ''
mv -v $out/bin/coloryou.py $out/bin/coloryou
'';
meta = {
description = ''
Get Material You colors from an image.
'';
};
}

View file

@ -0,0 +1,2 @@
material-color-utilities
utils

View file

@ -0,0 +1,7 @@
from distutils.core import setup
setup(
name='coloryou',
version='0.0.1',
scripts=['coloryou.py',],
)

View file

@ -0,0 +1,7 @@
with import <nixpkgs> {};
with pkgs.python311Packages;
buildPythonPackage {
name = "coloryou";
src = ./.;
propagatedBuildInputs = [material-color-utilities utils];
}

View file

@ -0,0 +1,13 @@
{
buildGoModule,
curseforge-server-downloader-src,
...
}:
buildGoModule {
pname = "curseforge-server-downloader";
version = "unstable";
src = curseforge-server-downloader-src;
doCheck = false;
vendorHash = null;
}

26
common/pkgs/default.nix Normal file
View file

@ -0,0 +1,26 @@
{
lib,
pkgs,
...
} @ inputs: let
inherit (lib) concatMapAttrs filterAttrs mkOption pathExists types;
mkPackage = name: v: {
${name} = pkgs.callPackage ./${name} inputs;
};
rmNotPackage = name: value:
value
== "directory"
&& pathExists ./${name}/default.nix;
packages = filterAttrs rmNotPackage (builtins.readDir ./.);
pkgSet = concatMapAttrs mkPackage packages;
in {
options.customPkgs = mkOption {
type = types.attrs;
};
config.customPkgs = pkgSet;
}

View file

@ -0,0 +1,41 @@
{
stdenv,
meson,
ninja,
pkg-config,
glib,
libfprint,
polkit,
dbus,
systemd,
pam,
libpam-wrapper,
pam-fprint-grosshack-src,
...
}:
stdenv.mkDerivation {
name = "pam-fprint-grosshack";
version = pam-fprint-grosshack-src.shortRev;
src = pam-fprint-grosshack-src;
nativeBuildInputs = [
meson
ninja
pkg-config
glib
libfprint
polkit
dbus
systemd
pam
libpam-wrapper
];
mesonFlags = [
"-Dpam_modules_dir=${placeholder "out"}/lib/security"
"-Dsysconfdir=${placeholder "out"}/etc"
"-Ddbus_service_dir=${placeholder "out"}/share/dbus-1/system-services"
"-Dsystemd_system_unit_dir=${placeholder "out"}/lib/systemd/system"
];
}

View file

@ -1,13 +1,12 @@
{
mkVersion,
stdenv,
python3Packages,
pokemon-colorscripts-src,
...
}:
stdenv.mkDerivation {
pname = "pokemon-colorscripts";
version = mkVersion pokemon-colorscripts-src;
name = "pokemon-colorscripts";
version = pokemon-colorscripts-src.shortRev;
src = pokemon-colorscripts-src;

View file

@ -0,0 +1,110 @@
{
config,
writeShellApplication,
stdenvNoCC,
jre,
fetchFromGitHub,
fetchurl,
makeWrapper,
makeDesktopItem,
rsync,
...
}:
stdenvNoCC.mkDerivation rec {
name = "rars-flatlaf";
src = fetchFromGitHub {
owner = "privat";
repo = "rars";
rev = "fd34014efd65b3cb5a52f1729c3b8240cae0c332";
hash = "sha256-D8X/cr+fnq/OOFYfMG9aPss95J8Z2yiROuF9kmHkK40=";
fetchSubmodules = true;
};
desktopItem = let
hyprland = config.home-manager.users.${config.vars.mainUser}.wayland.windowManager.hyprland.finalPackage;
execScript = writeShellApplication {
name = "execScript";
runtimeInputs = [hyprland];
text = "(sleep 1; hyprctl dispatch togglefloating) & ${name}";
};
in
makeDesktopItem {
name = "RARS";
desktopName = "RARS";
exec = "${execScript}/bin/execScript";
icon = name;
};
nativeBuildInputs = [makeWrapper rsync jre];
installPhase = let
flatlaf = fetchurl {
url = "https://repo1.maven.org/maven2/com/formdev/flatlaf/3.2/flatlaf-3.2.jar";
hash = "sha256-HAG+G9undDXWtySokKl7lkIUCFI7lEBduu+UgSVaxAA=";
};
icon = fetchurl {
url = "https://riscv.or.jp/wp-content/uploads/2019/06/cropped-RISC-V-logo-figonly-mod-2.png";
hash = "sha256-e1/iVmadVzyO77ikBr1cdXsJdDj8TiXh3Oyjek9GwqM=";
};
in
/*
bash
*/
''
# ./build-jar.sh
mkdir -p build
find src -name "*.java" | xargs javac --release 8 -d build
if [[ "$OSTYPE" == "darwin"* ]]; then
find src -type f -not -name "*.java" -exec rsync -R {} build \;
else
find src -type f -not -name "*.java" -exec cp --parents {} build \;
fi
cp -rf build/src/* build
rm -r build/src
cp README.md License.txt build
cd build
jar cfm ../rars.jar ./META-INF/MANIFEST.MF *
chmod +x ../rars.jar
cd ..
# ./build-jar-flatlaf.sh
mkdir -p build-flatlaf/
cd build-flatlaf/
cp ${flatlaf} ../flatlaf.jar
jar x < ../rars.jar
jar x < "../flatlaf.jar"
cat > META-INF/MANIFEST.MF <<EOF
Manifest-Version: 1.0
Implementation-Version: 3.1.1
Multi-Release: true
Main-Class: rars.Launch
EOF
jar cfm ../rars-flatlaf.jar META-INF/MANIFEST.MF *
chmod +x ../rars-flatlaf.jar
cd ..
# InstallPhase
runHook preInstall
cat > ./rars.desktop <<EOF
EOF
mkdir -p "$out/share/pixmaps"
cp "${icon}" "$out/share/pixmaps/${name}.png"
install -D $desktopItem/share/applications/* $out/share/applications/rars.desktop
export JAR=$out/share/java/${name}/${name}.jar
install -D ./${name}.jar $JAR
makeWrapper ${jre}/bin/java $out/bin/${name} \
--add-flags "-jar $JAR"
runHook postInstall
'';
}

View file

@ -0,0 +1,26 @@
# modified from https://github.com/gytis-ivaskevicius/flake-utils/plus
{
coreutils,
gnused,
writeShellScriptBin,
...
}: let
repl = ./repl.nix;
example = command: desc: ''\n\u001b[33m ${command}\u001b[0m - ${desc}'';
in
writeShellScriptBin "repl" ''
case "$1" in
"-h"|"--help"|"help")
printf "%b\n\e[4mUsage\e[0m: \
${example "repl" "Loads system flake if available."} \
${example "repl /path/to/flake.nix" "Loads specified flake."}\n"
;;
*)
if [ -z "$1" ]; then
nix repl --arg flakePath $(${coreutils}/bin/readlink -f "/etc/nixos") --file ${repl}
else
nix repl --arg flakePath $(${coreutils}/bin/readlink -f $1 | ${gnused}/bin/sed 's|/flake.nix||') --file ${repl}
fi
;;
esac
''

49
common/pkgs/repl/repl.nix Normal file
View file

@ -0,0 +1,49 @@
{
flakePath ? null,
hostnamePath ? "/etc/hostname",
registryPath ? /etc/nix/registry.json,
}: let
inherit (builtins) getFlake head match currentSystem readFile pathExists filter fromJSON;
selfFlake =
if pathExists registryPath
then filter (it: it.from.id == "self") (fromJSON (readFile registryPath)).flakes
else [];
flakePath' =
toString
(
if flakePath != null
then flakePath
else if selfFlake != []
then (head selfFlake).to.path
else "/etc/nixos"
);
flake =
if pathExists flakePath'
then getFlake flakePath'
else {};
hostname =
if pathExists hostnamePath
then head (match "([a-zA-Z0-9\\-]+)\n" (readFile hostnamePath))
else "";
nixpkgsFromInputsPath = flake.inputs.nixpkgs.outPath or "";
nixpkgs =
flake.pkgs.${currentSystem}.nixpkgs
or (
if nixpkgsFromInputsPath != ""
then import nixpkgsFromInputsPath {}
else {}
);
nixpkgsOutput = removeAttrs (nixpkgs // nixpkgs.lib or {}) ["options" "config"];
in
{inherit flake;}
// flake
// builtins
// (flake.nixosConfigurations or {})
// flake.nixosConfigurations.${hostname} or {}
// nixpkgsOutput
// {getFlake = path: getFlake (toString path);}

89
common/vars/default.nix Normal file
View file

@ -0,0 +1,89 @@
{
config,
lib,
...
}: let
inherit (lib) mkOption types;
flakeDir = config.environment.variables.FLAKE;
cfg = config.vars;
in {
options.vars = {
mainUser = mkOption {
type = types.str;
description = ''
Username that was defined at the initial setup process
'';
};
hostName = mkOption {
type = types.str;
description = ''
Hostname that was defined at the initial setup process
'';
};
promptMainColor = mkOption {
type = types.enum ["red" "green" "blue" "purple" "orange" "yellow" "cyan" "pink"];
default = "purple";
};
promptColors = mkOption {
description = ''
Colors used in starship prompt
'';
default = import ./prompt-schemes.nix cfg.promptMainColor;
readOnly = true;
type = with types;
submodule {
options = {
textColor = mkOption {type = str;};
firstColor = mkOption {type = str;};
secondColor = mkOption {type = str;};
thirdColor = mkOption {type = str;};
fourthColor = mkOption {type = str;};
};
};
};
configDir = mkOption {
type = types.str;
default = "${flakeDir}/devices/${cfg.hostName}/config";
description = ''
The path to where most of the devices' configs are in the .nix folder
'';
};
mainMonitor = mkOption {
type = types.str;
description = ''
The name of the main monitor used for Hyprland
and Regreet which also uses Hyprland
'';
# This is to allow a bash script to know whether this value exists
default = "null";
};
greetdDupe = mkOption {
type = types.bool;
description = ''
If we should duplicate regreet on all monitors
'';
default = true;
};
fontSize = mkOption {
type = types.nullOr types.float;
};
neovimIde = mkOption {
type = types.bool;
default = true;
};
};
config = {
environment.variables.FLAKE = lib.mkDefault "/home/${cfg.mainUser}/.nix";
};
}

View file

@ -1,6 +1,4 @@
{color ? null}: let
inherit (builtins) attrNames removeAttrs;
color: let
schemes = {
"purple" = {
textColor = "#090c0c";
@ -76,6 +74,4 @@
};
};
in
if ! isNull color
then schemes.${color}
else attrNames (removeAttrs schemes ["color"])
schemes.${color}

View file

@ -1,16 +0,0 @@
# Devices
This directory encompasses every device's main configuration file.
## List of my Devices
| Name | Description |
| ----------- | ------------------------------------------------------------------------------------------------------- |
| `android` | My [Nix-On-Droid](https://github.com/nix-community/nix-on-droid) configuration for my OnePlus 9 Pro |
| `bbsteamie` | My wife's SteamDeck that has a pink case |
| `binto` | My desktop PC with a multi-monitor setup and an NVIDIA (cringe) 3070 |
| `cluster` | Two Lenovo mini PCs that make use of [NixOS-pcsd](https://github.com/matt1432/nixos-pcsd) to form a cluster |
| `homie` | My Lenovo mini PC that will serve as a Home-assistant server |
| `nos` | My custom built NAS |
| `servivi` | A gaming PC in a previous life, it is now used as a build farm and hosts game servers |
| `wim` | My 2-1 Lenovo Laptop that I use for uni |

View file

@ -1,56 +0,0 @@
{
config,
lib,
pkgs,
...
}: let
inherit (lib) attrValues concatStringsSep;
in {
imports = [./nix-on-droid.nix];
environment.variables.FLAKE = "/data/data/com.termux.nix/files/home/.nix";
terminal.font = "${
pkgs.nerd-fonts.jetbrains-mono
}/share/fonts/truetype/NerdFonts/JetBrainsMono/JetBrainsMonoNerdFontMono-Regular.ttf";
environment.packages = [
(pkgs.writeShellApplication {
name = "switch";
runtimeInputs = attrValues {
inherit
(pkgs)
coreutils
nix-output-monitor
nvd
;
};
text = ''
oldProfile=$(realpath /nix/var/nix/profiles/per-user/nix-on-droid/profile)
nix-on-droid ${concatStringsSep " " [
"switch"
"--flake ${config.environment.variables.FLAKE}"
"--builders ssh-ng://matt@100.64.0.7"
''"$@"''
"|&"
"nom"
]} &&
nvd diff "$oldProfile" "$(realpath /nix/var/nix/profiles/per-user/nix-on-droid/profile)"
'';
})
];
environment.etcBackupExtension = ".bak";
environment.motd = null;
home-manager.backupFileExtension = "hm-bak";
# Set your time zone.
time.timeZone = "America/Montreal";
# No touchy
system.stateVersion = "23.05";
}

View file

@ -1,73 +0,0 @@
{
mainUser,
self,
...
}: {
# ------------------------------------------------
# Imports
# ------------------------------------------------
imports = [
./hardware-configuration.nix
./modules
self.nixosModules.base
self.nixosModules.kmscon
self.nixosModules.plymouth
self.nixosModules.server
];
# State Version: DO NOT CHANGE
system.stateVersion = "24.11";
# ------------------------------------------------
# User Settings
# ------------------------------------------------
users.users.${mainUser} = {
isNormalUser = true;
extraGroups = [
"wheel"
"adm"
];
};
networking = {
hostName = "bbsteamie";
networkmanager.enable = true;
};
time.timeZone = "America/Montreal";
# ------------------------------------------------
# `Self` Modules configuration
# ------------------------------------------------
roles.base = {
enable = true;
user = mainUser;
};
roles.server = {
user = mainUser;
sshd.enable = true;
};
boot.plymouth = {
enable = true;
theme = "bgrt";
};
services.kmscon.enable = true;
home-manager.users.${mainUser} = {
imports = [
self.homeManagerModules.shell
];
programs = {
bash = {
enable = true;
promptMainColor = "pink";
};
};
};
}

View file

@ -1,61 +0,0 @@
{
config,
jovian,
modulesPath,
...
}: {
nixpkgs.hostPlatform = "x86_64-linux";
nixpkgs.overlays = [jovian.overlays.default];
imports = [
(modulesPath + "/installer/scan/not-detected.nix")
jovian.nixosModules.default
];
jovian = {
steamos.useSteamOSConfig = true;
devices.steamdeck = {
enable = true;
enableGyroDsuService = true;
};
hardware.has.amd.gpu = true;
};
boot = {
kernelModules = ["kvm-amd"];
initrd.availableKernelModules = ["nvme" "xhci_pci" "usbhid" "sdhci_pci"];
loader = {
efi.canTouchEfiVariables = true;
systemd-boot = {
enable = true;
configurationLimit = 30;
};
};
};
virtualisation.waydroid.enable = true;
fileSystems = {
"/" = {
device = "/dev/disk/by-label/NIXROOT";
fsType = "ext4";
};
"/boot" = {
device = "/dev/disk/by-label/NIXBOOT";
fsType = "vfat";
options = ["fmask=0022" "dmask=0022"];
};
};
swapDevices = [
{
device = "/.swapfile";
size = 16 * 1024; # 16GB
}
];
hardware.cpu.amd.updateMicrocode = config.hardware.enableRedistributableFirmware;
}

View file

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

View file

@ -1,40 +0,0 @@
{pkgs, ...}: let
defaultSession = "plasma";
in {
imports = [
(import ./session-switching.nix defaultSession)
(import ./steam.nix defaultSession)
];
services.desktopManager.plasma6.enable = true;
programs = {
kdeconnect.enable = true;
xwayland.enable = true;
};
# Flatpak support for Discover
services.flatpak.enable = true;
services.packagekit.enable = true;
# Wayland env vars
environment.variables = {
NIXOS_OZONE_WL = "1";
ELECTRON_OZONE_PLATFORM_HINT = "auto";
};
environment.systemPackages = builtins.attrValues {
inherit
(pkgs)
firefox
wl-clipboard
xclip
;
inherit
(pkgs.kdePackages)
discover
krfb
;
};
}

View file

@ -1,81 +0,0 @@
# How to install Palia Map and Overwolf on Linux
Dependencies:
- latest GE-Proton: https://github.com/GloriousEggroll/proton-ge-custom
- protontricks: https://github.com/Matoking/protontricks
- protonhax: https://github.com/jcnils/protonhax
## First Step: Install and run Palia at least once
## Second Step: Setup Palia WINEPREFIX with latest GE-Proton
1. Delete prefix at /home/"$USER"/.steam/steam/steamapps/compatdata/2707930/pfx
```bash
rm -r /home/"$USER"/.steam/steam/steamapps/compatdata/2707930/pfx
```
2. Launch Palia with GE-Proton by going to game properties -> Compatibility -> Force the use ... -> Select GE-Proton...
3. Install dotnet48 and other Windows deps to allow for Overwolf installation
```bash
# Force proton version of protontricks
export PROTON_VERSION="GE-Proton9-10"
protontricks 2707930 dotnet48
# If VC is needed
protontricks 2707930 vcrun2010
protontricks 2707930 vcrun2012
protontricks 2707930 vcrun2013
```
## Third Step: Install Overwolf
1. Get this older version that worked for me here: https://overwolf.en.uptodown.com/windows/download/4714215
2. Install it with protontricks. Follow the GUI installer as if you were on Windows
```bash
export PROTON_VERSION="GE-Proton9-10"
protontricks-launch --appid 2707930 Downloads/overwolf-0-195-0-18.exe
```
## Fourth Step: Install Palia Map
1. Get the installer from here: https://www.overwolf.com/app/Leon_Machens-Palia_Map
2. Install it with protontricks.
```bash
export PROTON_VERSION="GE-Proton9-10"
protontricks-launch --appid 2707930 Downloads/Palia\ Map\ -\ Installer.exe
```
3. An error should popup saying `Installation failed` or something along those lines.
Close it and wait. You should see the Overwolf overlay on the left side of your screen
with the Palia Map icon saying `Installing` and then when it's done: `Palia Map`.
If nothing happens, try rebooting your PC and retrying the above shell commands until it works.
## Final Step: Setting it up in Steam
1. Add this line to Palia launch options
```bash
protonhax init %command%
```
2. Add random non-steam game to your library and then edit its properties:
Change the name to `Palia Map` or anything you like
Change the target to this command:
```bash
protonhax run 2707930 "/home/$USER/.local/share/Steam/steamapps/compatdata/2707930/pfx/drive_c/users/steamuser/AppData/Roaming/Microsoft/Windows/Start Menu/Programs/Overwolf/Palia Map.lnk"
```

View file

@ -1,114 +0,0 @@
defaultSession: {
config,
lib,
mainUser,
pkgs,
...
}: {
config = let
inherit (lib) findFirst getExe mkForce;
switch-session = pkgs.writeShellApplication {
name = "switch-session";
text = ''
mkdir -p /etc/sddm.conf.d
cat <<EOF | tee /etc/sddm.conf.d/autologin.conf
[Autologin]
User=${mainUser}
Session=$1
Relogin=true
EOF
'';
};
gaming-mode = pkgs.writeShellScriptBin "gaming-mode" ''
sudo ${pkgs.systemd}/bin/systemctl start to-gaming-mode.service
'';
in {
services.displayManager.sddm = {
enable = true;
autoLogin.relogin = true;
wayland = {
enable = true;
compositorCommand = "kwin";
};
};
# Sets the default session at launch
systemd.services."set-session" = {
wantedBy = ["multi-user.target"];
before = ["display-manager.service"];
path = [switch-session];
script = ''
switch-session "${defaultSession}"
'';
};
# Allows switching to gaming mode
systemd.services."to-gaming-mode" = {
wantedBy = mkForce [];
path = [switch-session];
script = ''
switch-session "gamescope-wayland"
systemctl restart display-manager
sleep 10
switch-session "${defaultSession}"
'';
};
# Make it so we don't need root to switch to gaming mode
security.sudo.extraRules = [
{
users = [mainUser];
groups = [100];
commands = [
{
command = "${pkgs.systemd}/bin/systemctl start to-gaming-mode.service";
options = ["SETENV" "NOPASSWD"];
}
];
}
];
home-manager.users.${mainUser} = {
# Add desktop entry to make it GUI friendly
xdg.desktopEntries."Gaming Mode" = {
name = "Gaming Mode";
exec = getExe gaming-mode;
icon = "steam";
terminal = false;
type = "Application";
};
home.file."Desktop/Gaming Mode.desktop".source =
(
findFirst
(x: x.meta.name == "Gaming Mode.desktop") {}
config.home-manager.users.mariah.home.packages
)
+ "/share/applications/Gaming Mode.desktop";
# Fix remote control prompt showing up everytime
xdg.configFile = let
mkAutostart = name: flags: {
"autostart/${name}.desktop".text = "[Desktop Entry]\nType=Application\nExec=${name} ${flags}";
};
in (
# Needs xdg-desktop-portal-kde patch provided by `self.overlays.xdg-desktop-portal-kde`
{"plasmaremotedesktoprc".text = "[Sharing]\nUnattended=true";}
// (mkAutostart "krfb" "--nodialog %c")
// (mkAutostart "steam" "-silent %U")
);
};
};
# For accurate stack trace
_file = ./session-switching.nix;
}

View file

@ -1,75 +0,0 @@
defaultSession: {
config,
lib,
mainUser,
pkgs,
self,
...
}: {
config = {
# Normal Steam Stuff
programs.steam = {
enable = true;
protontricks.enable = true;
remotePlay.openFirewall = true;
extraCompatPackages = [
self.packages.${pkgs.system}.proton-ge-latest
];
};
# Jovian Steam settings
jovian.steam = {
# Steam > Settings > System > Enable Developer Mode
# Steam > Developer > CEF Remote Debugging
enable = true;
user = mainUser;
environment = {
STEAM_EXTRA_COMPAT_TOOLS_PATHS =
lib.makeSearchPathOutput
"steamcompattool"
""
config.programs.steam.extraCompatPackages;
};
desktopSession = defaultSession;
};
# Decky settings
jovian.decky-loader = {
enable = true;
user = mainUser;
stateDir = "/home/${mainUser}/.local/share/decky"; # Keep scoped to user
# https://github.com/Jovian-Experiments/Jovian-NixOS/blob/1171169117f63f1de9ef2ea36efd8dcf377c6d5a/modules/decky-loader.nix#L80-L84
extraPackages = builtins.attrValues {
inherit
(pkgs)
curl
unzip
util-linux
gnugrep
readline
procps
pciutils
libpulseaudio
;
};
};
# Misc Packages
environment.systemPackages = [
pkgs.steam-rom-manager
pkgs.r2modman
self.packages.${pkgs.system}.protonhax
# Ryujinx ACNH crashes on Vulkan
pkgs.ryujinx
];
};
# For accurate stack trace
_file = ./steam.nix;
}

View file

@ -1,94 +0,0 @@
{
mainUser,
self,
...
}: {
# ------------------------------------------------
# Imports
# ------------------------------------------------
imports = [
./hardware-configuration.nix
./modules
self.nixosModules.base
self.nixosModules.desktop
self.nixosModules.kmscon
self.nixosModules.server
];
# State Version: DO NOT CHANGE
system.stateVersion = "23.11";
# ------------------------------------------------
# User Settings
# ------------------------------------------------
users.users.${mainUser} = {
isNormalUser = true;
extraGroups = [
"wheel"
"input"
"uinput"
"adm"
"video"
"libvirtd"
"adbusers"
];
};
programs.adb.enable = true;
networking = {
hostName = "binto";
networkmanager.enable = true;
firewall.enable = false;
};
time.timeZone = "America/Montreal";
# ------------------------------------------------
# `Self` Modules configuration
# ------------------------------------------------
roles.base = {
enable = true;
user = mainUser;
};
roles.desktop = {
user = mainUser;
ags.enable = true;
mainMonitor = "desc:GIGA-BYTE TECHNOLOGY CO. LTD. G27QC 0x00000B1D";
displayManager.duplicateScreen = false;
fontSize = 12.5;
};
roles.server = {
user = mainUser;
tailscale.enable = true;
sshd.enable = true;
};
services.kmscon.enable = true;
home-manager.users.${mainUser} = {
imports = [
self.homeManagerModules.firefox
self.homeManagerModules.neovim
self.homeManagerModules.shell
];
programs = {
bash = {
enable = true;
promptMainColor = "purple";
};
neovim = {
enable = true;
user = mainUser;
};
};
};
}

View file

@ -1,6 +0,0 @@
{...}: {
imports = [
./gpu-replay.nix
./nix-gaming.nix
];
}

Some files were not shown because too many files have changed in this diff Show more