Compare commits

..

No commits in common. "master" and "eww" have entirely different histories.
master ... eww

513 changed files with 4500 additions and 32355 deletions

View file

@ -1,19 +0,0 @@
name: Discord
on:
- workflow_dispatch
- push
jobs:
discord_commits:
runs-on: ubuntu-latest
name: discord commits
if: contains(github.event.head_commit.message, '(servers)')
steps:
- name: Discommit
uses: https://github.com/matt1432/discommit@v0.0.2
with:
discord_webhook: ${{ secrets.DISCORD_WEBHOOK }}
api_url: 'https://git.nelim.org/api/v1/repos/$OWNER/$REPO/git/commits/$REF'
title: 'New commit containing changes to server configs:'

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

21
.gitignore vendored
View file

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

View file

@ -1,16 +0,0 @@
MIT No Attribution
Copyright 2024 Mathis H.
Permission is hereby granted, free of charge, to any person obtaining a copy of this
software and associated documentation files (the "Software"), to deal in the Software
without restriction, including without limitation the rights to use, copy, modify,
merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

118
README.md
View file

@ -1,111 +1,13 @@
# My NixOS configs
what is currently not working:
- plymouth theme has no login prompt
- sddm theme flashes white
- fixme: swaync acts up with eww
- autosign in to keyring
## AGS
what i want to do:
- learn flakes
- add auto-rotate widget in eww control center
You might find it weird that most of my config is written in TypeScript.
That's because all my desktops run
[AGS](https://github.com/Aylur/ags)
for UI. Click on
[this](https://git.nelim.org/matt1432/nixos-configs/src/branch/master/nixosModules/ags)
to see my configuration.
# Docs
I'm also a victim of Stockholm syndrome at this point and make my scripts
in TypeScript because it's the scripting language I am most comfortable with.
## About
### 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).
### Flake Location
This git repo will always be located at `$FLAKE` (`config.environment.variables.FLAKE`)
and symlinked to `/etc/nixos` to have everything where NixOS tools
expect things to be.
ie.
```bash
sudo rm -r /etc/nixos
echo "$FLAKE" # /home/matt/.nix
sudo ln -sf /home/matt/.nix /etc/nixos
```
### Flake Outputs
| Output | Description |
| ---------------------------------- | ----------- |
| `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 |
| `legacyPackages` | Some custom [package scopes](https://git.nelim.org/matt1432/nixos-configs/src/branch/master/legacyPackages) 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/nixosModules) made for NixOS systems |
| `formatter` | I format nix code 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:
```nix
nixpkgs = {
type = "github";
owner = "NixOS";
repo = "nixpkgs";
# Branch name
ref = "nixos-unstable";
# Pin this input to a specific commit
rev = "842d9d80cfd4560648c785f8a4e6f3b096790e19";
};
```
to make it more clear what is what in the flake URI
### 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`:
```nix
let
wim = "somekey";
binto = "somekey2";
in {
creation_rules = [
{
path_regex = "secrets/[^/]+\\.(yaml|json|env|ini)$";
key_groups = [
{
age = [wim binto];
}
];
}
];
}
```
which is then converted to `.sops.yaml` using
[remarshal](https://github.com/remarshal-project/remarshal)
and this shell command:
```bash
nix eval --json --file ./.sops.nix | remarshal --if json --of yaml > .sops.yaml
```
TLDR: I
**[hate](https://ruudvanasseldonk.com/2023/01/11/the-yaml-document-from-hell)**
YAML
Since I use my laptop with one user, I symlinked the configs to my home directory following the tutorial [here](https://nixos.wiki/wiki/NixOS_configuration_editors)

View file

@ -1,38 +0,0 @@
{
runtimeInputs,
npmDepsHash,
src,
lib,
buildNpmPackage,
makeWrapper,
nodejs_latest,
jq,
...
}: let
inherit (lib) concatMapStringsSep getBin;
packageJSON = builtins.fromJSON (builtins.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/^ *\/\/.*//' ${./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: getBin p) runtimeInputs}
'';
nodejs = nodejs_latest;
meta.mainProgram = pname;
}

View file

@ -1,20 +0,0 @@
{
inputs,
pkgs,
...
}: let
inherit (pkgs.lib) getExe listToAttrs nameValuePair;
buildApp = attrs: (pkgs.callPackage ./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-XflXVdlsTonDHiR70Th/V6KUf4KSvcwnDod2mkz7rHQ=";
runtimeInputs = [
ffmpeg-full
];
}

View file

@ -1,454 +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,tsx}'],
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',
'@stylistic/jsx-indent-props': 'off',
'no-use-before-define': 'off',
'@typescript-eslint/no-use-before-define': 'error',
'@stylistic/indent-binary-ops': 'off',
'@stylistic/max-statements-per-line': [
'error',
{ max: 2 },
],
// 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',
],
},
],
'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',
{ allowSingleLine: true },
],
'@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',
],
},
});

Binary file not shown.

View file

@ -1,24 +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/js": "9.14.0",
"@stylistic/eslint-plugin": "2.10.1",
"@types/node": "22.9.0",
"esbuild": "0.24.0",
"eslint": "9.14.0",
"eslint-plugin-jsdoc": "50.5.0",
"jiti": "2.4.0",
"typescript": "5.6.3",
"typescript-eslint": "8.14.0"
}
}

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,373 +0,0 @@
export const ISO6391To3 = new Map([
['aa', 'aar'],
['ab', 'abk'],
['af', 'afr'],
['ak', 'aka'],
['am', 'amh'],
['ar', 'ara'],
['an', 'arg'],
['as', 'asm'],
['av', 'ava'],
['ae', 'ave'],
['ay', 'aym'],
['az', 'aze'],
['ba', 'bak'],
['bm', 'bam'],
['be', 'bel'],
['bn', 'ben'],
['bi', 'bis'],
['bo', 'bod'],
['bs', 'bos'],
['br', 'bre'],
['bg', 'bul'],
['ca', 'cat'],
['cs', 'ces'],
['ch', 'cha'],
['ce', 'che'],
['cu', 'chu'],
['cv', 'chv'],
['kw', 'cor'],
['co', 'cos'],
['cr', 'cre'],
['cy', 'cym'],
['da', 'dan'],
['de', 'deu'],
['dv', 'div'],
['dz', 'dzo'],
['el', 'ell'],
['en', 'eng'],
['eo', 'epo'],
['et', 'est'],
['eu', 'eus'],
['ee', 'ewe'],
['fo', 'fao'],
['fa', 'fas'],
['fj', 'fij'],
['fi', 'fin'],
['fr', 'fre'],
['fy', 'fry'],
['ff', 'ful'],
['gd', 'gla'],
['ga', 'gle'],
['gl', 'glg'],
['gv', 'glv'],
['gn', 'grn'],
['gu', 'guj'],
['ht', 'hat'],
['ha', 'hau'],
['sh', 'hbs'],
['he', 'heb'],
['hz', 'her'],
['hi', 'hin'],
['ho', 'hmo'],
['hr', 'hrv'],
['hu', 'hun'],
['hy', 'hye'],
['ig', 'ibo'],
['io', 'ido'],
['ii', 'iii'],
['iu', 'iku'],
['ie', 'ile'],
['ia', 'ina'],
['id', 'ind'],
['ik', 'ipk'],
['is', 'isl'],
['it', 'ita'],
['jv', 'jav'],
['ja', 'jpn'],
['kl', 'kal'],
['kn', 'kan'],
['ks', 'kas'],
['ka', 'kat'],
['kr', 'kau'],
['kk', 'kaz'],
['km', 'khm'],
['ki', 'kik'],
['rw', 'kin'],
['ky', 'kir'],
['kv', 'kom'],
['kg', 'kon'],
['ko', 'kor'],
['kj', 'kua'],
['ku', 'kur'],
['lo', 'lao'],
['la', 'lat'],
['lv', 'lav'],
['li', 'lim'],
['ln', 'lin'],
['lt', 'lit'],
['lb', 'ltz'],
['lu', 'lub'],
['lg', 'lug'],
['mh', 'mah'],
['ml', 'mal'],
['mr', 'mar'],
['mk', 'mkd'],
['mg', 'mlg'],
['mt', 'mlt'],
['mn', 'mon'],
['mi', 'mri'],
['ms', 'msa'],
['my', 'mya'],
['na', 'nau'],
['nv', 'nav'],
['nr', 'nbl'],
['nd', 'nde'],
['ng', 'ndo'],
['ne', 'nep'],
['nl', 'nld'],
['nn', 'nno'],
['nb', 'nob'],
['no', 'nor'],
['ny', 'nya'],
['oc', 'oci'],
['oj', 'oji'],
['or', 'ori'],
['om', 'orm'],
['os', 'oss'],
['pa', 'pan'],
['pi', 'pli'],
['pl', 'pol'],
['pt', 'por'],
['ps', 'pus'],
['qu', 'que'],
['rm', 'roh'],
['ro', 'ron'],
['rn', 'run'],
['ru', 'rus'],
['sg', 'sag'],
['sa', 'san'],
['si', 'sin'],
['sk', 'slk'],
['sl', 'slv'],
['se', 'sme'],
['sm', 'smo'],
['sn', 'sna'],
['sd', 'snd'],
['so', 'som'],
['st', 'sot'],
['es', 'spa'],
['sq', 'sqi'],
['sc', 'srd'],
['sr', 'srp'],
['ss', 'ssw'],
['su', 'sun'],
['sw', 'swa'],
['sv', 'swe'],
['ty', 'tah'],
['ta', 'tam'],
['tt', 'tat'],
['te', 'tel'],
['tg', 'tgk'],
['tl', 'tgl'],
['th', 'tha'],
['ti', 'tir'],
['to', 'ton'],
['tn', 'tsn'],
['ts', 'tso'],
['tk', 'tuk'],
['tr', 'tur'],
['tw', 'twi'],
['ug', 'uig'],
['uk', 'ukr'],
['ur', 'urd'],
['uz', 'uzb'],
['ve', 'ven'],
['vi', 'vie'],
['vo', 'vol'],
['wa', 'wln'],
['wo', 'wol'],
['xh', 'xho'],
['yi', 'yid'],
['yo', 'yor'],
['za', 'zha'],
['zh', 'zho'],
['zu', 'zul'],
]);
export const ISO6393To1 = new Map([
['aar', 'aa'],
['abk', 'ab'],
['afr', 'af'],
['aka', 'ak'],
['amh', 'am'],
['ara', 'ar'],
['arg', 'an'],
['asm', 'as'],
['ava', 'av'],
['ave', 'ae'],
['aym', 'ay'],
['aze', 'az'],
['bak', 'ba'],
['bam', 'bm'],
['bel', 'be'],
['ben', 'bn'],
['bis', 'bi'],
['bod', 'bo'],
['bos', 'bs'],
['bre', 'br'],
['bul', 'bg'],
['cat', 'ca'],
['ces', 'cs'],
['cha', 'ch'],
['che', 'ce'],
['chu', 'cu'],
['chv', 'cv'],
['cor', 'kw'],
['cos', 'co'],
['cre', 'cr'],
['cym', 'cy'],
['dan', 'da'],
['deu', 'de'],
['div', 'dv'],
['dzo', 'dz'],
['ell', 'el'],
['eng', 'en'],
['epo', 'eo'],
['est', 'et'],
['eus', 'eu'],
['ewe', 'ee'],
['fao', 'fo'],
['fas', 'fa'],
['fij', 'fj'],
['fin', 'fi'],
['fre', 'fr'],
['fry', 'fy'],
['ful', 'ff'],
['gla', 'gd'],
['gle', 'ga'],
['glg', 'gl'],
['glv', 'gv'],
['grn', 'gn'],
['guj', 'gu'],
['hat', 'ht'],
['hau', 'ha'],
['hbs', 'sh'],
['heb', 'he'],
['her', 'hz'],
['hin', 'hi'],
['hmo', 'ho'],
['hrv', 'hr'],
['hun', 'hu'],
['hye', 'hy'],
['ibo', 'ig'],
['ido', 'io'],
['iii', 'ii'],
['iku', 'iu'],
['ile', 'ie'],
['ina', 'ia'],
['ind', 'id'],
['ipk', 'ik'],
['isl', 'is'],
['ita', 'it'],
['jav', 'jv'],
['jpn', 'ja'],
['kal', 'kl'],
['kan', 'kn'],
['kas', 'ks'],
['kat', 'ka'],
['kau', 'kr'],
['kaz', 'kk'],
['khm', 'km'],
['kik', 'ki'],
['kin', 'rw'],
['kir', 'ky'],
['kom', 'kv'],
['kon', 'kg'],
['kor', 'ko'],
['kua', 'kj'],
['kur', 'ku'],
['lao', 'lo'],
['lat', 'la'],
['lav', 'lv'],
['lim', 'li'],
['lin', 'ln'],
['lit', 'lt'],
['ltz', 'lb'],
['lub', 'lu'],
['lug', 'lg'],
['mah', 'mh'],
['mal', 'ml'],
['mar', 'mr'],
['mkd', 'mk'],
['mlg', 'mg'],
['mlt', 'mt'],
['mon', 'mn'],
['mri', 'mi'],
['msa', 'ms'],
['mya', 'my'],
['nau', 'na'],
['nav', 'nv'],
['nbl', 'nr'],
['nde', 'nd'],
['ndo', 'ng'],
['nep', 'ne'],
['nld', 'nl'],
['nno', 'nn'],
['nob', 'nb'],
['nor', 'no'],
['nya', 'ny'],
['oci', 'oc'],
['oji', 'oj'],
['ori', 'or'],
['orm', 'om'],
['oss', 'os'],
['pan', 'pa'],
['pli', 'pi'],
['pol', 'pl'],
['por', 'pt'],
['pus', 'ps'],
['que', 'qu'],
['roh', 'rm'],
['ron', 'ro'],
['run', 'rn'],
['rus', 'ru'],
['sag', 'sg'],
['san', 'sa'],
['sin', 'si'],
['slk', 'sk'],
['slv', 'sl'],
['sme', 'se'],
['smo', 'sm'],
['sna', 'sn'],
['snd', 'sd'],
['som', 'so'],
['sot', 'st'],
['spa', 'es'],
['sqi', 'sq'],
['srd', 'sc'],
['srp', 'sr'],
['ssw', 'ss'],
['sun', 'su'],
['swa', 'sw'],
['swe', 'sv'],
['tah', 'ty'],
['tam', 'ta'],
['tat', 'tt'],
['tel', 'te'],
['tgk', 'tg'],
['tgl', 'tl'],
['tha', 'th'],
['tir', 'ti'],
['ton', 'to'],
['tsn', 'tn'],
['tso', 'ts'],
['tuk', 'tk'],
['tur', 'tr'],
['twi', 'tw'],
['uig', 'ug'],
['ukr', 'uk'],
['urd', 'ur'],
['uzb', 'uz'],
['ven', 've'],
['vie', 'vi'],
['vol', 'vo'],
['wln', 'wa'],
['wol', 'wo'],
['xho', 'xh'],
['yid', 'yi'],
['yor', 'yo'],
['zha', 'za'],
['zho', 'zh'],
['zul', 'zu'],
]);

View file

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

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,2 +0,0 @@
use flake $FLAKE#node
npm ci

View file

@ -1,13 +0,0 @@
{
buildApp,
callPackage,
...
}:
buildApp {
src = ./.;
npmDepsHash = "sha256-zl/UIwBQqpV89Rvagyq3mQDJxkWM0h1evtKg9TiTdiw=";
runtimeInputs = [
(callPackage ../../nixosModules/docker/updateImage.nix {})
];
}

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',
],
},
});

Binary file not shown.

View file

@ -1,20 +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/js": "9.14.0",
"@stylistic/eslint-plugin": "2.10.1",
"@types/node": "22.9.0",
"esbuild": "0.24.0",
"eslint": "9.14.0",
"eslint-plugin-jsdoc": "50.5.0",
"jiti": "2.4.0",
"typescript": "5.6.3",
"typescript-eslint": "8.14.0"
}
}

View file

@ -1,102 +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 { 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();
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('lovelace-components.custom-sidebar'));
}
if (args['s'] || args['some-sass-language-server']) {
console.log(updateCustomPackage('some-sass-language-server'));
}
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 vuetorrentOutput = updateVuetorrent();
console.log(vuetorrentOutput);
// This doesn't need to be added to commit msgs
console.log(updateCustomPackage('lovelace-components.custom-sidebar'));
console.log(updateCustomPackage('some-sass-language-server'));
spawnSync('nix-fast-build', ['-f', `${FLAKE}#nixFastChecks`], {
shell: true,
stdio: [process.stdin, process.stdout, process.stderr],
});
const output = [
'chore: update sources\n\n',
];
if (flakeOutput.length > 5) {
output.push(`Flake Inputs:\n${flakeOutput}\n\n`);
}
if (dockerOutput.length > 5) {
output.push(`Docker Images:\n${dockerOutput}\n`);
}
if (firefoxOutput.length > 5) {
output.push(`Firefox Addons:\n${firefoxOutput}\n\n`);
}
if (vuetorrentOutput.length > 5) {
output.push(`Misc Sources:\n${vuetorrentOutput}\n`);
}
if (args['f']) {
writeFileSync(args['f'] as string, output.join(''));
}
else {
console.log(output.join(''));
}
}
spawnSync('alejandra', ['-q', FLAKE], { shell: true });

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}/devices/nos/modules/jellyfin`) ?? '';
updates += updateImages(`${FLAKE}/devices/homie/modules/home-assistant/netdaemon`) ?? '';
const DIR = `${FLAKE}/devices/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}/legacyPackages/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',
'.#legacyPackages.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,35 +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((input) => ![
'systems',
'flake-utils',
'flake-parts',
'treefmt-nix',
'lib-aggregate',
'lib-aggregate/nixpkgs-lib',
'sops-nix/nixpkgs-stable',
].some((inputName) => input.startsWith(` Updated input '${inputName}'`)))
.join('\n\n•')
// Shorten git revs to help readability
.split('\n')
.map((l) => l
.replace(/.{33}\?narHash=sha256[^']*/, '')
.replace(/&rev=(.{7})[^'&]*/, (_, backref) => `&rev=${backref}`))
.join('\n');
return output;
};

View file

@ -1,30 +0,0 @@
import { spawnSync } from 'node:child_process';
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;

View file

@ -1,47 +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}/devices/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();

View file

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

View file

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

View file

@ -1,8 +0,0 @@
{
pkgs,
self,
}: let
apps = import ./apps.nix {inherit pkgs self;};
nixosMachines = import ./machines.nix {inherit pkgs self;};
in
apps // nixosMachines

View file

@ -1,10 +0,0 @@
# CI: https://github.com/Mic92/dotfiles/blob/c2f538934d67417941f83d8bb65b8263c43d32ca/flake.nix#L168
{
pkgs,
self,
}: let
inherit (pkgs.lib) filterAttrs mapAttrs' nameValuePair;
in
mapAttrs'
(name: config: nameValuePair "nixos-${name}" config.config.system.build.toplevel)
((filterAttrs (_: config: config.pkgs.system == pkgs.system)) self.nixosConfigurations)

View file

@ -1,131 +0,0 @@
{
config,
home-manager,
lib,
nh,
pkgs,
self,
...
}: {
imports = [
./vars
./modules
./packages.nix
self.nixosModules.borgbackup
home-manager.nixosModules.home-manager
];
boot.tmp.useTmpfs = true;
systemd.services.nix-daemon = {
environment.TMPDIR = "/home/nix-cache";
preStart = ''
mkdir -p ${config.systemd.services.nix-daemon.environment.TMPDIR}
'';
};
nix = {
package = pkgs.nixVersions.nix_2_24;
# 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;
allow-import-from-derivation = true;
# remote building
trusted-users = ["matt" "nixremote"];
};
};
programs.nh = {
enable = true;
package = nh.packages.${pkgs.system}.default;
# weekly cleanup
clean = {
enable = true;
extraArgs = "--keep-since 30d";
};
};
services = {
fwupd.enable = true;
xserver.xkb = {
layout = "ca";
variant = "multix";
};
};
boot.supportedFilesystems = ["ext4" "xfs" "btrfs" "vfat" "ntfs"];
system.fsPackages = builtins.attrValues {
inherit
(pkgs)
btrfs-progs
nfs-utils
ntfs3g
xfsprogs
;
};
environment.variables.NPM_CONFIG_GLOBALCONFIG = "/etc/npmrc";
environment.etc.npmrc.text = ''
fund = false
update-notifier = false
'';
environment.systemPackages = builtins.attrValues {
# Peripherals
inherit
(pkgs)
hdparm
pciutils
usbutils
rar
;
};
home-manager.users = let
inherit (lib) mkIf mkOption types;
inherit (config.vars) mainUser;
default = {
imports = [
# Make the vars be the same on Nix and HM
{
options.vars = mkOption {
type = types.attrs;
readOnly = true;
default = config.vars;
};
}
{
programs.bash.sessionVariables = {
FLAKE = config.environment.variables.FLAKE;
};
}
./home
./home/trash-d
];
home.stateVersion = config.system.stateVersion;
};
in {
root = default;
greeter = mkIf (config.services.greetd.enable) default;
${mainUser} = default;
};
}

View file

@ -1,27 +0,0 @@
# Check git status of nix configs
fetchNix() {(
cd "$FLAKE" || exit 1
git fetch --all --quiet
GIT=$(git -c color.status=always status |
grep -v -e "On branch" \
-e "up to date" \
-e 'use "git' \
-e "nothing to commit")
CHECK=$(echo "$GIT" | sed '/^$/d')
if [ "$CHECK" != "" ]; then
echo "$GIT"
echo
fi
)}
# Check for internet
if wget -q --spider https://git.nelim.org; then
fetchNix
else
echo "Offline"
fi
# Pokemon Sprite
pokemon-colorscripts -r 1-5

View file

@ -1,31 +0,0 @@
function colorgrid() {
iter=16
while [ $iter -lt 52 ]
do
second=$[$iter+36]
third=$[$second+36]
four=$[$third+36]
five=$[$four+36]
six=$[$five+36]
seven=$[$six+36]
if [ $seven -gt 250 ];then seven=$[$seven-251]; fi
echo -en "\033[38;5;$(echo $iter)m█ "
printf "%03d" $iter
echo -en " \033[38;5;$(echo $second)m█ "
printf "%03d" $second
echo -en " \033[38;5;$(echo $third)m█ "
printf "%03d" $third
echo -en " \033[38;5;$(echo $four)m█ "
printf "%03d" $four
echo -en " \033[38;5;$(echo $five)m█ "
printf "%03d" $five
echo -en " \033[38;5;$(echo $six)m█ "
printf "%03d" $six
echo -en " \033[38;5;$(echo $seven)m█ "
printf "%03d" $seven
iter=$[$iter+1]
printf '\r\n'
done
}

View file

@ -1,3 +0,0 @@
# Modified from https://github.com/dracula/fzf
export FZF_DEFAULT_OPTS='--color=fg:#f8f8f2,hl:#bd93f9 --color=fg+:#f8f8f2,hl+:#bd93f9 --color=info:#ffb86c,prompt:#50fa7b,pointer:#ff79c6 --color=marker:#ff79c6,spinner:#ffb86c,header:#6272a4'

View file

@ -1,10 +0,0 @@
# Modified from https://github.com/dracula/man-pages
#man-page colors
export LESS_TERMCAP_mb=$'\e[1;31m' # begin bold
export LESS_TERMCAP_md=$'\e[1;34m' # begin blink
export LESS_TERMCAP_so=$'\e[01;45;37m' # begin reverse video
export LESS_TERMCAP_us=$'\e[01;36m' # begin underline
export LESS_TERMCAP_me=$'\e[0m' # reset bold/blink
export LESS_TERMCAP_se=$'\e[0m' # reset reverse video
export LESS_TERMCAP_ue=$'\e[0m' # reset underline

View file

@ -1,143 +0,0 @@
{
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,54 +0,0 @@
{
pkgs,
config,
self,
...
}: {
programs = {
fzf = {
enable = true;
enableBashIntegration = true;
};
bash = {
sessionVariables = {
inherit (config.home.sessionVariables) RIPGREP_CONFIG_PATH;
};
shellAliases = {
rg = "rga";
cat = "bat ";
man = "BAT_THEME='default' batman ";
};
};
ripgrep = {
enable = true;
package = pkgs.ripgrep-all;
arguments = [
"--max-columns=150"
"--max-columns-preview"
"--hidden"
"--glob=!.git/*"
"--smart-case"
"--sort"
"path"
];
};
jq.enable = true;
htop.enable = true;
bat = {
enable = true;
config.theme = "dracula-bat";
themes.dracula-bat.src = self.legacyPackages.${pkgs.system}.dracula.bat;
extraPackages = builtins.attrValues {
inherit (pkgs.bat-extras) batman;
};
};
};
}

View file

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

View file

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

View file

@ -1,78 +0,0 @@
{
pkgs,
self,
...
}: let
mkRemoteConf = remote: email: name: {
condition = "hasconfig:remote.*.url:${remote}:*/**";
contents.user = {inherit email name;};
};
mkDefaultRemote = remote: mkRemoteConf remote "matt@nelim.org" "matt1432";
in {
programs = {
git = {
enable = true;
package = pkgs.gitFull;
lfs.enable = true;
includes = [
{path = toString self.legacyPackages.${pkgs.system}.dracula.git;}
(mkDefaultRemote "https://github.com")
(mkDefaultRemote "git@github.com")
(mkDefaultRemote "git@git.nelim.org")
(mkRemoteConf "git@gitlab.info.uqam.ca" "gj591944@ens.uqam.ca" "Mathis Hurtubise")
];
delta = {
enable = true;
options = {
side-by-side = true;
line-numbers-zero-style = "#E6EDF3";
};
};
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;
};
sendemail = {
smtpserver = "127.0.0.1";
smtpuser = "matt@nelim.org";
smtpencryption = "tls";
smtpserverport = 1025;
smtpsslcertpath = "";
};
};
};
};
home.packages = [
(pkgs.writeShellApplication {
name = "chore";
runtimeInputs = [pkgs.git];
text = ''
DIR=''${1:-"$FLAKE"}
cd "$DIR" || exit 1
git add flake.lock
git commit -m 'chore: update flake.lock'
git push
'';
})
];
}

View file

@ -1,107 +0,0 @@
# see https://github.com/CppCXY/EmmyLuaCodeStyle
[*.lua]
# [basic]
indent_style = space
indent_size = 4
quote_style = single
max_line_length = 120
end_of_line = lf
table_separator_style = comma
trailing_table_separator = smart
call_arg_parentheses = keep
# [space]
space_around_table_field_list = true
space_before_attribute = true
space_before_function_open_parenthesis = false
space_before_function_call_open_parenthesis = false
space_before_closure_open_parenthesis = false
space_before_function_call_single_arg = false
space_before_open_square_bracket = false
space_inside_function_call_parentheses = false
space_inside_function_param_list_parentheses = false
space_inside_square_brackets = false
# like t[#t+1] = 1
space_around_table_append_operator = false
ignore_spaces_inside_function_call = false
# detail number or 'keep'
space_before_inline_comment = 1
# convert '---' to '--- ' or '--' to '-- '
space_after_comment_dash = false
# [operator space]
space_around_math_operator = true
space_around_math_operator.exponent = false
space_around_concat_operator = true
space_around_logical_operator = true
space_around_assign_operator = true
space_after_comma = true
space_after_comma_in_for_statement = true
# [align]
align_call_args = false
align_function_params = true
align_continuous_assign_statement = true
align_continuous_rect_table_field = true
align_continuous_line_space = 2
align_if_branch = false
# option none / always / contain_curly/
align_array_table = true
align_continuous_similar_call_args = false
align_continuous_inline_comment = true
# option none / always / only_call_stmt
align_chain_expr = none
# [indent]
never_indent_before_if_condition = false
never_indent_comment_on_if_branch = false
keep_indents_on_empty_lines = false
allow_non_indented_comments = false
# [line space]
# The following configuration supports four expressions
# keep
# fixed(n)
# min(n)
# max(n)
# for eg. min(2)
line_space_after_if_statement = keep
line_space_after_do_statement = keep
line_space_after_while_statement = keep
line_space_after_repeat_statement = keep
line_space_after_for_statement = keep
line_space_after_local_or_assign_statement = keep
line_space_after_function_statement = fixed(2)
line_space_after_expression_statement = keep
line_space_after_comment = keep
line_space_around_block = fixed(1)
# [line break]
break_all_list_when_line_exceed = false
auto_collapse_lines = false
break_before_braces = false
# [preference]
ignore_space_after_colon = false
end_statement_with_semicolon = always

View file

@ -1,116 +0,0 @@
{
config,
pkgs,
...
}: {
imports = [
./git.nix
./langs
./theme.nix
./treesitter.nix
];
programs = {
neovim = {
enable = true;
extraLuaConfig =
# lua
''
-- by default, the indent is 2 spaces.
vim.opt.smartindent = true;
vim.opt.expandtab = true;
vim.opt.shiftwidth = 2;
vim.opt.softtabstop = 2;
vim.opt.tabstop = 2;
vim.opt.number = true;
vim.opt.relativenumber = true;
vim.opt.undofile = true;
vim.opt.undodir = '${config.xdg.cacheHome}/nvim/';
-- Always show the signcolumn, otherwise it would shift
-- the text each time diagnostics appear/become resolved
vim.opt.signcolumn = 'yes';
-- remove highlight on words
vim.keymap.set('n', '<esc>', ':noh<cr><esc>', {
noremap = true,
silent = true,
});
-- Get rid of deprecated messages
vim.tbl_add_reverse_lookup = function(tbl)
for k, v in pairs(tbl) do
tbl[v] = k;
end
end;
vim.tbl_islist = function(tbl)
return vim.islist(tbl);
end;
vim.diagnostic.is_disabled = function()
return not vim.diagnostic.is_enabled();
end;
vim.lsp.buf_get_clients = function()
return vim.lsp.get_clients();
end;
vim.lsp.get_active_clients = function()
return vim.lsp.get_clients();
end;
'';
plugins = [
pkgs.vimPlugins.fzfWrapper
pkgs.vimPlugins.fzf-vim
{
plugin = pkgs.vimPlugins.todo-comments-nvim;
type = "lua";
config =
# lua
''
require('todo-comments').setup();
'';
}
{
plugin = pkgs.vimPlugins.mini-nvim;
type = "lua";
config =
# lua
''
-- TODO: see how this works
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',
});
},
},
});
'';
}
{
plugin = pkgs.vimPlugins.nvim-config-local;
type = "lua";
config =
# lua
''
require('config-local').setup({
config_files = { '.nvim.lua', '.nvimrc', '.exrc' },
-- Where the plugin keeps files data
hashfile = '${config.xdg.cacheHome}/nvim/config-local',
});
'';
}
];
};
};
}

View file

@ -1,31 +0,0 @@
{pkgs, ...}: {
programs = {
neovim = {
plugins = [
pkgs.vimPlugins.fugitive
{
plugin = pkgs.vimPlugins.gitsigns-nvim;
type = "lua";
config =
# lua
''
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

@ -1,48 +0,0 @@
{
config,
pkgs,
lib,
...
}: let
inherit (lib) getExe mkIf;
inherit (config.vars) neovimIde;
in {
programs = {
# I love doing typos
bash.shellAliases = {
nivm = "nvim";
nivim = "nvim";
};
neovim = {
defaultEditor = true;
viAlias = true;
vimAlias = true;
extraPackages = mkIf neovimIde [
pkgs.nodePackages.bash-language-server
pkgs.shellcheck
];
extraLuaConfig =
mkIf neovimIde
# lua
''
vim.api.nvim_create_autocmd('FileType', {
pattern = 'sh',
command = 'setlocal ts=4 sw=4 sts=0 expandtab',
});
require('lspconfig').bashls.setup({
capabilities = require('cmp_nvim_lsp').default_capabilities(),
settings = {
bashIde = {
shellcheckPath = '${getExe pkgs.shellcheck}',
},
},
});
'';
};
};
}

View file

@ -1,52 +0,0 @@
{
config,
pkgs,
lib,
...
}: let
inherit (lib) mkIf;
inherit (config.vars) neovimIde;
in
mkIf neovimIde {
programs = {
neovim = {
extraPackages = builtins.attrValues {
inherit
(pkgs)
gcc
clang-tools
cmake-language-server
;
};
extraLuaConfig =
# lua
''
vim.api.nvim_create_autocmd('FileType', {
pattern = { 'cpp' , 'c'},
command = 'setlocal ts=4 sw=4 sts=0 expandtab',
});
local lsp = require('lspconfig');
lsp.cmake.setup({
capabilities = require('cmp_nvim_lsp').default_capabilities(),
});
lsp.clangd.setup({
capabilities = require('cmp_nvim_lsp').default_capabilities(),
handlers = require('lsp-status').extensions.clangd.setup(),
on_attach = function(_, bufnr)
require("clangd_extensions.inlay_hints").setup_autocmd()
require("clangd_extensions.inlay_hints").set_inlay_hints()
end,
});
'';
plugins = builtins.attrValues {
inherit (pkgs.vimPlugins) clangd_extensions-nvim;
};
};
};
}

View file

@ -1,66 +0,0 @@
{
config,
pkgs,
lib,
...
}: let
inherit (lib) mkIf;
inherit (config.vars) neovimIde;
in
mkIf neovimIde {
programs = {
neovim = {
extraPackages = builtins.attrValues {
inherit
(pkgs)
omnisharp-roslyn
;
};
extraLuaConfig =
# lua
''
vim.api.nvim_create_autocmd('FileType', {
pattern = { 'cs' },
command = 'setlocal ts=4 sw=4 sts=0 expandtab',
});
local omnisharp_extended = require('omnisharp_extended');
require('lspconfig').omnisharp.setup({
cmd = { "dotnet", "${pkgs.omnisharp-roslyn}/lib/omnisharp-roslyn/OmniSharp.dll" },
handlers = {
["textDocument/definition"] = omnisharp_extended.definition_handler,
["textDocument/typeDefinition"] = omnisharp_extended.type_definition_handler,
["textDocument/references"] = omnisharp_extended.references_handler,
["textDocument/implementation"] = omnisharp_extended.implementation_handler,
},
settings = {
FormattingOptions = {
EnableEditorConfigSupport = true,
OrganizeImports = true,
},
MsBuild = {
LoadProjectsOnDemand = false,
},
RoslynExtensionsOptions = {
EnableAnalyzersSupport = true,
EnableDecompilationSupport = true,
EnableImportCompletion = true,
AnalyzeOpenDocumentsOnly = false,
},
Sdk = {
IncludePrereleases = true,
},
},
});
'';
plugins = builtins.attrValues {
inherit (pkgs.vimPlugins) omnisharp-extended-lsp-nvim;
};
};
};
}

View file

@ -1,104 +0,0 @@
{
config,
lib,
pkgs,
...
}: let
inherit (lib) fileContents mkBefore mkIf;
inherit (config.vars) neovimIde;
in {
imports = [
./bash.nix
./clang.nix
./csharp.nix
./hyprlang.nix
./java.nix
./json.nix
./lua.nix
./markdown.nix
./nix.nix
./python.nix
./rust.nix
./web.nix
];
programs = mkIf neovimIde {
neovim = {
extraLuaConfig =
mkBefore
# lua
''
-- Start completion / snippet stuff
vim.g.coq_settings = {
auto_start = 'shut-up',
keymap = {
recommended = false,
},
-- https://github.com/NixOS/nixpkgs/issues/168928#issuecomment-1109581739
xdg = true,
};
-- Add formatting cmd
vim.api.nvim_create_user_command(
'Format',
function()
vim.lsp.buf.format({ async = true });
end,
{}
);
-- LSP-Status setup
local lsp_status = require('lsp-status');
lsp_status.register_progress();
-- Remove LSP highlighting to use Treesitter
vim.api.nvim_create_autocmd('LspAttach', {
callback = function(args)
local client = vim.lsp.get_client_by_id(args.data.client_id);
client.server_capabilities.semanticTokensProvider = nil;
lsp_status.on_attach(client);
end,
});
-- Disable virtual_text since it's redundant due to lsp_lines.
vim.diagnostic.config({
virtual_text = false,
});
require('lsp_lines').setup();
'';
plugins =
(builtins.attrValues {
inherit
(pkgs.vimPlugins)
nvim-lspconfig
lsp-status-nvim
lsp_lines-nvim
cmp-buffer
cmp-nvim-lsp
cmp-path
cmp-spell
vim-vsnip
;
})
++ [
{
plugin = pkgs.vimPlugins.nvim-cmp;
type = "lua";
config = fileContents ../plugins/cmp.lua;
}
{
plugin = pkgs.vimPlugins.nvim-autopairs;
type = "lua";
config =
# lua
''
require('nvim-autopairs').setup({});
'';
}
];
};
};
}

View file

@ -1,26 +0,0 @@
{
config,
lib,
...
}: let
inherit (lib) mkIf;
inherit (config.vars) neovimIde;
in
mkIf neovimIde {
programs = {
neovim = {
extraLuaConfig =
# lua
''
vim.filetype.add({
pattern = { ['.*/hypr/.*%.conf'] = 'hyprlang' },
});
vim.api.nvim_create_autocmd('FileType', {
pattern = 'hyprlang',
command = 'setlocal ts=4 sw=4 sts=0 expandtab',
});
'';
};
};
}

View file

@ -1,83 +0,0 @@
{
config,
lib,
pkgs,
...
}: let
inherit (lib) getExe mkIf;
inherit (config.vars) neovimIde;
javaSdk = pkgs.temurin-bin-17;
javaPkgs = builtins.attrValues {inherit (pkgs) gradle maven;};
in
mkIf neovimIde {
home.packages = javaPkgs;
xdg.dataFile.".gradle/gradle.properties".text = ''
org.gradle.java.home = ${javaSdk}
'';
programs = {
java = {
enable = true;
package = javaSdk;
};
neovim = {
extraPackages = javaPkgs;
extraLuaConfig =
# lua
''
vim.api.nvim_create_autocmd('FileType', {
pattern = 'java',
command = 'setlocal ts=4 sw=4 sts=0 expandtab',
});
'';
plugins = [
{
# TOOD: setup debugger https://github.com/mfussenegger/nvim-jdtls#debugger-via-nvim-dap
plugin = pkgs.vimPlugins.nvim-jdtls;
type = "lua";
config =
# lua
''
--
local startJdtls = function()
local config = {
capabilities = require('cmp_nvim_lsp').default_capabilities(),
cmd = { '${getExe pkgs.jdt-language-server}' },
root_dir = vim.fs.dirname(vim.fs.find(
{ 'gradlew', '.git', 'mvnw', 'pom.xml' },
{ upward = true }
)[1]),
settings = {
java = {
configuration = {
runtimes = {
{
name = 'JavaSE-17',
path = '${javaSdk}',
},
},
},
},
},
};
require('jdtls').start_or_attach(config);
end
vim.api.nvim_create_autocmd('FileType', {
pattern = 'java',
callback = startJdtls,
});
'';
}
];
};
};
}

View file

@ -1,55 +0,0 @@
{
config,
lib,
pkgs,
...
}: let
inherit (lib) mkIf;
inherit (config.vars) neovimIde;
in
mkIf neovimIde {
programs = {
neovim = {
extraPackages = builtins.attrValues {
inherit
(pkgs)
vscode-langservers-extracted
yaml-language-server
;
};
extraLuaConfig =
# lua
''
vim.api.nvim_create_autocmd('FileType', {
pattern = 'yaml',
command = 'setlocal ts=4 sw=4 sts=0 expandtab',
});
vim.api.nvim_create_autocmd('FileType', {
pattern = 'json',
command = 'setlocal ts=4 sw=4 sts=0 expandtab',
});
local lsp = require('lspconfig');
lsp.jsonls.setup({
capabilities = require('cmp_nvim_lsp').default_capabilities(),
});
lsp.yamlls.setup({
capabilities = require('cmp_nvim_lsp').default_capabilities(),
settings = {
yaml = {
schemas = {
[
"https://json.schemastore.org/github-workflow.json"
] = "/.github/workflows/*",
},
},
},
});
'';
};
};
}

View file

@ -1,49 +0,0 @@
{
config,
pkgs,
lib,
...
}: let
inherit (lib) mkIf;
inherit (config.vars) neovimIde;
flakeEnv = config.programs.bash.sessionVariables.FLAKE;
in
mkIf neovimIde {
programs = {
neovim = {
extraPackages = builtins.attrValues {
inherit (pkgs) lua-language-server;
};
plugins = [
{
plugin = pkgs.vimPlugins.neodev-nvim;
type = "lua";
config =
# lua
''
vim.api.nvim_create_autocmd('FileType', {
pattern = 'lua',
command = 'setlocal ts=4 sw=4 sts=0 expandtab',
});
-- IMPORTANT: make sure to setup neodev BEFORE lspconfig
require("neodev").setup({
override = function(root_dir, library)
if root_dir:find('${flakeEnv}', 1, true) == 1 then
library.enabled = true
library.plugins = true
end
end,
});
require('lspconfig').lua_ls.setup({
capabilities = require('cmp_nvim_lsp').default_capabilities(),
});
'';
}
];
};
};
}

View file

@ -1,128 +0,0 @@
{
config,
lib,
pkgs,
self,
vimplugin-easytables-src,
...
}: let
inherit (lib) mkIf;
inherit (config.vars) neovimIde;
inherit (import "${self}/lib" {inherit pkgs;}) buildPlugin;
in
mkIf neovimIde {
programs = {
neovim = {
extraPackages = builtins.attrValues {
inherit
(pkgs)
pandoc
texlab
texliveFull
rubber
;
};
extraLuaConfig =
# lua
''
local lsp = require('lspconfig');
lsp.texlab.setup({
capabilities = require('cmp_nvim_lsp').default_capabilities(),
settings = {
texlab = {
formatterLineLength = 100,
latexFormatter = 'latexindent',
latexindent = {
modifyLineBreaks = false,
["local"] = '.indentconfig.yaml';
},
},
},
});
'';
plugins = [
{
plugin = buildPlugin "easytables-nvim" vimplugin-easytables-src;
type = "lua";
config =
# lua
''
require('easytables').setup();
'';
}
{
plugin = pkgs.vimPlugins.knap;
type = "lua";
config =
# lua
''
--
vim.api.nvim_create_autocmd('FileType', {
pattern = 'tex',
command = 'setlocal ts=4 sw=4 sts=0 expandtab',
});
vim.g.knap_settings = {
-- HTML
htmloutputext = 'html',
htmltohtml = 'none',
htmltohtmlviewerlaunch = "",
htmltohtmlviewerrefresh = 'none',
-- Markdown
mdoutputext = 'html',
markdownoutputext = 'html',
-- Markdown to PDF
mdtopdf = 'pandoc %docroot% -o /tmp/%outputfile%',
markdowntopdf = 'pandoc %docroot% -o /tmp/%outputfile%',
mdtopdfviewerlaunch = 'sioyek /tmp/%outputfile%',
markdowntopdfviewerlaunch = 'sioyek /tmp/%outputfile%',
mdtopdfviewerrefresh = 'none',
markdowntopdfviewerrefresh = "none",
-- Markdown to HTML
mdtohtml = 'pandoc --standalone %docroot% -o /tmp/%outputfile%',
markdowntohtml = 'pandoc --standalone %docroot% -o /tmp/%outputfile%',
mdtohtmlviewerlaunch = 'firefox -new-window /tmp/%outputfile%',
markdowntohtmlviewerlaunch = 'firefox -new-window /tmp/%outputfile%',
mdtohtmlviewerrefresh = 'none',
markdowntohtmlviewerrefresh = 'none',
-- LaTeX
-- TODO: stop from polluting workspace
};
-- F4 processes the document once, and refreshes the view
vim.keymap.set({ 'n', 'v', 'i' }, '<F4>', function()
require('knap').process_once();
end);
-- F5 closes the viewer application, and
-- allows settings to be reset
vim.keymap.set({ 'n', 'v', 'i' }, '<F5>', function()
require('knap').close_viewer();
end);
-- F6 toggles the auto-processing on and off
vim.keymap.set({ 'n', 'v', 'i' }, '<F6>', function()
require('knap').toggle_autopreviewing();
end);
-- F7 invokes a SyncTeX forward search, or similar,
-- where appropriate
vim.keymap.set({ 'n', 'v', 'i' }, '<F7>', function()
require('knap').forward_jump();
end);
'';
}
];
};
};
}

View file

@ -1,75 +0,0 @@
{
config,
pkgs,
lib,
nixd,
self,
...
}: let
inherit (lib) getExe hasPrefix mkIf removePrefix;
inherit (config.vars) hostName mainUser neovimIde;
defaultFormatter = self.formatter.${pkgs.system};
nixdPkg = nixd.packages.${pkgs.system}.default;
flakeEnv = config.programs.bash.sessionVariables.FLAKE;
flakeDir = "${removePrefix "/home/${mainUser}/" flakeEnv}";
in
mkIf neovimIde {
assertions = [
{
assertion =
neovimIde
&& hasPrefix "/home/${mainUser}/" flakeEnv
|| !neovimIde;
message = ''
Your $FLAKE environment variable needs to point to a directory in
the main users' home to use the neovim module.
'';
}
];
home.packages = [
defaultFormatter
nixdPkg
];
# nixd by default kinda spams LspLog
home.sessionVariables.NIXD_FLAGS = "-log=error";
xdg.dataFile."${flakeDir}/.nixd.json".text = builtins.toJSON {
nixpkgs = {
expr = "import (builtins.getFlake \"${flakeDir}\").inputs.nixpkgs {}";
};
options.nixos = {
expr = "(builtins.getFlake \"${flakeDir}\").nixosConfigurations.${hostName}.options";
};
};
programs = {
neovim = {
extraPackages = [
nixdPkg
];
extraLuaConfig =
# lua
''
require('lspconfig').nixd.setup({
capabilities = require('cmp_nvim_lsp').default_capabilities(),
filetypes = { 'nix', 'in.nix' },
settings = {
nixd = {
formatting = {
-- TODO: Try to find <flake>.formatter
command = { '${getExe defaultFormatter}' },
},
},
},
});
'';
};
};
}

View file

@ -1,28 +0,0 @@
{
config,
lib,
pkgs,
...
}: let
inherit (lib) mkIf;
inherit (config.vars) neovimIde;
in
mkIf neovimIde {
programs = {
neovim = {
withPython3 = true;
extraPackages = [
pkgs.basedpyright
];
extraLuaConfig =
# lua
''
require('lspconfig').basedpyright.setup({
capabilities = require('cmp_nvim_lsp').default_capabilities(),
});
'';
};
};
}

View file

@ -1,37 +0,0 @@
{
config,
pkgs,
lib,
...
}: let
inherit (lib) mkIf;
inherit (config.vars) neovimIde;
in
mkIf neovimIde {
programs = {
neovim = {
extraPackages = builtins.attrValues {
inherit
(pkgs)
cargo
rustc
rust-analyzer
rustfmt
;
};
extraLuaConfig =
# lua
''
vim.api.nvim_create_autocmd('FileType', {
pattern = { 'rust' },
command = 'setlocal ts=4 sw=4 sts=0 expandtab',
});
require('lspconfig').rust_analyzer.setup({
capabilities = require('cmp_nvim_lsp').default_capabilities(),
});
'';
};
};
}

View file

@ -1,200 +0,0 @@
{
config,
lib,
pkgs,
self,
vimplugin-ts-error-translator-src,
...
}: let
inherit (lib) mkIf;
inherit (config.vars) neovimIde;
inherit (import "${self}/lib" {inherit pkgs;}) buildPlugin;
in
mkIf neovimIde {
programs = {
neovim = {
withNodeJs = true;
extraPackages = builtins.attrValues {
inherit
(pkgs)
nodejs_latest
vscode-langservers-extracted
;
inherit
(pkgs.nodePackages)
npm
neovim
;
inherit
(self.packages.${pkgs.system})
some-sass-language-server
;
};
extraLuaConfig =
# lua
''
vim.api.nvim_create_autocmd('FileType', {
pattern = { 'javascript', 'javascriptreact', 'javascript.jsx', 'typescript', 'typescriptreact', 'typescript.tsx', 'css', 'scss' },
command = 'setlocal ts=4 sw=4 sts=0 expandtab',
});
vim.api.nvim_create_autocmd('FileType', {
pattern = 'html',
command = 'setlocal ts=4 sw=4 expandtab',
});
vim.api.nvim_create_autocmd('FileType', {
pattern = 'scss',
command = 'setlocal iskeyword+=@-@',
});
local lsp = require('lspconfig');
local tsserver = require('typescript-tools');
local default_capabilities = require('cmp_nvim_lsp').default_capabilities();
tsserver.setup({
capabilities = default_capabilities,
handlers = {
-- format error code with better error message
['textDocument/publishDiagnostics'] = function(err, result, ctx, config)
require('ts-error-translator').translate_diagnostics(err, result, ctx, config)
vim.lsp.diagnostic.on_publish_diagnostics(err, result, ctx, config)
end,
},
});
lsp.eslint.setup({
capabilities = default_capabilities,
-- auto-save
on_attach = function(client, bufnr)
vim.api.nvim_create_autocmd('BufWritePre', {
buffer = bufnr,
command = 'EslintFixAll',
});
end,
settings = {
validate = 'on',
packageManager = 'npm',
useESLintClass = true,
useFlatConfig = true,
experimental = {
useFlatConfig = true,
},
codeAction = {
disableRuleComment = {
enable = true,
location = 'separateLine'
},
showDocumentation = {
enable = true,
},
},
codeActionOnSave = {
mode = 'all',
rules = {},
},
format = true,
quiet = false,
onIgnoredFiles = 'off',
rulesCustomizations = {},
run = 'onType',
problems = {
shortenToSingleLine = false,
},
nodePath = "",
workingDirectory = {
mode = 'location',
},
options = {
flags = {'unstable_ts_config'},
},
},
});
lsp.cssls.setup({
capabilities = default_capabilities,
settings = {
css = {
validate = false,
},
less = {
validate = false,
},
scss = {
validate = false,
},
},
});
lsp.somesass_ls.setup({
capabilities = default_capabilities,
});
lsp.somesass_ls.manager.config.settings = {
somesass = {
scss = {
completion = {
suggestFromUseOnly = true,
},
},
},
};
local html_caps = default_capabilities;
html_caps.textDocument.completion.completionItem.snippetSupport = true;
lsp.html.setup({
capabilities = html_caps,
settings = {
configurationSection = { "html", "css", "javascript" },
embeddedLanguages = {
css = true,
javascript = true,
},
provideFormatter = true,
tabSize = 4,
insertSpaces = true,
indentEmptyLines = false,
wrapAttributes = 'auto',
wrapAttributesIndentSize = 4,
endWithNewline = true,
},
});
'';
plugins = [
pkgs.vimPlugins.typescript-tools-nvim
(buildPlugin "ts-error-translator" vimplugin-ts-error-translator-src)
{
plugin = pkgs.vimPlugins.package-info-nvim;
type = "lua";
config =
# lua
''
local packageInfo = require('package-info');
packageInfo.setup({
hide_up_to_date = true,
package_manager = 'npm',
});
vim.api.nvim_create_autocmd({ 'BufRead', 'BufNewFile' }, {
pattern = { 'package.json' },
callback = function()
packageInfo.show({ force = true });
end,
});
'';
}
];
};
};
}

View file

@ -1,50 +0,0 @@
local cmp = require('cmp');
local cmp_autopairs = require('nvim-autopairs.completion.cmp');
cmp.event:on(
'confirm_done',
cmp_autopairs.on_confirm_done()
);
cmp.setup({
sources = {
{ name = 'nvim_lsp' },
{ name = 'buffer' },
{ name = 'path' },
},
snippet = {
expand = function(args)
vim.fn['vsnip#anonymous'](args.body);
end,
},
mapping = {
-- Confirm selection
['<Right>'] = cmp.mapping.confirm({ select = true }),
-- Next selection
['<Down>'] = cmp.mapping(function(fallback)
if cmp.visible() then
cmp.select_next_item();
else
fallback();
end;
end, {
'i',
's',
}),
-- Previous selection
['<Up>'] = cmp.mapping(function(fallback)
if cmp.visible() then
cmp.select_prev_item();
else
fallback();
end;
end, {
'i',
's',
}),
},
});

View file

@ -1,443 +0,0 @@
-- Modified from https://github.com/lauranaujokat/nvim/blob/4102c789d05667f636107e3dae4ac589053ee88d/lua/setups/heirline.lua#L4
local conditions = require('heirline.conditions');
local utils = require('heirline.utils');
---@class Palette
---@field [string] any
local dracula = require('dracula').colors();
local colors = {
bright_bg = dracula.selection,
dark_bg = dracula.menu,
bright_fg = dracula.fg,
red = dracula.red,
dark_red = utils.get_highlight('DiffDelete').bg,
green = dracula.green,
blue = dracula.blue,
gray = utils.get_highlight('NonText').fg,
orange = utils.get_highlight('Constant').fg,
purple = utils.get_highlight('Statement').fg,
cyan = dracula.cyan,
diag_warn = utils.get_highlight('DiagnosticWarn').fg,
diag_error = utils.get_highlight('DiagnosticError').fg,
diag_hint = utils.get_highlight('DiagnosticHint').fg,
diag_info = utils.get_highlight('DiagnosticInfo').fg,
git_del = utils.get_highlight('GitSignsDelete').fg,
git_add = utils.get_highlight('GitSignsAdd').fg,
git_change = utils.get_highlight('GitSignsChange').fg,
};
require('heirline').load_colors(colors);
local ViMode = {
-- get vim current mode, this information will be required by the provider
-- and the highlight functions, so we compute it only once per component
-- evaluation and store it as a component attribute
init = function(self)
self.mode = vim.fn.mode(1);
-- execute this only once, this is required if you want the ViMode
-- component to be updated on operator pending mode
if not self.once then
vim.api.nvim_create_autocmd('ModeChanged', {
pattern = '*:*o',
command = 'redrawstatus',
});
self.once = true;
end;
end,
static = {
mode_names = {
n = 'N',
no = 'N?',
nov = 'N?',
noV = 'N?',
['no\22'] = 'N?',
niI = 'Ni',
niR = 'Nr',
niV = 'Nv',
nt = 'Nt',
v = 'V',
vs = 'Vs',
V = 'V_',
Vs = 'Vs',
['\22'] = '^V',
['\22s'] = '^V',
s = 'S',
S = 'S_',
['\19'] = '^S',
i = 'I',
ic = 'Ic',
ix = 'Ix',
R = 'R',
Rc = 'Rc',
Rx = 'Rx',
Rv = 'Rv',
Rvc = 'Rv',
Rvx = 'Rv',
c = 'C',
cv = 'Ex',
r = '...',
rm = 'M',
['r?'] = '?',
['!'] = '!',
t = 'T',
},
mode_colors = {
n = 'red',
i = 'green',
v = 'cyan',
V = 'cyan',
['\22'] = 'cyan',
c = 'orange',
s = 'purple',
S = 'purple',
['\19'] = 'purple',
R = 'orange',
r = 'orange',
['!'] = 'red',
t = 'red',
},
},
-- To be extra meticulous, we can also add some vim statusline syntax to
-- control the padding and make sure our string is always at least 2
-- characters long. Plus a nice Icon.
provider = function(self)
return '' .. self.mode_names[self.mode] .. '%)';
end,
-- Same goes for the highlight. Now the foreground will change according to the current mode.
hl = function(self)
local mode = self.mode:sub(1, 1); -- get only the first mode character
return { fg = self.mode_colors[mode], bold = true };
end,
-- Re-evaluate the component only on ModeChanged event
update = {
'ModeChanged',
},
};
local FileNameBlock = {
init = function(self)
self.filename = vim.api.nvim_buf_get_name(0);
end,
};
-- FileNameBlock children
local FileIcon = {
init = function(self)
local filename = self.filename;
local extension = vim.fn.fnamemodify(filename, ':e');
self.icon, self.icon_color =
require('nvim-web-devicons').get_icon_color(filename, extension, { default = true });
end,
provider = function(self)
return self.icon and (self.icon .. ' ');
end,
hl = function(self)
return { fg = self.icon_color };
end,
};
local FileName = {
provider = function(self)
-- first, trim the pattern relative to the current directory. For other
-- options, see :h filename-modifers
local filename = vim.fn.fnamemodify(self.filename, ':.');
if filename == '' then
return '[No Name]';
end;
-- now, if the filename would occupy more than 1/4th of the available
-- space, we trim the file path to its initials
-- See Flexible Components section below for dynamic truncation
if not conditions.width_percent_below(#filename, 0.25) then
filename = vim.fn.pathshorten(filename);
end;
return filename;
end,
hl = { fg = utils.get_highlight('Directory').fg },
};
local FileFlags = {
{
condition = function()
return vim.bo.modified;
end,
provider = '[+]',
hl = { fg = 'green' },
},
{
condition = function()
return not vim.bo.modifiable or vim.bo.readonly;
end,
provider = '',
hl = { fg = 'orange' },
},
};
local FileNameModifer = {
hl = function()
if vim.bo.modified then
-- use `force` because we need to override the child's hl foreground
return { fg = 'cyan', bold = true, force = true };
end;
end,
};
-- let's add the children to our FileNameBlock component
FileNameBlock = utils.insert(
FileNameBlock,
FileIcon,
utils.insert(FileNameModifer, FileName), -- a new table where FileName is a child of FileNameModifier
unpack(FileFlags), -- A small optimisation, since their parent does nothing
{ provider = '%<' } -- this means that the statusline is cut here when there's not enough space
);
local Ruler = {
provider = ' line: %l col: %c',
hl = { fg = 'green', bold = false },
};
local ScrollRuler = {
-- %l = current line number
-- %L = number of lines in the buffer
-- %c = column number
-- %P = percentage through file of displayed window
provider = '%P',
};
local ScrollBar = {
static = {
sbar = { '', '', '', '', '', '', '', '' },
-- sbar = { '🭶', '🭷', '🭸', '🭹', '🭺', '🭻' }
},
provider = function(self)
local curr_line = vim.api.nvim_win_get_cursor(0)[1];
local lines = vim.api.nvim_buf_line_count(0);
local i = math.floor((curr_line - 1) / lines * #self.sbar) + 1;
return string.rep(self.sbar[i], 2);
end,
hl = { fg = 'cyan', bg = 'bright_bg' },
};
local LSPActive = {
condition = conditions.lsp_attached,
update = { 'LspAttach', 'LspDetach' },
provider = function()
local names = {};
for _, server in pairs(vim.lsp.get_clients()) do
table.insert(names, server.name);
end;
return ' [' .. table.concat(names, ' ') .. '] ';
end,
hl = { fg = 'green', bold = false },
};
local spinner_frames = { '', '', '', '', '', '', '', '', '', '' };
-- From https://github.com/mhartington/dotfiles/blob/5961460e3a492f7815259a692fca5ca2a1df924a/config/nvim/lua/mh/statusline/lsp_status.lua#L4
local function get_lsp_progress()
local messages = require('lsp-status/messaging').messages;
local buf_messages = messages();
local msgs = {};
for _, msg in ipairs(buf_messages) do
local contents;
if msg.progress then
contents = msg.title;
if msg.spinner then
contents = spinner_frames[(msg.spinner % #spinner_frames) + 1] .. ' ' .. contents;
end;
elseif msg.status then
contents = msg.content;
if msg.uri then
local space = math.min(60, math.floor(0.6 * vim.fn.winwidth(0)));
local filename = vim.uri_to_fname(msg.uri);
filename = vim.fn.fnamemodify(filename, ':~:.');
if #filename > space then
filename = vim.fn.pathshorten(filename);
end;
contents = '(' .. filename .. ') ' .. contents;
end;
else
contents = msg.content;
end;
table.insert(msgs, contents);
end;
return table.concat(msgs, ' ');
end;
local LSPMessages = {
provider = function()
local progress = get_lsp_progress();
if progress == '' then
return '';
else
return ' ' .. progress;
end;
end,
hl = { fg = 'purple' },
};
local Diagnostics = {
condition = conditions.has_diagnostics,
static = {
error_icon = '',
warn_icon = '',
info_icon = '',
hint_icon = '',
},
init = function(self)
self.errors = #vim.diagnostic.get(0, { severity = vim.diagnostic.severity.ERROR });
self.warnings = #vim.diagnostic.get(0, { severity = vim.diagnostic.severity.WARN });
self.hints = #vim.diagnostic.get(0, { severity = vim.diagnostic.severity.HINT });
self.info = #vim.diagnostic.get(0, { severity = vim.diagnostic.severity.INFO });
end,
update = { 'DiagnosticChanged', 'BufEnter' },
{
provider = function(self)
-- 0 is just another output, we can decide to print it or not!
return self.errors > 0 and (self.error_icon .. self.errors);
end,
hl = { fg = 'diag_error' },
},
{
provider = function(self)
return self.warnings > 0 and (self.warn_icon .. self.warnings);
end,
hl = { fg = 'diag_warn' },
},
{
provider = function(self)
return self.info > 0 and (self.info_icon .. self.info);
end,
hl = { fg = 'diag_info' },
},
{
provider = function(self)
return self.hints > 0 and (self.hint_icon .. self.hints);
end,
hl = { fg = 'diag_hint' },
},
};
local Git = {
condition = conditions.is_git_repo,
init = function(self)
self.status_dict = vim.b.gitsigns_status_dict;
self.has_changes = self.status_dict.added ~= 0 or
self.status_dict.removed ~= 0 or
self.status_dict.changed ~= 0;
end,
hl = { fg = 'orange' },
{ -- git branch name
provider = function(self)
return '' .. self.status_dict.head;
end,
hl = { bold = true },
},
-- You could handle delimiters, icons and counts similar to Diagnostics
{
condition = function(self)
return self.has_changes;
end,
provider = '(',
},
{
provider = function(self)
local count = self.status_dict.added or 0;
return count > 0 and ('+' .. count);
end,
hl = { fg = 'git_add' },
},
{
provider = function(self)
local count = self.status_dict.removed or 0;
return count > 0 and ('-' .. count);
end,
hl = { fg = 'git_del' },
},
{
provider = function(self)
local count = self.status_dict.changed or 0;
return count > 0 and ('~' .. count);
end,
hl = { fg = 'git_change' },
},
{
condition = function(self)
return self.has_changes;
end,
provider = ')',
},
};
local Align = { provider = '%=' };
local Space = { provider = ' ' };
Left = utils.surround({ '', '' }, 'bright_bg', { ViMode, Diagnostics, LSPMessages });
Middle = utils.surround({ '', '' }, 'bright_bg', { LSPActive, FileNameBlock, Ruler });
Right = utils.surround({ '', '' }, 'bright_bg', { Git, Space, ScrollRuler, Space, ScrollBar });
local DefaultStatusline = {
hl = { bg = 'dark_bg' },
condition = function()
return true;
end,
Left,
Align,
Middle,
Align,
Right,
};
local StatusLines = {
hl = function()
if conditions.is_active() then
return 'StatusLine';
else
return 'StatusLineNC';
end;
end,
-- the first statusline with no condition, or which condition returns true is used.
-- think of it as a switch case with breaks to stop fallthrough.
fallthrough = false,
DefaultStatusline,
};
-- Make it global
vim.opt.laststatus = 3;
require('heirline').setup({
statusline = StatusLines,
});

View file

@ -1,63 +0,0 @@
-- 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 = false,
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,
},
});
local function is_neotree_open()
local manager = require('neo-tree.sources.manager');
local renderer = require('neo-tree.ui.renderer');
local state = manager.get_state('filesystem');
return renderer.window_exists(state);
end;
-- Auto open Neo-Tree on big enough window
vim.api.nvim_create_autocmd({ 'VimEnter', 'VimResized' }, {
pattern = '*',
callback = function()
if vim.api.nvim_eval([[&columns]]) > 100 then
if is_neotree_open() == false then
vim.cmd[[Neotree show]];
vim.cmd[[Neotree close]];
vim.cmd[[Neotree show]];
end;
else
if is_neotree_open() then
vim.cmd[[Neotree close]];
end;
end;
end,
});

View file

@ -1,179 +0,0 @@
{
config,
pkgs,
lib,
nvim-theme-src,
...
}: let
inherit (lib) fileContents optionals;
inherit (config.vars) neovimIde;
in {
programs = {
neovim = {
extraPackages = builtins.attrValues {
inherit (pkgs) bat;
};
plugins =
[
{
plugin = pkgs.vimPlugins.dracula-nvim.overrideAttrs {
src = nvim-theme-src;
};
type = "lua";
config =
# lua
''
-- set dot icon in place of trailing whitespaces
vim.opt.listchars = {
tab = ' ',
trail = '',
extends = '',
precedes = '',
nbsp = '',
};
vim.opt.list = true;
-- Add visual indicator for trailing whitespaces
vim.opt.fillchars = { eob = " " };
vim.fn.matchadd('errorMsg', [[\s\+$]]);
vim.cmd.colorscheme('dracula');
'';
}
{
plugin = pkgs.vimPlugins.indent-blankline-nvim;
type = "lua";
config =
# lua
''
--
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 = "",
},
});
'';
}
{
plugin = pkgs.vimPlugins.nvim-highlight-colors;
type = "lua";
config =
# lua
''
-- Ensure termguicolors is enabled if not already
vim.opt.termguicolors = true;
require('nvim-highlight-colors').setup({});
'';
}
# Deps of heirline config
pkgs.vimPlugins.nvim-web-devicons
{
plugin = pkgs.vimPlugins.heirline-nvim;
type = "lua";
config = fileContents ./plugins/heirline.lua;
}
]
++ optionals neovimIde [
{
plugin = pkgs.vimPlugins.neo-tree-nvim;
type = "lua";
config = fileContents ./plugins/neotree.lua;
}
{
plugin = pkgs.vimPlugins.codewindow-nvim;
type = "lua";
config =
# lua
''
--
local codewindow = require('codewindow');
codewindow.setup({
auto_enable = false,
minimap_width = 8,
relative = 'editor',
window_border = 'none',
exclude_filetypes = { 'help' },
});
vim.api.nvim_create_autocmd({ 'VimEnter', 'VimResized' }, {
pattern = '*',
callback = function()
if vim.api.nvim_win_get_width(0) < 88 then
codewindow.close_minimap();
else
codewindow.open_minimap();
end
end,
});
'';
}
{
plugin = pkgs.vimPlugins.transparent-nvim;
type = "lua";
config =
# lua
''
require('transparent').setup({
groups = {
'Normal',
'NormalNC',
'Comment',
'Constant',
'Special',
'Identifier',
'Statement',
'PreProc',
'Type',
'Underlined',
'Todo',
'String',
'Function',
'Conditional',
'Repeat',
'Operator',
'Structure',
'LineNr',
'NonText',
'SignColumn',
'CursorLine',
'CursorLineNr',
'StatusLine',
'StatusLineNC',
'EndOfBuffer',
},
extra_groups = {},
exclude_groups = {},
});
'';
}
];
};
};
}

View file

@ -1,34 +0,0 @@
{pkgs, ...}: {
programs.neovim.plugins = [
{
plugin = pkgs.vimPlugins.nvim-treesitter-context;
type = "lua";
config =
# lua
''
require('treesitter-context').setup({
enable = true,
max_lines = 3,
min_window_height = 20,
});
vim.cmd.hi('TreesitterContextBottom', 'gui=underline guisp=Grey');
'';
}
pkgs.vimPlugins.nvim-treesitter-textobjects
{
plugin = pkgs.vimPlugins.nvim-treesitter.withAllGrammars;
type = "lua";
config =
# lua
''
require('nvim-treesitter.configs').setup({
highlight = { enable = true },
indent = { enable = true },
});
'';
}
];
}

View file

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

View file

@ -1,31 +0,0 @@
{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 = builtins.attrValues {
inherit (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

@ -1,9 +0,0 @@
{
pkgs,
self,
...
}: {
home.packages = [self.packages.${pkgs.system}.trash-d];
programs.bash.shellAliases.rm = "trash";
}

View file

@ -1,46 +0,0 @@
{
config,
lib,
pkgs,
...
}: let
inherit (lib) foldl isList mergeAttrsWithFunc optionals unique;
mergeAttrsList = list:
foldl (mergeAttrsWithFunc (a: b:
if isList a && isList b
then unique (a ++ b)
else b)) {}
list;
in {
environment.systemPackages = [
(pkgs.writeShellApplication {
name = "rebuild-no-cache";
runtimeInputs = [config.programs.nh.package];
text = ''
nh os switch -- --option binary-caches "https://cache.nixos.org" "$@"
'';
})
];
nix = {
settings = let
mkSubstituterConf = url: key: {
substituters = [url];
trusted-public-keys = optionals (key != null) [key];
};
in
mergeAttrsList ([
(mkSubstituterConf "https://cache.nixos.org" "cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY=")
(mkSubstituterConf "https://hyprland.cachix.org" "hyprland.cachix.org-1:a7pgxzMz7+chwVL3/pzj6jIBMioiJM7ypFP8PwtkuGc=")
(mkSubstituterConf "https://nix-gaming.cachix.org" "nix-gaming.cachix.org-1:nbjlureqMbRAxR1gJ/f3hxemL9svXaZF/Ees8vCUUs4=")
(mkSubstituterConf "https://nixpkgs-wayland.cachix.org" "nixpkgs-wayland.cachix.org-1:3lwxaILxMRkVhehr5StQprHdEo4IrE8sRho9R9HOLYA=")
(mkSubstituterConf "https://nix-community.cachix.org" "nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs=")
(mkSubstituterConf "https://viperml.cachix.org" "viperml.cachix.org-1:qZhKBMTfmcLL+OG6fj/hzsMEedgKvZVFRRAhq7j8Vh8=")
(mkSubstituterConf "https://cuda-maintainers.cachix.org" "cuda-maintainers.cachix.org-1:0dq3bujKpuEPMCX6U4WylrUDZ9JyUG0VpVZa7CNfq5E=")
]
++ optionals (!config.services.nix-serve.enable) [
(mkSubstituterConf "https://cache.nelim.org" "cache.nelim.org:JmFqkUdH11EA9EZOFAGVHuRYp7EbsdJDHvTQzG2pPyY=")
]);
};
}

View file

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

View file

@ -1,23 +0,0 @@
{
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;
}

View file

@ -1,45 +0,0 @@
{pkgs, ...}: {
fonts = {
fontconfig = {
enable = true;
defaultFonts = {
emoji = ["Noto Color Emoji"];
monospace = ["JetBrainsMono Nerd Font"];
sansSerif = ["Noto Nerd Font"];
serif = ["Noto Nerd Font"];
};
};
packages =
[
(pkgs.nerdfonts.override {
fonts = [
"JetBrainsMono"
"Go-Mono"
"Iosevka"
"NerdFontsSymbolsOnly"
"SpaceMono"
"Ubuntu"
"Noto"
];
})
]
++ (builtins.attrValues {
inherit
(pkgs)
noto-fonts
noto-fonts-cjk-sans
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;
}

View file

@ -1,79 +0,0 @@
{
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,77 +0,0 @@
{
config,
lib,
...
}: {
imports = [
./vars
./modules/global.nix
./packages.nix
];
nix = {
# Edit nix.conf
extraOptions = ''
experimental-features = nix-command flakes
keep-outputs = true
keep-derivations = true
warn-dirty = false
'';
substituters = [
# Nix-community
"https://nix-community.cachix.org"
];
trustedPublicKeys = [
# Nix-community
"nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs="
];
};
# Global hm settings
home-manager.config = {
imports = [
# Make the vars be the same on Nix and HM
{
options.vars = lib.mkOption {
type = lib.types.attrs;
readOnly = true;
default = config.vars;
};
}
./home
{
programs.bash.sessionVariables = {
FLAKE = config.environment.variables.FLAKE;
};
programs.bash.shellAliases = {
# Make ping work on nix-on-droid
# https://github.com/nix-community/nix-on-droid/issues/185#issuecomment-1659294700
ping = "/android/system/bin/linker64 /android/system/bin/ping";
# SSH
# Desktop
pc = "ssh -t matt@100.64.0.6 'tmux -2u new -At phone'";
# NAS
nos = "ssh -t matt@100.64.0.4 'tmux -2u new -At phone'";
# 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'";
};
}
];
home.stateVersion = "23.05";
};
}

View file

@ -1,116 +0,0 @@
inputs @ {
pkgs,
self,
...
}: {
nixpkgs.overlays =
(map (i: inputs.${i}.overlays.default) [
"discord-overlay"
"grim-hyprland"
"nixpkgs-wayland"
])
++ (builtins.attrValues {
inherit
(self.overlays)
xdg-desktop-portal-kde
;
});
environment.systemPackages =
(builtins.attrValues {
inherit
(self.packages.${pkgs.system})
pokemon-colorscripts
repl
;
inherit
(pkgs.nodePackages)
undollar
;
inherit (pkgs) alejandra;
# Archiving
inherit
(pkgs)
zip
unzip
p7zip
bzip2
gzip
gnutar
xz
;
# File management
inherit
(pkgs)
findutils
diffutils
util-linux
which
imagemagick
;
# Networking
inherit (pkgs.dig) dnsutils;
inherit
(pkgs)
arp-scan
openssh
rsync
wget
gnupg
;
# Misc CLI stuff
inherit
(pkgs)
hydra-check
killall
nix-output-monitor
nix-melt
progress
tree
gnugrep
gnused
;
# Expected Stuff
inherit
(pkgs)
hostname
man
perl
tzdata
;
})
++ [
# This could help as well: nix derivation show -r /run/current-system
(pkgs.writeShellApplication {
name = "listDerivs";
text = ''
exec nix-store --query --requisites /run/current-system | cut -d- -f2- | sort -u
'';
})
(pkgs.writeShellApplication {
name = "from";
runtimeInputs = builtins.attrValues {
inherit
(pkgs)
coreutils
which
;
};
text = ''
for var do
realpath "$(which "$var")"
done
'';
})
];
}

View file

@ -1,68 +0,0 @@
{
config,
lib,
...
}: let
inherit (lib) mkDefault 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 (import ./prompt-schemes.nix {});
default = "purple";
};
promptColors = mkOption {
description = ''
Colors used in starship prompt
'';
default = import ./prompt-schemes.nix {color = cfg.promptMainColor;};
readOnly = true;
type = types.submodule {
options = let
inherit (types) str;
in {
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
'';
};
neovimIde = mkOption {
type = types.bool;
default = true;
};
};
config = {
environment.variables.FLAKE = mkDefault "/home/${cfg.mainUser}/.nix";
};
}

View file

@ -1,81 +0,0 @@
{color ? null}: let
inherit (builtins) attrNames removeAttrs;
schemes = {
"purple" = {
textColor = "#090c0c";
firstColor = "#bd93f9";
secondColor = "#715895";
thirdColor = "#382c4a";
fourthColor = "#120e18";
};
"green" = {
textColor = "#090c0c";
firstColor = "#78ae66";
secondColor = "#567c49";
thirdColor = "#334a2c";
fourthColor = "#11180e";
};
"red" = {
textColor = "#090c0c";
firstColor = "#e04242";
secondColor = "#9c2e2e";
thirdColor = "#591a1a";
fourthColor = "#160606";
};
"blue" = {
textColor = "#090c0c";
firstColor = "#6684ee";
secondColor = "#475ca6";
thirdColor = "#28345f";
fourthColor = "#010617";
};
"orange" = {
textColor = "#090c0c";
firstColor = "#ff9c42";
secondColor = "#c66b00";
thirdColor = "#874500";
fourthColor = "#3a1c00";
};
"yellow" = {
textColor = "#090c0c";
firstColor = "#ffea42";
secondColor = "#d4c300";
thirdColor = "#8f8b00";
fourthColor = "#3e3c00";
};
"cyan" = {
textColor = "#090c0c";
firstColor = "#42eaff";
secondColor = "#00a2b8";
thirdColor = "#005768";
fourthColor = "#001f26";
};
"pink" = {
textColor = "#090c0c";
firstColor = "#ff42cb";
secondColor = "#b80073";
thirdColor = "#6b003f";
fourthColor = "#2d0017";
};
# Template
"color" = {
textColor = "#090c0c";
firstColor = "";
secondColor = "";
thirdColor = "";
fourthColor = "";
};
};
in
if ! isNull color
then schemes.${color}
else attrNames (removeAttrs schemes ["color"])

1
config/eww/README.md Normal file
View file

@ -0,0 +1 @@
inspired from: https://github.com/AlphaTechnolog/dotfiles/tree/openbox

View file

@ -0,0 +1 @@
always open this widget last

View file

@ -0,0 +1,60 @@
(defwidget closer []
(eventbox :onclick "$EWW_PATH/close-opened.sh && eww close closer")
)
(defwindow closer :monitor 0
:geometry (geometry :width "100%"
:height "100%")
:stacking "overlay"
:focusable false
(closer :window "")
)
(defwidget closer-notif []
(eventbox :onclick "$EWW_PATH/notif-toggle.sh off")
)
(defwindow closer-notif1 :monitor 0
:geometry (geometry :width "1360px"
:height "1200px")
:stacking "overlay"
:focusable false
:exclusive "ignore"
(closer-notif)
)
(defwindow closer-notif2 :monitor 0
:geometry (geometry :width "100%"
:height "200px"
:y "1060px")
:stacking "overlay"
:focusable false
:exclusive "ignore"
(closer-notif)
)
(defwindow closer-notif3 :monitor 0
:geometry (geometry :width "100%"
:height "60px")
:stacking "overlay"
:focusable false
:exclusive "ignore"
(closer-notif)
)
(defwindow closer-notif4 :monitor 0
:geometry (geometry :width "60px"
:height "100%"
:x "1860px")
:stacking "overlay"
:focusable false
:exclusive "ignore"
(closer-notif)
)
(defwidget on-release-fix []
(eventbox :onclick "eww close on-release-fix")
)
(defwindow on-release-fix :monitor 0
:geometry (geometry :width "100%"
:height "100%"
)
:stacking "overlay"
:exclusive "ignore"
(on-release-fix)
)

32
config/eww/colors.scss Normal file
View file

@ -0,0 +1,32 @@
$darkbg: #0b0d16;
$bg: rgba(40, 42, 54, 0.8); //rgba(69, 71, 90, 0.3); #0d0f18;
$bgfull: rgb(40, 42, 54);
$contrastbg: rgba(189, 147, 249, 0.8);
$bgSecondary: #11131c;
$bgSecondaryAlt: #a5b6cf;
$fg: #a5b6cf;
$fgDim: #a5b6cf;
$watermelon: #dd6777;
// Aliases
$background: $bg;
$backgroundSecondary: $bgSecondary;
$backgroundSecondaryAlt: $bgSecondaryAlt;
$foreground: $fg;
$foregroundDim: $fgDim;
$black: #151720;
$dimblack: #1a1c25;
$lightblack: #262831;
$red: #dd6777;
$blue: #86aaec;
$cyan: #93cee9;
$blue-desaturated: #93cee9;
$magenta: #c296eb;
$purple: #c296eb;
$green: #90ceaa;
$aquamarine: #90ceaa;
$yellow: #ecd3a0;
$accent: $blue;
$javacafeMagenta: #c296eb;
$javacafeBlue: #86aaec;

75
config/eww/date/date.scss Normal file
View file

@ -0,0 +1,75 @@
.date {
background-color: $bg;
color: $fg;
border-radius: 30px;
border: 2px solid $contrastbg;
}
.timebox {
margin: 30px 0px;
.time-container {
.content {
font-family: Product Sans;
font-weight: bolder;
font-size: 60px;
}
.divider {
margin: 8px 15px;
padding: 0px 1px;
background: linear-gradient($red, $magenta, $blue, $cyan);
}
}
.date-container {
font-family: Product Sans;
margin-top: 2px;
}
}
.cal-box {
font-family: Product Sans;
background-color: $bg;
border-radius: 30px;
padding: 0 1rem .2rem;
color: $fg;
background-color: $bgfull;
border-bottom: 2px solid $contrastbg;
border-top: 2px solid $contrastbg;
margin: 0px 12px 18px 12px;
.cal {
background-color: inherit;
padding: .5rem .10rem 0rem;
margin-left: 10px;
border-radius: 30px;
& > * {
border: solid 0px transparent;
}
&.highlight {
padding: 10rem;
}
}
}
calendar:selected {
color: $cyan;
}
calendar.header {
color: $cyan;
font-weight: bold;
}
calendar.button {
color: $cyan;
}
calendar.highlight {
color: $green;
font-weight: bold;
}
calendar:indeterminate {
color: $lightblack;
}

63
config/eww/date/date.yuck Normal file
View file

@ -0,0 +1,63 @@
(defwidget divider []
(box :class "divider"
:orientation "v"
:space-evenly true)
)
(defwidget time []
(box :class "timebox"
:orientation "v"
:space-evenly false
(box :class "time-container"
:orientation "h"
:space-evenly false
:halign "center"
:valign "center"
(label :text "${lithour}" :class "content")
(divider)
(label :text "${litmin}" :class "content")
)
(box :class "date-container"
:orientation "h"
:space-evenly true
:halign "center"
(label :text "${completeday}")
)
)
)
(defwidget cal []
(box :class "cal-box"
:orientation "v"
:space-evenly false
(calendar :class "cal"
:day calendar_day
:month calendar_month
:year calendar_year)
)
)
(defwidget date []
(box :class "date"
:orientation "v"
:space-evenly false
(time)
(cal)
)
)
(defvar date-visible false)
(defwindow date-reveal
:monitor 0
:stacking "overlay"
:geometry (geometry :x "70px"
:y "8px"
:width "0px" ; automatically generated
:height "0px" ; automatically generated
:anchor "top right")
(revealer
:transition "crossfade"
:reveal date-visible
:duration anim_duration
(date)))

10
config/eww/eww.scss Normal file
View file

@ -0,0 +1,10 @@
* {
all: unset;
}
@import "colors.scss";
@import "date/date.scss";
@import "powermenu/powermenu.scss";
@import "playerinfo/playerinfo.scss";
@import "quick-settings/quick-settings.scss";
@import "traybuttons/traybuttons.scss";

7
config/eww/eww.yuck Normal file
View file

@ -0,0 +1,7 @@
(include "variables.yuck")
(include "date/date.yuck")
(include "powermenu/powermenu.yuck")
(include "playerinfo/playerinfo.yuck")
(include "closer/closer.yuck")
(include "quick-settings/quick-settings.yuck")
(include "traybuttons/traybuttons.yuck")

View file

@ -0,0 +1,90 @@
.playerinfo {
padding: 10px;
min-width: 400px;
border-radius: 30px;
border-top: 2px solid $contrastbg;
border-bottom: 2px solid $contrastbg;
transition: background 250ms;
.top {
font-size: 23px;
}
.metadata {
.title{
font-weight: 500;
transition: text 250ms;
}
.artist{
font-weight: 400;
font-size: 15px;
transition: text 250ms;
}
}
.bottom {
font-size: 30px;
}
.pausebutton {
transition: background 250ms;
padding: 14px 16px;
font-size: 15px;
}
.playing {
transition: all ease .2s;
border-radius: 15px;
label {
padding-left: 4px;
}
}
.paused {
border-radius: 26px;
transition: all ease .2s;
padding: 14px 14px 14px 18px;
}
}
.previousbutton,
.nextbutton,
.shuffle,
.repeat {
border-radius: 100%;
transition: background-color 200ms;
&:hover {
border-radius: 100%;
background-color: rgba(127, 132, 156, 0.4);
transition: background-color 200ms;
}
}
.repeat {
label {
padding-right: 8px;
}
}
.song-pos {
scale {
highlight {
margin: 0px;
border-radius: 2em;
}
trough {
background-color: #363847;
border-radius: 2em;
}
slider {
margin: -8px;
min-height: 20px;
border-radius: 10px;
box-shadow: rgba(0, 0, 0, 0.25) 0px 54px 55px, rgba(0, 0, 0, 0.12) 0px -12px 30px, rgba(0, 0, 0, 0.12) 0px 4px 6px, rgba(0, 0, 0, 0.17) 0px 12px 13px, rgba(0, 0, 0, 0.09) 0px -3px 5px;
transition: background-color 0.5s ease-in-out;
}
slider:hover {
background-color: #303240;
transition: background-color 0.5s ease-in-out;
}
}
}

View file

@ -0,0 +1,124 @@
(defpoll player :interval "1s" "echo Spot")
(defpoll music_cover :interval "1s" "$EWW_PATH/music.sh cover") ;done
(defvar music_accent "rgb(0,0,0)") ;done
(defvar button_accent "rgb(0,0,0)") ;done
(defvar button_text "rgb(255,255,255)") ;done
(defpoll music_status :interval "1s" "playerctl -p Spot status")
(defpoll title :interval "1s" "playerctl -p Spot metadata title")
(defpoll artist :interval "1s" "playerctl -p Spot metadata artist")
(defvar button_height "42")
(defpoll shuffle_status :interval "1s" "playerctl -p Spot shuffle")
(defpoll repeat_icon :interval "1s" "$EWW_PATH/music.sh loop_status")
(defvar song_pos "0")
(defpoll song_length :interval "1s" "$EWW_PATH/music.sh length")
(defvar get_pos "true")
(defwidget playerinfo []
(centerbox :class "playerinfo"
:style "background: radial-gradient(circle, rgba(0, 0, 0, 0.4) 30%, ${music_accent}), url(\"${music_cover}\");
background-size: cover;
background-position: center;"
:orientation "v"
(box :class "top"
:halign "start"
:valign "start"
:style "color: ${button_accent};"
"${player == 'Spot' ? '' : '爵' }"
)
(box :class "center"
:orientation "h"
:space-evenly false
(box :class "metadata"
:orientation "v"
:halign "start"
:valign "center"
:hexpand true
(label :limit-width 25 :halign "start" :text title :class "title")
(label :limit-width 25 :halign "start" :text artist :class "artist")
)
(centerbox :orientation "v"
(label)
(eventbox :class "pausebutton ${music_status == 'Playing' ? 'playing' : 'paused'}"
:halign "left"
:style "background-color: ${button_accent};
color: ${button_text};"
:onclick "playerctl -p Spot play-pause"
:cursor "pointer"
:onhover "eww update button_height=41"
:onhoverlost "eww update button_height=42"
(label :text "${music_status == 'Playing' ? ' ' : ''}"
:width button_height
:height button_height
)
)
(label)
)
)
(box :class "bottom"
:style "color: ${button_accent};"
:space-evenly false
:spacing 0
(eventbox :valign "end"
:halign "start"
:onclick "playerctl -p Spot previous & $EWW_PATH/music.sh cover"
:class "previousbutton"
:width 40
:cursor "pointer"
"󰒮"
)
(eventbox :cursor "pointer"
:class "song-pos"
:hexpand true
:onhover "eww update get_pos=false"
:onhoverlost "eww update get_pos=true"
(scale :value song_pos
:min 0
:max song_length
:orientation "h"
:onchange "playerctl -p Spot position {}"
:css "highlight { background-color: ${button_accent}; }
slider { background-color: ${button_accent}; }
trough { background-color: rgba(${button_accent}, 0.4); }"
)
)
(box :valign "end"
:halign "end"
(eventbox :onclick "playerctl -p Spot next & $EWW_PATH/music.sh cover"
:class "nextbutton"
:width 40
:cursor "pointer"
"󰒭"
)
(eventbox :onclick "playerctl -p Spot shuffle toggle"
:class "shuffle"
:width 40
:cursor "pointer"
"${shuffle_status == 'On' ? '󰒝' : '󰒞'}"
)
(eventbox :onclick "$EWW_PATH/music.sh loop"
:class "repeat"
:width 40
:cursor "pointer"
"${repeat_icon}"
)
)
)
)
)
(defwindow playerinfo
:monitor 0
:stacking "overlay"
:exclusive "ignore"
:focusable "false"
:geometry (geometry :x "800px"
:y "10px"
:width "0px"
:height "0px"
:anchor "top left"
)
(playerinfo)
)

View file

@ -0,0 +1,28 @@
.powermenu {
background-color: $bg;
color: $fg;
padding: 20px;
font-family: MesloLGS NF;
/*font-family: Iosevka Nerd Font;*/
font-size: 70px;
border-radius: 30px;
border: 2px solid $contrastbg;
button {
border-radius: 12px;
min-width: 80px;
transition: all ease .2s;
&:hover { background-color: $bgSecondary; }
&:active { background-color: $bgSecondary; }
.content {
border-radius: 4px;
padding: 0px 15px 0px 15px;
}
}
.shutdown { color: $red; }
.reboot { color: $magenta; }
.logout { color: $yellow; }
}
.powermenu-clickhandler {
background-color: black;
}

View file

@ -0,0 +1,55 @@
(defwidget powermenu []
(box :class "powermenu"
:orientation "h"
:space-evenly true
:spacing 20
(button :class "shutdown"
:onclick "systemctl poweroff"
(label :text "襤" :class "content")
)
(button :class "reboot"
:onclick "systemctl reboot"
(label :text "勒" :class "content")
)
(button :class "logout"
:onclick "hyprctl dispatch exit"
(label :text "" :class "content")
)
)
)
(defwidget powermenu-clickhandler []
(button :class "powermenu-clickhandler"
:onclick "eww close powermenu powermenu-clickhandler"
""
)
)
(defwindow powermenu-clickhandler
:monitor 0
:geometry (geometry :x "0px"
:y "0px"
:width "100%"
:height "100%"
:anchor "center")
:wm-ignore true
(powermenu-clickhandler)
)
(defvar powermenu-visible false)
(defwindow powermenu-reveal
:monitor 0
:stacking "overlay"
:geometry (geometry :x "0px"
:y "0px"
:width "500px"
:height "150px"
:anchor "center")
(revealer
:transition "crossfade"
:reveal powermenu-visible
:duration anim_duration
(powermenu)
)
)

View file

@ -0,0 +1,190 @@
.quick-settings-smol {
font-size: 2px;
min-height: 52px;
min-width: 36px;
padding: 0px 0px 0px 0px;
background-color: $bg;
color: rgba(0,0,0,0);
border: 2px solid $contrastbg;
border-bottom: none;
border-top-right-radius: 80px;
border-top-left-radius: 80px;
border-bottom-left-radius: 0px;
border-bottom-right-radius: 0px;
}
.quick-settings-logo {
font-size: 24px;
min-height: 36px;
min-width: 36px;
padding: 0px 0px 0px 0px;
background-color: rgba(0,0,0,0);
color: #CBA6F7;
border-radius: 80px;
border: 2px solid rgba(0,0,0,0);
transition: background-color 0.5s ease-in-out;
}
.quick-settings-logo:hover, .quick-settings-logo:active {
background-color: rgba(127, 132, 156, 0.4);
transition: background-color 0.5s ease-in-out;
}
.quick-settings {
font-size: 30px;
min-width: 500px;
padding: 0px 0px 0px 0px;
background-color: $bg;
border-top-right-radius: 0px;
border-top-left-radius: 30px;
border-bottom-left-radius: 30px;
border-bottom-right-radius: 30px;
border: 2px solid $contrastbg;
}
.title {
font-size: 22px;
margin-top: 30px;
}
.grid-label {
font-size: 30px;
margin-left: 15px;
margin-right: 10px;
min-width: 50px;
}
.sub-label {
font-size: 14px;
margin-top: -10px;
margin-left: 0px;
margin-bottom: 10px;
padding: 3px;
border: 2px solid $contrastbg;
border-top-right-radius: 20px;
border-top-left-radius: 10px;
border-bottom-left-radius: 10px;
border-bottom-right-radius: 20px;
min-width: 106px;
background: #1b1b1b;
}
.grid-chev {
margin-left: 0px;
font-size: 40px;
margin-right: 5px;
}
.button-grid {
font-size: 10px;
min-height: 160px;
min-width: 470px;
background-color: $bgfull;
border-top: 2px solid $contrastbg;
border-bottom: 2px solid $contrastbg;
border-radius: 15px;
margin-top: 30px;
}
.button-row {
min-height: 70px;
min-width: 450px;
margin-left: 20px;
}
.grid-button {
min-height: 65px;
min-width: 70px;
margin: 5px;
}
.left-part {
background: #1b1b1b;
border-top-left-radius: 15px;
border-bottom-left-radius: 15px;
border-left: 2px solid $contrastbg;
border-top: 2px solid $contrastbg;
border-bottom: 2px solid $contrastbg;
transition: all 0.5s ease-in-out;
}
.right-part {
background: #1b1b1b;
border-top-right-radius: 30px;
border-bottom-right-radius: 30px;
border-right: 2px solid $contrastbg;
border-top: 2px solid $contrastbg;
border-bottom: 2px solid $contrastbg;
transition: all 0.5s ease-in-out;
}
.right-part:hover, .right-part:active {
color: $contrastbg;
border: 2px solid $contrastbg;
border-top-left-radius: 7px;
border-bottom-left-radius: 7px;
transition: all 0.5s ease-in-out;
}
.left-part:hover, .left-part:active {
color: $contrastbg;
border: 2px solid $contrastbg;
border-top-right-radius: 7px;
border-bottom-right-radius: 7px;
transition: all 0.5s ease-in-out;
}
.player {
margin-top: 6px;
min-height: 220px;
opacity: 0;
}
.slider-box {
min-height: 100px;
min-width: 470px;
background-color: $bgfull;
border-top: 2px solid $contrastbg;
border-bottom: 2px solid $contrastbg;
border-radius: 15px;
margin-top: 30px;
margin-bottom: 20px;
.slider-label {
font-size: 30px;
min-width: 30px;
}
scale {
min-height: 55px;
min-width: 400px;
margin-left: 18px;
margin-right: 20px;
highlight {
margin: 0px;
background-color: #79659f;
border-radius: 2em;
}
trough {
background-color: #363847;
border-radius: 2em;
}
slider {
margin: -4px;
min-width: 20px;
min-height: 20px;
background: #3e4153;
border-radius: 100%;
box-shadow: rgba(0, 0, 0, 0.25) 0px 54px 55px, rgba(0, 0, 0, 0.12) 0px -12px 30px, rgba(0, 0, 0, 0.12) 0px 4px 6px, rgba(0, 0, 0, 0.17) 0px 12px 13px, rgba(0, 0, 0, 0.09) 0px -3px 5px;
transition: background-color 0.5s ease-in-out;
}
slider:hover {
background-color: #303240;
transition: background-color 0.5s ease-in-out;
}
}
}

View file

@ -0,0 +1,360 @@
(defvar showqs false)
(defvar showplayer false)
(defwidget quick-settings-smol []
(box :class "quick-settings-smol"
:orientation "h"
(label :text "  ")
)
)
(defwindow quick-settings-smol-reveal
:monitor 0
:stacking "overlay"
:exclusive "ignore"
:geometry (geometry :x "5px"
:y "10px"
:width "0px"
:height "0px"
:anchor "top right"
)
(revealer
:transition "crossfade"
:reveal showqs
:duration anim_duration
(quick-settings-smol)
)
)
(defvar qs-run-off "false")
(defwidget quick-settings-logo []
(eventbox :class "quick-settings-logo"
:onclick "$EWW_PATH/run.sh '$EWW_PATH/qs-toggle.sh off' qs-run-off &"
:cursor "pointer"
:onhover "eww update qs-run-off=true"
:onhoverlost "eww update qs-run-off=false"
(box :class "quick-settings-logo"
:orientation "h"
(label :text "  ")
)
)
)
(defwindow quick-settings-logo-reveal
:monitor 0
:stacking "overlay"
:exclusive "ignore"
:geometry (geometry :x "5px"
:y "10px"
:width "0px"
:height "0px"
:anchor "top right"
)
(revealer
:transition "crossfade"
:reveal showqs
:duration anim_duration
(quick-settings-logo)
)
)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defvar expand_player "false")
(defwidget quick-settings []
(box :orientation "v"
:space-evenly false
(box :class "quick-settings"
:orientation "v"
:space-evenly false
(label :text "Control Center"
:class "title"
:xalign 0.04
)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Button Grid
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(box :class "button-grid"
:orientation "v"
:valign "start"
:width 0
:height 0
:halign "center"
:space-evenly false
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Row ONE
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(box :class "button-row"
:orientation "h"
:space-evenly true
:width 0
:height 0
:halign "center"
:style "margin-top: 15px;
margin-bottom: 7px"
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(box :class "grid-button"
:orientation "h"
:space-evenly false
:width 0
:height 0
(eventbox :class "left-part"
:cursor "pointer"
:onclick "$EWW_PATH/network.sh toggle"
(label :text " ${network_icon} "
:class "grid-label"
)
)
(eventbox :class "right-part"
:cursor "pointer"
:onclick "nm-connection-editor &"
(label :text " " :class "grid-chev")
)
)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(box :class "grid-button"
:orientation "h"
:space-evenly false
:width 0
:height 0
(eventbox :class "left-part"
:cursor "pointer"
:onclick "$EWW_PATH/bluetooth.sh toggle"
(label :text " ${bluetooth_icon} "
:class "grid-label"
)
)
(eventbox :class "right-part"
:cursor "pointer"
:onclick "blueberry &"
(label :text " " :class "grid-chev")
)
)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(box :class "grid-button"
:orientation "h"
:space-evenly false
:width 0
:height 0
(eventbox :class "left-part"
:cursor "pointer"
:onclick "$EWW_PATH/network.sh toggle-radio"
(label :text "${network_radio == 'on' ? '󰀝 ' : '󱡻 '}"
:class "grid-label"
)
)
(eventbox :class "right-part"
:cursor "pointer"
:onclick "notify-send 'set this up moron'"
(label :text " "
:class "grid-chev"
)
)
)
)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; SUB ROW
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(box :orientation "h"
:space-evenly true
:spacing 34
:width 0
:height 0
:halign "center"
(label :text "${network_ssid}"
:class "sub-label"
:width 0
:height 0
:xalign 0.4
:limit-width 12
)
(label :text "${bluetooth_dev}"
:class "sub-label"
:width 0
:height 0
:xalign 0.4
:limit-width 12
)
(label :text ""
:class ""
:width 0
:height 0
:xalign 0.4
:limit-width 12
)
)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Row TWO
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(box :class "button-row"
:orientation "h"
:space-evenly true
:width 0
:height 0
:halign "center"
:style "margin-top: 7px;
margin-bottom: 15px;"
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(box :class "grid-button"
:orientation "h"
:space-evenly false
:width 0
:height 0
(eventbox :class "left-part"
:cursor "pointer"
:onclick "swayosd --output-volume mute-toggle"
(label :text " ${volume_icon} "
:class "grid-label"
)
)
(eventbox :class "right-part"
:cursor "pointer"
:onclick "pavucontrol &"
(label :text " " :class "grid-chev")
)
)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(box :class "grid-button"
:orientation "h"
:space-evenly false
:width 0
:height 0
(eventbox :class "left-part"
:cursor "pointer"
:onclick "$EWW_PATH/mic.sh toggle-muted"
(label :text " ${mic_icon} "
:class "grid-label"
)
)
(eventbox :class "right-part"
:cursor "pointer"
:onclick "pavucontrol &"
(label :text " " :class "grid-chev")
)
)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(box :class "grid-button"
:orientation "h"
:space-evenly false
:width 0
:height 0
(eventbox :class "left-part"
:cursor "pointer"
:onclick "$LOCK_PATH/lock.sh &"
(label :text " 󰌾 "
:class "grid-label"
)
)
(eventbox :class "right-part"
:cursor "pointer"
:onclick "$EWW_PATH/open.sh powermenu"
(label :text " " :class "grid-chev")
)
)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
)
)
(box :class "slider-box"
:orientation "v"
:space-evenly true
:spacing 0
:width 0
:height 0
:halign "center"
(box :class "slider"
:orientation "h"
:valign "start"
:halign "center"
:width 0
:height 0
:space-evenly false
(label :text "${volume_icon}" :class "slider-label")
(scale :value volume_value
:onchange "$EWW_PATH/volume.sh set {}"
:min 0
:max 101
:height 0
:width 0
)
)
(box :class "slider"
:orientation "h"
:valign "start"
:halign "center"
:width 0
:height 0
:space-evenly false
(label :text " ${br_icon} " :class "slider-label" :style "margin-left: 6px;
margin-right: -6px")
(scale :value br
:onchange "$EWW_PATH/brightness.sh set {}"
:min 0
:max 256
:height 0
:width 0
)
)
)
(centerbox :orientation "h"
:style "margin-bottom: 10px;"
(label)
(revealer :reveal showplayer
(eventbox :cursor "pointer"
:onclick "${expand_player == 'true' ? 'eww update expand_player=false' : 'eww update expand_player=true'}"
"${expand_player == 'true' ? ' ' : ' ' }"
)
)
(label)
)
)
(revealer :reveal expand_player
:transition "slidedown"
(box :class "player"
:style "${expand_player == 'true' ? 'opacity: 1; transition: opacity ${anim_duration}' :
'opacity: 0; transition: opacity ${anim_duration}'}"
(playerinfo)
)
)
)
)
(defwindow quick-settings-reveal
:monitor 0
:stacking "overlay"
:geometry (geometry :x "5px"
:y "7px"
:width "0px"
:height "0px"
:anchor "top right"
)
(revealer
:transition "crossfade"
:reveal showqs
:duration anim_duration
(quick-settings)
)
)

35
config/eww/scripts/bluetooth.sh Executable file
View file

@ -0,0 +1,35 @@
#!/usr/bin/env bash
FILE="$HOME/.config/.bluetooth"
get_device() {
if [[ $(bluetoothctl devices Connected) != "" ]]; then
bluetoothctl devices Connected | awk '{ for (i = 3; i <= NF; i++) { printf("%s ", $i) } printf("\n") }'
else
echo "Disconnected"
fi
}
get_state() {
if [[ "$(rfkill list | grep -A 1 hci0 | grep -o no)" == "no" ]]; then
eww update bluetooth_icon=" 󰂯 "
echo " 󰂯 " > "$FILE"
else
eww update bluetooth_icon=" 󰂲 "
echo " 󰂲 " > "$FILE"
fi
}
[[ "$1" == "device" ]] && get_device
if [[ "$1" == "toggle" ]]; then
rfkill toggle bluetooth
get_state
fi
if [[ $1 == "icon" ]]; then
while true; do
get_state
tail "$FILE"
sleep 1
done
fi

View file

@ -0,0 +1,46 @@
#!/usr/bin/env bash
get_icon () {
val=$(brightnessctl get)
if [ "$val" -le 3 ]; then
eww update br_icon=" "
elif [ "$val" -le 38 ]; then
eww update br_icon=" "
elif [ "$val" -le 77 ]; then
eww update br_icon=" "
elif [ "$val" -le 115 ]; then
eww update br_icon=" "
elif [ "$val" -le 153 ]; then
eww update br_icon=" "
elif [ "$val" -le 191 ]; then
eww update br_icon=" "
elif [ "$val" -le 230 ]; then
eww update br_icon=" "
else
eww update br_icon=" "
fi
}
if [[ $1 == "br" ]]; then
brightnessctl get
fi
if [[ $1 == "icon" ]]; then
while true; do
get_icon
sleep 1
done
fi
if [[ $1 == "set" ]]; then
brightnessctl set "$2"
get_icon
fi

View file

@ -0,0 +1,20 @@
#!/usr/bin/env bash
# Store the output of the command in an array, keeping only lines with '*'
readarray -t array <<< "$(eww windows | grep '^\*')"
# Remove the '*' from each element
for ((i=0; i<${#array[@]}; i++))
do
array[i]=${array[i]#'*'}
done
# Close every window except permanent ones
for element in "${array[@]}"
do
[[ "$element" != "left-bar" ]] &&
[[ "$element" != "notif-panel" ]] &&
[[ "$element" != "quick-settings-toggle" ]] &&
[[ "$element" != "playerinfo" ]] &&
eww close "$element"
done

46
config/eww/scripts/heart.sh Executable file
View file

@ -0,0 +1,46 @@
#!/usr/bin/env bash
FILE="$HOME/.config/.heart"
toggle() {
if grep -q 󰣐 "$FILE"; then
eww update heart-ts=false
echo  > "$FILE"
else
eww update heart-ts=true
echo 󰣐 >> "$FILE"
fi
}
[[ "$1" == "toggle" ]] && toggle
startup() {
(
if [[ ! -f "$FILE" ]]; then
echo 󰣐 > "$FILE"
fi
if [[ ! -f "$HOME/.config/.bluetooth" ]]; then
echo 󰂲 > "$FILE"
fi
if grep -q 󰂲 "$HOME/.config/.bluetooth"; then
rfkill block bluetooth
fi
"$HYPR_PATH"/osk-toggle.sh getState &
"$EWW_PATH"/on-release.sh &
"$EWW_PATH"/music.sh accents &
input-emulator start mouse -n &
if grep -q 󰣐 "$FILE"; then
sleep 0.9 &&
eww update heart-ts=true
fi
) &
tail -f "$FILE"
}
[[ "$1" == "startup" ]] && startup

30
config/eww/scripts/mic.sh Executable file
View file

@ -0,0 +1,30 @@
#!/usr/bin/env bash
SOURCE="@DEFAULT_SOURCE@"
is_muted () {
pactl get-source-mute $SOURCE | awk '{print $2}'
}
get_icon () {
if [[ $(is_muted) == "yes" ]]; then
echo " 󰍭"
else
echo " 󰍬"
fi
}
if [[ $1 == "icon" ]]; then
while true; do
sleep 0.01
get_icon
done
fi
if [[ $1 == "muted" ]]; then
is_muted
fi
if [[ $1 == "toggle-muted" ]]; then
swayosd --input-volume mute-toggle
fi

87
config/eww/scripts/music.sh Executable file
View file

@ -0,0 +1,87 @@
#!/usr/bin/env bash
loop() {
loop_status=$(playerctl -p Spot loop)
case $loop_status in
"None" )
playerctl -p Spot loop Playlist
eww update repeat_icon="󰑖"
;;
"Track" )
playerctl -p Spot loop None
eww update repeat_icon="󰑗"
;;
"Playlist" )
playerctl -p Spot loop Track
eww update repeat_icon="󰑘"
;;
* )
echo "Unknown loop status."
;;
esac
}
loop_status() {
loop_status=$(playerctl -p Spot loop)
case $loop_status in
"None" )
eww update repeat_icon="󰑗"
;;
"Track" )
eww update repeat_icon="󰑘"
;;
"Playlist" )
eww update repeat_icon="󰑖"
;;
* )
echo "Unknown loop status."
;;
esac
}
get_length() {
if [[ $(eww get get_pos) == "true" ]]; then
eww update song_pos="$(playerctl -p Spot position)"
fi
eww update song_length="$(echo "$(playerctl -p Spot metadata mpris:length)/1000000" | bc -l)"
}
get_accents() {
accents="$(coloryou /tmp/cover.jpg | sed 's/,//g' | sed 's/}//' | sed 's/'\''//g')"
music_accent=$(echo "$accents" | awk '{ print $2 }')
eww update music_accent="$music_accent"
button_accent=$(echo "$accents" | awk '{ print $4 }')
eww update button_accent="$button_accent"
button_text=$(echo "$accents" | awk '{ print $6 }')
eww update button_text="$button_text"
}
get_cover() {
existing_file="/tmp/cover.jpg"
new_image_url=$(playerctl -p Spot metadata mpris:artUrl)
existing_hash=$(md5sum "$existing_file" | awk '{print $1}')
# Download the new image only if the hashes are different
if [[ "$(wget -qO- "$new_image_url" | md5sum | awk '{print $1}')" != "$existing_hash" ]]; then
wget -qO "$existing_file" "$new_image_url"
get_accents
fi
if [[ -s "/tmp/cover.jpg" ]]; then
eww update showplayer=true
echo "/tmp/cover.jpg"
else
eww update showplayer=false
echo "randomfile"
fi
}
[[ "$1" == "accents" ]] && get_accents
[[ "$1" == "loop" ]] && loop
[[ "$1" == "loop_status" ]] && loop_status
[[ "$1" == "length" ]] && get_length
[[ "$1" == "cover" ]] && get_cover

53
config/eww/scripts/network.sh Executable file
View file

@ -0,0 +1,53 @@
#!/usr/bin/env bash
get_ssid() {
if nmcli -t -f NAME c show --active | grep -v lo; then
true
else
echo "Disconnected"
fi
}
get_state() {
if [[ "$(rfkill list | grep -A 1 LAN | grep -o no)" == "no" ]]; then
eww update network_icon=" 󰖩 "
else
eww update network_icon=" 󰖪 "
fi
}
[[ "$1" == "ssid" ]] && get_ssid
if [[ "$1" == "toggle" ]]; then
rfkill toggle wlan
get_state
fi
if [[ $1 == "icon" ]]; then
while true; do
get_state
sleep 1
done
fi
radio_status () {
radio_status=$(nmcli radio wifi)
if [[ $radio_status == "enabled" ]]; then
echo "on"
else
echo "off"
fi
}
if [[ $1 == "radio-status" ]]; then
radio_status
fi
if [[ $1 == "toggle-radio" ]]; then
stat=$(radio_status)
if [[ $stat == "on" ]]; then
nmcli radio wifi off
else
nmcli radio wifi on
fi
fi

View file

@ -0,0 +1,29 @@
#!/usr/bin/env bash
on() {
# open notif panel
swaync-client -op
# open closers to close when outside control center
eww open closer-notif1
eww open closer-notif2
eww open closer-notif3
eww open closer-notif4
eww close notif-panel; eww open notif-panel &&
eww update notif-panel-state=true
}
off() {
swaync-client -cp
eww update notif-panel-state=false
eww close closer-notif1
eww close closer-notif2
eww close closer-notif3
eww close closer-notif4
}
[[ "$1" == "on" ]] && on
[[ "$1" == "off" ]] && off

30
config/eww/scripts/notif.sh Executable file
View file

@ -0,0 +1,30 @@
#!/usr/bin/env bash
state () {
if [[ $(hyprctl layers | grep swaync-control-center) == "" ]]; then
if [[ $(eww get notif-panel-state) == "true" ]]; then
eww update notif-panel-state=false
fi
fi
}
icon () {
COUNT=$(swaync-client -c)
if [[ $(swaync-client -D) == "true" ]]; then
echo " 󱏨"
elif [[ $COUNT == "0" ]]; then
echo "$COUNT 󰂜"
else
echo "$COUNT 󰂚"
fi
state
}
if [[ $1 == "icon" ]]; then
while true; do
sleep 0.01
icon
done
fi

View file

@ -0,0 +1,22 @@
#!/usr/bin/env bash
FILE="$HOME/.config/.on-release"
function run() {
echo "can_run" > "$FILE"
}
while IFS='$\n' read -r line; do
if [[ $(echo "$line" | grep TOUCH_UP) != "" ]]; then
run
if [[ $(echo "$line" | grep '1 (1)') != "" ]]; then
eww update cancel_touch=false
fi
elif [[ $(echo "$line" | grep release) != "" ]]; then
run
elif [[ $(echo "$line" | grep 'TOUCH_DOWN.*1 (1)') != "" ]]; then
eww update cancel_touch=true
else
echo "other" > "$FILE"
fi
done < <(stdbuf -oL libinput debug-events)

7
config/eww/scripts/open.sh Executable file
View file

@ -0,0 +1,7 @@
#!/usr/bin/env bash
eww open closer &&
WINDOW="$1"
eww open "$WINDOW"-reveal
eww update "$WINDOW"-visible=true

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